about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--html/000organization.cc.html8
-rw-r--r--html/001help.cc.html8
-rw-r--r--html/002test.cc.html10
-rw-r--r--html/003trace.cc.html13
-rw-r--r--html/003trace.test.cc.html8
-rw-r--r--html/010vm.cc.html13
-rw-r--r--html/011load.cc.html19
-rw-r--r--html/012transform.cc.html10
-rw-r--r--html/013literal_string.cc.html146
-rw-r--r--html/014literal_noninteger.cc.html8
-rw-r--r--html/014types.cc.html10
-rw-r--r--html/020run.cc.html45
-rw-r--r--html/021arithmetic.cc.html8
-rw-r--r--html/022boolean.cc.html8
-rw-r--r--html/023jump.cc.html10
-rw-r--r--html/024compare.cc.html8
-rw-r--r--html/025trace.cc.html12
-rw-r--r--html/026assert.cc.html8
-rw-r--r--html/027debug.cc.html12
-rw-r--r--html/030container.cc.html49
-rw-r--r--html/031address.cc.html12
-rw-r--r--html/032array.cc.html16
-rw-r--r--html/033length.cc.html8
-rw-r--r--html/034exclusive_container.cc.html29
-rw-r--r--html/035call.cc.html10
-rw-r--r--html/036call_ingredient.cc.html10
-rw-r--r--html/037call_reply.cc.html36
-rw-r--r--html/038scheduler.cc.html13
-rw-r--r--html/039wait.cc.html10
-rw-r--r--html/040brace.cc.html22
-rw-r--r--html/041name.cc.html25
-rw-r--r--html/042new.cc.html38
-rw-r--r--html/043space.cc.html10
-rw-r--r--html/044space_surround.cc.html10
-rw-r--r--html/045closure_name.cc.html24
-rw-r--r--html/046tangle.cc.html10
-rw-r--r--html/047jump_label.cc.html12
-rw-r--r--html/048call_variable.cc.html10
-rw-r--r--html/049continuation.cc.html10
-rw-r--r--html/050scenario.cc.html54
-rw-r--r--html/051scenario_test.mu.html6
-rw-r--r--html/060string.mu.html580
-rw-r--r--html/061channel.mu.html50
-rw-r--r--html/062array.mu.html16
-rw-r--r--html/063list.mu.html10
-rw-r--r--html/064random.cc.html8
-rw-r--r--html/065duplex_list.mu.html407
-rw-r--r--html/066stream.mu.html79
-rw-r--r--html/070display.cc.html109
-rw-r--r--html/071print.mu.html143
-rw-r--r--html/072scenario_screen.cc.html25
-rw-r--r--html/073scenario_screen_test.mu.html6
-rw-r--r--html/074keyboard.mu.html114
-rw-r--r--html/075scenario_console.cc.html258
-rw-r--r--html/075scenario_keyboard.cc.html10
-rw-r--r--html/076scenario_console_test.mu.html59
-rw-r--r--html/076scenario_keyboard_test.mu.html6
-rw-r--r--html/077mouse.cc.html10
-rw-r--r--html/077trace_browser.cc.html10
-rw-r--r--html/078run_interactive.cc.html10
-rw-r--r--html/080trace_browser.cc.html10
-rw-r--r--html/081run_interactive.cc.html10
-rw-r--r--html/999spaces.cc.html8
-rw-r--r--html/callcc.mu.html8
-rw-r--r--html/channel.mu.html12
-rw-r--r--html/chessboard.mu.html69
-rw-r--r--html/console.mu.html50
-rw-r--r--html/counters.mu.html16
-rw-r--r--html/display.mu.html28
-rw-r--r--html/edit.mu.html527
-rw-r--r--html/factorial.mu.html10
-rw-r--r--html/fork.mu.html10
-rw-r--r--html/keyboard.mu.html10
-rw-r--r--html/mouse.mu.html8
-rw-r--r--html/repl.mu.html317
-rw-r--r--html/screen.mu.html24
-rw-r--r--html/tangle.mu.html10
-rw-r--r--html/x.mu.html6
-rwxr-xr-xupdate_html6
79 files changed, 3011 insertions, 826 deletions
diff --git a/html/000organization.cc.html b/html/000organization.cc.html
index c64fef78..641dae8c 100644
--- a/html/000organization.cc.html
+++ b/html/000organization.cc.html
@@ -12,12 +12,12 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .Identifier { color: #804000; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .PreProc { color: #c000c0; }
-.Delimiter { color: #c000c0; }
+.Delimiter { color: #a04060; }
 -->
 </style>
 
diff --git a/html/001help.cc.html b/html/001help.cc.html
index bed37ea9..052fd061 100644
--- a/html/001help.cc.html
+++ b/html/001help.cc.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .SalientComment { color: #00ffff; }
 .Identifier { color: #804000; }
 .PreProc { color: #c000c0; }
diff --git a/html/002test.cc.html b/html/002test.cc.html
index 6b2f883a..65b63a5a 100644
--- a/html/002test.cc.html
+++ b/html/002test.cc.html
@@ -12,13 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .PreProc { color: #c000c0; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
diff --git a/html/003trace.cc.html b/html/003trace.cc.html
index 12d04729..b0fd9266 100644
--- a/html/003trace.cc.html
+++ b/html/003trace.cc.html
@@ -12,13 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .PreProc { color: #c000c0; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
@@ -203,6 +203,7 @@ struct die <span class="Delimiter">{};</span>
 <span class="Delimiter">:(before &quot;End Tracing&quot;)</span>
 ostream&amp; operator&lt;&lt;<span class="Delimiter">(</span>ostream&amp; os<span class="Delimiter">,</span> unused die<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   if <span class="Delimiter">(</span>Hide_warnings<span class="Delimiter">)</span> <span class="Identifier">return</span> os<span class="Delimiter">;</span>
+  tb_shutdown<span class="Delimiter">();</span>
   os &lt;&lt; <span class="Constant">&quot;dying&quot;</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> Trace_stream<span class="Delimiter">-&gt;</span>newline<span class="Delimiter">();</span>
   exit<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
@@ -382,6 +383,8 @@ using std::ostringstream<span class="Delimiter">;</span>
 using std::ifstream<span class="Delimiter">;</span>
 using std::ofstream<span class="Delimiter">;</span>
 
+<span class="PreProc">#include</span><span class="Constant">&quot;termbox/termbox.h&quot;</span>
+
 <span class="PreProc">#define unused  __attribute__((unused))</span>
 
 <span class="Delimiter">:(before &quot;End Globals&quot;)</span>
diff --git a/html/003trace.test.cc.html b/html/003trace.test.cc.html
index 2bb648f5..91391d7b 100644
--- a/html/003trace.test.cc.html
+++ b/html/003trace.test.cc.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .cSpecial { color: #008000; }
-.Delimiter { color: #c000c0; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
+.Delimiter { color: #a04060; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
diff --git a/html/010vm.cc.html b/html/010vm.cc.html
index 97703c55..5f40619e 100644
--- a/html/010vm.cc.html
+++ b/html/010vm.cc.html
@@ -12,14 +12,14 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .PreProc { color: #c000c0; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .SalientComment { color: #00ffff; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
@@ -230,12 +230,14 @@ reagent::reagent<span class="Delimiter">(</span>string s<span class="Delimiter">
     properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">&quot;dummy&quot;</span><span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
+
 reagent::reagent<span class="Delimiter">()</span> :value<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> initialized<span class="Delimiter">(</span><span class="Constant">false</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
   <span class="Comment">// The first property is special, so ensure we always have it.</span>
   <span class="Comment">// Other properties can be pushed back, but the first must always be</span>
   <span class="Comment">// assigned to.</span>
   properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair&lt;string<span class="Delimiter">,</span> vector&lt;string&gt; &gt;<span class="Delimiter">(</span><span class="Constant">&quot;&quot;</span><span class="Delimiter">,</span> vector&lt;string&gt;<span class="Delimiter">()));</span>
 <span class="Delimiter">}</span>
+
 string reagent::to_string<span class="Delimiter">()</span> const <span class="Delimiter">{</span>
   ostringstream out<span class="Delimiter">;</span>
   out &lt;&lt; <span class="Constant">&quot;{name: </span><span class="cSpecial">\&quot;</span><span class="Constant">&quot;</span> &lt;&lt; name &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\&quot;</span><span class="Constant">&quot;</span><span class="Delimiter">;</span>
@@ -252,6 +254,7 @@ string reagent::to_string<span class="Delimiter">()</span> const <span class="De
     <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
   out &lt;&lt; <span class="Constant">&quot;}&quot;</span><span class="Delimiter">;</span>
+<span class="CommentedCode">//?   if (properties.at(0).second.empty()) cerr &lt;&lt; out.str(); //? 1</span>
   <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
 <span class="Delimiter">}</span>
 
diff --git a/html/011load.cc.html b/html/011load.cc.html
index 547e81ce..fe74ef6e 100644
--- a/html/011load.cc.html
+++ b/html/011load.cc.html
@@ -12,15 +12,15 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
@@ -51,14 +51,17 @@ vector&lt;recipe_number&gt; load<span class="Delimiter">(</span>string form<span
 <span class="Delimiter">}</span>
 
 vector&lt;recipe_number&gt; load<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  in &gt;&gt; std::noskipws<span class="Delimiter">;</span>
   vector&lt;recipe_number&gt; result<span class="Delimiter">;</span>
   while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;===\n&quot;; //? 1</span>
     skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
     string command = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     <span class="Comment">// Command Handlers</span>
     if <span class="Delimiter">(</span>command == <span class="Constant">&quot;recipe&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
       string recipe_name = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;recipe: &quot; &lt;&lt; recipe_name &lt;&lt; '\n'; //? 1</span>
       if <span class="Delimiter">(</span>recipe_name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span>
         raise &lt;&lt; <span class="Constant">&quot;empty recipe name</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">;</span>
       if <span class="Delimiter">(</span>Recipe_number<span class="Delimiter">.</span>find<span class="Delimiter">(</span>recipe_name<span class="Delimiter">)</span> == Recipe_number<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
@@ -94,12 +97,14 @@ recipe slurp_recipe<span class="Delimiter">(</span>istream&amp; in<span class="D
   instruction curr<span class="Delimiter">;</span>
   while <span class="Delimiter">(</span>next_instruction<span class="Delimiter">(</span>in<span class="Delimiter">,</span> &amp;curr<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     <span class="Comment">// End Rewrite Instruction(curr)</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;instruction: &quot; &lt;&lt; curr.to_string() &lt;&lt; '\n'; //? 2</span>
     result<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>curr<span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
   <span class="Identifier">return</span> result<span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
 bool next_instruction<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">,</span> instruction* curr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  in &gt;&gt; std::noskipws<span class="Delimiter">;</span>
   curr<span class="Delimiter">-&gt;</span>clear<span class="Delimiter">();</span>
   if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
 <span class="CommentedCode">//?   show_rest_of_stream(in); //? 1</span>
@@ -113,6 +118,7 @@ bool next_instruction<span class="Delimiter">(</span>istream&amp; in<span class=
     skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
 <span class="CommentedCode">//?     show_rest_of_stream(in); //? 1</span>
     string word = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;AAA: &quot; &lt;&lt; word &lt;&lt; '\n'; //? 1</span>
     words<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>word<span class="Delimiter">);</span>
     skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
@@ -136,6 +142,7 @@ bool next_instruction<span class="Delimiter">(</span>istream&amp; in<span class=
     for <span class="Delimiter">(;</span> *p != <span class="Constant">&quot;&lt;-&quot;</span><span class="Delimiter">;</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       if <span class="Delimiter">(</span>*p == <span class="Constant">&quot;,&quot;</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
       curr<span class="Delimiter">-&gt;</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span>*p<span class="Delimiter">));</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;product: &quot; &lt;&lt; curr-&gt;products.back().to_string() &lt;&lt; '\n'; //? 1</span>
     <span class="Delimiter">}</span>
     ++p<span class="Delimiter">;</span>  <span class="Comment">// skip &lt;-</span>
   <span class="Delimiter">}</span>
@@ -153,6 +160,7 @@ bool next_instruction<span class="Delimiter">(</span>istream&amp; in<span class=
   for <span class="Delimiter">(;</span> p != words<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     if <span class="Delimiter">(</span>*p == <span class="Constant">&quot;,&quot;</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
     curr<span class="Delimiter">-&gt;</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span>*p<span class="Delimiter">));</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;ingredient: &quot; &lt;&lt; curr-&gt;ingredients.back().to_string() &lt;&lt; '\n'; //? 1</span>
   <span class="Delimiter">}</span>
 
   trace<span class="Delimiter">(</span><span class="Constant">&quot;parse&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;instruction: &quot;</span> &lt;&lt; curr<span class="Delimiter">-&gt;</span>name<span class="Delimiter">;</span>
@@ -172,6 +180,7 @@ string next_word<span class="Delimiter">(</span>istream&amp; in<span class="Deli
   slurp_word<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">);</span>
   skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   skip_comment<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; '^' &lt;&lt; out.str() &lt;&lt; &quot;$\n&quot;; //? 1</span>
   <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
 <span class="Delimiter">}</span>
 
diff --git a/html/012transform.cc.html b/html/012transform.cc.html
index 425e4efe..a03c39c2 100644
--- a/html/012transform.cc.html
+++ b/html/012transform.cc.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
-.CommentedCode { color: #6c6c6c; }
+* { font-size: 1.05em; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
diff --git a/html/013literal_string.cc.html b/html/013literal_string.cc.html
index c81057d7..fae6a0f2 100644
--- a/html/013literal_string.cc.html
+++ b/html/013literal_string.cc.html
@@ -12,15 +12,15 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
 -->
 </style>
 
@@ -44,13 +44,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 recipe main [
   <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy [abc def]  <span class="Comment"># copy can't really take a string</span>
 ]
-<span class="traceContains">+parse:   ingredient: {name: &quot;abc def&quot;, properties: [&quot;abc def&quot;: &quot;literal-string&quot;]}</span>
+<span class="traceContains">+parse:   ingredient: {name: &quot;abc def&quot;, properties: [_: &quot;literal-string&quot;]}</span>
 
 <span class="Delimiter">:(scenario string_literal_with_colons)</span>
 recipe main [
   <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy [abc:def/ghi]
 ]
-<span class="traceContains">+parse:   ingredient: {name: &quot;abc:def/ghi&quot;, properties: [&quot;abc:def/ghi&quot;: &quot;literal-string&quot;]}</span>
+<span class="traceContains">+parse:   ingredient: {name: &quot;abc:def/ghi&quot;, properties: [_: &quot;literal-string&quot;]}</span>
 
 <span class="Delimiter">:(before &quot;End Mu Types Initialization&quot;)</span>
 Type_number[<span class="Constant">&quot;literal-string&quot;</span>] = <span class="Constant">0</span><span class="Delimiter">;</span>
@@ -60,20 +60,51 @@ Type_number[<span class="Constant">&quot;literal-string&quot;</span>] = <span cl
     string result = slurp_quoted<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     skip_comment<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; '^' &lt;&lt; result &lt;&lt; &quot;$\n&quot;; //? 1</span>
     <span class="Identifier">return</span> result<span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(code)</span>
 string slurp_quoted<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  assert<span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">());</span>
-  assert<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span>
   ostringstream out<span class="Delimiter">;</span>
-  int brace_depth = <span class="Constant">0</span><span class="Delimiter">;</span>
+  assert<span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">());</span>  assert<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span>  out &lt;&lt; static_cast&lt;char&gt;<span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span>  <span class="Comment">// slurp the '['</span>
+  if <span class="Delimiter">(</span>code_string<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">))</span>
+    slurp_quoted_comment_aware<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">);</span>
+  else
+    slurp_quoted_comment_oblivious<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">);</span>
+  <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">// A string is a code string if it contains a newline before any non-whitespace</span>
+<span class="Comment">// todo: support comments before the newline. But that gets messy.</span>
+bool code_string<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">,</span> ostringstream&amp; out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+    char c = in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
+    if <span class="Delimiter">(</span>!isspace<span class="Delimiter">(</span>c<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+      in<span class="Delimiter">.</span>putback<span class="Delimiter">(</span>c<span class="Delimiter">);</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;code_string: &quot; &lt;&lt; out.str() &lt;&lt; '\n'; //? 1</span>
+      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
+    out &lt;&lt; c<span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>c == <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;code_string: &quot; &lt;&lt; out.str() &lt;&lt; '\n'; //? 1</span>
+      <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
+  <span class="Delimiter">}</span>
+  <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">// Read a regular string. Regular strings can only contain other regular</span>
+<span class="Comment">// strings.</span>
+void slurp_quoted_comment_oblivious<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">,</span> ostringstream&amp; out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;comment oblivious\n&quot;; //? 1</span>
+  int brace_depth = <span class="Constant">1</span><span class="Delimiter">;</span>
   while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
     char c = in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; '%' &lt;&lt; (int)c &lt;&lt; ' ' &lt;&lt; brace_depth &lt;&lt; &quot;: &quot; &lt;&lt; out.str() &lt;&lt; &quot;%$\n&quot;; //? 1</span>
 <span class="CommentedCode">//?     cout &lt;&lt; (int)c &lt;&lt; &quot;: &quot; &lt;&lt; brace_depth &lt;&lt; '\n'; //? 2</span>
     if <span class="Delimiter">(</span>c == <span class="cSpecial">'\\'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-      out &lt;&lt; <span class="Delimiter">(</span>char<span class="Delimiter">)</span>in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
+      out &lt;&lt; static_cast&lt;char&gt;<span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span>
       <span class="Identifier">continue</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
     out &lt;&lt; c<span class="Delimiter">;</span>
@@ -84,9 +115,36 @@ string slurp_quoted<span class="Delimiter">(</span>istream&amp; in<span class="D
   <span class="Delimiter">}</span>
   if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> &amp;&amp; brace_depth &gt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
     raise &lt;&lt; <span class="Constant">&quot;unbalanced '['</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">;</span>
-    <span class="Identifier">return</span> <span class="Constant">&quot;&quot;</span><span class="Delimiter">;</span>
+    out<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
   <span class="Delimiter">}</span>
-  <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">// Read a code string. Code strings can contain either code or regular strings.</span>
+void slurp_quoted_comment_aware<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">,</span> ostringstream&amp; out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;comment aware\n&quot;; //? 1</span>
+  char c<span class="Delimiter">;</span>
+  while <span class="Delimiter">(</span>in &gt;&gt; c<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; '^' &lt;&lt; (int)c &lt;&lt; &quot;: &quot; &lt;&lt; out.str() &lt;&lt; &quot;$\n&quot;; //? 1</span>
+    if <span class="Delimiter">(</span>c == <span class="cSpecial">'\\'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      out &lt;&lt; static_cast&lt;char&gt;<span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span>
+      <span class="Identifier">continue</span><span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
+    if <span class="Delimiter">(</span>c == <span class="Constant">'#'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      out &lt;&lt; c<span class="Delimiter">;</span>
+      while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> &amp;&amp; in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> out &lt;&lt; static_cast&lt;char&gt;<span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span>
+      <span class="Identifier">continue</span><span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
+    if <span class="Delimiter">(</span>c == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      in<span class="Delimiter">.</span>putback<span class="Delimiter">(</span>c<span class="Delimiter">);</span>
+      <span class="Comment">// recurse</span>
+      out &lt;&lt; slurp_quoted<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+      <span class="Identifier">continue</span><span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
+    out &lt;&lt; c<span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>c == <span class="Constant">']'</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  raise &lt;&lt; <span class="Constant">&quot;unbalanced '['</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">;</span>
+  out<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
 <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(after &quot;reagent::reagent(string s)&quot;)</span>
@@ -95,7 +153,7 @@ string slurp_quoted<span class="Delimiter">(</span>istream&amp; in<span class="D
     assert<span class="Delimiter">(</span>*s<span class="Delimiter">.</span>rbegin<span class="Delimiter">()</span> == <span class="Constant">']'</span><span class="Delimiter">);</span>
     <span class="Comment">// delete [] delimiters</span>
     s<span class="Delimiter">.</span>erase<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span>
-    s<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>s<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">,</span> SIZE<span class="Delimiter">(</span>s<span class="Delimiter">));</span>
+    s<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>s<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">);</span>
     name = s<span class="Delimiter">;</span>
     types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
     properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair&lt;string<span class="Delimiter">,</span> vector&lt;string&gt; &gt;<span class="Delimiter">(</span>name<span class="Delimiter">,</span> vector&lt;string&gt;<span class="Delimiter">()));</span>
@@ -103,27 +161,81 @@ string slurp_quoted<span class="Delimiter">(</span>istream&amp; in<span class="D
     <span class="Identifier">return</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
 
+<span class="Comment">//: Two tweaks to printing literal strings compared to other reagents:</span>
+<span class="Comment">//:   a) Don't print the string twice in the representation, just put '_' in</span>
+<span class="Comment">//:   the property list.</span>
+<span class="Comment">//:   b) Escape newlines in the string to make it more friendly to trace().</span>
+
+<span class="Delimiter">:(after &quot;string reagent::to_string()&quot;)</span>
+  if <span class="Delimiter">(</span>!properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> &amp;&amp; properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">&quot;literal-string&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    <span class="Identifier">return</span> emit_literal_string<span class="Delimiter">(</span>name<span class="Delimiter">);</span>
+  <span class="Delimiter">}</span>
+
+<span class="Delimiter">:(code)</span>
+string emit_literal_string<span class="Delimiter">(</span>string name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  size_t pos = <span class="Constant">0</span><span class="Delimiter">;</span>
+  while <span class="Delimiter">(</span>pos != string::npos<span class="Delimiter">)</span>
+    pos = replace<span class="Delimiter">(</span>name<span class="Delimiter">,</span> <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">,</span> <span class="Constant">&quot;</span><span class="cSpecial">\\</span><span class="Constant">n&quot;</span><span class="Delimiter">,</span> pos<span class="Delimiter">);</span>
+  <span class="Identifier">return</span> <span class="Constant">&quot;{name: </span><span class="cSpecial">\&quot;</span><span class="Constant">&quot;</span>+name+<span class="Constant">&quot;</span><span class="cSpecial">\&quot;</span><span class="Constant">, properties: [_: </span><span class="cSpecial">\&quot;</span><span class="Constant">literal-string</span><span class="cSpecial">\&quot;</span><span class="Constant">]}&quot;</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+size_t replace<span class="Delimiter">(</span>string&amp; str<span class="Delimiter">,</span> const string&amp; from<span class="Delimiter">,</span> const string&amp; to<span class="Delimiter">,</span> size_t n<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  size_t result = str<span class="Delimiter">.</span>find<span class="Delimiter">(</span>from<span class="Delimiter">,</span> n<span class="Delimiter">);</span>
+  if <span class="Delimiter">(</span>result != string::npos<span class="Delimiter">)</span>
+    str<span class="Delimiter">.</span>replace<span class="Delimiter">(</span>result<span class="Delimiter">,</span> from<span class="Delimiter">.</span>length<span class="Delimiter">(),</span> to<span class="Delimiter">);</span>
+  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
 <span class="Delimiter">:(scenario string_literal_nested)</span>
 recipe main [
   <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy [abc [def]]
 ]
-<span class="traceContains">+parse:   ingredient: {name: &quot;abc [def]&quot;, properties: [&quot;abc [def]&quot;: &quot;literal-string&quot;]}</span>
+<span class="traceContains">+parse:   ingredient: {name: &quot;abc [def]&quot;, properties: [_: &quot;literal-string&quot;]}</span>
 
 <span class="Delimiter">:(scenario string_literal_escaped)</span>
 recipe main [
   <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy [abc \[def]
 ]
-<span class="traceContains">+parse:   ingredient: {name: &quot;abc [def&quot;, properties: [&quot;abc [def&quot;: &quot;literal-string&quot;]}</span>
+<span class="traceContains">+parse:   ingredient: {name: &quot;abc [def&quot;, properties: [_: &quot;literal-string&quot;]}</span>
+
+<span class="Delimiter">:(scenario string_literal_escaped_comment_aware)</span>
+recipe main [
+  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy [
+abc \\\[def]
+]
+<span class="traceContains">+parse:   ingredient: {name: &quot;\nabc \[def&quot;, properties: [_: &quot;literal-string&quot;]}</span>
 
 <span class="Delimiter">:(scenario string_literal_and_comment)</span>
 recipe main [
   <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy [abc]  <span class="Comment"># comment</span>
 ]
 <span class="traceContains">+parse: instruction: copy</span>
-<span class="traceContains">+parse:   ingredient: {name: &quot;abc&quot;, properties: [&quot;abc&quot;: &quot;literal-string&quot;]}</span>
+<span class="traceContains">+parse:   ingredient: {name: &quot;abc&quot;, properties: [_: &quot;literal-string&quot;]}</span>
 <span class="traceContains">+parse:   product: {name: &quot;1&quot;, properties: [&quot;1&quot;: &quot;address&quot;:&quot;array&quot;:&quot;character&quot;]}</span>
 <span class="Comment"># no other ingredients</span>
 $parse: <span class="Constant">3</span>
+
+<span class="Delimiter">:(scenario string_literal_escapes_newlines_in_trace)</span>
+recipe main [
+  copy [abc
+def]
+]
+<span class="traceContains">+parse:   ingredient: {name: &quot;abc\ndef&quot;, properties: [_: &quot;literal-string&quot;]}</span>
+
+<span class="Delimiter">:(scenario string_literal_can_skip_past_comments)</span>
+recipe main [
+  copy [
+    <span class="Comment"># ']' inside comment</span>
+    bar
+  ]
+]
+<span class="traceContains">+parse:   ingredient: {name: &quot;\n    # ']' inside comment\n    bar\n  &quot;, properties: [_: &quot;literal-string&quot;]}</span>
+
+<span class="Delimiter">:(scenario string_literal_empty)</span>
+recipe main [
+  copy []
+]
+<span class="traceContains">+parse:   ingredient: {name: &quot;&quot;, properties: [_: &quot;literal-string&quot;]}</span>
 </pre>
 </body>
 </html>
diff --git a/html/014literal_noninteger.cc.html b/html/014literal_noninteger.cc.html
index e49f12fc..f24ed9ac 100644
--- a/html/014literal_noninteger.cc.html
+++ b/html/014literal_noninteger.cc.html
@@ -12,12 +12,12 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
 -->
diff --git a/html/014types.cc.html b/html/014types.cc.html
index 3eac20ad..596ac7dc 100644
--- a/html/014types.cc.html
+++ b/html/014types.cc.html
@@ -12,14 +12,14 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #d0d0d0; background-color: #000000; }
 body { font-family: monospace; color: #d0d0d0; background-color: #000000; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .cSpecial { color: #008000; }
 .Identifier { color: #008080; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .SalientComment { color: #00ffff; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .traceContains { color: #008000; }
 -->
 </style>
diff --git a/html/020run.cc.html b/html/020run.cc.html
index 497766fa..c9b0fa2e 100644
--- a/html/020run.cc.html
+++ b/html/020run.cc.html
@@ -12,16 +12,16 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
 .traceAbsent { color: #c00000; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
@@ -90,11 +90,11 @@ void run<span class="Delimiter">(</span>recipe_number r<span class="Delimiter">)
 
 void run_current_routine<span class="Delimiter">()</span>
 <span class="Delimiter">{</span>  <span class="Comment">// curly on a separate line, because later layers will modify header</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;AAA 6\n&quot;; //? 2</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;AAA 6\n&quot;; //? 3</span>
   while <span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-&gt;</span>completed<span class="Delimiter">())</span>  <span class="Comment">// later layers will modify condition</span>
   <span class="Delimiter">{</span>
 <span class="CommentedCode">//?     cerr &lt;&lt; &quot;AAA 7: &quot; &lt;&lt; current_step_index() &lt;&lt; '\n'; //? 1</span>
-    <span class="Comment">// Running One Instruction.</span>
+    <span class="Comment">// Running One Instruction</span>
     if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>is_label<span class="Delimiter">)</span> <span class="Delimiter">{</span> ++current_step_index<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span>
     trace<span class="Delimiter">(</span>Initial_callstack_depth+Callstack_depth<span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">();</span>
     assert<span class="Delimiter">(</span>Memory[<span class="Constant">0</span>] == <span class="Constant">0</span><span class="Delimiter">);</span>
@@ -108,6 +108,7 @@ void run_current_routine<span class="Delimiter">()</span>
     <span class="Comment">// Instructions below will write to 'products'.</span>
     vector&lt;vector&lt;double&gt; &gt; products<span class="Delimiter">;</span>
 <span class="CommentedCode">//?     cerr &lt;&lt; &quot;AAA 8: &quot; &lt;&lt; current_instruction().operation &lt;&lt; &quot; ^&quot; &lt;&lt; Recipe[current_instruction().operation].name &lt;&lt; &quot;$\n&quot;; //? 1</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;% &quot; &lt;&lt; current_recipe_name() &lt;&lt; &quot;/&quot; &lt;&lt; current_step_index() &lt;&lt; &quot;: &quot; &lt;&lt; Memory[1013] &lt;&lt; ' ' &lt;&lt; Memory[1014] &lt;&lt; '\n'; //? 1</span>
     switch <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       <span class="Comment">// Primitive Recipe Implementations</span>
       case COPY: <span class="Delimiter">{</span>
@@ -124,9 +125,10 @@ void run_current_routine<span class="Delimiter">()</span>
     for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       write_memory<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
     <span class="Delimiter">}</span>
+    <span class="Comment">// End of Instruction</span>
     ++current_step_index<span class="Delimiter">();</span>
   <span class="Delimiter">}</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;AAA 9\n&quot;; //? 1</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;AAA 9\n&quot;; //? 2</span>
   stop_running_current_routine:<span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
@@ -198,13 +200,14 @@ load_permanently<span class="Delimiter">(</span><span class="Constant">&quot;cor
 <span class="Delimiter">:(code)</span>
 <span class="Comment">// helper for tests</span>
 void run<span class="Delimiter">(</span>string form<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;AAA 2\n&quot;; //? 1</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;AAA 2\n&quot;; //? 2</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; form &lt;&lt; '\n'; //? 1</span>
   vector&lt;recipe_number&gt; tmp = load<span class="Delimiter">(</span>form<span class="Delimiter">);</span>
   if <span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   transform_all<span class="Delimiter">();</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;AAA 3\n&quot;; //? 1</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;AAA 3\n&quot;; //? 2</span>
   run<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>front<span class="Delimiter">());</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;YYY\n&quot;; //? 1</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;YYY\n&quot;; //? 2</span>
 <span class="Delimiter">}</span>
 
 <span class="SalientComment">//:: Reading from memory, writing to memory.</span>
@@ -212,7 +215,7 @@ void run<span class="Delimiter">(</span>string form<span class="Delimiter">)</sp
 vector&lt;double&gt; read_memory<span class="Delimiter">(</span>reagent x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
 <span class="CommentedCode">//?   cout &lt;&lt; &quot;read_memory: &quot; &lt;&lt; x.to_string() &lt;&lt; '\n'; //? 2</span>
   vector&lt;double&gt; result<span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>x<span class="Delimiter">.</span>value<span class="Delimiter">);</span>
     <span class="Identifier">return</span> result<span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
@@ -228,9 +231,11 @@ vector&lt;double&gt; read_memory<span class="Delimiter">(</span>reagent x<span c
 
 void write_memory<span class="Delimiter">(</span>reagent x<span class="Delimiter">,</span> vector&lt;double&gt; data<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   if <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   long long int base = x<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>size_of<span class="Delimiter">(</span>x<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>data<span class="Delimiter">))</span>
-    raise &lt;&lt; <span class="Constant">&quot;size mismatch in storing to &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>size_mismatch<span class="Delimiter">(</span>x<span class="Delimiter">,</span> data<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+    raise &lt;&lt; current_recipe_name<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: size mismatch in storing to &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot; at &quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; die<span class="Delimiter">();</span>
+  <span class="Delimiter">}</span>
   for <span class="Delimiter">(</span>long long int offset = <span class="Constant">0</span><span class="Delimiter">;</span> offset &lt; SIZE<span class="Delimiter">(</span>data<span class="Delimiter">);</span> ++offset<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">&quot;mem&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;storing &quot;</span> &lt;&lt; data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; in location &quot;</span> &lt;&lt; base+offset<span class="Delimiter">;</span>
     Memory[base+offset] = data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset<span class="Delimiter">);</span>
@@ -246,11 +251,15 @@ long long int size_of<span class="Delimiter">(</span>const vector&lt;type_number
   <span class="Identifier">return</span> <span class="Constant">1</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
+bool size_mismatch<span class="Delimiter">(</span>const reagent&amp; x<span class="Delimiter">,</span> const vector&lt;double&gt;&amp; data<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>x<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>data<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
 bool is_dummy<span class="Delimiter">(</span>const reagent&amp; x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   <span class="Identifier">return</span> x<span class="Delimiter">.</span>name == <span class="Constant">&quot;_&quot;</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
-bool isa_literal<span class="Delimiter">(</span>const reagent&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+bool is_literal<span class="Delimiter">(</span>const reagent&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">)</span> == <span class="Constant">1</span> &amp;&amp; r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
@@ -269,6 +278,12 @@ recipe main [
   _<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>:literal
 ]
 <span class="traceContains">+run: _ &lt;- copy 0:literal</span>
+
+<span class="Delimiter">:(scenario run_literal)</span>
+recipe main [
+  <span class="Constant">0</span>:literal/screen<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>:literal
+]
+<span class="traceAbsent">-mem: storing 0 in location 0</span>
 </pre>
 </body>
 </html>
diff --git a/html/021arithmetic.cc.html b/html/021arithmetic.cc.html
index 69c07668..479a6f4c 100644
--- a/html/021arithmetic.cc.html
+++ b/html/021arithmetic.cc.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
 -->
diff --git a/html/022boolean.cc.html b/html/022boolean.cc.html
index 836117eb..c5b5bcff 100644
--- a/html/022boolean.cc.html
+++ b/html/022boolean.cc.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
 -->
diff --git a/html/023jump.cc.html b/html/023jump.cc.html
index 3f66359a..9a8206a8 100644
--- a/html/023jump.cc.html
+++ b/html/023jump.cc.html
@@ -12,14 +12,14 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .traceAbsent { color: #c00000; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
diff --git a/html/024compare.cc.html b/html/024compare.cc.html
index 86581fda..fb97b2a0 100644
--- a/html/024compare.cc.html
+++ b/html/024compare.cc.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
 -->
diff --git a/html/025trace.cc.html b/html/025trace.cc.html
index 5af8da24..11c3c6bd 100644
--- a/html/025trace.cc.html
+++ b/html/025trace.cc.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Identifier { color: #804000; }
 -->
 </style>
@@ -43,9 +43,9 @@ TRACE<span class="Delimiter">,</span>
 Recipe_number[<span class="Constant">&quot;trace&quot;</span>] = TRACE<span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
 case TRACE: <span class="Delimiter">{</span>
-  assert<span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
+  assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
   string label = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">;</span>
-  assert<span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
+  assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
   string message = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">;</span>
   trace<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">,</span> label<span class="Delimiter">)</span> &lt;&lt; message<span class="Delimiter">;</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
diff --git a/html/026assert.cc.html b/html/026assert.cc.html
index 0f86b9bf..685cf2e4 100644
--- a/html/026assert.cc.html
+++ b/html/026assert.cc.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
 -->
@@ -46,7 +46,7 @@ case ASSERT: <span class="Delimiter">{</span>
   assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> == <span class="Constant">2</span><span class="Delimiter">);</span>
   assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
   if <span class="Delimiter">(</span>!ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
-    assert<span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
+    assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
     raise &lt;&lt; current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; die<span class="Delimiter">();</span>
   <span class="Delimiter">}</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
diff --git a/html/027debug.cc.html b/html/027debug.cc.html
index 5dbf28a9..994729c2 100644
--- a/html/027debug.cc.html
+++ b/html/027debug.cc.html
@@ -12,12 +12,12 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+* { font-size: 1.05em; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
@@ -38,7 +38,7 @@ Recipe_number[<span class="Constant">&quot;$print&quot;</span>] = _PRINT<span cl
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
 case _PRINT: <span class="Delimiter">{</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    if <span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
       trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;$print: &quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">;</span>
       cout &lt;&lt; current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
diff --git a/html/030container.cc.html b/html/030container.cc.html
index 851c5357..4531e5da 100644
--- a/html/030container.cc.html
+++ b/html/030container.cc.html
@@ -12,17 +12,17 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
 .traceAbsent { color: #c00000; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
@@ -143,8 +143,9 @@ case GET: <span class="Delimiter">{</span>
   reagent base = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
   long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
   type_number base_type = base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
-  assert<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>kind == container<span class="Delimiter">);</span>
-  assert<span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
+  if <span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>kind != container<span class="Delimiter">)</span>
+    raise &lt;&lt; <span class="Constant">&quot;'get' on a non-container in &quot;</span> &lt;&lt; current_recipe_name <span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; die<span class="Delimiter">();</span>
+  assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
   assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
   long long int offset = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
   long long int src = base_address<span class="Delimiter">;</span>
@@ -155,7 +156,7 @@ case GET: <span class="Delimiter">{</span>
   assert<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>kind == container<span class="Delimiter">);</span>
   assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>elements<span class="Delimiter">)</span> &gt; offset<span class="Delimiter">);</span>
   type_number src_type = Type[base_type]<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
-  trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;its type is &quot;</span> &lt;&lt; src_type<span class="Delimiter">;</span>
+  trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;its type is &quot;</span> &lt;&lt; Type[src_type]<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
   reagent tmp<span class="Delimiter">;</span>
   tmp<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>src<span class="Delimiter">);</span>
   tmp<span class="Delimiter">.</span>types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>src_type<span class="Delimiter">);</span>
@@ -191,8 +192,9 @@ case GET_ADDRESS: <span class="Delimiter">{</span>
   reagent base = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
   long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
   type_number base_type = base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
-  assert<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>kind == container<span class="Delimiter">);</span>
-  assert<span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
+  if <span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>kind != container<span class="Delimiter">)</span>
+    raise &lt;&lt; <span class="Constant">&quot;'get' on a non-container in &quot;</span> &lt;&lt; current_recipe_name <span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; die<span class="Delimiter">();</span>
+  assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
   assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
   long long int offset = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
   long long int result = base_address<span class="Delimiter">;</span>
@@ -405,6 +407,33 @@ void check_container_field_types<span class="Delimiter">()</span> <span class="D
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
+<span class="SalientComment">//:: Construct types out of their constituent fields. Doesn't currently do</span>
+<span class="SalientComment">//:: type-checking but *does* match sizes.</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
+MERGE<span class="Delimiter">,</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
+Recipe_number[<span class="Constant">&quot;merge&quot;</span>] = MERGE<span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
+case MERGE: <span class="Delimiter">{</span>
+  products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+    for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j &lt; SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> ++j<span class="Delimiter">)</span>
+      products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">));</span>
+  <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario merge)</span>
+container foo [
+  x:number
+  y:number
+]
+
+recipe main [
+  <span class="Constant">1</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">3</span>:literal<span class="Delimiter">,</span> <span class="Constant">4</span>:literal
+]
+<span class="traceContains">+mem: storing 3 in location 1</span>
+<span class="traceContains">+mem: storing 4 in location 2</span>
+
 <span class="SalientComment">//:: helpers</span>
 
 <span class="Delimiter">:(code)</span>
diff --git a/html/031address.cc.html b/html/031address.cc.html
index 88e8c294..04ee869d 100644
--- a/html/031address.cc.html
+++ b/html/031address.cc.html
@@ -12,15 +12,15 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
@@ -61,7 +61,7 @@ x = canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
 
 <span class="Delimiter">:(code)</span>
 reagent canonize<span class="Delimiter">(</span>reagent x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  if <span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> x<span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> x<span class="Delimiter">;</span>
 <span class="CommentedCode">//?   cout &lt;&lt; &quot;canonize\n&quot;; //? 1</span>
   reagent r = x<span class="Delimiter">;</span>
 <span class="CommentedCode">//?   cout &lt;&lt; x.to_string() &lt;&lt; &quot; =&gt; &quot; &lt;&lt; r.to_string() &lt;&lt; '\n'; //? 1</span>
diff --git a/html/032array.cc.html b/html/032array.cc.html
index f0850f2f..27cef879 100644
--- a/html/032array.cc.html
+++ b/html/032array.cc.html
@@ -12,16 +12,16 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
@@ -73,8 +73,8 @@ recipe main [
 <span class="traceContains">+mem: storing 16 in location 9</span>
 
 <span class="Comment">//: disable the size mismatch check since the destination array need not be initialized</span>
-<span class="Delimiter">:(replace &quot;if (size_of(x) != SIZE(data))&quot; following &quot;void write_memory(reagent x, vector&lt;double&gt; data)&quot;)</span>
-if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != Type_number[<span class="Constant">&quot;array&quot;</span>] &amp;&amp; size_of<span class="Delimiter">(</span>x<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>data<span class="Delimiter">))</span>
+<span class="Delimiter">:(after &quot;bool size_mismatch(const reagent&amp; x, const vector&lt;double&gt;&amp; data)&quot;)</span>
+if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == Type_number[<span class="Constant">&quot;array&quot;</span>]<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
 <span class="Delimiter">:(after &quot;long long int size_of(const reagent&amp; r)&quot;)</span>
   if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == Type_number[<span class="Constant">&quot;array&quot;</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">)</span> &gt; <span class="Constant">1</span><span class="Delimiter">);</span>
@@ -124,7 +124,7 @@ case INDEX: <span class="Delimiter">{</span>
 <span class="CommentedCode">//?   trace(Primitive_recipe_depth, &quot;run&quot;) &lt;&lt; &quot;size of elements: &quot; &lt;&lt; size_of(element_type); //? 1</span>
   long long int src = base_address + <span class="Constant">1</span> + offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>*size_of<span class="Delimiter">(</span>element_type<span class="Delimiter">);</span>
   trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;address to copy is &quot;</span> &lt;&lt; src<span class="Delimiter">;</span>
-  trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;its type is &quot;</span> &lt;&lt; element_type<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+  trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;its type is &quot;</span> &lt;&lt; Type[element_type<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
   reagent tmp<span class="Delimiter">;</span>
   tmp<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>src<span class="Delimiter">);</span>
   copy<span class="Delimiter">(</span>element_type<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> element_type<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>types<span class="Delimiter">,</span> tmp<span class="Delimiter">.</span>types<span class="Delimiter">.</span>begin<span class="Delimiter">()));</span>
diff --git a/html/033length.cc.html b/html/033length.cc.html
index e0b21238..033a29f2 100644
--- a/html/033length.cc.html
+++ b/html/033length.cc.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #d0d0d0; background-color: #000000; }
 body { font-family: monospace; color: #d0d0d0; background-color: #000000; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #008080; }
 .traceContains { color: #008000; }
diff --git a/html/034exclusive_container.cc.html b/html/034exclusive_container.cc.html
index 5dc88c30..cc6a0316 100644
--- a/html/034exclusive_container.cc.html
+++ b/html/034exclusive_container.cc.html
@@ -12,14 +12,14 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
@@ -129,7 +129,7 @@ case MAYBE_CONVERT: <span class="Delimiter">{</span>
   long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
   type_number base_type = base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
   assert<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>kind == exclusive_container<span class="Delimiter">);</span>
-  assert<span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
+  assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
   long long int tag = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>value<span class="Delimiter">;</span>
   long long int result<span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>tag == static_cast&lt;long long int&gt;<span class="Delimiter">(</span>Memory[base_address]<span class="Delimiter">))</span> <span class="Delimiter">{</span>
@@ -160,6 +160,23 @@ exclusive-container foo [
 else if <span class="Delimiter">(</span>command == <span class="Constant">&quot;exclusive-container&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
   insert_container<span class="Delimiter">(</span>command<span class="Delimiter">,</span> exclusive_container<span class="Delimiter">,</span> in<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
+
+<span class="SalientComment">//:: To construct exclusive containers out of variant types, use 'merge'.</span>
+<span class="Delimiter">:(scenario lift_to_exclusive_container)</span>
+exclusive-container foo [
+  x:number
+  y:number
+]
+
+recipe main [
+  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>:literal
+  <span class="Constant">2</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">0</span>:literal/x<span class="Delimiter">,</span> <span class="Constant">1</span>:number
+  <span class="Constant">4</span>:foo<span class="Special"> &lt;- </span>merge <span class="Constant">1</span>:literal/x<span class="Delimiter">,</span> <span class="Constant">1</span>:number
+]
+<span class="traceContains">+mem: storing 0 in location 2</span>
+<span class="traceContains">+mem: storing 34 in location 3</span>
+<span class="traceContains">+mem: storing 1 in location 4</span>
+<span class="traceContains">+mem: storing 34 in location 5</span>
 </pre>
 </body>
 </html>
diff --git a/html/035call.cc.html b/html/035call.cc.html
index c493e9dc..9cab8e21 100644
--- a/html/035call.cc.html
+++ b/html/035call.cc.html
@@ -12,17 +12,17 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
 .PreProc { color: #c000c0; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
diff --git a/html/036call_ingredient.cc.html b/html/036call_ingredient.cc.html
index 995bbbcf..c19b4166 100644
--- a/html/036call_ingredient.cc.html
+++ b/html/036call_ingredient.cc.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
 -->
@@ -127,7 +127,7 @@ INGREDIENT<span class="Delimiter">,</span>
 Recipe_number[<span class="Constant">&quot;ingredient&quot;</span>] = INGREDIENT<span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
 case INGREDIENT: <span class="Delimiter">{</span>
-  assert<span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
+  assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
   assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
   if <span class="Delimiter">(</span>static_cast&lt;long long int&gt;<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> &lt; SIZE<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
diff --git a/html/037call_reply.cc.html b/html/037call_reply.cc.html
index 711bc8c4..82517f08 100644
--- a/html/037call_reply.cc.html
+++ b/html/037call_reply.cc.html
@@ -12,14 +12,14 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
@@ -53,6 +53,7 @@ Recipe_number[<span class="Constant">&quot;reply&quot;</span>] = REPLY<span clas
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
 case REPLY: <span class="Delimiter">{</span>
   const instruction&amp; reply_inst = current_instruction<span class="Delimiter">();</span>  <span class="Comment">// save pointer into recipe before pop</span>
+  const string&amp; callee = current_recipe_name<span class="Delimiter">();</span>
   --Callstack_depth<span class="Delimiter">;</span>
 <span class="CommentedCode">//?   if (tb_is_active()) { //? 1</span>
 <span class="CommentedCode">//?     tb_clear(); //? 1</span>
@@ -74,7 +75,7 @@ case REPLY: <span class="Delimiter">{</span>
       assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>tmp<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">);</span>
       long long int ingredient_index = to_integer<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
       if <span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>value != caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">).</span>value<span class="Delimiter">)</span>
-        raise &lt;&lt; <span class="Constant">&quot;'same-as-ingredient' result &quot;</span> &lt;&lt; caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>value &lt;&lt; <span class="Constant">&quot; must be location &quot;</span> &lt;&lt; caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">).</span>value &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+        raise &lt;&lt; current_recipe_name<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: 'same-as-ingredient' result &quot;</span> &lt;&lt; caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>value &lt;&lt; <span class="Constant">&quot; from call to &quot;</span> &lt;&lt; callee &lt;&lt; <span class="Constant">&quot; must be location &quot;</span> &lt;&lt; caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">).</span>value &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>  <span class="Comment">// continue to process rest of *caller* instruction</span>
@@ -109,7 +110,7 @@ recipe test1 [
   <span class="Constant">10</span>:address:number<span class="Special"> &lt;- </span>next-ingredient
   reply <span class="Constant">10</span>:address:number/same-as-ingredient:<span class="Constant">0</span>
 ]
-<span class="traceContains">+warn: 'same-as-ingredient' result 2 must be location 1</span>
+<span class="traceContains">+warn: main: 'same-as-ingredient' result 2 from call to test1 must be location 1</span>
 
 <span class="Delimiter">:(code)</span>
 string to_string<span class="Delimiter">(</span>const vector&lt;double&gt;&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -159,6 +160,7 @@ recipe test1 [
 if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">&quot;reply-if&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
   assert<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
   curr<span class="Delimiter">.</span>operation = Recipe_number[<span class="Constant">&quot;jump-unless&quot;</span>]<span class="Delimiter">;</span>
+  curr<span class="Delimiter">.</span>name = <span class="Constant">&quot;jump-unless&quot;</span><span class="Delimiter">;</span>
   vector&lt;reagent&gt; results<span class="Delimiter">;</span>
   copy<span class="Delimiter">(</span>++curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>results<span class="Delimiter">,</span> results<span class="Delimiter">.</span>end<span class="Delimiter">()));</span>
   curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
@@ -166,6 +168,26 @@ if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <
   result<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>curr<span class="Delimiter">);</span>
   curr<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
   curr<span class="Delimiter">.</span>operation = Recipe_number[<span class="Constant">&quot;reply&quot;</span>]<span class="Delimiter">;</span>
+  curr<span class="Delimiter">.</span>name = <span class="Constant">&quot;reply&quot;</span><span class="Delimiter">;</span>
+  curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>swap<span class="Delimiter">(</span>results<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+<span class="Comment">// rewrite `reply-unless a, b, c, ...` to</span>
+<span class="Comment">//   ```</span>
+<span class="Comment">//   jump-if a, 1:offset</span>
+<span class="Comment">//   reply b, c, ...</span>
+<span class="Comment">//   ```</span>
+if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">&quot;reply-unless&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  assert<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
+  curr<span class="Delimiter">.</span>operation = Recipe_number[<span class="Constant">&quot;jump-if&quot;</span>]<span class="Delimiter">;</span>
+  curr<span class="Delimiter">.</span>name = <span class="Constant">&quot;jump-if&quot;</span><span class="Delimiter">;</span>
+  vector&lt;reagent&gt; results<span class="Delimiter">;</span>
+  copy<span class="Delimiter">(</span>++curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>results<span class="Delimiter">,</span> results<span class="Delimiter">.</span>end<span class="Delimiter">()));</span>
+  curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+  curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">&quot;1:offset&quot;</span><span class="Delimiter">));</span>
+  result<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>curr<span class="Delimiter">);</span>
+  curr<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+  curr<span class="Delimiter">.</span>operation = Recipe_number[<span class="Constant">&quot;reply&quot;</span>]<span class="Delimiter">;</span>
+  curr<span class="Delimiter">.</span>name = <span class="Constant">&quot;reply&quot;</span><span class="Delimiter">;</span>
   curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>swap<span class="Delimiter">(</span>results<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 </pre>
diff --git a/html/038scheduler.cc.html b/html/038scheduler.cc.html
index 6dda74ca..80316b38 100644
--- a/html/038scheduler.cc.html
+++ b/html/038scheduler.cc.html
@@ -12,16 +12,16 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
 .traceAbsent { color: #c00000; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
@@ -80,6 +80,7 @@ long long int Current_routine_index = <span class="Constant">0</span><span class
 long long int Scheduling_interval = <span class="Constant">500</span><span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End Setup&quot;)</span>
 Scheduling_interval = <span class="Constant">500</span><span class="Delimiter">;</span>
+Routines<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
 <span class="Delimiter">:(replace{} &quot;void run(recipe_number r)&quot;)</span>
 void run<span class="Delimiter">(</span>recipe_number r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
 <span class="CommentedCode">//?   cerr &lt;&lt; &quot;AAA 4\n&quot;; //? 1</span>
@@ -179,7 +180,7 @@ START_RUNNING<span class="Delimiter">,</span>
 Recipe_number[<span class="Constant">&quot;start-running&quot;</span>] = START_RUNNING<span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
 case START_RUNNING: <span class="Delimiter">{</span>
-  assert<span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
+  assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
   assert<span class="Delimiter">(</span>!current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>initialized<span class="Delimiter">);</span>
   routine* new_routine = new routine<span class="Delimiter">(</span>Recipe_number[current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name]<span class="Delimiter">);</span>
 <span class="CommentedCode">//?   cerr &lt;&lt; new_routine-&gt;id &lt;&lt; &quot; -&gt; &quot; &lt;&lt; Current_routine-&gt;id &lt;&lt; '\n'; //? 1</span>
diff --git a/html/039wait.cc.html b/html/039wait.cc.html
index 92798fcd..57dd3e75 100644
--- a/html/039wait.cc.html
+++ b/html/039wait.cc.html
@@ -12,14 +12,14 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
diff --git a/html/040brace.cc.html b/html/040brace.cc.html
index 9b81bc98..eb7f66a9 100644
--- a/html/040brace.cc.html
+++ b/html/040brace.cc.html
@@ -12,14 +12,14 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
@@ -98,7 +98,7 @@ void transform_braces<span class="Delimiter">(</span>const recipe_number r<span
       <span class="Delimiter">;</span>  <span class="Comment">// do nothing</span>
     else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_number[<span class="Constant">&quot;loop&quot;</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       inst<span class="Delimiter">.</span>operation = Recipe_number[<span class="Constant">&quot;jump&quot;</span>]<span class="Delimiter">;</span>
-      if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> &amp;&amp; isa_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+      if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> &amp;&amp; is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
         <span class="Comment">// explicit target; a later phase will handle it</span>
         trace<span class="Delimiter">(</span><span class="Constant">&quot;after-brace&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;jump &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot;:offset&quot;</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
@@ -114,7 +114,7 @@ void transform_braces<span class="Delimiter">(</span>const recipe_number r<span
     <span class="Delimiter">}</span>
     else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_number[<span class="Constant">&quot;break&quot;</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       inst<span class="Delimiter">.</span>operation = Recipe_number[<span class="Constant">&quot;jump&quot;</span>]<span class="Delimiter">;</span>
-      if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> &amp;&amp; isa_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+      if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> &amp;&amp; is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
         <span class="Comment">// explicit target; a later phase will handle it</span>
         trace<span class="Delimiter">(</span><span class="Constant">&quot;after-brace&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;jump &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot;:offset&quot;</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
@@ -128,7 +128,7 @@ void transform_braces<span class="Delimiter">(</span>const recipe_number r<span
     <span class="Delimiter">}</span>
     else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_number[<span class="Constant">&quot;loop-if&quot;</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       inst<span class="Delimiter">.</span>operation = Recipe_number[<span class="Constant">&quot;jump-if&quot;</span>]<span class="Delimiter">;</span>
-      if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> &gt; <span class="Constant">1</span> &amp;&amp; isa_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+      if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> &gt; <span class="Constant">1</span> &amp;&amp; is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
         <span class="Comment">// explicit target; a later phase will handle it</span>
         trace<span class="Delimiter">(</span><span class="Constant">&quot;after-brace&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;jump &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot;:offset&quot;</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
@@ -142,7 +142,7 @@ void transform_braces<span class="Delimiter">(</span>const recipe_number r<span
     <span class="Delimiter">}</span>
     else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_number[<span class="Constant">&quot;break-if&quot;</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       inst<span class="Delimiter">.</span>operation = Recipe_number[<span class="Constant">&quot;jump-if&quot;</span>]<span class="Delimiter">;</span>
-      if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> &gt; <span class="Constant">1</span> &amp;&amp; isa_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+      if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> &gt; <span class="Constant">1</span> &amp;&amp; is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
         <span class="Comment">// explicit target; a later phase will handle it</span>
         trace<span class="Delimiter">(</span><span class="Constant">&quot;after-brace&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;jump &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot;:offset&quot;</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
@@ -156,7 +156,7 @@ void transform_braces<span class="Delimiter">(</span>const recipe_number r<span
     <span class="Delimiter">}</span>
     else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_number[<span class="Constant">&quot;loop-unless&quot;</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       inst<span class="Delimiter">.</span>operation = Recipe_number[<span class="Constant">&quot;jump-unless&quot;</span>]<span class="Delimiter">;</span>
-      if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> &gt; <span class="Constant">1</span> &amp;&amp; isa_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+      if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> &gt; <span class="Constant">1</span> &amp;&amp; is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
         <span class="Comment">// explicit target; a later phase will handle it</span>
         trace<span class="Delimiter">(</span><span class="Constant">&quot;after-brace&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;jump &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot;:offset&quot;</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
@@ -171,7 +171,7 @@ void transform_braces<span class="Delimiter">(</span>const recipe_number r<span
     else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_number[<span class="Constant">&quot;break-unless&quot;</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
 <span class="CommentedCode">//?       cout &lt;&lt; &quot;AAA break-unless\n&quot;; //? 1</span>
       inst<span class="Delimiter">.</span>operation = Recipe_number[<span class="Constant">&quot;jump-unless&quot;</span>]<span class="Delimiter">;</span>
-      if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> &gt; <span class="Constant">1</span> &amp;&amp; isa_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+      if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> &gt; <span class="Constant">1</span> &amp;&amp; is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
         <span class="Comment">// explicit target; a later phase will handle it</span>
         trace<span class="Delimiter">(</span><span class="Constant">&quot;after-brace&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;jump &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot;:offset&quot;</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
diff --git a/html/041name.cc.html b/html/041name.cc.html
index 76fa114e..5dd8195e 100644
--- a/html/041name.cc.html
+++ b/html/041name.cc.html
@@ -12,17 +12,17 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
 .traceAbsent { color: #c00000; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
@@ -103,7 +103,7 @@ void transform_names<span class="Delimiter">(</span>const recipe_number r<span c
 <span class="Delimiter">}</span>
 
 void check_metadata<span class="Delimiter">(</span>map&lt;string<span class="Delimiter">,</span> vector&lt;type_number&gt; &gt;&amp; metadata<span class="Delimiter">,</span> const reagent&amp; x<span class="Delimiter">,</span> const recipe_number r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  if <span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>metadata<span class="Delimiter">.</span>find<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">)</span> == metadata<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
     metadata[x<span class="Delimiter">.</span>name] = x<span class="Delimiter">.</span>types<span class="Delimiter">;</span>
@@ -112,11 +112,12 @@ void check_metadata<span class="Delimiter">(</span>map&lt;string<span class="Del
 <span class="Delimiter">}</span>
 
 bool disqualified<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">mutable</span><span class="Comment">*/</span> reagent&amp; x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; x.to_string() &lt;&lt; '\n'; //? 1</span>
   if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span>
     raise &lt;&lt; <span class="Constant">&quot;missing type in &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
   assert<span class="Delimiter">(</span>!x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
   if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
   <span class="Comment">// End Disqualified Reagents</span>
   if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>initialized<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
@@ -145,19 +146,19 @@ int find_element_name<span class="Delimiter">(</span>const type_number t<span cl
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>container<span class="Delimiter">.</span>element_names<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     if <span class="Delimiter">(</span>container<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == name<span class="Delimiter">)</span> <span class="Identifier">return</span> i<span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  raise &lt;&lt; <span class="Constant">&quot;unknown element &quot;</span> &lt;&lt; name &lt;&lt; <span class="Constant">&quot; in container &quot;</span> &lt;&lt; t &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; die<span class="Delimiter">();</span>
+  raise &lt;&lt; <span class="Constant">&quot;unknown element &quot;</span> &lt;&lt; name &lt;&lt; <span class="Constant">&quot; in container &quot;</span> &lt;&lt; Type[t]<span class="Delimiter">.</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; die<span class="Delimiter">();</span>
   <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
 bool is_numeric_location<span class="Delimiter">(</span>const reagent&amp; x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  if <span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">&quot;0&quot;</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>  <span class="Comment">// used for chaining lexical scopes</span>
   <span class="Identifier">return</span> is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
 bool is_named_location<span class="Delimiter">(</span>const reagent&amp; x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  if <span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>is_special_name<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   <span class="Identifier">return</span> !is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
@@ -258,7 +259,7 @@ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation
   <span class="Comment">// at least 2 args, and second arg is offset</span>
   assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> &gt;= <span class="Constant">2</span><span class="Delimiter">);</span>
 <span class="CommentedCode">//?   cout &lt;&lt; inst.ingredients.at(1).to_string() &lt;&lt; '\n'; //? 1</span>
-  assert<span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
+  assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
   if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">&quot;0123456789&quot;</span><span class="Delimiter">)</span> == string::npos<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
   <span class="Comment">// since first non-address in base type must be a container, we don't have to canonize</span>
   type_number base_type = skip_addresses<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>types<span class="Delimiter">);</span>
@@ -294,7 +295,7 @@ recipe main [
 if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_number[<span class="Constant">&quot;maybe-convert&quot;</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   <span class="Comment">// at least 2 args, and second arg is offset</span>
   assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> &gt;= <span class="Constant">2</span><span class="Delimiter">);</span>
-  assert<span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
+  assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
   if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">&quot;0123456789&quot;</span><span class="Delimiter">)</span> == string::npos<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
   <span class="Comment">// since first non-address in base type must be an exclusive container, we don't have to canonize</span>
   type_number base_type = skip_addresses<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>types<span class="Delimiter">);</span>
diff --git a/html/042new.cc.html b/html/042new.cc.html
index f1ca46a1..aaa6f2bf 100644
--- a/html/042new.cc.html
+++ b/html/042new.cc.html
@@ -12,16 +12,15 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
-.PreProc { color: #c000c0; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
@@ -71,14 +70,15 @@ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation
   <span class="Comment">// End NEW Transform Special-cases</span>
   <span class="Comment">// first arg must be of type 'type'</span>
   assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> &gt;= <span class="Constant">1</span><span class="Delimiter">);</span>
-  assert<span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
+  if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span>
+    raise &lt;&lt; <span class="Constant">&quot;expected literal, got &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; die<span class="Delimiter">();</span>
   if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != <span class="Constant">&quot;type&quot;</span><span class="Delimiter">)</span>
     raise &lt;&lt; <span class="Constant">&quot;tried to allocate non-type &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot; in recipe &quot;</span> &lt;&lt; Recipe[r]<span class="Delimiter">.</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; die<span class="Delimiter">();</span>
   if <span class="Delimiter">(</span>Type_number<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">)</span> == Type_number<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
     raise &lt;&lt; <span class="Constant">&quot;unknown type &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; in recipe &quot;</span> &lt;&lt; Recipe[r]<span class="Delimiter">.</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; die<span class="Delimiter">();</span>
 <span class="CommentedCode">//?   cerr &lt;&lt; &quot;type &quot; &lt;&lt; inst.ingredients.at(0).name &lt;&lt; &quot; =&gt; &quot; &lt;&lt; Type_number[inst.ingredients.at(0).name] &lt;&lt; '\n'; //? 1</span>
   inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>Type_number[inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name]<span class="Delimiter">);</span>
-  trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">&quot;new&quot;</span><span class="Delimiter">)</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; -&gt; &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>value<span class="Delimiter">;</span>
+  trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">&quot;new&quot;</span><span class="Delimiter">)</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; -&gt; &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">;</span>
   end_new_transform:<span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
@@ -96,7 +96,7 @@ case NEW: <span class="Delimiter">{</span>
   long long int array_length = <span class="Constant">0</span><span class="Delimiter">;</span>
   <span class="Delimiter">{</span>
     vector&lt;type_number&gt; type<span class="Delimiter">;</span>
-    assert<span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
+    assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
     type<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>value<span class="Delimiter">);</span>
 <span class="CommentedCode">//?     trace(Primitive_recipe_depth, &quot;mem&quot;) &lt;&lt; &quot;type &quot; &lt;&lt; current_instruction().ingredients.at(0).to_string() &lt;&lt; ' ' &lt;&lt; type.size() &lt;&lt; ' ' &lt;&lt; type.back() &lt;&lt; &quot; has size &quot; &lt;&lt; size_of(type); //? 1</span>
     if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">)</span> &gt; <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -166,6 +166,16 @@ recipe main [
 <span class="Comment"># don't forget the extra location for array size</span>
 <span class="traceContains">+mem: storing 6 in location 3</span>
 
+<span class="Delimiter">:(scenario new_empty_array)</span>
+recipe main [
+  <span class="Constant">1</span>:address:array:number/<span class="Special">raw &lt;- </span>new number:type<span class="Delimiter">,</span> <span class="Constant">0</span>:literal
+  <span class="Constant">2</span>:address:number/<span class="Special">raw &lt;- </span>new number:type
+  <span class="Constant">3</span>:number/<span class="Special">raw &lt;- </span>subtract <span class="Constant">2</span>:address:number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:address:array:number/<span class="Special">raw</span>
+]
+<span class="traceContains">+run: 1:address:array:number/raw &lt;- new number:type, 0:literal</span>
+<span class="traceContains">+mem: array size is 0</span>
+<span class="traceContains">+mem: storing 1 in location 3</span>
+
 <span class="Comment">//: Make sure that each routine gets a different alloc to start.</span>
 <span class="Delimiter">:(scenario new_concurrent)</span>
 recipe f1 [
@@ -216,14 +226,17 @@ recipe main [
 <span class="traceContains">+mem: storing 171 in location 3</span>
 
 <span class="Delimiter">:(before &quot;End NEW Transform Special-cases&quot;)</span>
-  if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">&quot;literal-string&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span>
+      &amp;&amp; !inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>empty<span class="Delimiter">()</span>
+      &amp;&amp; !inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span>
+      &amp;&amp; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">&quot;literal-string&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
     <span class="Comment">// skip transform</span>
     inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>initialized = <span class="Constant">true</span><span class="Delimiter">;</span>
     <span class="Identifier">goto</span> end_new_transform<span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(after &quot;case NEW&quot; following &quot;Primitive Recipe Implementations&quot;)</span>
-if <span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span>
+if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span>
     &amp;&amp; current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">&quot;literal-string&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
   <span class="Comment">// allocate an array just large enough for it</span>
   long long int string_length = unicode_length<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span>
@@ -272,9 +285,6 @@ long long int unicode_length<span class="Delimiter">(</span>const string&amp; s<
   <span class="Delimiter">}</span>
   <span class="Identifier">return</span> result<span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
-
-<span class="Delimiter">:(before &quot;End Includes&quot;)</span>
-<span class="PreProc">#include</span><span class="Constant">&quot;termbox/termbox.h&quot;</span>  <span class="Comment">// for unicode primitives</span>
 </pre>
 </body>
 </html>
diff --git a/html/043space.cc.html b/html/043space.cc.html
index 005e1e9e..df051ab3 100644
--- a/html/043space.cc.html
+++ b/html/043space.cc.html
@@ -12,17 +12,17 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
 .traceAbsent { color: #c00000; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
diff --git a/html/044space_surround.cc.html b/html/044space_surround.cc.html
index c82e9e2f..575f33bb 100644
--- a/html/044space_surround.cc.html
+++ b/html/044space_surround.cc.html
@@ -12,13 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
diff --git a/html/045closure_name.cc.html b/html/045closure_name.cc.html
index d3aa6f01..30ed6538 100644
--- a/html/045closure_name.cc.html
+++ b/html/045closure_name.cc.html
@@ -12,14 +12,14 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
@@ -40,14 +40,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="Delimiter">:(scenario closure)</span>
 recipe main [
   default-space:address:array:location<span class="Special"> &lt;- </span>new location:type<span class="Delimiter">,</span> <span class="Constant">30</span>:literal
-  <span class="Constant">1</span>:address:array:location/names:init-counter<span class="Special"> &lt;- </span>init-counter
+  <span class="Constant">1</span>:address:array:location/names:new-counter<span class="Special"> &lt;- </span>new-counter
 <span class="CommentedCode">#?   $print [AAAAAAAAAAAAAAAA]</span>
 <span class="CommentedCode">#?   $print 1:address:array:location</span>
-  <span class="Constant">2</span>:number/<span class="Special">raw &lt;- </span>increment-counter <span class="Constant">1</span>:address:array:location/names:init-counter
-  <span class="Constant">3</span>:number/<span class="Special">raw &lt;- </span>increment-counter <span class="Constant">1</span>:address:array:location/names:init-counter
+  <span class="Constant">2</span>:number/<span class="Special">raw &lt;- </span>increment-counter <span class="Constant">1</span>:address:array:location/names:new-counter
+  <span class="Constant">3</span>:number/<span class="Special">raw &lt;- </span>increment-counter <span class="Constant">1</span>:address:array:location/names:new-counter
 ]
 
-recipe init-counter [
+recipe new-counter [
   default-space:address:array:location<span class="Special"> &lt;- </span>new location:type<span class="Delimiter">,</span> <span class="Constant">30</span>:literal
   x:number<span class="Special"> &lt;- </span>copy <span class="Constant">23</span>:literal
   y:number<span class="Special"> &lt;- </span>copy <span class="Constant">3</span>:literal  <span class="Comment"># variable that will be incremented</span>
@@ -56,13 +56,13 @@ recipe init-counter [
 
 recipe increment-counter [
   default-space:address:array:location<span class="Special"> &lt;- </span>new location:type<span class="Delimiter">,</span> <span class="Constant">30</span>:literal
-  <span class="Constant">0</span>:address:array:location/names:init-counter<span class="Special"> &lt;- </span>next-ingredient  <span class="Comment"># outer space must be created by 'init-counter' above</span>
+  <span class="Constant">0</span>:address:array:location/names:new-counter<span class="Special"> &lt;- </span>next-ingredient  <span class="Comment"># outer space must be created by 'new-counter' above</span>
   y:number/space:<span class="Constant">1</span><span class="Special"> &lt;- </span>add y:number/space:<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">1</span>:literal  <span class="Comment"># increment</span>
   y:number<span class="Special"> &lt;- </span>copy <span class="Constant">234</span>:literal  <span class="Comment"># dummy</span>
   reply y:number/space:<span class="Constant">1</span>
 ]
 
-<span class="traceContains">+name: recipe increment-counter is surrounded by init-counter</span>
+<span class="traceContains">+name: recipe increment-counter is surrounded by new-counter</span>
 <span class="traceContains">+mem: storing 5 in location 3</span>
 
 <span class="Comment">//: To make this work, compute the recipe that provides names for the</span>
@@ -80,7 +80,7 @@ void collect_surrounding_spaces<span class="Delimiter">(</span>const recipe_numb
     const instruction&amp; inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
     if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
     for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-      if <span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+      if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
       if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>name != <span class="Constant">&quot;0&quot;</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
       if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>types<span class="Delimiter">)</span> != <span class="Constant">3</span>
           || inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != Type_number[<span class="Constant">&quot;address&quot;</span>]
diff --git a/html/046tangle.cc.html b/html/046tangle.cc.html
index 40afd84d..2bf8d51c 100644
--- a/html/046tangle.cc.html
+++ b/html/046tangle.cc.html
@@ -12,14 +12,14 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
diff --git a/html/047jump_label.cc.html b/html/047jump_label.cc.html
index abff627d..2c53c4d8 100644
--- a/html/047jump_label.cc.html
+++ b/html/047jump_label.cc.html
@@ -12,15 +12,15 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceAbsent { color: #c00000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .traceContains { color: #008000; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
@@ -82,7 +82,7 @@ void transform_labels<span class="Delimiter">(</span>const recipe_number r<span
 <span class="Delimiter">:(code)</span>
 void replace_offset<span class="Delimiter">(</span>reagent&amp; x<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">const</span><span class="Comment">*/</span> map&lt;string<span class="Delimiter">,</span> long long int&gt;&amp; offset<span class="Delimiter">,</span> const long long int current_offset<span class="Delimiter">,</span> const recipe_number r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
 <span class="CommentedCode">//?   cerr &lt;&lt; &quot;AAA &quot; &lt;&lt; x.to_string() &lt;&lt; '\n'; //? 1</span>
-  assert<span class="Delimiter">(</span>isa_literal<span class="Delimiter">(</span>x<span class="Delimiter">));</span>
+  assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">));</span>
 <span class="CommentedCode">//?   cerr &lt;&lt; &quot;BBB &quot; &lt;&lt; x.to_string() &lt;&lt; '\n'; //? 1</span>
   assert<span class="Delimiter">(</span>!x<span class="Delimiter">.</span>initialized<span class="Delimiter">);</span>
 <span class="CommentedCode">//?   cerr &lt;&lt; &quot;CCC &quot; &lt;&lt; x.to_string() &lt;&lt; '\n'; //? 1</span>
diff --git a/html/048call_variable.cc.html b/html/048call_variable.cc.html
index 404abffc..6bbbc545 100644
--- a/html/048call_variable.cc.html
+++ b/html/048call_variable.cc.html
@@ -12,13 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
diff --git a/html/049continuation.cc.html b/html/049continuation.cc.html
index 9852638d..bb7b0f14 100644
--- a/html/049continuation.cc.html
+++ b/html/049continuation.cc.html
@@ -12,16 +12,16 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
 .traceAbsent { color: #c00000; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
diff --git a/html/050scenario.cc.html b/html/050scenario.cc.html
index 18576b21..ae05aa68 100644
--- a/html/050scenario.cc.html
+++ b/html/050scenario.cc.html
@@ -12,16 +12,16 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
 .traceAbsent { color: #c00000; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
@@ -110,11 +110,18 @@ scenario parse_scenario<span class="Delimiter">(</span>istream&amp; in<span clas
 <span class="CommentedCode">//?   cerr &lt;&lt; &quot;parse scenario\n&quot;; //? 1</span>
   scenario result<span class="Delimiter">;</span>
   result<span class="Delimiter">.</span>name = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;scenario: &quot; &lt;&lt; result.name &lt;&lt; '\n'; //? 2</span>
   skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   assert<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span>
   <span class="Comment">// scenarios are take special 'code' strings so we need to ignore brackets</span>
   <span class="Comment">// inside comments</span>
-  result<span class="Delimiter">.</span>to_run = slurp_quoted_ignoring_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  result<span class="Delimiter">.</span>to_run = slurp_quoted<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  <span class="Comment">// delete [] delimiters</span>
+  assert<span class="Delimiter">(</span>result<span class="Delimiter">.</span>to_run<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">'['</span><span class="Delimiter">);</span>
+  result<span class="Delimiter">.</span>to_run<span class="Delimiter">.</span>erase<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; (int)result.to_run.at(SIZE(result.to_run)-1) &lt;&lt; '\n'; //? 1</span>
+  assert<span class="Delimiter">(</span>result<span class="Delimiter">.</span>to_run<span class="Delimiter">.</span>at<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>result<span class="Delimiter">.</span>to_run<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">)</span> == <span class="Constant">']'</span><span class="Delimiter">);</span>
+  result<span class="Delimiter">.</span>to_run<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>result<span class="Delimiter">.</span>to_run<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">);</span>
   <span class="Identifier">return</span> result<span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
@@ -161,13 +168,16 @@ const scenario* Current_scenario = <span class="Constant">NULL</span><span class
 void run_mu_scenario<span class="Delimiter">(</span>const scenario&amp; s<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   Current_scenario = &amp;s<span class="Delimiter">;</span>
   bool not_already_inside_test = !Trace_stream<span class="Delimiter">;</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; s.name &lt;&lt; '\n'; //? 4</span>
   if <span class="Delimiter">(</span>not_already_inside_test<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     Trace_file = s<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
     Trace_stream = new trace_stream<span class="Delimiter">;</span>
     setup<span class="Delimiter">();</span>
   <span class="Delimiter">}</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; '^' &lt;&lt; s.to_run &lt;&lt; &quot;$\n&quot;; //? 1</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; '^' &lt;&lt; s.to_run &lt;&lt; &quot;$\n&quot;; //? 4</span>
+  assert<span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
   run<span class="Delimiter">(</span><span class="Constant">&quot;recipe &quot;</span>+s<span class="Delimiter">.</span>name+<span class="Constant">&quot; [ &quot;</span> + s<span class="Delimiter">.</span>to_run + <span class="Constant">&quot; ]&quot;</span><span class="Delimiter">);</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; s.name &lt;&lt; &quot; done\n&quot;; //? 1</span>
   if <span class="Delimiter">(</span>not_already_inside_test &amp;&amp; Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     teardown<span class="Delimiter">();</span>
     ofstream fout<span class="Delimiter">((</span>Trace_dir+Trace_file<span class="Delimiter">).</span>c_str<span class="Delimiter">());</span>
@@ -557,36 +567,6 @@ void run_mu_scenario<span class="Delimiter">(</span>const string&amp; form<span
   scenario s = parse_scenario<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   run_mu_scenario<span class="Delimiter">(</span>s<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
-
-string slurp_quoted_ignoring_comments<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  assert<span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span>  <span class="Comment">// drop initial '['</span>
-  char c<span class="Delimiter">;</span>
-  ostringstream out<span class="Delimiter">;</span>
-  while <span class="Delimiter">(</span>in &gt;&gt; c<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-<span class="CommentedCode">//?     cerr &lt;&lt; c &lt;&lt; '\n'; //? 3</span>
-    if <span class="Delimiter">(</span>c == <span class="Constant">'#'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-      <span class="Comment">// skip comment</span>
-      in<span class="Delimiter">.</span>putback<span class="Delimiter">(</span>c<span class="Delimiter">);</span>
-      skip_comment<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-      <span class="Identifier">continue</span><span class="Delimiter">;</span>
-    <span class="Delimiter">}</span>
-    if <span class="Delimiter">(</span>c == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-      <span class="Comment">// nested strings won't detect comments</span>
-      <span class="Comment">// can't yet handle scenarios inside strings inside scenarios..</span>
-      in<span class="Delimiter">.</span>putback<span class="Delimiter">(</span>c<span class="Delimiter">);</span>
-      out &lt;&lt; slurp_quoted<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-<span class="CommentedCode">//?       cerr &lt;&lt; &quot;snapshot: ^&quot; &lt;&lt; out.str() &lt;&lt; &quot;$\n&quot;; //? 1</span>
-      <span class="Identifier">continue</span><span class="Delimiter">;</span>
-    <span class="Delimiter">}</span>
-    if <span class="Delimiter">(</span>c == <span class="Constant">']'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-      <span class="Comment">// must be at the outermost level; drop final ']'</span>
-      <span class="Identifier">break</span><span class="Delimiter">;</span>
-    <span class="Delimiter">}</span>
-    out &lt;&lt; c<span class="Delimiter">;</span>
-  <span class="Delimiter">}</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;done\n&quot;; //? 2</span>
-  <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
-<span class="Delimiter">}</span>
 </pre>
 </body>
 </html>
diff --git a/html/051scenario_test.mu.html b/html/051scenario_test.mu.html
index 1b65f9a3..4a996b81 100644
--- a/html/051scenario_test.mu.html
+++ b/html/051scenario_test.mu.html
@@ -12,10 +12,10 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .muScenario { color: #00af00; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
 -->
 </style>
diff --git a/html/060string.mu.html b/html/060string.mu.html
index 43ecdd77..06164424 100644
--- a/html/060string.mu.html
+++ b/html/060string.mu.html
@@ -12,14 +12,14 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .muScenario { color: #00af00; }
-.Delimiter { color: #c000c0; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+.Delimiter { color: #a04060; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
-.muControl { color: #804000; }
+.Comment { color: #9090ff; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
@@ -137,7 +137,7 @@ container buffer [
   data:address:array:character
 ]
 
-<span class="muRecipe">recipe</span> init-buffer [
+<span class="muRecipe">recipe</span> new-buffer [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
 <span class="CommentedCode">#?   $print default-space:address:array:location, [</span>
 <span class="CommentedCode">#? ]</span>
@@ -216,7 +216,7 @@ container buffer [
 <span class="muScenario">scenario</span> buffer-append-works [
   run [
     <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
-    x:address:buffer<span class="Special"> &lt;- </span>init-buffer <span class="Constant">3:literal</span>
+    x:address:buffer<span class="Special"> &lt;- </span>new-buffer <span class="Constant">3:literal</span>
     s1:address:array:character<span class="Special"> &lt;- </span>get x:address:buffer/deref, data:offset
     x:address:buffer<span class="Special"> &lt;- </span>buffer-append x:address:buffer, <span class="Constant">97:literal</span>  <span class="Comment"># 'a'</span>
     x:address:buffer<span class="Special"> &lt;- </span>buffer-append x:address:buffer, <span class="Constant">98:literal</span>  <span class="Comment"># 'b'</span>
@@ -268,7 +268,7 @@ container buffer [
 <span class="muScenario">scenario</span> buffer-append-handles-backspace [
   run [
     <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
-    x:address:buffer<span class="Special"> &lt;- </span>init-buffer <span class="Constant">3:literal</span>
+    x:address:buffer<span class="Special"> &lt;- </span>new-buffer <span class="Constant">3:literal</span>
     x:address:buffer<span class="Special"> &lt;- </span>buffer-append x:address:buffer, <span class="Constant">97:literal</span>  <span class="Comment"># 'a'</span>
     x:address:buffer<span class="Special"> &lt;- </span>buffer-append x:address:buffer, <span class="Constant">98:literal</span>  <span class="Comment"># 'b'</span>
     x:address:buffer<span class="Special"> &lt;- </span>buffer-append x:address:buffer, <span class="Constant">8:literal/backspace</span>
@@ -301,7 +301,7 @@ container buffer [
     n:number<span class="Special"> &lt;- </span>multiply n:number, <span class="Constant">-1:literal</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># add digits from right to left into intermediate buffer</span>
-  tmp:address:buffer<span class="Special"> &lt;- </span>init-buffer <span class="Constant">30:literal</span>
+  tmp:address:buffer<span class="Special"> &lt;- </span>new-buffer <span class="Constant">30:literal</span>
   digit-base:number<span class="Special"> &lt;- </span>copy <span class="Constant">48:literal</span>  <span class="Comment"># '0'</span>
   <span class="Delimiter">{</span>
     done?:boolean<span class="Special"> &lt;- </span>equal n:number, <span class="Constant">0:literal</span>
@@ -756,6 +756,566 @@ container buffer [
     3:string<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
   ]
 ]
+
+<span class="Comment"># next-index:number &lt;- find-next text:address:array:character, pattern:character</span>
+<span class="muRecipe">recipe</span> find-next [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  text:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  pattern:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  idx:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  len:number<span class="Special"> &lt;- </span>length text:address:array:character/deref
+  <span class="Delimiter">{</span>
+    eof?:boolean<span class="Special"> &lt;- </span>greater-or-equal idx:number, len:number
+    <span class="muControl">break-if</span> eof?:boolean
+    curr:character<span class="Special"> &lt;- </span>index text:address:array:character/deref, idx:number
+    found?:boolean<span class="Special"> &lt;- </span>equal curr:character, pattern:character
+    <span class="muControl">break-if</span> found?:boolean
+    idx:number<span class="Special"> &lt;- </span>add idx:number, <span class="Constant">1:literal</span>
+    <span class="muControl">loop</span>
+  <span class="Delimiter">}</span>
+  <span class="muControl">reply</span> idx:number
+]
+
+<span class="muScenario">scenario</span> string-find-next [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[a/b]</span>
+    2:number<span class="Special"> &lt;- </span>find-next 1:address:array:character, <span class="Constant">47:literal/slash</span>, <span class="Constant">0:literal/start-index</span>
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>1
+  ]
+]
+
+<span class="muScenario">scenario</span> string-find-next-empty [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
+    2:number<span class="Special"> &lt;- </span>find-next 1:address:array:character, <span class="Constant">47:literal/slash</span>, <span class="Constant">0:literal/start-index</span>
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>0
+  ]
+]
+
+<span class="muScenario">scenario</span> string-find-next-initial [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[/abc]</span>
+    2:number<span class="Special"> &lt;- </span>find-next 1:address:array:character, <span class="Constant">47:literal/slash</span>, <span class="Constant">0:literal/start-index</span>
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>0  <span class="Comment"># prefix match</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> string-find-next-final [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc/]</span>
+    2:number<span class="Special"> &lt;- </span>find-next 1:address:array:character, <span class="Constant">47:literal/slash</span>, <span class="Constant">0:literal/start-index</span>
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>3  <span class="Comment"># suffix match</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> string-find-next-missing [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:number<span class="Special"> &lt;- </span>find-next 1:address:array:character, <span class="Constant">47:literal/slash</span>, <span class="Constant">0:literal/start-index</span>
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>3  <span class="Comment"># no match</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> string-find-next-invalid-index [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:number<span class="Special"> &lt;- </span>find-next 1:address:array:character, <span class="Constant">47:literal/slash</span>, <span class="Constant">4:literal/start-index</span>
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>4  <span class="Comment"># no change</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> string-find-next-first [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[ab/c/]</span>
+    2:number<span class="Special"> &lt;- </span>find-next 1:address:array:character, <span class="Constant">47:literal/slash</span>, <span class="Constant">0:literal/start-index</span>
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>2  <span class="Comment"># first '/' of multiple</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> string-find-next-second [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[ab/c/]</span>
+    2:number<span class="Special"> &lt;- </span>find-next 1:address:array:character, <span class="Constant">47:literal/slash</span>, <span class="Constant">3:literal/start-index</span>
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>4  <span class="Comment"># second '/' of multiple</span>
+  ]
+]
+
+<span class="Comment"># like find-next, but searches for multiple characters</span>
+<span class="Comment"># fairly dumb algorithm</span>
+<span class="muRecipe">recipe</span> find-substring [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  text:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  pattern:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  idx:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  first:character<span class="Special"> &lt;- </span>index pattern:address:array:character/deref, <span class="Constant">0:literal</span>
+  <span class="Comment"># repeatedly check for match at current idx</span>
+  len:number<span class="Special"> &lt;- </span>length text:address:array:character/deref
+  <span class="Delimiter">{</span>
+    <span class="Comment"># does some unnecessary work checking for substrings even when there isn't enough of text left</span>
+    done?:boolean<span class="Special"> &lt;- </span>greater-or-equal idx:number, len:number
+    <span class="muControl">break-if</span> done?:boolean
+    found?:boolean<span class="Special"> &lt;- </span>match-at text:address:array:character pattern:address:array:character, idx:number
+    <span class="muControl">break-if</span> found?:boolean
+    idx:number<span class="Special"> &lt;- </span>add idx:number, <span class="Constant">1:literal</span>
+    <span class="Comment"># optimization: skip past indices that definitely won't match</span>
+    idx:number<span class="Special"> &lt;- </span>find-next text:address:array:character, first:character, idx:number
+    <span class="muControl">loop</span>
+  <span class="Delimiter">}</span>
+  <span class="muControl">reply</span> idx:number
+]
+
+<span class="muScenario">scenario</span> find-substring-1 [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[bc]</span>
+    3:number<span class="Special"> &lt;- </span>find-substring 1:address:array:character, 2:address:array:character, <span class="Constant">0:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>1
+  ]
+]
+
+<span class="muScenario">scenario</span> find-substring-2 [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abcd]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[bc]</span>
+    3:number<span class="Special"> &lt;- </span>find-substring 1:address:array:character, 2:address:array:character, <span class="Constant">1:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>1
+  ]
+]
+
+<span class="muScenario">scenario</span> find-substring-no-match [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[bd]</span>
+    3:number<span class="Special"> &lt;- </span>find-substring 1:address:array:character, 2:address:array:character, <span class="Constant">0:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>3  <span class="Comment"># not found</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> find-substring-suffix-match [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abcd]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[cd]</span>
+    3:number<span class="Special"> &lt;- </span>find-substring 1:address:array:character, 2:address:array:character, <span class="Constant">0:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>2
+  ]
+]
+
+<span class="muScenario">scenario</span> find-substring-suffix-match-2 [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abcd]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[cde]</span>
+    3:number<span class="Special"> &lt;- </span>find-substring 1:address:array:character, 2:address:array:character, <span class="Constant">0:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>4  <span class="Comment"># not found</span>
+  ]
+]
+
+<span class="Comment"># result:boolean &lt;- match-at text:address:array:character, pattern:address:array:character, idx:number</span>
+<span class="Comment"># checks if substring matches at index 'idx'</span>
+<span class="muRecipe">recipe</span> match-at [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  text:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  pattern:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  idx:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  pattern-len:number<span class="Special"> &lt;- </span>length pattern:address:array:character/deref
+  <span class="Comment"># check that there's space left for the pattern</span>
+  <span class="Delimiter">{</span>
+    x:number<span class="Special"> &lt;- </span>length text:address:array:character/deref
+    x:number<span class="Special"> &lt;- </span>subtract x:number, pattern-len:number
+    enough-room?:boolean<span class="Special"> &lt;- </span>lesser-or-equal idx:number, x:number
+    <span class="muControl">break-if</span> enough-room?:boolean
+    <span class="muControl">reply</span> <span class="Constant">0:literal/not-found</span>
+  <span class="Delimiter">}</span>
+  <span class="Comment"># check each character of pattern</span>
+  pattern-idx:number<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
+  <span class="Delimiter">{</span>
+    done?:boolean<span class="Special"> &lt;- </span>greater-or-equal pattern-idx:number, pattern-len:number
+    <span class="muControl">break-if</span> done?:boolean
+    c:character<span class="Special"> &lt;- </span>index text:address:array:character/deref, idx:number
+    exp:character<span class="Special"> &lt;- </span>index pattern:address:array:character/deref, pattern-idx:number
+    <span class="Delimiter">{</span>
+      match?:boolean<span class="Special"> &lt;- </span>equal c:character, exp:character
+      <span class="muControl">break-if</span> match?:boolean
+      <span class="muControl">reply</span> <span class="Constant">0:literal/not-found</span>
+    <span class="Delimiter">}</span>
+    idx:number<span class="Special"> &lt;- </span>add idx:number, <span class="Constant">1:literal</span>
+    pattern-idx:number<span class="Special"> &lt;- </span>add pattern-idx:number, <span class="Constant">1:literal</span>
+    <span class="muControl">loop</span>
+  <span class="Delimiter">}</span>
+  <span class="muControl">reply</span> <span class="Constant">1:literal/found</span>
+]
+
+<span class="muScenario">scenario</span> match-at-checks-substring-at-index [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[ab]</span>
+    3:boolean<span class="Special"> &lt;- </span>match-at 1:address:array:character, 2:address:array:character, <span class="Constant">0:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>1  <span class="Comment"># match found</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> match-at-reflexive [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    3:boolean<span class="Special"> &lt;- </span>match-at 1:address:array:character, 1:address:array:character, <span class="Constant">0:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>1  <span class="Comment"># match found</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> match-at-outside-bounds [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[a]</span>
+    3:boolean<span class="Special"> &lt;- </span>match-at 1:address:array:character, 2:address:array:character, <span class="Constant">4:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>0  <span class="Comment"># never matches</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> match-at-empty-pattern [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
+    3:boolean<span class="Special"> &lt;- </span>match-at 1:address:array:character, 2:address:array:character, <span class="Constant">0:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>1  <span class="Comment"># always matches empty pattern given a valid index</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> match-at-empty-pattern-outside-bound [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
+    3:boolean<span class="Special"> &lt;- </span>match-at 1:address:array:character, 2:address:array:character, <span class="Constant">4:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>0  <span class="Comment"># no match</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> match-at-empty-text [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    3:boolean<span class="Special"> &lt;- </span>match-at 1:address:array:character, 2:address:array:character, <span class="Constant">0:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>0  <span class="Comment"># no match</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> match-at-empty-against-empty [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
+    3:boolean<span class="Special"> &lt;- </span>match-at 1:address:array:character, 1:address:array:character, <span class="Constant">0:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>1  <span class="Comment"># matches because pattern is also empty</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> match-at-inside-bounds [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[bc]</span>
+    3:boolean<span class="Special"> &lt;- </span>match-at 1:address:array:character, 2:address:array:character, <span class="Constant">1:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>1  <span class="Comment"># matches inner substring</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> match-at-inside-bounds-2 [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[bc]</span>
+    3:boolean<span class="Special"> &lt;- </span>match-at 1:address:array:character, 2:address:array:character, <span class="Constant">0:literal</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>0  <span class="Comment"># no match</span>
+  ]
+]
+
+<span class="Comment"># result:address:array:address:array:character &lt;- split s:address:array:character, delim:character</span>
+<span class="muRecipe">recipe</span> split [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  s:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  delim:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Comment"># empty string? return empty array</span>
+  len:number<span class="Special"> &lt;- </span>length s:address:array:character/deref
+  <span class="Delimiter">{</span>
+    empty?:boolean<span class="Special"> &lt;- </span>equal len:number, <span class="Constant">0:literal</span>
+    <span class="muControl">break-unless</span> empty?:boolean
+    result:address:array:address:array:character<span class="Special"> &lt;- </span>new location:type, <span class="Constant">0:literal</span>
+    <span class="muControl">reply</span> result:address:array:address:array:character
+  <span class="Delimiter">}</span>
+  <span class="Comment"># count #pieces we need room for</span>
+  count:number<span class="Special"> &lt;- </span>copy <span class="Constant">1:literal</span>  <span class="Comment"># n delimiters = n+1 pieces</span>
+  idx:number<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
+  <span class="Delimiter">{</span>
+    idx:number<span class="Special"> &lt;- </span>find-next s:address:array:character, delim:character, idx:number
+    done?:boolean<span class="Special"> &lt;- </span>greater-or-equal idx:number, len:number
+    <span class="muControl">break-if</span> done?:boolean
+    idx:number<span class="Special"> &lt;- </span>add idx:number, <span class="Constant">1:literal</span>
+    count:number<span class="Special"> &lt;- </span>add count:number, <span class="Constant">1:literal</span>
+    <span class="muControl">loop</span>
+  <span class="Delimiter">}</span>
+  <span class="Comment"># allocate space</span>
+  result:address:array:address:array:character<span class="Special"> &lt;- </span>new location:type, count:number
+  <span class="Comment"># repeatedly copy slices start..end until delimiter into result[curr-result]</span>
+  curr-result:number<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
+  start:number<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
+  <span class="Delimiter">{</span>
+    <span class="Comment"># while next delim exists</span>
+    done?:boolean<span class="Special"> &lt;- </span>greater-or-equal start:number, len:number
+    <span class="muControl">break-if</span> done?:boolean
+    end:number<span class="Special"> &lt;- </span>find-next s:address:array:character, delim:character, start:number
+    <span class="Comment"># copy start..end into result[curr-result]</span>
+    dest:address:address:array:character<span class="Special"> &lt;- </span>index-address result:address:array:address:array:character/deref, curr-result:number
+    dest:address:address:array:character/deref<span class="Special"> &lt;- </span>string-copy s:address:array:character, start:number, end:number
+    <span class="Comment"># slide over to next slice</span>
+    start:number<span class="Special"> &lt;- </span>add end:number, <span class="Constant">1:literal</span>
+    curr-result:number<span class="Special"> &lt;- </span>add curr-result:number, <span class="Constant">1:literal</span>
+    <span class="muControl">loop</span>
+  <span class="Delimiter">}</span>
+  <span class="muControl">reply</span> result:address:array:address:array:character
+]
+
+<span class="muScenario">scenario</span> string-split-1 [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[a/b]</span>
+    2:address:array:address:array:character<span class="Special"> &lt;- </span>split 1:address:array:character, <span class="Constant">47:literal/slash</span>
+    3:number<span class="Special"> &lt;- </span>length 2:address:array:address:array:character/deref
+    4:address:array:character<span class="Special"> &lt;- </span>index 2:address:array:address:array:character/deref, <span class="Constant">0:literal</span>
+    5:address:array:character<span class="Special"> &lt;- </span>index 2:address:array:address:array:character/deref, <span class="Constant">1:literal</span>
+    10:array:character<span class="Special"> &lt;- </span>copy 4:address:array:character/deref
+    20:array:character<span class="Special"> &lt;- </span>copy 5:address:array:character/deref
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>2  <span class="Comment"># length of result</span>
+    10:string<span class="Special"> &lt;- </span><span class="Constant">[a]</span>
+    20:string<span class="Special"> &lt;- </span><span class="Constant">[b]</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> string-split-2 [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[a/b/c]</span>
+    2:address:array:address:array:character<span class="Special"> &lt;- </span>split 1:address:array:character, <span class="Constant">47:literal/slash</span>
+    3:number<span class="Special"> &lt;- </span>length 2:address:array:address:array:character/deref
+    4:address:array:character<span class="Special"> &lt;- </span>index 2:address:array:address:array:character/deref, <span class="Constant">0:literal</span>
+    5:address:array:character<span class="Special"> &lt;- </span>index 2:address:array:address:array:character/deref, <span class="Constant">1:literal</span>
+    6:address:array:character<span class="Special"> &lt;- </span>index 2:address:array:address:array:character/deref, <span class="Constant">2:literal</span>
+    10:array:character<span class="Special"> &lt;- </span>copy 4:address:array:character/deref
+    20:array:character<span class="Special"> &lt;- </span>copy 5:address:array:character/deref
+    30:array:character<span class="Special"> &lt;- </span>copy 6:address:array:character/deref
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>3  <span class="Comment"># length of result</span>
+    10:string<span class="Special"> &lt;- </span><span class="Constant">[a]</span>
+    20:string<span class="Special"> &lt;- </span><span class="Constant">[b]</span>
+    30:string<span class="Special"> &lt;- </span><span class="Constant">[c]</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> string-split-missing [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:address:array:address:array:character<span class="Special"> &lt;- </span>split 1:address:array:character, <span class="Constant">47:literal/slash</span>
+    3:number<span class="Special"> &lt;- </span>length 2:address:array:address:array:character/deref
+    4:address:array:character<span class="Special"> &lt;- </span>index 2:address:array:address:array:character/deref, <span class="Constant">0:literal</span>
+    10:array:character<span class="Special"> &lt;- </span>copy 4:address:array:character/deref
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>1  <span class="Comment"># length of result</span>
+    10:string<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> string-split-empty [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
+    2:address:array:address:array:character<span class="Special"> &lt;- </span>split 1:address:array:character, <span class="Constant">47:literal/slash</span>
+    3:number<span class="Special"> &lt;- </span>length 2:address:array:address:array:character/deref
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>0  <span class="Comment"># empty result</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> string-split-empty-piece [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[a/b//c]</span>
+    2:address:array:address:array:character<span class="Special"> &lt;- </span>split 1:address:array:character, <span class="Constant">47:literal/slash</span>
+    3:number<span class="Special"> &lt;- </span>length 2:address:array:address:array:character/deref
+    4:address:array:character<span class="Special"> &lt;- </span>index 2:address:array:address:array:character/deref, <span class="Constant">0:literal</span>
+    5:address:array:character<span class="Special"> &lt;- </span>index 2:address:array:address:array:character/deref, <span class="Constant">1:literal</span>
+    6:address:array:character<span class="Special"> &lt;- </span>index 2:address:array:address:array:character/deref, <span class="Constant">2:literal</span>
+    7:address:array:character<span class="Special"> &lt;- </span>index 2:address:array:address:array:character/deref, <span class="Constant">3:literal</span>
+    10:array:character<span class="Special"> &lt;- </span>copy 4:address:array:character/deref
+    20:array:character<span class="Special"> &lt;- </span>copy 5:address:array:character/deref
+    30:array:character<span class="Special"> &lt;- </span>copy 6:address:array:character/deref
+    40:array:character<span class="Special"> &lt;- </span>copy 7:address:array:character/deref
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>4  <span class="Comment"># length of result</span>
+    10:string<span class="Special"> &lt;- </span><span class="Constant">[a]</span>
+    20:string<span class="Special"> &lt;- </span><span class="Constant">[b]</span>
+    30:string<span class="Special"> &lt;- </span><span class="Constant">[]</span>
+    40:string<span class="Special"> &lt;- </span><span class="Constant">[c]</span>
+  ]
+]
+
+<span class="Comment"># x:address:array:character, y:address:array:character &lt;- split-first text:address:array:character, delim:character</span>
+<span class="muRecipe">recipe</span> split-first [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  text:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  delim:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Comment"># empty string? return empty strings</span>
+  len:number<span class="Special"> &lt;- </span>length text:address:array:character/deref
+  <span class="Delimiter">{</span>
+    empty?:boolean<span class="Special"> &lt;- </span>equal len:number, <span class="Constant">0:literal</span>
+    <span class="muControl">break-unless</span> empty?:boolean
+    x:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
+    y:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
+    <span class="muControl">reply</span> x:address:array:character, y:address:array:character
+  <span class="Delimiter">}</span>
+  idx:number<span class="Special"> &lt;- </span>find-next text:address:array:character, delim:character, <span class="Constant">0:literal</span>
+  x:address:array:character<span class="Special"> &lt;- </span>string-copy text:address:array:character, <span class="Constant">0:literal</span>, idx:number
+  idx:number<span class="Special"> &lt;- </span>add idx:number, <span class="Constant">1:literal</span>
+  y:address:array:character<span class="Special"> &lt;- </span>string-copy text:address:array:character, idx:number, len:number
+  <span class="muControl">reply</span> x:address:array:character, y:address:array:character
+]
+
+<span class="muScenario">scenario</span> string-split-first [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[a/b]</span>
+    2:address:array:character, 3:address:array:character<span class="Special"> &lt;- </span>split-first 1:address:array:character, <span class="Constant">47:literal/slash</span>
+    10:array:character<span class="Special"> &lt;- </span>copy 2:address:array:character/deref
+    20:array:character<span class="Special"> &lt;- </span>copy 3:address:array:character/deref
+  ]
+  memory-should-contain [
+    10:string<span class="Special"> &lt;- </span><span class="Constant">[a]</span>
+    20:string<span class="Special"> &lt;- </span><span class="Constant">[b]</span>
+  ]
+]
+
+<span class="Comment"># result:address:array:character &lt;- string-copy buf:address:array:character, start:number, end:number</span>
+<span class="Comment"># todo: make this generic</span>
+<span class="muRecipe">recipe</span> string-copy [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  buf:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  start:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  end:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Comment"># if end is out of bounds, trim it</span>
+  len:number<span class="Special"> &lt;- </span>length buf:address:array:character/deref
+  end:number<span class="Special"> &lt;- </span>min len:number, end:number
+  <span class="Comment"># allocate space for result</span>
+  len:number<span class="Special"> &lt;- </span>subtract end:number, start:number
+  result:address:array:character<span class="Special"> &lt;- </span>new character:type, len:number
+  <span class="Comment"># copy start..end into result[curr-result]</span>
+  src-idx:number<span class="Special"> &lt;- </span>copy start:number
+  dest-idx:number<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
+  <span class="Delimiter">{</span>
+    done?:boolean<span class="Special"> &lt;- </span>greater-or-equal src-idx:number, end:number
+    <span class="muControl">break-if</span> done?:boolean
+    src:character<span class="Special"> &lt;- </span>index buf:address:array:character/deref, src-idx:number
+    dest:address:character<span class="Special"> &lt;- </span>index-address result:address:array:character/deref, dest-idx:number
+    dest:address:character/deref<span class="Special"> &lt;- </span>copy src:character
+    src-idx:number<span class="Special"> &lt;- </span>add src-idx:number, <span class="Constant">1:literal</span>
+    dest-idx:number<span class="Special"> &lt;- </span>add dest-idx:number, <span class="Constant">1:literal</span>
+    <span class="muControl">loop</span>
+  <span class="Delimiter">}</span>
+  <span class="muControl">reply</span> result:address:array:character
+]
+
+<span class="muScenario">scenario</span> string-copy-copies-substring [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>string-copy 1:address:array:character, <span class="Constant">1:literal</span>, <span class="Constant">3:literal</span>
+    3:array:character<span class="Special"> &lt;- </span>copy 2:address:array:character/deref
+  ]
+  memory-should-contain [
+    3:string<span class="Special"> &lt;- </span><span class="Constant">[bc]</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> string-copy-out-of-bounds [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>string-copy 1:address:array:character, <span class="Constant">2:literal</span>, <span class="Constant">4:literal</span>
+    3:array:character<span class="Special"> &lt;- </span>copy 2:address:array:character/deref
+  ]
+  memory-should-contain [
+    3:string<span class="Special"> &lt;- </span><span class="Constant">[c]</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> string-copy-out-of-bounds-2 [
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:address:array:character<span class="Special"> &lt;- </span>string-copy 1:address:array:character, <span class="Constant">3:literal</span>, <span class="Constant">3:literal</span>
+    3:array:character<span class="Special"> &lt;- </span>copy 2:address:array:character/deref
+  ]
+  memory-should-contain [
+    3:string<span class="Special"> &lt;- </span><span class="Constant">[]</span>
+  ]
+]
+
+<span class="muRecipe">recipe</span> min [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  x:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  y:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Delimiter">{</span>
+    return-x?:boolean<span class="Special"> &lt;- </span>lesser-than x:number, y:number
+    <span class="muControl">break-if</span> return-x?:boolean
+    <span class="muControl">reply</span> y:number
+  <span class="Delimiter">}</span>
+  <span class="muControl">reply</span> x:number
+]
+
+<span class="muRecipe">recipe</span> max [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  x:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  y:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Delimiter">{</span>
+    return-x?:boolean<span class="Special"> &lt;- </span>greater-than x:number, y:number
+    <span class="muControl">break-if</span> return-x?:boolean
+    <span class="muControl">reply</span> y:number
+  <span class="Delimiter">}</span>
+  <span class="muControl">reply</span> x:number
+]
 </pre>
 </body>
 </html>
diff --git a/html/061channel.mu.html b/html/061channel.mu.html
index 4122d241..42ffdada 100644
--- a/html/061channel.mu.html
+++ b/html/061channel.mu.html
@@ -12,15 +12,15 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .muScenario { color: #00af00; }
-.Delimiter { color: #c000c0; }
+.Delimiter { color: #a04060; }
 .SalientComment { color: #00ffff; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
-.muControl { color: #804000; }
+.Comment { color: #9090ff; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
@@ -45,7 +45,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> channel [
   run [
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">3:literal/capacity</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">3:literal/capacity</span>
     1:address:channel<span class="Special"> &lt;- </span>write 1:address:channel, <span class="Constant">34:literal</span>
     2:number, 1:address:channel<span class="Special"> &lt;- </span>read 1:address:channel
   ]
@@ -66,8 +66,8 @@ container channel [
   data:address:array:location
 ]
 
-<span class="Comment"># result:address:channel &lt;- init-channel capacity:number</span>
-<span class="muRecipe">recipe</span> init-channel [
+<span class="Comment"># result:address:channel &lt;- new-channel capacity:number</span>
+<span class="muRecipe">recipe</span> new-channel [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   <span class="Comment"># result = new channel</span>
   result:address:channel<span class="Special"> &lt;- </span>new channel:type
@@ -154,7 +154,7 @@ container channel [
 
 <span class="muScenario">scenario</span> channel-initialization [
   run [
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">3:literal/capacity</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">3:literal/capacity</span>
     2:number<span class="Special"> &lt;- </span>get 1:address:channel/deref, first-full:offset
     3:number<span class="Special"> &lt;- </span>get 1:address:channel/deref, first-free:offset
   ]
@@ -166,7 +166,7 @@ container channel [
 
 <span class="muScenario">scenario</span> channel-write-increments-free [
   run [
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">3:literal/capacity</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">3:literal/capacity</span>
     1:address:channel<span class="Special"> &lt;- </span>write 1:address:channel, <span class="Constant">34:literal</span>
     2:number<span class="Special"> &lt;- </span>get 1:address:channel/deref, first-full:offset
     3:number<span class="Special"> &lt;- </span>get 1:address:channel/deref, first-free:offset
@@ -179,7 +179,7 @@ container channel [
 
 <span class="muScenario">scenario</span> channel-read-increments-full [
   run [
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">3:literal/capacity</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">3:literal/capacity</span>
     1:address:channel<span class="Special"> &lt;- </span>write 1:address:channel, <span class="Constant">34:literal</span>
     _, 1:address:channel<span class="Special"> &lt;- </span>read 1:address:channel
     2:number<span class="Special"> &lt;- </span>get 1:address:channel/deref, first-full:offset
@@ -194,7 +194,7 @@ container channel [
 <span class="muScenario">scenario</span> channel-wrap [
   run [
     <span class="Comment"># channel with just 1 slot</span>
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">1:literal/capacity</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">1:literal/capacity</span>
     <span class="Comment"># write and read a value</span>
     1:address:channel<span class="Special"> &lt;- </span>write 1:address:channel, <span class="Constant">34:literal</span>
     _, 1:address:channel<span class="Special"> &lt;- </span>read 1:address:channel
@@ -261,7 +261,7 @@ container channel [
 
 <span class="muScenario">scenario</span> channel-new-empty-not-full [
   run [
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">3:literal/capacity</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">3:literal/capacity</span>
     2:boolean<span class="Special"> &lt;- </span>channel-empty? 1:address:channel
     3:boolean<span class="Special"> &lt;- </span>channel-full? 1:address:channel
   ]
@@ -273,7 +273,7 @@ container channel [
 
 <span class="muScenario">scenario</span> channel-write-not-empty [
   run [
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">3:literal/capacity</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">3:literal/capacity</span>
     1:address:channel<span class="Special"> &lt;- </span>write 1:address:channel, <span class="Constant">34:literal</span>
     2:boolean<span class="Special"> &lt;- </span>channel-empty? 1:address:channel
     3:boolean<span class="Special"> &lt;- </span>channel-full? 1:address:channel
@@ -286,7 +286,7 @@ container channel [
 
 <span class="muScenario">scenario</span> channel-write-full [
   run [
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">1:literal/capacity</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">1:literal/capacity</span>
     1:address:channel<span class="Special"> &lt;- </span>write 1:address:channel, <span class="Constant">34:literal</span>
     2:boolean<span class="Special"> &lt;- </span>channel-empty? 1:address:channel
     3:boolean<span class="Special"> &lt;- </span>channel-full? 1:address:channel
@@ -299,7 +299,7 @@ container channel [
 
 <span class="muScenario">scenario</span> channel-read-not-full [
   run [
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">1:literal/capacity</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">1:literal/capacity</span>
     1:address:channel<span class="Special"> &lt;- </span>write 1:address:channel, <span class="Constant">34:literal</span>
     _, 1:address:channel<span class="Special"> &lt;- </span>read 1:address:channel
     2:boolean<span class="Special"> &lt;- </span>channel-empty? 1:address:channel
@@ -321,7 +321,7 @@ container channel [
   out:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="Comment"># repeat forever</span>
   <span class="Delimiter">{</span>
-    line:address:buffer<span class="Special"> &lt;- </span>init-buffer, <span class="Constant">30:literal</span>
+    line:address:buffer<span class="Special"> &lt;- </span>new-buffer, <span class="Constant">30:literal</span>
     <span class="Comment"># read characters from 'in' until newline, copy into line</span>
     <span class="Delimiter">{</span>
 <span class="Constant">      +next-character</span>
@@ -332,7 +332,7 @@ container channel [
         backspace?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">8:literal</span>
         <span class="muControl">break-unless</span> backspace?:boolean
         <span class="Comment"># drop previous character</span>
-<span class="CommentedCode">#?         return-to-console #? 2</span>
+<span class="CommentedCode">#?         close-console #? 2</span>
 <span class="CommentedCode">#?         $print [backspace! #? 1</span>
 <span class="CommentedCode">#? ] #? 1</span>
         <span class="Delimiter">{</span>
@@ -355,12 +355,12 @@ container channel [
       line:address:buffer<span class="Special"> &lt;- </span>buffer-append line:address:buffer, c:character
       line-done?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">10:literal/newline</span>
       <span class="muControl">break-if</span> line-done?:boolean
-      <span class="Comment"># stop buffering on eof (currently only generated by fake keyboard)</span>
-      empty-fake-keyboard?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">0:literal/eof</span>
-      <span class="muControl">break-if</span> empty-fake-keyboard?:boolean
+      <span class="Comment"># stop buffering on eof (currently only generated by fake console)</span>
+      eof?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">0:literal/eof</span>
+      <span class="muControl">break-if</span> eof?:boolean
       <span class="muControl">loop</span>
     <span class="Delimiter">}</span>
-<span class="CommentedCode">#?     return-to-console #? 1</span>
+<span class="CommentedCode">#?     close-console #? 1</span>
     <span class="Comment"># copy line into 'out'</span>
 <span class="CommentedCode">#?     $print [buffer-lines: emitting</span>
 <span class="CommentedCode">#? ]</span>
@@ -386,8 +386,8 @@ container channel [
 
 <span class="muScenario">scenario</span> buffer-lines-blocks-until-newline [
   run [
-    1:address:channel/stdin<span class="Special"> &lt;- </span>init-channel <span class="Constant">10:literal/capacity</span>
-    2:address:channel/buffered-stdin<span class="Special"> &lt;- </span>init-channel <span class="Constant">10:literal/capacity</span>
+    1:address:channel/stdin<span class="Special"> &lt;- </span>new-channel <span class="Constant">10:literal/capacity</span>
+    2:address:channel/buffered-stdin<span class="Special"> &lt;- </span>new-channel <span class="Constant">10:literal/capacity</span>
     3:boolean<span class="Special"> &lt;- </span>channel-empty? 2:address:channel/buffered-stdin
     assert 3:boolean, [
 F buffer-lines-blocks-until-newline: channel should be empty <span class="muRecipe">after</span> init]
diff --git a/html/062array.mu.html b/html/062array.mu.html
index e7b4cb3a..299748d7 100644
--- a/html/062array.mu.html
+++ b/html/062array.mu.html
@@ -12,13 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .muScenario { color: #00af00; }
-.Delimiter { color: #c000c0; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+.Delimiter { color: #a04060; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.muControl { color: #804000; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
@@ -33,7 +33,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <pre id='vimCodeElement'>
 <span class="muScenario">scenario</span> array-from-args [
   run [
-    1:address:array:location<span class="Special"> &lt;- </span>init-array <span class="Constant">0:literal</span>, <span class="Constant">1:literal</span>, <span class="Constant">2:literal</span>
+    1:address:array:location<span class="Special"> &lt;- </span>new-array <span class="Constant">0:literal</span>, <span class="Constant">1:literal</span>, <span class="Constant">2:literal</span>
     2:array:location<span class="Special"> &lt;- </span>copy 1:address:array:location/deref
   ]
   memory-should-contain [
@@ -45,7 +45,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 ]
 
 <span class="Comment"># create an array out of a list of scalar args</span>
-<span class="muRecipe">recipe</span> init-array [
+<span class="muRecipe">recipe</span> new-array [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   capacity:number<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
   <span class="Delimiter">{</span>
@@ -63,7 +63,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     done?:boolean<span class="Special"> &lt;- </span>greater-or-equal i:number, capacity:number
     <span class="muControl">break-if</span> done?:boolean
     curr-value:location, exists?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-    assert exists?:boolean, <span class="Constant">[error in rewinding ingredients to init-array]</span>
+    assert exists?:boolean, <span class="Constant">[error in rewinding ingredients to new-array]</span>
     tmp:address:location<span class="Special"> &lt;- </span>index-address result:address:array:location/deref, i:number
     tmp:address:location/deref<span class="Special"> &lt;- </span>copy curr-value:location
     i:number<span class="Special"> &lt;- </span>add i:number, <span class="Constant">1:literal</span>
diff --git a/html/063list.mu.html b/html/063list.mu.html
index cd1a7b40..fa128a0b 100644
--- a/html/063list.mu.html
+++ b/html/063list.mu.html
@@ -12,13 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .muScenario { color: #00af00; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
-.muControl { color: #804000; }
+.Comment { color: #9090ff; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
diff --git a/html/064random.cc.html b/html/064random.cc.html
index 27c847a2..f783de38 100644
--- a/html/064random.cc.html
+++ b/html/064random.cc.html
@@ -12,12 +12,12 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Constant { color: #008080; }
+.Constant { color: #00a0a0; }
 .PreProc { color: #c000c0; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
 -->
diff --git a/html/065duplex_list.mu.html b/html/065duplex_list.mu.html
new file mode 100644
index 00000000..6f81c5fa
--- /dev/null
+++ b/html/065duplex_list.mu.html
@@ -0,0 +1,407 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 065duplex_list.mu</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="none">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.muScenario { color: #00af00; }
+.Delimiter { color: #a04060; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
+.Special { color: #ff6060; }
+.Comment { color: #9090ff; }
+.muControl { color: #c0a020; }
+.muRecipe { color: #ff8700; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment"># A doubly linked list permits bidirectional traversal.</span>
+
+container duplex-list [
+  value:location
+  next:address:duplex-list
+  prev:address:duplex-list
+]
+
+<span class="Comment"># result:address:duplex-list &lt;- push-duplex x:location, in:address:duplex-list</span>
+<span class="muRecipe">recipe</span> push-duplex [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  x:location<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  in:address:duplex-list<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  result:address:duplex-list<span class="Special"> &lt;- </span>new duplex-list:type
+  val:address:location<span class="Special"> &lt;- </span>get-address result:address:duplex-list/deref, value:offset
+  val:address:location/deref<span class="Special"> &lt;- </span>copy x:location
+  next:address:address:duplex-list<span class="Special"> &lt;- </span>get-address result:address:duplex-list/deref, next:offset
+  next:address:address:duplex-list/deref<span class="Special"> &lt;- </span>copy in:address:duplex-list
+  <span class="muControl">reply-unless</span> in:address:duplex-list, result:address:duplex-list
+  prev:address:address:duplex-list<span class="Special"> &lt;- </span>get-address in:address:duplex-list/deref, prev:offset
+  prev:address:address:duplex-list/deref<span class="Special"> &lt;- </span>copy result:address:duplex-list
+  <span class="muControl">reply</span> result:address:duplex-list
+]
+
+<span class="Comment"># result:location &lt;- first-duplex in:address:duplex-list</span>
+<span class="muRecipe">recipe</span> first-duplex [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  in:address:duplex-list<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="muControl">reply-unless</span> in:address:duplex-list, <span class="Constant">0:literal</span>
+  result:location<span class="Special"> &lt;- </span>get in:address:duplex-list/deref, value:offset
+  <span class="muControl">reply</span> result:location
+]
+
+<span class="Comment"># result:address:duplex-list &lt;- next-duplex in:address:duplex-list</span>
+<span class="muRecipe">recipe</span> next-duplex [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  in:address:duplex-list<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="muControl">reply-unless</span> in:address:duplex-list, <span class="Constant">0:literal</span>
+  result:address:duplex-list<span class="Special"> &lt;- </span>get in:address:duplex-list/deref, next:offset
+  <span class="muControl">reply</span> result:address:duplex-list
+]
+
+<span class="Comment"># result:address:duplex-list &lt;- prev-duplex in:address:duplex-list</span>
+<span class="muRecipe">recipe</span> prev-duplex [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  in:address:duplex-list<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="muControl">reply-unless</span> in:address:duplex-list, <span class="Constant">0:literal</span>
+  result:address:duplex-list<span class="Special"> &lt;- </span>get in:address:duplex-list/deref, prev:offset
+  <span class="muControl">reply</span> result:address:duplex-list
+]
+
+<span class="muScenario">scenario</span> duplex-list-handling [
+  run [
+    <span class="Comment"># reserve locations 0, 1 and 2 to check for missing null check</span>
+    1:number<span class="Special"> &lt;- </span>copy <span class="Constant">34:literal</span>
+    2:number<span class="Special"> &lt;- </span>copy <span class="Constant">35:literal</span>
+    3:address:duplex-list<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
+    3:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3:literal</span>, 3:address:duplex-list
+    3:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">4:literal</span>, 3:address:duplex-list
+    3:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">5:literal</span>, 3:address:duplex-list
+    4:address:duplex-list<span class="Special"> &lt;- </span>copy 3:address:duplex-list
+    5:number<span class="Special"> &lt;- </span>first 4:address:duplex-list
+    4:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 4:address:duplex-list
+    6:number<span class="Special"> &lt;- </span>first 4:address:duplex-list
+    4:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 4:address:duplex-list
+    7:number<span class="Special"> &lt;- </span>first 4:address:duplex-list
+    8:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 4:address:duplex-list
+    9:number<span class="Special"> &lt;- </span>first 8:address:duplex-list
+    10:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 8:address:duplex-list
+    11:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 8:address:duplex-list
+    4:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 4:address:duplex-list
+    12:number<span class="Special"> &lt;- </span>first 4:address:duplex-list
+    4:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 4:address:duplex-list
+    13:number<span class="Special"> &lt;- </span>first 4:address:duplex-list
+    14:boolean<span class="Special"> &lt;- </span>equal 3:address:duplex-list, 4:address:duplex-list
+<span class="CommentedCode">#?     $dump-trace #? 1</span>
+  ]
+  memory-should-contain [
+    0<span class="Special"> &lt;- </span>0  <span class="Comment"># no modifications to null pointers</span>
+    1<span class="Special"> &lt;- </span>34
+    2<span class="Special"> &lt;- </span>35
+    5<span class="Special"> &lt;- </span>5  <span class="Comment"># scanning next</span>
+    6<span class="Special"> &lt;- </span>4
+    7<span class="Special"> &lt;- </span>3
+    8<span class="Special"> &lt;- </span>0  <span class="Comment"># null</span>
+    9<span class="Special"> &lt;- </span>0  <span class="Comment"># first of null</span>
+    10<span class="Special"> &lt;- </span>0  <span class="Comment"># next of null</span>
+    11<span class="Special"> &lt;- </span>0  <span class="Comment"># prev of null</span>
+    12<span class="Special"> &lt;- </span>4  <span class="Comment"># then start scanning prev</span>
+    13<span class="Special"> &lt;- </span>5
+    14<span class="Special"> &lt;- </span>1  <span class="Comment"># list back at start</span>
+  ]
+]
+
+<span class="Comment"># l:address:duplex-list &lt;- insert-duplex x:location, in:address:duplex-list</span>
+<span class="Comment"># Inserts 'x' after 'in'. Returns some pointer into the list.</span>
+<span class="muRecipe">recipe</span> insert-duplex [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  x:location<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  in:address:duplex-list<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  new-node:address:duplex-list<span class="Special"> &lt;- </span>new duplex-list:type
+  val:address:location<span class="Special"> &lt;- </span>get-address new-node:address:duplex-list/deref, value:offset
+  val:address:location/deref<span class="Special"> &lt;- </span>copy x:location
+  next-node:address:duplex-list<span class="Special"> &lt;- </span>get in:address:duplex-list/deref, next:offset
+  <span class="Comment"># in.next = new-node</span>
+  y:address:address:duplex-list<span class="Special"> &lt;- </span>get-address in:address:duplex-list/deref, next:offset
+  y:address:address:duplex-list/deref<span class="Special"> &lt;- </span>copy new-node:address:duplex-list
+  <span class="Comment"># new-node.prev = in</span>
+  y:address:address:duplex-list<span class="Special"> &lt;- </span>get-address new-node:address:duplex-list/deref, prev:offset
+  y:address:address:duplex-list/deref<span class="Special"> &lt;- </span>copy in:address:duplex-list
+  <span class="Comment"># new-node.next = next-node</span>
+  y:address:address:duplex-list<span class="Special"> &lt;- </span>get-address new-node:address:duplex-list/deref, next:offset
+  y:address:address:duplex-list/deref<span class="Special"> &lt;- </span>copy next-node:address:duplex-list
+  <span class="Comment"># if next-node is not null</span>
+  <span class="muControl">reply-unless</span> next-node:address:duplex-list, new-node:address:duplex-list
+  <span class="Comment"># next-node.prev = new-node</span>
+  y:address:address:duplex-list<span class="Special"> &lt;- </span>get-address next-node:address:duplex-list/deref, prev:offset
+  y:address:address:duplex-list/deref<span class="Special"> &lt;- </span>copy new-node:address:duplex-list
+  <span class="muControl">reply</span> new-node:address:duplex-list  <span class="Comment"># just signalling something changed; don't rely on the result</span>
+]
+
+<span class="muScenario">scenario</span> inserting-into-duplex-list [
+  run [
+    1:address:duplex-list<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>  <span class="Comment"># 1 points to head of list</span>
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3:literal</span>, 1:address:duplex-list
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">4:literal</span>, 1:address:duplex-list
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">5:literal</span>, 1:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 1:address:duplex-list  <span class="Comment"># 2 points inside list</span>
+    2:address:duplex-list<span class="Special"> &lt;- </span>insert-duplex <span class="Constant">6:literal</span>, 2:address:duplex-list
+    <span class="Comment"># check structure like before</span>
+    2:address:duplex-list<span class="Special"> &lt;- </span>copy 1:address:duplex-list
+    3:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    4:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    5:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    6:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 2:address:duplex-list
+    7:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 2:address:duplex-list
+    8:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 2:address:duplex-list
+    9:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    10:boolean<span class="Special"> &lt;- </span>equal 1:address:duplex-list, 2:address:duplex-list
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>5  <span class="Comment"># scanning next</span>
+    4<span class="Special"> &lt;- </span>4
+    5<span class="Special"> &lt;- </span>6  <span class="Comment"># inserted element</span>
+    6<span class="Special"> &lt;- </span>3
+    7<span class="Special"> &lt;- </span>6  <span class="Comment"># then prev</span>
+    8<span class="Special"> &lt;- </span>4
+    9<span class="Special"> &lt;- </span>5
+    10<span class="Special"> &lt;- </span>1  <span class="Comment"># list back at start</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> inserting-at-end-of-duplex-list [
+  run [
+    1:address:duplex-list<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>  <span class="Comment"># 1 points to head of list</span>
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3:literal</span>, 1:address:duplex-list
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">4:literal</span>, 1:address:duplex-list
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">5:literal</span>, 1:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 1:address:duplex-list  <span class="Comment"># 2 points inside list</span>
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list  <span class="Comment"># now at end of list</span>
+    2:address:duplex-list<span class="Special"> &lt;- </span>insert-duplex <span class="Constant">6:literal</span>, 2:address:duplex-list
+    <span class="Comment"># check structure like before</span>
+    2:address:duplex-list<span class="Special"> &lt;- </span>copy 1:address:duplex-list
+    3:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    4:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    5:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    6:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 2:address:duplex-list
+    7:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 2:address:duplex-list
+    8:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 2:address:duplex-list
+    9:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    10:boolean<span class="Special"> &lt;- </span>equal 1:address:duplex-list, 2:address:duplex-list
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>5  <span class="Comment"># scanning next</span>
+    4<span class="Special"> &lt;- </span>4
+    5<span class="Special"> &lt;- </span>3
+    6<span class="Special"> &lt;- </span>6  <span class="Comment"># inserted element</span>
+    7<span class="Special"> &lt;- </span>3  <span class="Comment"># then prev</span>
+    8<span class="Special"> &lt;- </span>4
+    9<span class="Special"> &lt;- </span>5
+    10<span class="Special"> &lt;- </span>1  <span class="Comment"># list back at start</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> inserting-after-start-of-duplex-list [
+  run [
+    1:address:duplex-list<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>  <span class="Comment"># 1 points to head of list</span>
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3:literal</span>, 1:address:duplex-list
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">4:literal</span>, 1:address:duplex-list
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">5:literal</span>, 1:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>insert-duplex <span class="Constant">6:literal</span>, 1:address:duplex-list
+    <span class="Comment"># check structure like before</span>
+    2:address:duplex-list<span class="Special"> &lt;- </span>copy 1:address:duplex-list
+    3:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    4:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    5:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    6:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 2:address:duplex-list
+    7:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 2:address:duplex-list
+    8:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 2:address:duplex-list
+    9:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    10:boolean<span class="Special"> &lt;- </span>equal 1:address:duplex-list, 2:address:duplex-list
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>5  <span class="Comment"># scanning next</span>
+    4<span class="Special"> &lt;- </span>6  <span class="Comment"># inserted element</span>
+    5<span class="Special"> &lt;- </span>4
+    6<span class="Special"> &lt;- </span>3
+    7<span class="Special"> &lt;- </span>4  <span class="Comment"># then prev</span>
+    8<span class="Special"> &lt;- </span>6
+    9<span class="Special"> &lt;- </span>5
+    10<span class="Special"> &lt;- </span>1  <span class="Comment"># list back at start</span>
+  ]
+]
+
+<span class="Comment"># l:address:duplex-list &lt;- remove-duplex in:address:duplex-list</span>
+<span class="Comment"># Removes 'in' from its surrounding list. Returns some valid pointer into the</span>
+<span class="Comment"># rest of the list.</span>
+<span class="Comment">#</span>
+<span class="Comment"># Returns null if and only if list is empty. Beware: in that case any pointers</span>
+<span class="Comment"># to the head are now invalid.</span>
+<span class="muRecipe">recipe</span> remove-duplex [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  in:address:duplex-list<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Comment"># if 'in' is null, return</span>
+  <span class="muControl">reply-unless</span> in:address:duplex-list, in:address:duplex-list
+  next-node:address:duplex-list<span class="Special"> &lt;- </span>get in:address:duplex-list/deref, next:offset
+  prev-node:address:duplex-list<span class="Special"> &lt;- </span>get in:address:duplex-list/deref, prev:offset
+  <span class="Comment"># null in's pointers</span>
+  x:address:address:duplex-list<span class="Special"> &lt;- </span>get-address in:address:duplex-list/deref, next:offset
+  x:address:address:duplex-list/deref<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
+  x:address:address:duplex-list<span class="Special"> &lt;- </span>get-address in:address:duplex-list/deref, prev:offset
+  x:address:address:duplex-list/deref<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
+  <span class="Delimiter">{</span>
+    <span class="Comment"># if next-node is not null</span>
+    <span class="muControl">break-unless</span> next-node:address:duplex-list
+    <span class="Comment"># next-node.prev = prev-node</span>
+    x:address:address:duplex-list<span class="Special"> &lt;- </span>get-address next-node:address:duplex-list/deref, prev:offset
+    x:address:address:duplex-list/deref<span class="Special"> &lt;- </span>copy prev-node:address:duplex-list
+  <span class="Delimiter">}</span>
+  <span class="Delimiter">{</span>
+    <span class="Comment"># if prev-node is not null</span>
+    <span class="muControl">break-unless</span> prev-node:address:duplex-list
+    <span class="Comment"># prev-node.next = next-node</span>
+    x:address:address:duplex-list<span class="Special"> &lt;- </span>get-address prev-node:address:duplex-list/deref, next:offset
+    x:address:address:duplex-list/deref<span class="Special"> &lt;- </span>copy next-node:address:duplex-list
+    <span class="muControl">reply</span> prev-node:address:duplex-list
+  <span class="Delimiter">}</span>
+  <span class="muControl">reply</span> next-node:address:duplex-list
+]
+
+<span class="muScenario">scenario</span> removing-from-duplex-list [
+  run [
+    1:address:duplex-list<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>  <span class="Comment"># 1 points to head of list</span>
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3:literal</span>, 1:address:duplex-list
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">4:literal</span>, 1:address:duplex-list
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">5:literal</span>, 1:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 1:address:duplex-list  <span class="Comment"># 2 points at second element</span>
+    2:address:duplex-list<span class="Special"> &lt;- </span>remove-duplex 2:address:duplex-list
+    3:boolean<span class="Special"> &lt;- </span>equal 2:address:duplex-list, <span class="Constant">0:literal</span>
+    <span class="Comment"># check structure like before</span>
+    2:address:duplex-list<span class="Special"> &lt;- </span>copy 1:address:duplex-list
+    4:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    5:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    6:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 2:address:duplex-list
+    7:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    8:boolean<span class="Special"> &lt;- </span>equal 1:address:duplex-list, 2:address:duplex-list
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>0  <span class="Comment"># remove returned non-null</span>
+    4<span class="Special"> &lt;- </span>5  <span class="Comment"># scanning next, skipping deleted element</span>
+    5<span class="Special"> &lt;- </span>3
+    6<span class="Special"> &lt;- </span>0  <span class="Comment"># no more elements</span>
+    7<span class="Special"> &lt;- </span>5  <span class="Comment"># prev of final element</span>
+    8<span class="Special"> &lt;- </span>1  <span class="Comment"># list back at start</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> removing-from-start-of-duplex-list [
+  run [
+    1:address:duplex-list<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>  <span class="Comment"># 1 points to head of list</span>
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3:literal</span>, 1:address:duplex-list
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">4:literal</span>, 1:address:duplex-list
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">5:literal</span>, 1:address:duplex-list
+    <span class="Comment"># removing from head? return value matters.</span>
+    1:address:duplex-list<span class="Special"> &lt;- </span>remove-duplex 1:address:duplex-list
+    <span class="Comment"># check structure like before</span>
+    2:address:duplex-list<span class="Special"> &lt;- </span>copy 1:address:duplex-list
+    3:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    4:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    5:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 2:address:duplex-list
+    6:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    7:boolean<span class="Special"> &lt;- </span>equal 1:address:duplex-list, 2:address:duplex-list
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>4  <span class="Comment"># scanning next, skipping deleted element</span>
+    4<span class="Special"> &lt;- </span>3
+    5<span class="Special"> &lt;- </span>0  <span class="Comment"># no more elements</span>
+    6<span class="Special"> &lt;- </span>4  <span class="Comment"># prev of final element</span>
+    7<span class="Special"> &lt;- </span>1  <span class="Comment"># list back at start</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> removing-from-end-of-duplex-list [
+  run [
+    1:address:duplex-list<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>  <span class="Comment"># 1 points to head of list</span>
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3:literal</span>, 1:address:duplex-list
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">4:literal</span>, 1:address:duplex-list
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">5:literal</span>, 1:address:duplex-list
+    <span class="Comment"># delete last element</span>
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 1:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>remove-duplex 2:address:duplex-list
+    3:boolean<span class="Special"> &lt;- </span>equal 2:address:duplex-list, <span class="Constant">0:literal</span>
+    <span class="Comment"># check structure like before</span>
+    2:address:duplex-list<span class="Special"> &lt;- </span>copy 1:address:duplex-list
+    4:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    5:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    6:address:duplex-list<span class="Special"> &lt;- </span>next-duplex 2:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>prev-duplex 2:address:duplex-list
+    7:number<span class="Special"> &lt;- </span>first 2:address:duplex-list
+    8:boolean<span class="Special"> &lt;- </span>equal 1:address:duplex-list, 2:address:duplex-list
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>0  <span class="Comment"># remove returned non-null</span>
+    4<span class="Special"> &lt;- </span>5  <span class="Comment"># scanning next, skipping deleted element</span>
+    5<span class="Special"> &lt;- </span>4
+    6<span class="Special"> &lt;- </span>0  <span class="Comment"># no more elements</span>
+    7<span class="Special"> &lt;- </span>5  <span class="Comment"># prev of final element</span>
+    8<span class="Special"> &lt;- </span>1  <span class="Comment"># list back at start</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> removing-from-singleton-list [
+  run [
+    1:address:duplex-list<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>  <span class="Comment"># 1 points to singleton list</span>
+    1:address:duplex-list<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3:literal</span>, 1:address:duplex-list
+    2:address:duplex-list<span class="Special"> &lt;- </span>remove-duplex 1:address:duplex-list
+    3:address:duplex-list<span class="Special"> &lt;- </span>get 1:address:duplex-list/deref, next:offset
+    4:address:duplex-list<span class="Special"> &lt;- </span>get 1:address:duplex-list/deref, prev:offset
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>0  <span class="Comment"># remove returned null</span>
+    3<span class="Special"> &lt;- </span>0  <span class="Comment"># removed node is also detached</span>
+    4<span class="Special"> &lt;- </span>0
+  ]
+]
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/066stream.mu.html b/html/066stream.mu.html
new file mode 100644
index 00000000..feba9cf7
--- /dev/null
+++ b/html/066stream.mu.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 066stream.mu</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="none">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
+.Special { color: #ff6060; }
+.muControl { color: #c0a020; }
+.muRecipe { color: #ff8700; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment"># new type to help incrementally read strings</span>
+container stream [
+  index:number
+  data:address:array:character
+]
+
+<span class="muRecipe">recipe</span> new-stream [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  result:address:stream<span class="Special"> &lt;- </span>new stream:type
+  i:address:number<span class="Special"> &lt;- </span>get-address result:address:stream/deref, index:offset
+  i:address:number/deref<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
+  d:address:address:array:character<span class="Special"> &lt;- </span>get-address result:address:stream/deref, data:offset
+  d:address:address:array:character/deref<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="muControl">reply</span> result:address:stream
+]
+
+<span class="muRecipe">recipe</span> rewind-stream [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  in:address:stream<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  x:address:number<span class="Special"> &lt;- </span>get-address in:address:stream/deref, index:offset
+  x:address:number/deref<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
+  <span class="muControl">reply</span> in:address:stream/same-as-arg:0
+]
+
+<span class="muRecipe">recipe</span> read-line [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  in:address:stream<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  idx:address:number<span class="Special"> &lt;- </span>get-address in:address:stream/deref, index:offset
+  s:address:array:character<span class="Special"> &lt;- </span>get in:address:stream/deref, data:offset
+  next-idx:number<span class="Special"> &lt;- </span>find-next s:address:array:character, <span class="Constant">10:literal/newline</span>, idx:address:number/deref
+  result:address:array:character<span class="Special"> &lt;- </span>string-copy s:address:array:character, idx:address:number/deref, next-idx:number
+  idx:address:number/deref<span class="Special"> &lt;- </span>add next-idx:number, <span class="Constant">1:literal</span>  <span class="Comment"># skip newline</span>
+  <span class="muControl">reply</span> result:address:array:character
+]
+
+<span class="muRecipe">recipe</span> end-of-stream? [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  in:address:stream<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  idx:number<span class="Special"> &lt;- </span>get in:address:stream/deref, index:offset
+  s:address:array:character<span class="Special"> &lt;- </span>get in:address:stream/deref, data:offset
+  len:number<span class="Special"> &lt;- </span>length s:address:array:character/deref
+  result:boolean<span class="Special"> &lt;- </span>greater-or-equal idx:number, len:number
+  <span class="muControl">reply</span> result:boolean
+]
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/070display.cc.html b/html/070display.cc.html
index 9b31520f..24b460f0 100644
--- a/html/070display.cc.html
+++ b/html/070display.cc.html
@@ -12,14 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.PreProc { color: #c000c0; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .SalientComment { color: #00ffff; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
@@ -32,10 +31,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 </head>
 <body>
 <pre id='vimCodeElement'>
-<span class="Comment">//: Take charge of the text-mode display and keyboard.</span>
+<span class="Comment">//: Take charge of the text-mode display and console.</span>
 
-<span class="Comment">// uncomment to debug console programs</span>
 <span class="Delimiter">:(before &quot;End Globals&quot;)</span>
+<span class="Comment">// uncomment to debug console programs</span>
 <span class="CommentedCode">//? ofstream LOG(&quot;log.txt&quot;);</span>
 
 <span class="SalientComment">//:: Display management</span>
@@ -44,23 +43,23 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 long long int Display_row = <span class="Constant">0</span><span class="Delimiter">,</span> Display_column = <span class="Constant">0</span><span class="Delimiter">;</span>
 
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
-SWITCH_TO_DISPLAY<span class="Delimiter">,</span>
+OPEN_CONSOLE<span class="Delimiter">,</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
-Recipe_number[<span class="Constant">&quot;switch-to-display&quot;</span>] = SWITCH_TO_DISPLAY<span class="Delimiter">;</span>
-<span class="CommentedCode">//? cerr &lt;&lt; &quot;switch-to-display: &quot; &lt;&lt; SWITCH_TO_DISPLAY &lt;&lt; '\n'; //? 1</span>
+Recipe_number[<span class="Constant">&quot;open-console&quot;</span>] = OPEN_CONSOLE<span class="Delimiter">;</span>
+<span class="CommentedCode">//? cerr &lt;&lt; &quot;open-console: &quot; &lt;&lt; OPEN_CONSOLE &lt;&lt; '\n'; //? 1</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
-case SWITCH_TO_DISPLAY: <span class="Delimiter">{</span>
+case OPEN_CONSOLE: <span class="Delimiter">{</span>
   tb_init<span class="Delimiter">();</span>
   Display_row = Display_column = <span class="Constant">0</span><span class="Delimiter">;</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
-RETURN_TO_CONSOLE<span class="Delimiter">,</span>
+CLOSE_CONSOLE<span class="Delimiter">,</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
-Recipe_number[<span class="Constant">&quot;return-to-console&quot;</span>] = RETURN_TO_CONSOLE<span class="Delimiter">;</span>
+Recipe_number[<span class="Constant">&quot;close-console&quot;</span>] = CLOSE_CONSOLE<span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
-case RETURN_TO_CONSOLE: <span class="Delimiter">{</span>
+case CLOSE_CONSOLE: <span class="Delimiter">{</span>
   tb_shutdown<span class="Delimiter">();</span>
 <span class="CommentedCode">//?   Trace_stream-&gt;dump_layer = &quot;all&quot;; //? 1</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -253,53 +252,73 @@ case DISPLAY_HEIGHT: <span class="Delimiter">{</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
-<span class="SalientComment">//:: Keyboard management</span>
+<span class="SalientComment">//:: Keyboard/mouse management</span>
 
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
-WAIT_FOR_KEY_FROM_KEYBOARD<span class="Delimiter">,</span>
+WAIT_FOR_SOME_INTERACTION<span class="Delimiter">,</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
-Recipe_number[<span class="Constant">&quot;wait-for-key-from-keyboard&quot;</span>] = WAIT_FOR_KEY_FROM_KEYBOARD<span class="Delimiter">;</span>
+Recipe_number[<span class="Constant">&quot;wait-for-some-interaction&quot;</span>] = WAIT_FOR_SOME_INTERACTION<span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
-case WAIT_FOR_KEY_FROM_KEYBOARD: <span class="Delimiter">{</span>
+case WAIT_FOR_SOME_INTERACTION: <span class="Delimiter">{</span>
   tb_event event<span class="Delimiter">;</span>
-  do <span class="Delimiter">{</span>
-    tb_poll_event<span class="Delimiter">(</span>&amp;event<span class="Delimiter">);</span>
-  <span class="Delimiter">}</span> while <span class="Delimiter">(</span>event<span class="Delimiter">.</span>type != TB_EVENT_KEY<span class="Delimiter">);</span>
-  long long int result = event<span class="Delimiter">.</span>key ? event<span class="Delimiter">.</span>key : event<span class="Delimiter">.</span>ch<span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>result == TB_KEY_CTRL_C<span class="Delimiter">)</span> tb_shutdown<span class="Delimiter">(),</span> exit<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
-  if <span class="Delimiter">(</span>result == TB_KEY_BACKSPACE2<span class="Delimiter">)</span> result = TB_KEY_BACKSPACE<span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>result == TB_KEY_CARRIAGE_RETURN<span class="Delimiter">)</span> result = TB_KEY_NEWLINE<span class="Delimiter">;</span>
-  products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
-  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
+  tb_poll_event<span class="Delimiter">(</span>&amp;event<span class="Delimiter">);</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
-READ_KEY_FROM_KEYBOARD<span class="Delimiter">,</span>
+CHECK_FOR_INTERACTION<span class="Delimiter">,</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
-Recipe_number[<span class="Constant">&quot;read-key-from-keyboard&quot;</span>] = READ_KEY_FROM_KEYBOARD<span class="Delimiter">;</span>
+Recipe_number[<span class="Constant">&quot;check-for-interaction&quot;</span>] = CHECK_FOR_INTERACTION<span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
-case READ_KEY_FROM_KEYBOARD: <span class="Delimiter">{</span>
+case CHECK_FOR_INTERACTION: <span class="Delimiter">{</span>
+  products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span>  <span class="Comment">// result and status</span>
   tb_event event<span class="Delimiter">;</span>
   int event_type = tb_peek_event<span class="Delimiter">(</span>&amp;event<span class="Delimiter">,</span> <span class="Constant">5</span><span class="Comment">/*</span><span class="Comment">ms</span><span class="Comment">*/</span><span class="Delimiter">);</span>
-  long long int result = <span class="Constant">0</span><span class="Delimiter">;</span>
-  long long int found = <span class="Constant">false</span><span class="Delimiter">;</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; event_type &lt;&lt; '\n'; //? 1</span>
+  if <span class="Delimiter">(</span>event_type == TB_EVENT_KEY &amp;&amp; event<span class="Delimiter">.</span>ch<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">text event</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>event<span class="Delimiter">.</span>ch<span class="Delimiter">);</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">found</span><span class="Comment">*/</span><span class="Constant">true</span><span class="Delimiter">);</span>
+    <span class="Identifier">break</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  <span class="Comment">// treat keys within ascii as unicode characters</span>
+  if <span class="Delimiter">(</span>event_type == TB_EVENT_KEY &amp;&amp; event<span class="Delimiter">.</span>key &lt; <span class="Constant">0xff</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">text event</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span>
+    if <span class="Delimiter">(</span>event<span class="Delimiter">.</span>key == TB_KEY_CTRL_C<span class="Delimiter">)</span> tb_shutdown<span class="Delimiter">(),</span> exit<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+    if <span class="Delimiter">(</span>event<span class="Delimiter">.</span>key == TB_KEY_BACKSPACE2<span class="Delimiter">)</span> event<span class="Delimiter">.</span>key = TB_KEY_BACKSPACE<span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>event<span class="Delimiter">.</span>key == TB_KEY_CARRIAGE_RETURN<span class="Delimiter">)</span> event<span class="Delimiter">.</span>key = TB_KEY_NEWLINE<span class="Delimiter">;</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>event<span class="Delimiter">.</span>key<span class="Delimiter">);</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">found</span><span class="Comment">*/</span><span class="Constant">true</span><span class="Delimiter">);</span>
+    <span class="Identifier">break</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  <span class="Comment">// keys outside ascii aren't unicode characters but arbitrary termbox inventions</span>
   if <span class="Delimiter">(</span>event_type == TB_EVENT_KEY<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    result = event<span class="Delimiter">.</span>key ? event<span class="Delimiter">.</span>key : event<span class="Delimiter">.</span>ch<span class="Delimiter">;</span>
-    if <span class="Delimiter">(</span>result == TB_KEY_CTRL_C<span class="Delimiter">)</span> tb_shutdown<span class="Delimiter">(),</span> exit<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
-    if <span class="Delimiter">(</span>result == TB_KEY_BACKSPACE2<span class="Delimiter">)</span> result = TB_KEY_BACKSPACE<span class="Delimiter">;</span>
-    if <span class="Delimiter">(</span>result == TB_KEY_CARRIAGE_RETURN<span class="Delimiter">)</span> result = TB_KEY_NEWLINE<span class="Delimiter">;</span>
-    found = <span class="Constant">true</span><span class="Delimiter">;</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">keycode event</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">);</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>event<span class="Delimiter">.</span>key<span class="Delimiter">);</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">found</span><span class="Comment">*/</span><span class="Constant">true</span><span class="Delimiter">);</span>
+    <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span>
-  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
-  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>found<span class="Delimiter">);</span>
+  if <span class="Delimiter">(</span>event_type == TB_EVENT_MOUSE<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">mouse event</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">);</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>event<span class="Delimiter">.</span>key<span class="Delimiter">);</span>  <span class="Comment">// which button, etc.</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>event<span class="Delimiter">.</span>y<span class="Delimiter">);</span>  <span class="Comment">// row</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>event<span class="Delimiter">.</span>x<span class="Delimiter">);</span>  <span class="Comment">// column</span>
+    products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">found</span><span class="Comment">*/</span><span class="Constant">true</span><span class="Delimiter">);</span>
+    <span class="Identifier">break</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  <span class="Comment">// ignore TB_EVENT_RESIZE events for now</span>
+  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+  products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">found</span><span class="Comment">*/</span><span class="Constant">false</span><span class="Delimiter">);</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
-
-<span class="Delimiter">:(before &quot;End Includes&quot;)</span>
-<span class="PreProc">#include</span><span class="Constant">&quot;termbox/termbox.h&quot;</span>
 </pre>
 </body>
 </html>
diff --git a/html/071print.mu.html b/html/071print.mu.html
index 56ea1f74..b9a67840 100644
--- a/html/071print.mu.html
+++ b/html/071print.mu.html
@@ -12,14 +12,14 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .muScenario { color: #00af00; }
-.Delimiter { color: #c000c0; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+.Delimiter { color: #a04060; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
-.muControl { color: #804000; }
+.Comment { color: #9090ff; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
@@ -48,7 +48,7 @@ container screen-cell [
   color:number
 ]
 
-<span class="muRecipe">recipe</span> init-fake-screen [
+<span class="muRecipe">recipe</span> new-fake-screen [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal/capacity</span>
   result:address:screen<span class="Special"> &lt;- </span>new screen:type
   width:address:number<span class="Special"> &lt;- </span>get-address result:address:screen/deref, num-columns:offset
@@ -119,7 +119,6 @@ container screen-cell [
     column:address:number<span class="Special"> &lt;- </span>get-address x:address:screen/deref, cursor-column:offset
     width:number<span class="Special"> &lt;- </span>get x:address:screen/deref, num-columns:offset
     height:number<span class="Special"> &lt;- </span>get x:address:screen/deref, num-rows:offset
-    max-row:number<span class="Special"> &lt;- </span>subtract height:number, <span class="Constant">1:literal</span>
     <span class="Comment"># special-case: newline</span>
     <span class="Delimiter">{</span>
       newline?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">10:literal/newline</span>
@@ -128,7 +127,8 @@ container screen-cell [
       <span class="muControl">break-unless</span> newline?:boolean
       <span class="Delimiter">{</span>
         <span class="Comment"># unless cursor is already at bottom</span>
-        at-bottom?:boolean<span class="Special"> &lt;- </span>greater-or-equal row:address:number/deref, max-row:number
+        bottom:number<span class="Special"> &lt;- </span>subtract height:number, <span class="Constant">1:literal</span>
+        at-bottom?:boolean<span class="Special"> &lt;- </span>greater-or-equal row:address:number/deref, bottom:number
         <span class="muControl">break-if</span> at-bottom?:boolean
         <span class="Comment"># move it to the next row</span>
         column:address:number/deref<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
@@ -137,6 +137,8 @@ container screen-cell [
       <span class="muControl">reply</span> x:address:screen/same-as-ingredient:0
     <span class="Delimiter">}</span>
     <span class="Comment"># save character in fake screen</span>
+<span class="CommentedCode">#?     $print row:address:number/deref, [, ], column:address:number/deref, [ </span>
+<span class="CommentedCode">#? ] #? 1</span>
     index:number<span class="Special"> &lt;- </span>multiply row:address:number/deref, width:number
     index:number<span class="Special"> &lt;- </span>add index:number, column:address:number/deref
     buf:address:array:screen-cell<span class="Special"> &lt;- </span>get x:address:screen/deref, data:offset
@@ -168,7 +170,8 @@ container screen-cell [
     cursor-color:address:number/deref<span class="Special"> &lt;- </span>copy color:number
     <span class="Comment"># increment column unless it's already all the way to the right</span>
     <span class="Delimiter">{</span>
-      at-right?:boolean<span class="Special"> &lt;- </span>equal column:address:number/deref, width:number
+      right:number<span class="Special"> &lt;- </span>subtract width:number, <span class="Constant">1:literal</span>
+      at-right?:boolean<span class="Special"> &lt;- </span>greater-or-equal column:address:number/deref, right:number
       <span class="muControl">break-if</span> at-right?:boolean
       column:address:number/deref<span class="Special"> &lt;- </span>add column:address:number/deref, <span class="Constant">1:literal</span>
     <span class="Delimiter">}</span>
@@ -182,7 +185,7 @@ container screen-cell [
 <span class="muScenario">scenario</span> print-character-at-top-left [
   run [
 <span class="CommentedCode">#?     $start-tracing #? 3</span>
-    1:address:screen<span class="Special"> &lt;- </span>init-fake-screen <span class="Constant">3:literal/width</span>, <span class="Constant">2:literal/height</span>
+    1:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3:literal/width</span>, <span class="Constant">2:literal/height</span>
     1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">97:literal</span>  <span class="Comment"># 'a'</span>
     2:address:array:screen-cell<span class="Special"> &lt;- </span>get 1:address:screen/deref, data:offset
     3:array:screen-cell<span class="Special"> &lt;- </span>copy 2:address:array:screen-cell/deref
@@ -197,7 +200,7 @@ container screen-cell [
 
 <span class="muScenario">scenario</span> print-character-color [
   run [
-    1:address:screen<span class="Special"> &lt;- </span>init-fake-screen <span class="Constant">3:literal/width</span>, <span class="Constant">2:literal/height</span>
+    1:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3:literal/width</span>, <span class="Constant">2:literal/height</span>
     1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">97:literal/a</span>, <span class="Constant">1:literal/red</span>
     2:address:array:screen-cell<span class="Special"> &lt;- </span>get 1:address:screen/deref, data:offset
     3:array:screen-cell<span class="Special"> &lt;- </span>copy 2:address:array:screen-cell/deref
@@ -213,9 +216,28 @@ container screen-cell [
 <span class="muScenario">scenario</span> print-backspace-character [
   run [
 <span class="CommentedCode">#?     $start-tracing #? 3</span>
-    1:address:screen<span class="Special"> &lt;- </span>init-fake-screen <span class="Constant">3:literal/width</span>, <span class="Constant">2:literal/height</span>
+    1:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3:literal/width</span>, <span class="Constant">2:literal/height</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">97:literal</span>  <span class="Comment"># 'a'</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">8:literal</span>  <span class="Comment"># backspace</span>
+    2:number<span class="Special"> &lt;- </span>get 1:address:screen/deref, cursor-column:offset
+    3:address:array:screen-cell<span class="Special"> &lt;- </span>get 1:address:screen/deref, data:offset
+    4:array:screen-cell<span class="Special"> &lt;- </span>copy 3:address:array:screen-cell/deref
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>0  <span class="Comment"># cursor column</span>
+    4<span class="Special"> &lt;- </span>6  <span class="Comment"># width*height</span>
+    5<span class="Special"> &lt;- </span>32  <span class="Comment"># space, not 'a'</span>
+    6<span class="Special"> &lt;- </span>7  <span class="Comment"># white</span>
+    7<span class="Special"> &lt;- </span>0
+  ]
+]
+
+<span class="muScenario">scenario</span> print-extra-backspace-character [
+  run [
+    1:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3:literal/width</span>, <span class="Constant">2:literal/height</span>
     1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">97:literal</span>  <span class="Comment"># 'a'</span>
     1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">8:literal</span>  <span class="Comment"># backspace</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">8:literal</span>  <span class="Comment"># backspace</span>
     2:number<span class="Special"> &lt;- </span>get 1:address:screen/deref, cursor-column:offset
     3:address:array:screen-cell<span class="Special"> &lt;- </span>get 1:address:screen/deref, data:offset
     4:array:screen-cell<span class="Special"> &lt;- </span>copy 3:address:array:screen-cell/deref
@@ -229,10 +251,31 @@ container screen-cell [
   ]
 ]
 
+<span class="muScenario">scenario</span> print-at-right-margin [
+  run [
+    1:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">2:literal/width</span>, <span class="Constant">2:literal/height</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">97:literal</span>  <span class="Comment"># 'a'</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">98:literal</span>  <span class="Comment"># 'b'</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">99:literal</span>  <span class="Comment"># 'c'</span>
+    2:number<span class="Special"> &lt;- </span>get 1:address:screen/deref, cursor-column:offset
+    3:address:array:screen-cell<span class="Special"> &lt;- </span>get 1:address:screen/deref, data:offset
+    4:array:screen-cell<span class="Special"> &lt;- </span>copy 3:address:array:screen-cell/deref
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>1  <span class="Comment"># cursor column</span>
+    4<span class="Special"> &lt;- </span>4  <span class="Comment"># width*height</span>
+    5<span class="Special"> &lt;- </span>97  <span class="Comment"># 'a'</span>
+    6<span class="Special"> &lt;- </span>7  <span class="Comment"># white</span>
+    7<span class="Special"> &lt;- </span>99  <span class="Comment"># 'c' over 'b'</span>
+    8<span class="Special"> &lt;- </span>7  <span class="Comment"># white</span>
+    9<span class="Special"> &lt;- </span>0
+  ]
+]
+
 <span class="muScenario">scenario</span> print-newline-character [
   run [
 <span class="CommentedCode">#?     $start-tracing #? 3</span>
-    1:address:screen<span class="Special"> &lt;- </span>init-fake-screen <span class="Constant">3:literal/width</span>, <span class="Constant">2:literal/height</span>
+    1:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3:literal/width</span>, <span class="Constant">2:literal/height</span>
     1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">97:literal</span>  <span class="Comment"># 'a'</span>
     1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">10:literal/newline</span>
     2:number<span class="Special"> &lt;- </span>get 1:address:screen/deref, cursor-row:offset
@@ -250,13 +293,58 @@ container screen-cell [
   ]
 ]
 
+<span class="muScenario">scenario</span> print-newline-at-bottom-line [
+  run [
+    1:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3:literal/width</span>, <span class="Constant">2:literal/height</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">10:literal/newline</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">10:literal/newline</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">10:literal/newline</span>
+    2:number<span class="Special"> &lt;- </span>get 1:address:screen/deref, cursor-row:offset
+    3:number<span class="Special"> &lt;- </span>get 1:address:screen/deref, cursor-column:offset
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>1  <span class="Comment"># cursor row</span>
+    3<span class="Special"> &lt;- </span>0  <span class="Comment"># cursor column</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> print-at-bottom-right [
+  run [
+    1:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">2:literal/width</span>, <span class="Constant">2:literal/height</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">10:literal/newline</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">97:literal</span>  <span class="Comment"># 'a'</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">98:literal</span>  <span class="Comment"># 'b'</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">99:literal</span>  <span class="Comment"># 'c'</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">10:literal/newline</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">100:literal</span>  <span class="Comment"># 'd'</span>
+    2:number<span class="Special"> &lt;- </span>get 1:address:screen/deref, cursor-row:offset
+    3:number<span class="Special"> &lt;- </span>get 1:address:screen/deref, cursor-column:offset
+    4:address:array:screen-cell<span class="Special"> &lt;- </span>get 1:address:screen/deref, data:offset
+    5:array:screen-cell<span class="Special"> &lt;- </span>copy 4:address:array:screen-cell/deref
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>1  <span class="Comment"># cursor row</span>
+    3<span class="Special"> &lt;- </span>1  <span class="Comment"># cursor column</span>
+    5<span class="Special"> &lt;- </span>4  <span class="Comment"># width*height</span>
+    6<span class="Special"> &lt;- </span>0  <span class="Comment"># unused</span>
+    7<span class="Special"> &lt;- </span>7  <span class="Comment"># white</span>
+    8<span class="Special"> &lt;- </span>0  <span class="Comment"># unused</span>
+    9<span class="Special"> &lt;- </span>7  <span class="Comment"># white</span>
+    10<span class="Special"> &lt;- </span>97 <span class="Comment"># 'a'</span>
+    11<span class="Special"> &lt;- </span>7  <span class="Comment"># white</span>
+    12<span class="Special"> &lt;- </span>100  <span class="Comment"># 'd' over 'b' and 'c' and newline</span>
+    13<span class="Special"> &lt;- </span>7  <span class="Comment"># white</span>
+    14<span class="Special"> &lt;- </span>0
+  ]
+]
+
 <span class="muRecipe">recipe</span> clear-line [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   x:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="Comment"># if x exists, clear line in fake screen</span>
   <span class="Delimiter">{</span>
     <span class="muControl">break-unless</span> x:address:screen
-    n:number<span class="Special"> &lt;- </span>get x:address:screen/deref, num-columns:offset
+    width:number<span class="Special"> &lt;- </span>get x:address:screen/deref, num-columns:offset
     column:address:number<span class="Special"> &lt;- </span>get-address x:address:screen/deref, cursor-column:offset
     original-column:number<span class="Special"> &lt;- </span>copy column:address:number/deref
     <span class="Comment"># space over the entire line</span>
@@ -264,7 +352,8 @@ container screen-cell [
     <span class="Delimiter">{</span>
 <span class="CommentedCode">#?       $print column:address:number/deref, [ </span>
 <span class="CommentedCode">#? ] #? 1</span>
-      done?:boolean<span class="Special"> &lt;- </span>greater-or-equal column:address:number/deref, n:number
+      right:number<span class="Special"> &lt;- </span>subtract width:number, <span class="Constant">1:literal</span>
+      done?:boolean<span class="Special"> &lt;- </span>greater-or-equal column:address:number/deref, right:number
       <span class="muControl">break-if</span> done?:boolean
       print-character x:address:screen, <span class="Constant">[ ]</span>  <span class="Comment"># implicitly updates 'column'</span>
       <span class="muControl">loop</span>
@@ -314,7 +403,7 @@ container screen-cell [
 <span class="muScenario">scenario</span> clear-line-erases-printed-characters [
   run [
 <span class="CommentedCode">#?     $start-tracing #? 4</span>
-    1:address:screen<span class="Special"> &lt;- </span>init-fake-screen <span class="Constant">3:literal/width</span>, <span class="Constant">2:literal/height</span>
+    1:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3:literal/width</span>, <span class="Constant">2:literal/height</span>
     <span class="Comment"># print a character</span>
     1:address:screen<span class="Special"> &lt;- </span>print-character 1:address:screen, <span class="Constant">97:literal</span>  <span class="Comment"># 'a'</span>
     <span class="Comment"># move cursor to start of line</span>
@@ -501,6 +590,26 @@ container screen-cell [
   <span class="muControl">reply</span> x:address:screen/same-as-ingredient:0
 ]
 
+<span class="muScenario">scenario</span> print-string-stops-at-right-margin [
+  run [
+    1:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3:literal/width</span>, <span class="Constant">2:literal/height</span>
+    2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abcd]</span>
+    1:address:screen<span class="Special"> &lt;- </span>print-string 1:address:screen, 2:address:array:character
+    3:address:array:screen-cell<span class="Special"> &lt;- </span>get 1:address:screen/deref, data:offset
+    4:array:screen-cell<span class="Special"> &lt;- </span>copy 3:address:array:screen-cell/deref
+  ]
+  memory-should-contain [
+    4<span class="Special"> &lt;- </span>6  <span class="Comment"># width*height</span>
+    5<span class="Special"> &lt;- </span>97  <span class="Comment"># 'a'</span>
+    6<span class="Special"> &lt;- </span>7  <span class="Comment"># white</span>
+    7<span class="Special"> &lt;- </span>98  <span class="Comment"># 'b'</span>
+    8<span class="Special"> &lt;- </span>7  <span class="Comment"># white</span>
+    9<span class="Special"> &lt;- </span>100  <span class="Comment"># 'd' overwrites 'c'</span>
+    10<span class="Special"> &lt;- </span>7  <span class="Comment"># white</span>
+    11<span class="Special"> &lt;- </span>0  <span class="Comment"># unused</span>
+  ]
+]
+
 <span class="muRecipe">recipe</span> print-integer [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   x:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
diff --git a/html/072scenario_screen.cc.html b/html/072scenario_screen.cc.html
index 87ef1158..e14ae7de 100644
--- a/html/072scenario_screen.cc.html
+++ b/html/072scenario_screen.cc.html
@@ -12,14 +12,14 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
@@ -164,15 +164,17 @@ Name[tmp_recipe<span class="Delimiter">.</span>at<span class="Delimiter">(</span
 
 <span class="Delimiter">:(before &quot;End Rewrite Instruction(curr)&quot;)</span>
 <span class="Comment">// rewrite `assume-screen width, height` to</span>
-<span class="Comment">// `screen:address &lt;- init-fake-screen width, height`</span>
+<span class="Comment">// `screen:address &lt;- new-fake-screen width, height`</span>
 <span class="CommentedCode">//? cout &lt;&lt; &quot;before: &quot; &lt;&lt; curr.to_string() &lt;&lt; '\n'; //? 1</span>
 if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">&quot;assume-screen&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  curr<span class="Delimiter">.</span>operation = Recipe_number[<span class="Constant">&quot;init-fake-screen&quot;</span>]<span class="Delimiter">;</span>
+  curr<span class="Delimiter">.</span>operation = Recipe_number[<span class="Constant">&quot;new-fake-screen&quot;</span>]<span class="Delimiter">;</span>
+  curr<span class="Delimiter">.</span>name = <span class="Constant">&quot;new-fake-screen&quot;</span><span class="Delimiter">;</span>
+  assert<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>operation<span class="Delimiter">);</span>
   assert<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
   curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">&quot;screen:address&quot;</span><span class="Delimiter">));</span>
   curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>SCREEN<span class="Delimiter">);</span>
 <span class="CommentedCode">//? cout &lt;&lt; &quot;after: &quot; &lt;&lt; curr.to_string() &lt;&lt; '\n'; //? 1</span>
-<span class="CommentedCode">//? cout &lt;&lt; &quot;AAA &quot; &lt;&lt; Recipe_number[&quot;init-fake-screen&quot;] &lt;&lt; '\n'; //? 1</span>
+<span class="CommentedCode">//? cout &lt;&lt; &quot;AAA &quot; &lt;&lt; Recipe_number[&quot;new-fake-screen&quot;] &lt;&lt; '\n'; //? 1</span>
 <span class="Delimiter">}</span>
 
 <span class="Comment">//: screen-should-contain is a regular instruction</span>
@@ -360,9 +362,12 @@ void dump_screen<span class="Delimiter">()</span> <span class="Delimiter">{</spa
   assert<span class="Delimiter">(</span>Memory[screen_data_start] == screen_width*screen_height<span class="Delimiter">);</span>
   long long int curr = screen_data_start+<span class="Constant">1</span><span class="Delimiter">;</span>  <span class="Comment">// skip length</span>
   for <span class="Delimiter">(</span>long long int row = <span class="Constant">0</span><span class="Delimiter">;</span> row &lt; screen_height<span class="Delimiter">;</span> ++row<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-<span class="CommentedCode">//?     cerr &lt;&lt; curr &lt;&lt; &quot;:\n&quot;; //? 1</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; curr &lt;&lt; &quot;:\n&quot;; //? 2</span>
     for <span class="Delimiter">(</span>long long int col = <span class="Constant">0</span><span class="Delimiter">;</span> col &lt; screen_width<span class="Delimiter">;</span> ++col<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-      cerr &lt;&lt; static_cast&lt;char&gt;<span class="Delimiter">(</span>Memory[curr]<span class="Delimiter">);</span>
+      if <span class="Delimiter">(</span>Memory[curr]<span class="Delimiter">)</span>
+        cerr &lt;&lt; to_unicode<span class="Delimiter">(</span>Memory[curr]<span class="Delimiter">);</span>
+      else
+        cerr &lt;&lt; <span class="Constant">' '</span><span class="Delimiter">;</span>
       curr += <span class="Comment">/*</span><span class="Comment">size of screen-cell</span><span class="Comment">*/</span><span class="Constant">2</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
     cerr &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
diff --git a/html/073scenario_screen_test.mu.html b/html/073scenario_screen_test.mu.html
index cf432dc2..229a2e90 100644
--- a/html/073scenario_screen_test.mu.html
+++ b/html/073scenario_screen_test.mu.html
@@ -12,10 +12,10 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .muScenario { color: #00af00; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
 -->
 </style>
diff --git a/html/074keyboard.mu.html b/html/074keyboard.mu.html
index 75e9a0e5..9769da2e 100644
--- a/html/074keyboard.mu.html
+++ b/html/074keyboard.mu.html
@@ -12,13 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Delimiter { color: #c000c0; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+* { font-size: 1.05em; }
+.Delimiter { color: #a04060; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
-.muControl { color: #804000; }
+.Comment { color: #9090ff; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
@@ -31,78 +31,108 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 </head>
 <body>
 <pre id='vimCodeElement'>
-<span class="Comment"># Wrappers around keyboard primitives that take a 'keyboard' object and are thus</span>
-<span class="Comment"># easier to test.</span>
+<span class="Comment"># Wrappers around interaction primitives that take a potentially fake object</span>
+<span class="Comment"># and are thus easier to test.</span>
 
-<span class="Comment"># display:screen as keyboard:__? Can't think of another word.</span>
-container keyboard [
+exclusive-container event [
+  text:character
+  keycode:number  <span class="Comment"># keys on keyboard without a unicode representation</span>
+  touch:touch-event  <span class="Comment"># mouse, track ball, etc.</span>
+  <span class="Comment"># update the assume-console handler if you add more variants</span>
+]
+
+container touch-event [
+  type:number
+  row:number
+  column:number
+]
+
+container console [
   index:number
-  data:address:array:character
+  data:address:array:event
 ]
 
-<span class="muRecipe">recipe</span> init-fake-keyboard [
+<span class="muRecipe">recipe</span> new-fake-console [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
-  result:address:keyboard<span class="Special"> &lt;- </span>new keyboard:type
-  buf:address:address:array:character<span class="Special"> &lt;- </span>get-address result:address:keyboard/deref, data:offset
+  result:address:console<span class="Special"> &lt;- </span>new console:type
+  buf:address:address:array:character<span class="Special"> &lt;- </span>get-address result:address:console/deref, data:offset
 <span class="CommentedCode">#?   $start-tracing #? 1</span>
   buf:address:address:array:character/deref<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
 <span class="CommentedCode">#?   $stop-tracing #? 1</span>
-  idx:address:number<span class="Special"> &lt;- </span>get-address result:address:keyboard/deref, index:offset
+  idx:address:number<span class="Special"> &lt;- </span>get-address result:address:console/deref, index:offset
   idx:address:number/deref<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
-  <span class="muControl">reply</span> result:address:keyboard
+  <span class="muControl">reply</span> result:address:console
 ]
 
-<span class="muRecipe">recipe</span> read-key [
+<span class="muRecipe">recipe</span> read-event [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
-  x:address:keyboard<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  x:address:console<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> x:address:keyboard
-    idx:address:number<span class="Special"> &lt;- </span>get-address x:address:keyboard/deref, index:offset
-    buf:address:array:character<span class="Special"> &lt;- </span>get x:address:keyboard/deref, data:offset
-    max:number<span class="Special"> &lt;- </span>length buf:address:array:character/deref
+    <span class="muControl">break-unless</span> x:address:console
+    idx:address:number<span class="Special"> &lt;- </span>get-address x:address:console/deref, index:offset
+    buf:address:array:event<span class="Special"> &lt;- </span>get x:address:console/deref, data:offset
     <span class="Delimiter">{</span>
+      max:number<span class="Special"> &lt;- </span>length buf:address:array:event/deref
       done?:boolean<span class="Special"> &lt;- </span>greater-or-equal idx:address:number/deref, max:number
       <span class="muControl">break-unless</span> done?:boolean
-      <span class="muControl">reply</span> <span class="Constant">0:literal/eof</span>, <span class="Constant">1:literal/found</span>, x:address:keyboard/same-as-ingredient:0
+      dummy:address:event<span class="Special"> &lt;- </span>new event:type
+      <span class="muControl">reply</span> dummy:address:event/deref, x:address:console/same-as-ingredient:0, <span class="Constant">1:literal/found</span>, <span class="Constant">1:literal/quit</span>
     <span class="Delimiter">}</span>
-    c:character<span class="Special"> &lt;- </span>index buf:address:array:character/deref, idx:address:number/deref
+    result:event<span class="Special"> &lt;- </span>index buf:address:array:event/deref, idx:address:number/deref
     idx:address:number/deref<span class="Special"> &lt;- </span>add idx:address:number/deref, <span class="Constant">1:literal</span>
-    <span class="muControl">reply</span> c:character, <span class="Constant">1:literal/found</span>, x:address:keyboard/same-as-ingredient:0
+    <span class="muControl">reply</span> result:event, x:address:console/same-as-ingredient:0, <span class="Constant">1:literal/found</span>, <span class="Constant">0:literal/quit</span>
   <span class="Delimiter">}</span>
-  <span class="Comment"># real keyboard input is infrequent; avoid polling it too much</span>
+  <span class="Comment"># real event source is infrequent; avoid polling it too much</span>
   switch
-  c:character, found?:boolean<span class="Special"> &lt;- </span>read-key-from-keyboard
-  <span class="muControl">reply</span> c:character, found?:boolean, x:address:keyboard/same-as-ingredient:0
+  result:event, found?:boolean<span class="Special"> &lt;- </span>check-for-interaction
+  <span class="muControl">reply</span> result:event, x:address:console/same-as-ingredient:0, found?:boolean, <span class="Constant">0:literal/quit</span>
 ]
 
-<span class="muRecipe">recipe</span> wait-for-key [
+<span class="Comment"># variant of read-event for just keyboard events. Discards everything that</span>
+<span class="Comment"># isn't unicode, so no arrow keys, page-up/page-down, etc. But you still get</span>
+<span class="Comment"># newlines, tabs, ctrl-d..</span>
+<span class="muRecipe">recipe</span> read-key [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
-  x:address:keyboard<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> x:address:keyboard
-    <span class="Comment"># on fake keyboards 'wait-for-key' behaves just like 'read-key'</span>
-    c:character, found?:boolean, x:address:keyboard<span class="Special"> &lt;- </span>read-key x:address:keyboard
-    <span class="muControl">reply</span> c:character, x:address:keyboard/same-as-ingredient:0
-  <span class="Delimiter">}</span>
-  c:character<span class="Special"> &lt;- </span>wait-for-key-from-keyboard
-  <span class="muControl">reply</span> c:character, x:address:keyboard/same-as-ingredient:0
+<span class="CommentedCode">#?   $print default-space:address:array:location #? 1</span>
+<span class="CommentedCode">#?   $exit #? 1</span>
+<span class="CommentedCode">#?   $start-tracing #? 1</span>
+  console:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  x:event, console:address, found?:boolean, quit?:boolean<span class="Special"> &lt;- </span>read-event console:address
+<span class="CommentedCode">#?   $print [aaa 1] #? 1</span>
+  <span class="muControl">reply-if</span> quit?:boolean, <span class="Constant">0:literal</span>, console:address/same-as-ingredient:0, found?:boolean, quit?:boolean
+<span class="CommentedCode">#?   $print [aaa 2] #? 1</span>
+  <span class="muControl">reply-unless</span> found?:boolean, <span class="Constant">0:literal</span>, console:address/same-as-ingredient:0, found?:boolean, quit?:boolean
+<span class="CommentedCode">#?   $print [aaa 3] #? 1</span>
+  c:address:character<span class="Special"> &lt;- </span>maybe-convert x:event, text:variant
+  <span class="muControl">reply-unless</span> c:address:character, <span class="Constant">0:literal</span>, console:address/same-as-ingredient:0, <span class="Constant">0:literal/found</span>, <span class="Constant">0:literal/quit</span>
+<span class="CommentedCode">#?   $print [aaa 4] #? 1</span>
+  <span class="muControl">reply</span> c:address:character/deref, console:address/same-as-ingredient:0, <span class="Constant">1:literal/found</span>, <span class="Constant">0:literal/quit</span>
 ]
 
 <span class="muRecipe">recipe</span> send-keys-to-channel [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
-  keyboard:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  console:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   chan:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="Delimiter">{</span>
-    c:character, found?:boolean, keyboard:address<span class="Special"> &lt;- </span>read-key keyboard:address
+    c:character, console:address, found?:boolean, quit?:boolean<span class="Special"> &lt;- </span>read-key console:address
     <span class="muControl">loop-unless</span> found?:boolean
-<span class="CommentedCode">#?     print-integer screen:address, c:character #? 1</span>
+    <span class="muControl">break-if</span> quit?:boolean
+    assert c:character, <span class="Constant">[invalid event, expected text]</span>
     print-character screen:address, c:character
     chan:address:channel<span class="Special"> &lt;- </span>write chan:address:channel, c:character
-    <span class="Comment"># todo: eof</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
 ]
+
+<span class="muRecipe">recipe</span> wait-for-event [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  console:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Delimiter">{</span>
+    _, console:address, found?:boolean<span class="Special"> &lt;- </span>read-event console:address
+    <span class="muControl">loop-unless</span> found?:boolean
+  <span class="Delimiter">}</span>
+]
 </pre>
 </body>
 </html>
diff --git a/html/075scenario_console.cc.html b/html/075scenario_console.cc.html
new file mode 100644
index 00000000..65499aa9
--- /dev/null
+++ b/html/075scenario_console.cc.html
@@ -0,0 +1,258 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 075scenario_console.cc</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.cSpecial { color: #008000; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Special { color: #ff6060; }
+.Identifier { color: #804000; }
+.Comment { color: #9090ff; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment">//: Clean syntax to manipulate and check the console in scenarios.</span>
+<span class="Comment">//: Instruction 'assume-console' implicitly creates a variable called</span>
+<span class="Comment">//: 'console' that is accessible inside other 'run' instructions in the</span>
+<span class="Comment">//: scenario. Like with the fake screen, 'assume-console' transparently</span>
+<span class="Comment">//: supports unicode.</span>
+
+<span class="Delimiter">:(scenarios run_mu_scenario)</span>
+<span class="Delimiter">:(scenario keyboard_in_scenario)</span>
+scenario keyboard-in-scenario [
+  assume-console [
+    type [abc]
+  ]
+  run [
+    <span class="Constant">1</span>:character<span class="Delimiter">,</span> console:address<span class="Delimiter">,</span> <span class="Constant">2</span>:boolean<span class="Special"> &lt;- </span>read-key console:address
+    <span class="Constant">3</span>:character<span class="Delimiter">,</span> console:address<span class="Delimiter">,</span> <span class="Constant">4</span>:boolean<span class="Special"> &lt;- </span>read-key console:address
+    <span class="Constant">5</span>:character<span class="Delimiter">,</span> console:address<span class="Delimiter">,</span> <span class="Constant">6</span>:boolean<span class="Special"> &lt;- </span>read-key console:address
+    <span class="Constant">7</span>:character<span class="Delimiter">,</span> console:address<span class="Delimiter">,</span> <span class="Constant">8</span>:boolean<span class="Delimiter">,</span> <span class="Constant">9</span>:boolean<span class="Special"> &lt;- </span>read-key console:address
+  ]
+  memory-should-contain [
+    <span class="Constant">1</span><span class="Special"> &lt;- </span><span class="Constant">97</span>  <span class="Comment"># 'a'</span>
+    <span class="Constant">2</span><span class="Special"> &lt;- </span><span class="Constant">1</span>
+    <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">98</span>  <span class="Comment"># 'b'</span>
+    <span class="Constant">4</span><span class="Special"> &lt;- </span><span class="Constant">1</span>
+    <span class="Constant">5</span><span class="Special"> &lt;- </span><span class="Constant">99</span>  <span class="Comment"># 'c'</span>
+    <span class="Constant">6</span><span class="Special"> &lt;- </span><span class="Constant">1</span>
+    <span class="Constant">7</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># unset</span>
+    <span class="Constant">8</span><span class="Special"> &lt;- </span><span class="Constant">1</span>
+    <span class="Constant">9</span><span class="Special"> &lt;- </span><span class="Constant">1</span>  <span class="Comment"># end of test events</span>
+  ]
+]
+
+<span class="Delimiter">:(before &quot;End Scenario Globals&quot;)</span>
+const long long int CONSOLE = Next_predefined_global_for_scenarios++<span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End Predefined Scenario Locals In Run&quot;)</span>
+Name[tmp_recipe<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>][<span class="Constant">&quot;console&quot;</span>] = CONSOLE<span class="Delimiter">;</span>
+
+<span class="Comment">//: allow naming just for 'console'</span>
+<span class="Delimiter">:(before &quot;End is_special_name Cases&quot;)</span>
+if <span class="Delimiter">(</span>s == <span class="Constant">&quot;console&quot;</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+
+<span class="Comment">//: Unlike assume-keyboard, assume-console is easiest to implement as just a</span>
+<span class="Comment">//: primitive recipe.</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
+ASSUME_CONSOLE<span class="Delimiter">,</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
+Recipe_number[<span class="Constant">&quot;assume-console&quot;</span>] = ASSUME_CONSOLE<span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
+case ASSUME_CONSOLE: <span class="Delimiter">{</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;aaa: &quot; &lt;&lt; current_instruction().ingredients.at(0).name &lt;&lt; '\n'; //? 2</span>
+  <span class="Comment">// create a temporary recipe just for parsing; it won't contain valid instructions</span>
+  istringstream in<span class="Delimiter">(</span><span class="Constant">&quot;[&quot;</span> + current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name + <span class="Constant">&quot;]&quot;</span><span class="Delimiter">);</span>
+  recipe r = slurp_recipe<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  long long int num_events = count_events<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;fff: &quot; &lt;&lt; num_events &lt;&lt; '\n'; //? 3</span>
+  <span class="Comment">// initialize the events</span>
+  long long int size = num_events*size_of_event<span class="Delimiter">()</span> + <span class="Comment">/*</span><span class="Comment">space for length</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span>
+  ensure_space<span class="Delimiter">(</span>size<span class="Delimiter">);</span>
+  long long int event_data_address = Current_routine<span class="Delimiter">-&gt;</span>alloc<span class="Delimiter">;</span>
+  Memory[event_data_address] = num_events<span class="Delimiter">;</span>
+  ++Current_routine<span class="Delimiter">-&gt;</span>alloc<span class="Delimiter">;</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    const instruction&amp; curr = r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+    if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">&quot;left-click&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      Memory[Current_routine<span class="Delimiter">-&gt;</span>alloc] = <span class="Comment">/*</span><span class="Comment">tag for 'touch-event' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">2</span><span class="Delimiter">;</span>
+      Memory[Current_routine<span class="Delimiter">-&gt;</span>alloc+<span class="Constant">1</span>+<span class="Comment">/*</span><span class="Comment">offset of 'type' in 'mouse-event'</span><span class="Comment">*/</span><span class="Constant">0</span>] = TB_KEY_MOUSE_LEFT<span class="Delimiter">;</span>
+      Memory[Current_routine<span class="Delimiter">-&gt;</span>alloc+<span class="Constant">1</span>+<span class="Comment">/*</span><span class="Comment">offset of 'row' in 'mouse-event'</span><span class="Comment">*/</span><span class="Constant">1</span>] = to_integer<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span>
+      Memory[Current_routine<span class="Delimiter">-&gt;</span>alloc+<span class="Constant">1</span>+<span class="Comment">/*</span><span class="Comment">offset of 'column' in 'mouse-event'</span><span class="Comment">*/</span><span class="Constant">2</span>] = to_integer<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;AA left click: &quot; &lt;&lt; Memory[Current_routine-&gt;alloc+2] &lt;&lt; ' ' &lt;&lt; Memory[Current_routine-&gt;alloc+3] &lt;&lt; '\n'; //? 1</span>
+      Current_routine<span class="Delimiter">-&gt;</span>alloc += size_of_event<span class="Delimiter">();</span>
+    <span class="Delimiter">}</span>
+    else if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">&quot;press&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      Memory[Current_routine<span class="Delimiter">-&gt;</span>alloc] = <span class="Comment">/*</span><span class="Comment">tag for 'keycode' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span>
+      Memory[Current_routine<span class="Delimiter">-&gt;</span>alloc+<span class="Constant">1</span>] = to_integer<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;AA press: &quot; &lt;&lt; Memory[Current_routine-&gt;alloc+1] &lt;&lt; '\n'; //? 3</span>
+      Current_routine<span class="Delimiter">-&gt;</span>alloc += size_of_event<span class="Delimiter">();</span>
+    <span class="Delimiter">}</span>
+    <span class="Comment">// End Event Handlers</span>
+    else <span class="Delimiter">{</span>
+      <span class="Comment">// keyboard input</span>
+      assert<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">&quot;type&quot;</span><span class="Delimiter">);</span>
+      const string&amp; contents = curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">;</span>
+      const char* raw_contents = contents<span class="Delimiter">.</span>c_str<span class="Delimiter">();</span>
+      long long int num_keyboard_events = unicode_length<span class="Delimiter">(</span>contents<span class="Delimiter">);</span>
+      long long int curr = <span class="Constant">0</span><span class="Delimiter">;</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;AAA: &quot; &lt;&lt; num_keyboard_events &lt;&lt; '\n'; //? 1</span>
+      for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; num_keyboard_events<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+        Memory[Current_routine<span class="Delimiter">-&gt;</span>alloc] = <span class="Comment">/*</span><span class="Comment">tag for 'text' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">;</span>
+        uint32_t curr_character<span class="Delimiter">;</span>
+        assert<span class="Delimiter">(</span>curr &lt; SIZE<span class="Delimiter">(</span>contents<span class="Delimiter">));</span>
+        tb_utf8_char_to_unicode<span class="Delimiter">(</span>&amp;curr_character<span class="Delimiter">,</span> &amp;raw_contents[curr]<span class="Delimiter">);</span>
+<span class="CommentedCode">//?         cerr &lt;&lt; &quot;AA keyboard: &quot; &lt;&lt; curr_character &lt;&lt; '\n'; //? 3</span>
+        Memory[Current_routine<span class="Delimiter">-&gt;</span>alloc+<span class="Comment">/*</span><span class="Comment">skip exclusive container tag</span><span class="Comment">*/</span><span class="Constant">1</span>] = curr_character<span class="Delimiter">;</span>
+        curr += tb_utf8_char_length<span class="Delimiter">(</span>raw_contents[curr]<span class="Delimiter">);</span>
+        Current_routine<span class="Delimiter">-&gt;</span>alloc += size_of_event<span class="Delimiter">();</span>
+      <span class="Delimiter">}</span>
+    <span class="Delimiter">}</span>
+  <span class="Delimiter">}</span>
+  assert<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-&gt;</span>alloc == event_data_address+size<span class="Delimiter">);</span>
+  <span class="Comment">// wrap the array of events in an event object</span>
+  ensure_space<span class="Delimiter">(</span>size_of_events<span class="Delimiter">());</span>
+  Memory[CONSOLE] = Current_routine<span class="Delimiter">-&gt;</span>alloc<span class="Delimiter">;</span>
+  Current_routine<span class="Delimiter">-&gt;</span>alloc += size_of_events<span class="Delimiter">();</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;writing &quot; &lt;&lt; event_data_address &lt;&lt; &quot; to location &quot; &lt;&lt; Memory[CONSOLE]+1 &lt;&lt; '\n'; //? 1</span>
+  Memory[Memory[CONSOLE]+<span class="Comment">/*</span><span class="Comment">offset of 'data' in container 'events'</span><span class="Comment">*/</span><span class="Constant">1</span>] = event_data_address<span class="Delimiter">;</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; Memory[Memory[CONSOLE]+1] &lt;&lt; '\n'; //? 1</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;alloc now &quot; &lt;&lt; Current_routine-&gt;alloc &lt;&lt; '\n'; //? 1</span>
+  <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario events_in_scenario)</span>
+scenario events-in-scenario [
+  assume-console [
+    type [abc]
+    left-click <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span>
+    press <span class="Constant">65515</span>  <span class="Comment"># up arrow</span>
+    type [d]
+  ]
+  run [
+    <span class="Comment"># 3 keyboard events; each event occupies 4 locations</span>
+<span class="CommentedCode">#?     $start-tracing #? 2</span>
+    <span class="Constant">1</span>:event<span class="Special"> &lt;- </span>read-event console:address
+    <span class="Constant">5</span>:event<span class="Special"> &lt;- </span>read-event console:address
+    <span class="Constant">9</span>:event<span class="Special"> &lt;- </span>read-event console:address
+    <span class="Comment"># mouse click</span>
+    <span class="Constant">13</span>:event<span class="Special"> &lt;- </span>read-event console:address
+    <span class="Comment"># non-character keycode</span>
+    <span class="Constant">17</span>:event<span class="Special"> &lt;- </span>read-event console:address
+    <span class="Comment"># final keyboard event</span>
+    <span class="Constant">21</span>:event<span class="Special"> &lt;- </span>read-event console:address
+  ]
+  memory-should-contain [
+    <span class="Constant">1</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># 'text'</span>
+    <span class="Constant">2</span><span class="Special"> &lt;- </span><span class="Constant">97</span>  <span class="Comment"># 'a'</span>
+    <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># unused</span>
+    <span class="Constant">4</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># unused</span>
+    <span class="Constant">5</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># 'text'</span>
+    <span class="Constant">6</span><span class="Special"> &lt;- </span><span class="Constant">98</span>  <span class="Comment"># 'b'</span>
+    <span class="Constant">7</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># unused</span>
+    <span class="Constant">8</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># unused</span>
+    <span class="Constant">9</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># 'text'</span>
+    <span class="Constant">10</span><span class="Special"> &lt;- </span><span class="Constant">99</span>  <span class="Comment"># 'c'</span>
+    <span class="Constant">11</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># unused</span>
+    <span class="Constant">12</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># unused</span>
+    <span class="Constant">13</span><span class="Special"> &lt;- </span><span class="Constant">2</span>  <span class="Comment"># 'mouse'</span>
+    <span class="Constant">14</span><span class="Special"> &lt;- </span><span class="Constant">65513</span>  <span class="Comment"># mouse click</span>
+    <span class="Constant">15</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># row</span>
+    <span class="Constant">16</span><span class="Special"> &lt;- </span><span class="Constant">1</span>  <span class="Comment"># column</span>
+    <span class="Constant">17</span><span class="Special"> &lt;- </span><span class="Constant">1</span>  <span class="Comment"># 'keycode'</span>
+    <span class="Constant">18</span><span class="Special"> &lt;- </span><span class="Constant">65515</span>  <span class="Comment"># up arrow</span>
+    <span class="Constant">19</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># unused</span>
+    <span class="Constant">20</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># unused</span>
+    <span class="Constant">21</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># 'text'</span>
+    <span class="Constant">22</span><span class="Special"> &lt;- </span><span class="Constant">100</span>  <span class="Comment"># 'd'</span>
+    <span class="Constant">23</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># unused</span>
+    <span class="Constant">24</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># unused</span>
+    <span class="Constant">25</span><span class="Special"> &lt;- </span><span class="Constant">0</span>
+  ]
+]
+
+<span class="Comment">//: Deal with special keys and unmatched brackets by allowing each test to</span>
+<span class="Comment">//: independently choose the unicode symbol to denote them.</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
+REPLACE_IN_CONSOLE<span class="Delimiter">,</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
+Recipe_number[<span class="Constant">&quot;replace-in-console&quot;</span>] = REPLACE_IN_CONSOLE<span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
+case REPLACE_IN_CONSOLE: <span class="Delimiter">{</span>
+  assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;console: &quot; &lt;&lt; Memory[CONSOLE] &lt;&lt; '\n'; //? 1</span>
+  if <span class="Delimiter">(</span>!Memory[CONSOLE]<span class="Delimiter">)</span>
+    raise &lt;&lt; <span class="Constant">&quot;console not initialized</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; die<span class="Delimiter">();</span>
+  long long int console_data = Memory[Memory[CONSOLE]+<span class="Constant">1</span>]<span class="Delimiter">;</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;console data starts at &quot; &lt;&lt; console_data &lt;&lt; '\n'; //? 1</span>
+  long long int size = Memory[console_data]<span class="Delimiter">;</span>  <span class="Comment">// array size</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;size of console data is &quot; &lt;&lt; size &lt;&lt; '\n'; //? 1</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">,</span> curr = console_data+<span class="Constant">1</span><span class="Delimiter">;</span> i &lt; size<span class="Delimiter">;</span> ++i<span class="Delimiter">,</span> curr+=size_of_event<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; curr &lt;&lt; '\n'; //? 1</span>
+    if <span class="Delimiter">(</span>Memory[curr] != <span class="Comment">/*</span><span class="Comment">text</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>Memory[curr+<span class="Constant">1</span>] != ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+    for <span class="Delimiter">(</span>long long int n = <span class="Constant">0</span><span class="Delimiter">;</span> n &lt; size_of_event<span class="Delimiter">();</span> ++n<span class="Delimiter">)</span>
+      Memory[curr+n] = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span>n<span class="Delimiter">);</span>
+  <span class="Delimiter">}</span>
+  <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(code)</span>
+long long int count_events<span class="Delimiter">(</span>const recipe&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  long long int result = <span class="Constant">0</span><span class="Delimiter">;</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    const instruction&amp; curr = r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;aa: &quot; &lt;&lt; curr.name &lt;&lt; '\n'; //? 3</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;bb: &quot; &lt;&lt; curr.ingredients.at(0).name &lt;&lt; '\n'; //? 1</span>
+    if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">&quot;type&quot;</span><span class="Delimiter">)</span>
+      result += unicode_length<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span>
+    else
+      result++<span class="Delimiter">;</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;cc: &quot; &lt;&lt; result &lt;&lt; '\n'; //? 1</span>
+  <span class="Delimiter">}</span>
+  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+long long int size_of_event<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+  <span class="Comment">// memoize result if already computed</span>
+  static long long int result = <span class="Constant">0</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>result<span class="Delimiter">)</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+  vector&lt;type_number&gt; type<span class="Delimiter">;</span>
+  type<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Type_number[<span class="Constant">&quot;event&quot;</span>]<span class="Delimiter">);</span>
+  result = size_of<span class="Delimiter">(</span>type<span class="Delimiter">);</span>
+  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+long long int size_of_events<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+  <span class="Comment">// memoize result if already computed</span>
+  static long long int result = <span class="Constant">0</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>result<span class="Delimiter">)</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+  vector&lt;type_number&gt; type<span class="Delimiter">;</span>
+  assert<span class="Delimiter">(</span>Type_number[<span class="Constant">&quot;console&quot;</span>]<span class="Delimiter">);</span>
+  type<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Type_number[<span class="Constant">&quot;console&quot;</span>]<span class="Delimiter">);</span>
+  result = size_of<span class="Delimiter">(</span>type<span class="Delimiter">);</span>
+  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/075scenario_keyboard.cc.html b/html/075scenario_keyboard.cc.html
index b58ca988..7657b451 100644
--- a/html/075scenario_keyboard.cc.html
+++ b/html/075scenario_keyboard.cc.html
@@ -12,13 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+* { font-size: 1.05em; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
diff --git a/html/076scenario_console_test.mu.html b/html/076scenario_console_test.mu.html
new file mode 100644
index 00000000..a3fa6101
--- /dev/null
+++ b/html/076scenario_console_test.mu.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 076scenario_console_test.mu</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="none">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.muScenario { color: #00af00; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
+.Special { color: #ff6060; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment"># To check our support for consoles in scenarios, rewrite tests from</span>
+<span class="Comment"># scenario_console.mu</span>
+<span class="Comment"># Tests for console interface.</span>
+
+<span class="muScenario">scenario</span> read-key-in-mu [
+  assume-console [
+    type <span class="Constant">[abc]</span>
+  ]
+  run [
+    1:character, console:address, 2:boolean<span class="Special"> &lt;- </span>read-key console:address
+    3:character, console:address, 4:boolean<span class="Special"> &lt;- </span>read-key console:address
+    5:character, console:address, 6:boolean<span class="Special"> &lt;- </span>read-key console:address
+    7:character, console:address, 8:boolean<span class="Special"> &lt;- </span>read-key console:address
+  ]
+  memory-should-contain [
+    1<span class="Special"> &lt;- </span>97  <span class="Comment"># 'a'</span>
+    2<span class="Special"> &lt;- </span>1
+    3<span class="Special"> &lt;- </span>98  <span class="Comment"># 'b'</span>
+    4<span class="Special"> &lt;- </span>1
+    5<span class="Special"> &lt;- </span>99  <span class="Comment"># 'c'</span>
+    6<span class="Special"> &lt;- </span>1
+    7<span class="Special"> &lt;- </span>0  <span class="Comment"># eof</span>
+    8<span class="Special"> &lt;- </span>1
+  ]
+]
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/076scenario_keyboard_test.mu.html b/html/076scenario_keyboard_test.mu.html
index 9cc3b21a..ec148812 100644
--- a/html/076scenario_keyboard_test.mu.html
+++ b/html/076scenario_keyboard_test.mu.html
@@ -12,10 +12,10 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .muScenario { color: #00af00; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
 -->
 </style>
diff --git a/html/077mouse.cc.html b/html/077mouse.cc.html
index 0c3f775e..bf7f11b8 100644
--- a/html/077mouse.cc.html
+++ b/html/077mouse.cc.html
@@ -12,12 +12,12 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+* { font-size: 1.05em; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
diff --git a/html/077trace_browser.cc.html b/html/077trace_browser.cc.html
index 87447353..8fa5bf00 100644
--- a/html/077trace_browser.cc.html
+++ b/html/077trace_browser.cc.html
@@ -12,13 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Identifier { color: #008080; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
diff --git a/html/078run_interactive.cc.html b/html/078run_interactive.cc.html
index b8166497..834924c2 100644
--- a/html/078run_interactive.cc.html
+++ b/html/078run_interactive.cc.html
@@ -12,13 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .SalientComment { color: #00ffff; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #008080; }
 -->
 </style>
diff --git a/html/080trace_browser.cc.html b/html/080trace_browser.cc.html
index 62ad443a..7659e81a 100644
--- a/html/080trace_browser.cc.html
+++ b/html/080trace_browser.cc.html
@@ -12,13 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 -->
 </style>
 
diff --git a/html/081run_interactive.cc.html b/html/081run_interactive.cc.html
index a271fe60..35ce1476 100644
--- a/html/081run_interactive.cc.html
+++ b/html/081run_interactive.cc.html
@@ -12,13 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .cSpecial { color: #008000; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .SalientComment { color: #00ffff; }
-.CommentedCode { color: #6c6c6c; }
+.Comment { color: #9090ff; }
 .Identifier { color: #804000; }
 -->
 </style>
diff --git a/html/999spaces.cc.html b/html/999spaces.cc.html
index 4294eaad..784a5cd5 100644
--- a/html/999spaces.cc.html
+++ b/html/999spaces.cc.html
@@ -12,10 +12,10 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+* { font-size: 1.05em; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .SalientComment { color: #00ffff; }
 -->
 </style>
diff --git a/html/callcc.mu.html b/html/callcc.mu.html
index 42dda8e5..e16e87c4 100644
--- a/html/callcc.mu.html
+++ b/html/callcc.mu.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+* { font-size: 1.05em; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.muControl { color: #804000; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
diff --git a/html/channel.mu.html b/html/channel.mu.html
index 82a17f6f..14530ec8 100644
--- a/html/channel.mu.html
+++ b/html/channel.mu.html
@@ -12,12 +12,12 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Delimiter { color: #c000c0; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+* { font-size: 1.05em; }
+.Delimiter { color: #a04060; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.muControl { color: #804000; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
@@ -66,7 +66,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muRecipe">recipe</span> main [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
-  chan:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">3:literal</span>
+  chan:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">3:literal</span>
   <span class="Comment"># create two background 'routines' that communicate by a channel</span>
   routine1:number<span class="Special"> &lt;- </span>start-running producer:<span class="muRecipe">recipe</span>, chan:address:channel
   routine2:number<span class="Special"> &lt;- </span>start-running consumer:<span class="muRecipe">recipe</span>, chan:address:channel
diff --git a/html/chessboard.mu.html b/html/chessboard.mu.html
index 046395e3..ad6d9e2d 100644
--- a/html/chessboard.mu.html
+++ b/html/chessboard.mu.html
@@ -12,15 +12,15 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .muScenario { color: #00af00; }
-.Delimiter { color: #c000c0; }
+.Delimiter { color: #a04060; }
 .SalientComment { color: #00ffff; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
-.muControl { color: #804000; }
+.Comment { color: #9090ff; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
@@ -38,7 +38,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="Comment"># recipes are mu's names for functions</span>
 <span class="muRecipe">recipe</span> main [
-  switch-to-display  <span class="Comment"># take control of screen and keyboard</span>
+  open-console  <span class="Comment"># take control of screen, keyboard and mouse</span>
 
   <span class="Comment"># The chessboard recipe takes keyboard and screen objects as 'ingredients'.</span>
 <span class="Constant">  #</span>
@@ -50,11 +50,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Comment"># results. Here we clearly modify both keyboard and screen, so we return</span>
   <span class="Comment"># both.</span>
 <span class="Constant">  #</span>
-  <span class="Comment"># Here the keyboard and screen are both 0, which usually indicates real</span>
+  <span class="Comment"># Here the console and screen are both 0, which usually indicates real</span>
   <span class="Comment"># hardware rather than a fake for testing as you'll see below.</span>
-  <span class="Constant">0:literal/real-screen</span>, <span class="Constant">0:literal/real-keyboard</span><span class="Special"> &lt;- </span>chessboard <span class="Constant">0:literal/real-screen</span>, <span class="Constant">0:literal/real-keyboard</span>
+  <span class="Constant">0:literal/screen</span>, <span class="Constant">0:literal/console</span><span class="Special"> &lt;- </span>chessboard <span class="Constant">0:literal/screen</span>, <span class="Constant">0:literal/console</span>
 
-  return-to-console  <span class="Comment"># cleanup screen and keyboard</span>
+  close-console  <span class="Comment"># cleanup screen, keyboard and mouse</span>
 ]
 
 <span class="SalientComment">## But enough about mu. Here's what it looks like to run the chessboard program.</span>
@@ -64,10 +64,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Comment"># we'll make the screen really wide because the program currently prints out a long line</span>
   assume-screen <span class="Constant">120:literal/width</span>, <span class="Constant">20:literal/height</span>
   <span class="Comment"># initialize keyboard to type in a move</span>
-  assume-keyboard <span class="Constant">[a2-a4</span>
+  assume-console [
+    type <span class="Constant">[a2-a4</span>
 <span class="Constant">]</span>
+  ]
   run [
-    screen:address, keyboard:address<span class="Special"> &lt;- </span>chessboard screen:address, keyboard:address
+    screen:address, console:address<span class="Special"> &lt;- </span>chessboard screen:address, console:address
 <span class="CommentedCode">#?     $browse-trace #? 1</span>
 <span class="CommentedCode">#?     $close-trace #? 1</span>
     <span class="Comment"># icon for the cursor</span>
@@ -99,6 +101,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
+<span class="CommentedCode">#? scenario foo [ #? 1</span>
+<span class="CommentedCode">#?   $print [aaa] #? 1</span>
+<span class="CommentedCode">#?   run [ #? 1</span>
+<span class="CommentedCode">#?     1:number &lt;- copy 34:literal #? 1</span>
+<span class="CommentedCode">#?   ] #? 1</span>
+<span class="CommentedCode">#?   memory-should-contain [ #? 1</span>
+<span class="CommentedCode">#?     1 &lt;- 34 #? 1</span>
+<span class="CommentedCode">#?   ] #? 1</span>
+<span class="CommentedCode">#?   $print [zzz] #? 1</span>
+<span class="CommentedCode">#? ] #? 1</span>
+
 <span class="SalientComment">## Here's how 'chessboard' is implemented.</span>
 
 <span class="muRecipe">recipe</span> chessboard [
@@ -106,15 +119,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="CommentedCode">#?   $start-tracing #? 1</span>
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  keyboard:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-<span class="CommentedCode">#?   $print [screen: ], screen:address, [, keyboard: ], keyboard:address, [ </span>
+  console:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+<span class="CommentedCode">#?   $print [screen: ], screen:address, [, console: ], console:address, [ </span>
 <span class="CommentedCode">#? ] #? 1</span>
   board:address:array:address:array:character<span class="Special"> &lt;- </span>initial-position
   <span class="Comment"># hook up stdin</span>
-  stdin:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">10:literal/capacity</span>
-  start-running send-keys-to-channel:<span class="muRecipe">recipe</span>, keyboard:address, stdin:address:channel, screen:address
+  stdin:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">10:literal/capacity</span>
+  start-running send-keys-to-channel:<span class="muRecipe">recipe</span>, console:address, stdin:address:channel, screen:address
   <span class="Comment"># buffer lines in stdin</span>
-  buffered-stdin:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">10:literal/capacity</span>
+  buffered-stdin:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">10:literal/capacity</span>
   start-running buffer-lines:<span class="muRecipe">recipe</span>, stdin:address:channel, buffered-stdin:address:channel
   <span class="Delimiter">{</span>
     msg:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[Stupid text-mode chessboard. White pieces in uppercase; black pieces in lowercase. No checking for legal moves.</span>
@@ -159,7 +172,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="SalientComment">## a board is an array of files, a file is an array of characters (squares)</span>
 
-<span class="muRecipe">recipe</span> init-board [
+<span class="muRecipe">recipe</span> new-board [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   initial-position:address:array:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="Comment"># assert(length(initial-position) == 64)</span>
@@ -173,14 +186,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     done?:boolean<span class="Special"> &lt;- </span>equal col:number, <span class="Constant">8:literal</span>
     <span class="muControl">break-if</span> done?:boolean
     file:address:address:array:character<span class="Special"> &lt;- </span>index-address board:address:array:address:array:character/deref, col:number
-    file:address:address:array:character/deref<span class="Special"> &lt;- </span>init-file initial-position:address:array:number, col:number
+    file:address:address:array:character/deref<span class="Special"> &lt;- </span>new-file initial-position:address:array:number, col:number
     col:number<span class="Special"> &lt;- </span>add col:number, <span class="Constant">1:literal</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
   <span class="muControl">reply</span> board:address:array:address:array:character
 ]
 
-<span class="muRecipe">recipe</span> init-file [
+<span class="muRecipe">recipe</span> new-file [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   position:address:array:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   index:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
@@ -259,7 +272,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Comment">#   B P _ _ _ _ p B</span>
   <span class="Comment">#   N P _ _ _ _ p n</span>
   <span class="Comment">#   R P _ _ _ _ p r</span>
-  initial-position:address:array:number<span class="Special"> &lt;- </span>init-array <span class="Constant">82:literal/R</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">114:literal/r</span>, <span class="Constant">78:literal/N</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">110:literal/n</span>, <span class="Constant">66:literal/B</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">98:literal/b</span>, <span class="Constant">81:literal/Q</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">113:literal/q</span>, <span class="Constant">75:literal/K</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">107:literal/k</span>, <span class="Constant">66:literal/B</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">98:literal/b</span>, <span class="Constant">78:literal/N</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">110:literal/n</span>, <span class="Constant">82:literal/R</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">114:literal/r</span>
+  initial-position:address:array:number<span class="Special"> &lt;- </span>new-array <span class="Constant">82:literal/R</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">114:literal/r</span>, <span class="Constant">78:literal/N</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">110:literal/n</span>, <span class="Constant">66:literal/B</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">98:literal/b</span>, <span class="Constant">81:literal/Q</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">113:literal/q</span>, <span class="Constant">75:literal/K</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">107:literal/k</span>, <span class="Constant">66:literal/B</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">98:literal/b</span>, <span class="Constant">78:literal/N</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">110:literal/n</span>, <span class="Constant">82:literal/R</span>, <span class="Constant">80:literal/P</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">32:literal/blank</span>, <span class="Constant">112:literal/p</span>, <span class="Constant">114:literal/r</span>
 <span class="CommentedCode">#?       82:literal/R, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 114:literal/r,</span>
 <span class="CommentedCode">#?       78:literal/N, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 110:literal/n,</span>
 <span class="CommentedCode">#?       66:literal/B, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 98:literal/b, </span>
@@ -268,7 +281,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="CommentedCode">#?       66:literal/B, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 98:literal/b,</span>
 <span class="CommentedCode">#?       78:literal/N, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 110:literal/n,</span>
 <span class="CommentedCode">#?       82:literal/R, 80:literal/P, 32:literal/blank, 32:literal/blank, 32:literal/blank, 32:literal/blank, 112:literal/p, 114:literal/r</span>
-  board:address:array:address:array:character<span class="Special"> &lt;- </span>init-board initial-position:address:array:number
+  board:address:array:address:array:character<span class="Special"> &lt;- </span>new-board initial-position:address:array:number
   <span class="muControl">reply</span> board:address:array:address:array:character
 ]
 
@@ -316,7 +329,7 @@ container move [
   from-file:number, quit?:boolean, error?:boolean<span class="Special"> &lt;- </span>read-file stdin:address:channel, screen:address
   <span class="muControl">reply-if</span> quit?:boolean, <span class="Constant">0:literal/dummy</span>, quit?:boolean, error?:boolean
   <span class="muControl">reply-if</span> error?:boolean, <span class="Constant">0:literal/dummy</span>, quit?:boolean, error?:boolean
-<span class="CommentedCode">#?   return-to-console #? 1</span>
+<span class="CommentedCode">#?   close-console #? 1</span>
   <span class="Comment"># construct the move object</span>
   result:address:move<span class="Special"> &lt;- </span>new move:type
   x:address:number<span class="Special"> &lt;- </span>get-address result:address:move/deref, from-file:offset
@@ -463,7 +476,7 @@ container move [
   assume-screen <span class="Constant">20:literal/width</span>, <span class="Constant">2:literal/height</span>
   run [
 <span class="CommentedCode">#?     $start-tracing #? 1</span>
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">2:literal</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">2:literal</span>
 <span class="CommentedCode">#?     $print [aaa channel address: ], 1:address:channel, [ </span>
 <span class="CommentedCode">#? ] #? 1</span>
     2:number/routine<span class="Special"> &lt;- </span>start-running read-move:<span class="muRecipe">recipe</span>, 1:address:channel, screen:address
@@ -556,7 +569,7 @@ F read-move-blocking: routine failed to terminate on newline]
 <span class="muScenario">scenario</span> read-move-quit [
   assume-screen <span class="Constant">20:literal/width</span>, <span class="Constant">2:literal/height</span>
   run [
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">2:literal</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">2:literal</span>
     2:number/routine<span class="Special"> &lt;- </span>start-running read-move:<span class="muRecipe">recipe</span>, 1:address:channel, screen:address
     <span class="Comment"># 'read-move' is waiting for input</span>
     wait-for-routine 2:number
@@ -583,7 +596,7 @@ F read-move-quit: routine failed to terminate on 'q']
 <span class="muScenario">scenario</span> read-move-illegal-file [
   assume-screen <span class="Constant">20:literal/width</span>, <span class="Constant">2:literal/height</span>
   run [
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">2:literal</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">2:literal</span>
     2:number/routine<span class="Special"> &lt;- </span>start-running read-move:<span class="muRecipe">recipe</span>, 1:address:channel, screen:address
     <span class="Comment"># 'read-move' is waiting for input</span>
     wait-for-routine 2:number
@@ -604,7 +617,7 @@ F read-move-file: routine failed to pause <span class="muRecipe">after</span> co
 <span class="muScenario">scenario</span> read-move-illegal-rank [
   assume-screen <span class="Constant">20:literal/width</span>, <span class="Constant">2:literal/height</span>
   run [
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">2:literal</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">2:literal</span>
     2:number/routine<span class="Special"> &lt;- </span>start-running read-move:<span class="muRecipe">recipe</span>, 1:address:channel, screen:address
     <span class="Comment"># 'read-move' is waiting for input</span>
     wait-for-routine 2:number
@@ -626,7 +639,7 @@ F read-move-file: routine failed to pause <span class="muRecipe">after</span> co
 <span class="muScenario">scenario</span> read-move-empty [
   assume-screen <span class="Constant">20:literal/width</span>, <span class="Constant">2:literal/height</span>
   run [
-    1:address:channel<span class="Special"> &lt;- </span>init-channel <span class="Constant">2:literal</span>
+    1:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">2:literal</span>
     2:number/routine<span class="Special"> &lt;- </span>start-running read-move:<span class="muRecipe">recipe</span>, 1:address:channel, screen:address
     <span class="Comment"># 'read-move' is waiting for input</span>
     wait-for-routine 2:number
diff --git a/html/console.mu.html b/html/console.mu.html
new file mode 100644
index 00000000..098c7e43
--- /dev/null
+++ b/html/console.mu.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - console.mu</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="none">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Special { color: #ff6060; }
+.muControl { color: #c0a020; }
+.muRecipe { color: #ff8700; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment"># example program: reading events from keyboard or mouse</span>
+<span class="Comment">#</span>
+<span class="Comment"># Keeps printing 'a' until you press a key or click on the mouse.</span>
+
+<span class="muRecipe">recipe</span> main [
+  open-console
+  <span class="Delimiter">{</span>
+    _, found?:boolean<span class="Special"> &lt;- </span>check-for-interaction
+    <span class="muControl">break-if</span> found?:boolean
+    print-character-to-display <span class="Constant">97:literal</span>, <span class="Constant">7:literal/white</span>
+    <span class="muControl">loop</span>
+  <span class="Delimiter">}</span>
+  close-console
+]
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/counters.mu.html b/html/counters.mu.html
index 1846c64e..9129fed8 100644
--- a/html/counters.mu.html
+++ b/html/counters.mu.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+* { font-size: 1.05em; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.muControl { color: #804000; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
@@ -32,7 +32,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="Comment"># example program: maintain multiple counters with isolated lexical scopes</span>
 <span class="Comment"># (spaces)</span>
 
-<span class="muRecipe">recipe</span> init-counter [
+<span class="muRecipe">recipe</span> new-counter [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   n:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="muControl">reply</span> <span class="Constant">default-space</span>:address:array:location
@@ -40,7 +40,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muRecipe">recipe</span> increment-counter [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
-  0:address:array:location/names:init-counter<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>  <span class="Comment"># setup outer space; it *must* come from 'init-counter'</span>
+  0:address:array:location/names:new-counter<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>  <span class="Comment"># setup outer space; it *must* come from 'new-counter'</span>
   x:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   n:number/space:1<span class="Special"> &lt;- </span>add n:number/space:1, x:number
   <span class="muControl">reply</span> n:number/space:1
@@ -49,9 +49,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muRecipe">recipe</span> main [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   <span class="Comment"># counter A</span>
-  a:address:array:location<span class="Special"> &lt;- </span>init-counter <span class="Constant">34:literal</span>
+  a:address:array:location<span class="Special"> &lt;- </span>new-counter <span class="Constant">34:literal</span>
   <span class="Comment"># counter B</span>
-  b:address:array:location<span class="Special"> &lt;- </span>init-counter <span class="Constant">23:literal</span>
+  b:address:array:location<span class="Special"> &lt;- </span>new-counter <span class="Constant">23:literal</span>
   <span class="Comment"># increment both by 2 but in different ways</span>
   increment-counter a:address:array:location, <span class="Constant">1:literal</span>
   b-value:number<span class="Special"> &lt;- </span>increment-counter b:address:array:location, <span class="Constant">2:literal</span>
diff --git a/html/display.mu.html b/html/display.mu.html
index efae38f5..2137d471 100644
--- a/html/display.mu.html
+++ b/html/display.mu.html
@@ -12,10 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+* { font-size: 1.05em; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
+.Comment { color: #9090ff; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
@@ -31,26 +32,27 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="Comment"># example program: managing the display</span>
 
 <span class="muRecipe">recipe</span> main [
-  switch-to-display
-  print-character-to-display <span class="Constant">97:literal</span>, <span class="Constant">2:literal/red</span>
+  open-console
+  print-character-to-display <span class="Constant">97:literal</span>, <span class="Constant">1:literal/red</span>
   1:number/<span class="Special">raw</span>, 2:number/<span class="Special">raw &lt;- </span>cursor-position-on-display
-  wait-for-key-from-keyboard
+  wait-for-some-interaction
   clear-display
   move-cursor-on-display <span class="Constant">0:literal</span>, <span class="Constant">4:literal</span>
   print-character-to-display <span class="Constant">98:literal</span>
-  wait-for-key-from-keyboard
+  wait-for-some-interaction
   move-cursor-on-display <span class="Constant">0:literal</span>, <span class="Constant">0:literal</span>
   clear-line-on-display
-  wait-for-key-from-keyboard
+  wait-for-some-interaction
   move-cursor-down-on-display
-  wait-for-key-from-keyboard
+  wait-for-some-interaction
   move-cursor-right-on-display
-  wait-for-key-from-keyboard
+  wait-for-some-interaction
   move-cursor-left-on-display
-  wait-for-key-from-keyboard
+  wait-for-some-interaction
   move-cursor-up-on-display
-  wait-for-key-from-keyboard
-  return-to-console
+  wait-for-some-interaction
+<span class="CommentedCode">#?   $print [aaa] #? 1</span>
+  close-console
 ]
 </pre>
 </body>
diff --git a/html/edit.mu.html b/html/edit.mu.html
index 16ba4cac..574c5281 100644
--- a/html/edit.mu.html
+++ b/html/edit.mu.html
@@ -12,13 +12,15 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Delimiter { color: #c000c0; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+* { font-size: 1.05em; }
+.muScenario { color: #00af00; }
+.Delimiter { color: #a04060; }
+.SalientComment { color: #00ffff; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
-.muControl { color: #804000; }
+.Comment { color: #9090ff; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
@@ -31,139 +33,480 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 </head>
 <body>
 <pre id='vimCodeElement'>
+<span class="Comment"># Editor widget: takes a string and screen coordinates, modifying them in place.</span>
+
 <span class="muRecipe">recipe</span> main [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
-  switch-to-display
+  open-console
   width:number<span class="Special"> &lt;- </span>display-width
-  <span class="Delimiter">{</span>
-    wide-enough?:boolean<span class="Special"> &lt;- </span>greater-than width:number, <span class="Constant">100:literal</span>
-    <span class="muControl">break-if</span> wide-enough?:boolean
-    return-to-console
-    assert wide-enough?:boolean, <span class="Constant">[screen too narrow; we don't support less than 100 characters yet]</span>
-  <span class="Delimiter">}</span>
+  height:number<span class="Special"> &lt;- </span>display-height
   divider:number, _<span class="Special"> &lt;- </span>divide-with-remainder width:number, <span class="Constant">2:literal</span>
-  draw-column <span class="Constant">0:literal/screen</span>, divider:number
-  x:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[1:integer &lt;- add 2:literal, 2:literal]</span>
-  y:address:array:character<span class="Special"> &lt;- </span>edit x:address:array:character, <span class="Constant">0:literal/screen</span>, <span class="Constant">0:literal</span>, <span class="Constant">0:literal</span>, <span class="Constant">5:literal</span>, divider:number
-<span class="CommentedCode">#?   draw-bounding-box 0:literal/screen, 0:literal, 0:literal, 5:literal, divider:number</span>
-  left:number<span class="Special"> &lt;- </span>add divider:number, <span class="Constant">1:literal</span>
-  y:address:array:character<span class="Special"> &lt;- </span>edit <span class="Constant">0:literal</span>, <span class="Constant">0:literal/screen</span>, <span class="Constant">0:literal</span>, left:number, <span class="Constant">2:literal</span>, width:number
-  move-cursor <span class="Constant">0:literal/screen</span>, <span class="Constant">0:literal</span>, <span class="Constant">0:literal</span>
-  wait-for-key-from-keyboard
-  return-to-console
-]
-
-<span class="muRecipe">recipe</span> draw-column [
+  draw-vertical <span class="Constant">0:literal/screen</span>, divider:number, <span class="Constant">0:literal/top</span>, height:number
+  in:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abcdef</span>
+<span class="Constant">def</span>
+<span class="Constant">ghi</span>
+<span class="Constant">jkl</span>
+<span class="Constant">]</span>
+  editor:address:editor-data<span class="Special"> &lt;- </span>new-editor in:address:array:character, <span class="Constant">0:literal/screen</span>, <span class="Constant">0:literal/top</span>, <span class="Constant">0:literal/left</span>, divider:number/right
+  event-loop <span class="Constant">0:literal/screen</span>, <span class="Constant">0:literal/events</span>, editor:address:editor-data
+  close-console
+]
+
+<span class="muScenario">scenario</span> editor-initially-prints-string-to-screen [
+  assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span>
+  run [
+    s:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    new-editor s:address:array:character, screen:address, <span class="Constant">0:literal/top</span>, <span class="Constant">0:literal/left</span>, <span class="Constant">5:literal/right</span>
+  ]
+  screen-should-contain [
+   <span class="Constant"> .abc       .</span>
+   <span class="Constant"> .          .</span>
+  ]
+]
+
+<span class="SalientComment">## In which we introduce the editor data structure, and show how it displays</span>
+<span class="SalientComment">## text to the screen.</span>
+
+container editor-data [
+  <span class="Comment"># doubly linked list of characters</span>
+  data:address:duplex-list
+  <span class="Comment"># location of top-left of screen inside data (scrolling)</span>
+  top-of-screen:address:duplex-list
+  <span class="Comment"># location of cursor inside data</span>
+  cursor:address:duplex-list
+
+  screen:address:screen
+  <span class="Comment"># raw bounds of display area on screen</span>
+  top:number
+  left:number
+  bottom:number
+  right:number
+  <span class="Comment"># raw screen coordinates of cursor</span>
+  cursor-row:number
+  cursor-column:number
+]
+
+<span class="Comment"># editor:address, screen:address &lt;- new-editor s:address:array:character, screen:address, top:number, left:number, bottom:number</span>
+<span class="Comment"># creates a new editor widget and renders its initial appearance to screen.</span>
+<span class="Comment">#   top/left/right constrain the screen area available to the new editor.</span>
+<span class="Comment">#   right is exclusive.</span>
+<span class="muRecipe">recipe</span> new-editor [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  s:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  col:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  curr:number<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
-  max:number<span class="Special"> &lt;- </span>screen-height screen:address
+  <span class="Comment"># no clipping of bounds</span>
+  top:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  left:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  right:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  right:number<span class="Special"> &lt;- </span>subtract right:number, <span class="Constant">1:literal</span>
+  result:address:editor-data<span class="Special"> &lt;- </span>new editor-data:type
+  <span class="Comment"># initialize screen-related fields</span>
+  sc:address:address:screen<span class="Special"> &lt;- </span>get-address result:address:editor-data/deref, screen:offset
+  sc:address:address:screen/deref<span class="Special"> &lt;- </span>copy screen:address
+  x:address:number<span class="Special"> &lt;- </span>get-address result:address:editor-data/deref, top:offset
+  x:address:number/deref<span class="Special"> &lt;- </span>copy top:number
+  x:address:number<span class="Special"> &lt;- </span>get-address result:address:editor-data/deref, left:offset
+  x:address:number/deref<span class="Special"> &lt;- </span>copy left:number
+  x:address:number<span class="Special"> &lt;- </span>get-address result:address:editor-data/deref, right:offset
+  x:address:number/deref<span class="Special"> &lt;- </span>copy right:number
+  <span class="Comment"># initialize bottom to top for starters</span>
+  x:address:number<span class="Special"> &lt;- </span>get-address result:address:editor-data/deref, bottom:offset
+  x:address:number/deref<span class="Special"> &lt;- </span>copy top:number
+  <span class="Comment"># initialize cursor</span>
+  x:address:number<span class="Special"> &lt;- </span>get-address result:address:editor-data/deref, cursor-row:offset
+  x:address:number/deref<span class="Special"> &lt;- </span>copy top:number
+  x:address:number<span class="Special"> &lt;- </span>get-address result:address:editor-data/deref, cursor-column:offset
+  x:address:number/deref<span class="Special"> &lt;- </span>copy left:number
+  <span class="Comment"># early exit if s is empty</span>
+  <span class="muControl">reply-unless</span> s:address:array:character, result:address:editor-data
+  len:number<span class="Special"> &lt;- </span>length s:address:array:character/deref
+  <span class="muControl">reply-unless</span> len:number, result:address:editor-data
+  idx:number<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
+  <span class="Comment"># s is guaranteed to have at least one character, so initialize result's</span>
+  <span class="Comment"># duplex-list</span>
+  init:address:address:duplex-list<span class="Special"> &lt;- </span>get-address result:address:editor-data/deref, top-of-screen:offset
+  init:address:address:duplex-list/deref<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
+  c:character<span class="Special"> &lt;- </span>index s:address:array:character/deref, idx:number
+  idx:number<span class="Special"> &lt;- </span>add idx:number, <span class="Constant">1:literal</span>
+  init:address:address:duplex-list/deref<span class="Special"> &lt;- </span>push c:character, init:address:address:duplex-list/deref
+  curr:address:duplex-list<span class="Special"> &lt;- </span>copy init:address:address:duplex-list/deref
+  <span class="Comment"># now we can start appending the rest, character by character</span>
   <span class="Delimiter">{</span>
-    continue?:boolean<span class="Special"> &lt;- </span>lesser-than curr:number, max:number
-    <span class="muControl">break-unless</span> continue?:boolean
-    move-cursor screen:address, curr:number, col:number
-    print-character screen:address, <span class="Constant">9474:literal/vertical</span>, <span class="Constant">245:literal/grey</span>
-    curr:number<span class="Special"> &lt;- </span>add curr:number, <span class="Constant">1:literal</span>
+<span class="CommentedCode">#?     $print idx:number, [ vs ], len:number, [ </span>
+<span class="CommentedCode">#? ] #? 1</span>
+    done?:boolean<span class="Special"> &lt;- </span>greater-or-equal idx:number, len:number
+    <span class="muControl">break-if</span> done?:boolean
+    c:character<span class="Special"> &lt;- </span>index s:address:array:character/deref, idx:number
+<span class="CommentedCode">#?     $print [aa: ], c:character, [ </span>
+<span class="CommentedCode">#? ] #? 1</span>
+    insert-duplex c:character, curr:address:duplex-list
+    <span class="Comment"># next iter</span>
+    curr:address:duplex-list<span class="Special"> &lt;- </span>next-duplex curr:address:duplex-list
+    idx:number<span class="Special"> &lt;- </span>add idx:number, <span class="Constant">1:literal</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  move-cursor screen:address, <span class="Constant">0:literal</span>, <span class="Constant">0:literal</span>
+  <span class="Comment"># initialize cursor to top of screen</span>
+  y:address:address:duplex-list<span class="Special"> &lt;- </span>get-address result:address:editor-data/deref, cursor:offset
+  y:address:address:duplex-list/deref<span class="Special"> &lt;- </span>copy init:address:address:duplex-list/deref
+  <span class="Comment"># perform initial rendering to screen</span>
+  bottom:address:number<span class="Special"> &lt;- </span>get-address result:address:editor-data/deref, bottom:offset
+  bottom:address:number/deref, screen:address<span class="Special"> &lt;- </span>render result:address:editor-data, screen:address, top:number, left:number, right:number
+  <span class="muControl">reply</span> result:address:editor-data
+]
+
+<span class="muScenario">scenario</span> editor-initializes-without-data [
+  assume-screen <span class="Constant">5:literal/width</span>, <span class="Constant">3:literal/height</span>
+  run [
+    1:address:editor-data<span class="Special"> &lt;- </span>new-editor <span class="Constant">0:literal/data</span>, screen:address, <span class="Constant">1:literal/top</span>, <span class="Constant">2:literal/left</span>, <span class="Constant">5:literal/right</span>
+    2:editor-data<span class="Special"> &lt;- </span>copy 1:address:editor-data/deref
+  ]
+  memory-should-contain [
+    2<span class="Special"> &lt;- </span>0  <span class="Comment"># data</span>
+    3<span class="Special"> &lt;- </span>0  <span class="Comment"># pointer into data to top of screen</span>
+    4<span class="Special"> &lt;- </span>0  <span class="Comment"># pointer into data to cursor</span>
+    <span class="Comment"># 5 &lt;- screen</span>
+    6<span class="Special"> &lt;- </span>1  <span class="Comment"># top</span>
+    7<span class="Special"> &lt;- </span>2  <span class="Comment"># left</span>
+    8<span class="Special"> &lt;- </span>1  <span class="Comment"># bottom</span>
+    9<span class="Special"> &lt;- </span>4  <span class="Comment"># right  (inclusive)</span>
+    10<span class="Special"> &lt;- </span>1  <span class="Comment"># cursor row</span>
+    11<span class="Special"> &lt;- </span>2  <span class="Comment"># cursor column</span>
+  ]
+  screen-should-contain [
+   <span class="Constant"> .     .</span>
+   <span class="Constant"> .     .</span>
+   <span class="Constant"> .     .</span>
+  ]
 ]
 
-<span class="muRecipe">recipe</span> edit [
+<span class="muRecipe">recipe</span> render [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
-  in:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  editor:address:editor-data<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   top:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   left:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  bottom:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  screen-height:number<span class="Special"> &lt;- </span>screen-height screen:address
   right:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  <span class="Comment"># draw bottom boundary</span>
-  curr:number<span class="Special"> &lt;- </span>copy left:number
+  cursor:address:duplex-list<span class="Special"> &lt;- </span>get editor:address:editor-data/deref, cursor:offset
+  <span class="Comment"># traversing editor</span>
+  curr:address:duplex-list<span class="Special"> &lt;- </span>get editor:address:editor-data/deref, top-of-screen:offset
+  <span class="Comment"># traversing screen</span>
+  row:number<span class="Special"> &lt;- </span>copy top:number
+  column:number<span class="Special"> &lt;- </span>copy left:number
+  move-cursor screen:address, row:number, column:number
   <span class="Delimiter">{</span>
-    continue?:boolean<span class="Special"> &lt;- </span>lesser-than curr:number, right:number
-    <span class="muControl">break-unless</span> continue?:boolean
-    move-cursor screen:address, bottom:number, curr:number
-    print-character screen:address, <span class="Constant">9472:literal/vertical</span>, <span class="Constant">245:literal/grey</span>
-    curr:number<span class="Special"> &lt;- </span>add curr:number, <span class="Constant">1:literal</span>
+<span class="Constant">    +next-character</span>
+<span class="CommentedCode">#?     $print curr:address:duplex-list, [ </span>
+<span class="CommentedCode">#? ] #? 1</span>
+    <span class="muControl">break-unless</span> curr:address:duplex-list
+    off-screen?:boolean<span class="Special"> &lt;- </span>greater-or-equal row:number, screen-height:number
+    <span class="muControl">break-if</span> off-screen?:boolean
+    <span class="Delimiter">{</span>
+      at-cursor?:boolean<span class="Special"> &lt;- </span>equal curr:address:duplex-list, cursor:address:duplex-list
+      <span class="muControl">break-unless</span> at-cursor?:boolean
+      cursor-row:number<span class="Special"> &lt;- </span>copy row:number
+      cursor-column:number<span class="Special"> &lt;- </span>copy column:number
+    <span class="Delimiter">}</span>
+    c:character<span class="Special"> &lt;- </span>get curr:address:duplex-list/deref, value:offset
+    <span class="Delimiter">{</span>
+      <span class="Comment"># newline? move to left rather than 0</span>
+      newline?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">10:literal/newline</span>
+      <span class="muControl">break-unless</span> newline?:boolean
+      row:number<span class="Special"> &lt;- </span>add row:number, <span class="Constant">1:literal</span>
+      column:number<span class="Special"> &lt;- </span>copy left:number
+      move-cursor screen:address, row:number, column:number
+      curr:address:duplex-list<span class="Special"> &lt;- </span>next-duplex curr:address:duplex-list
+      <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
+    <span class="Delimiter">}</span>
+    <span class="Delimiter">{</span>
+      <span class="Comment"># at right? more than one letter left in the line? wrap</span>
+      at-right?:boolean<span class="Special"> &lt;- </span>equal column:number, right:number
+      <span class="muControl">break-unless</span> at-right?:boolean
+      next-node:address:duplex-list<span class="Special"> &lt;- </span>next-duplex curr:address:duplex-list
+      <span class="muControl">break-unless</span> next-node:address:duplex-list
+      next:character<span class="Special"> &lt;- </span>get next-node:address:duplex-list/deref, value:offset
+      next-character-is-newline?:boolean<span class="Special"> &lt;- </span>equal next:character, <span class="Constant">10:literal/newline</span>
+      <span class="muControl">break-if</span> next-character-is-newline?:boolean
+      <span class="Comment"># wrap</span>
+      print-character screen:address, <span class="Constant">8617:literal/loop-back-to-left</span>, <span class="Constant">245:literal/grey</span>
+      column:number<span class="Special"> &lt;- </span>copy left:number
+      row:number<span class="Special"> &lt;- </span>add row:number, <span class="Constant">1:literal</span>
+      move-cursor screen:address, row:number, column:number
+      <span class="Comment"># don't increment curr</span>
+      <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
+    <span class="Delimiter">}</span>
+    print-character screen:address, c:character
+    curr:address:duplex-list<span class="Special"> &lt;- </span>next-duplex curr:address:duplex-list
+    column:number<span class="Special"> &lt;- </span>add column:number, <span class="Constant">1:literal</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  move-cursor screen:address, top:number, left:number
+  move-cursor screen:address, cursor-row:number, cursor-column:number
+  <span class="muControl">reply</span> row:number, screen:address/same-as-ingredient:1
+]
+
+<span class="muScenario">scenario</span> editor-initially-prints-multiple-lines [
+  assume-screen <span class="Constant">5:literal/width</span>, <span class="Constant">3:literal/height</span>
+  run [
+    s:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc</span>
+<span class="Constant">def]</span>
+    new-editor s:address:array:character, screen:address, <span class="Constant">0:literal/top</span>, <span class="Constant">0:literal/left</span>, <span class="Constant">5:literal/right</span>
+  ]
+  screen-should-contain [
+   <span class="Constant"> .abc  .</span>
+   <span class="Constant"> .def  .</span>
+   <span class="Constant"> .     .</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> editor-initially-handles-offsets [
+  assume-screen <span class="Constant">5:literal/width</span>, <span class="Constant">3:literal/height</span>
+  run [
+    s:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    new-editor s:address:array:character, screen:address, <span class="Constant">0:literal/top</span>, <span class="Constant">1:literal/left</span>, <span class="Constant">5:literal/right</span>
+  ]
+  screen-should-contain [
+   <span class="Constant"> . abc .</span>
+   <span class="Constant"> .     .</span>
+   <span class="Constant"> .     .</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> editor-initially-prints-multiple-lines-at-offset [
+  assume-screen <span class="Constant">5:literal/width</span>, <span class="Constant">3:literal/height</span>
+  run [
+    s:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc</span>
+<span class="Constant">def]</span>
+    new-editor s:address:array:character, screen:address, <span class="Constant">0:literal/top</span>, <span class="Constant">1:literal/left</span>, <span class="Constant">5:literal/right</span>
+  ]
+  screen-should-contain [
+   <span class="Constant"> . abc .</span>
+   <span class="Constant"> . def .</span>
+   <span class="Constant"> .     .</span>
+  ]
 ]
 
-<span class="muRecipe">recipe</span> draw-bounding-box [
+<span class="muScenario">scenario</span> editor-initially-wraps-long-lines [
+  assume-screen <span class="Constant">5:literal/width</span>, <span class="Constant">3:literal/height</span>
+  run [
+    s:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc def]</span>
+    new-editor s:address:array:character, screen:address, <span class="Constant">0:literal/top</span>, <span class="Constant">0:literal/left</span>, <span class="Constant">5:literal/right</span>
+  ]
+  screen-should-contain [
+   <span class="Constant"> .abc ↩.</span>
+   <span class="Constant"> .def  .</span>
+   <span class="Constant"> .     .</span>
+  ]
+  screen-should-contain-in-color, <span class="Constant">245:literal/grey</span> [
+   <span class="Constant"> .    ↩.</span>
+   <span class="Constant"> .     .</span>
+   <span class="Constant"> .     .</span>
+  ]
+]
+
+<span class="SalientComment">## handling events from the keyboard and mouse</span>
+
+<span class="muRecipe">recipe</span> event-loop [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  <span class="Comment"># sanity-check the box bounds</span>
-  top:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  console:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  editor:address:editor-data<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="Delimiter">{</span>
-    out?:boolean<span class="Special"> &lt;- </span>lesser-than top:number, <span class="Constant">0:literal</span>
-    <span class="muControl">break-unless</span> out?:boolean
-    top:number<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
+<span class="Constant">    +next-event</span>
+    e:event, console:address, found?:boolean, quit?:boolean<span class="Special"> &lt;- </span>read-event console:address
+    <span class="muControl">loop-unless</span> found?:boolean
+    <span class="muControl">break-if</span> quit?:boolean  <span class="Comment"># only in tests</span>
+    trace <span class="Constant">[app]</span>, <span class="Constant">[next-event]</span>
+    <span class="Delimiter">{</span>
+      t:address:touch-event<span class="Special"> &lt;- </span>maybe-convert e:event, touch:variant
+      <span class="muControl">break-unless</span> t:address:touch-event
+      editor:address:editor-data<span class="Special"> &lt;- </span>move-cursor-in-editor editor:address:editor-data, t:address:touch-event
+      <span class="muControl">loop</span> <span class="Constant">+next-event:label</span>
+    <span class="Delimiter">}</span>
+    c:address:character<span class="Special"> &lt;- </span>maybe-convert e:event, text:variant
+    assert c:address:character, <span class="Constant">[event was of unknown type; neither keyboard nor mouse]</span>
+    <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
+]
+
+<span class="muRecipe">recipe</span> move-cursor-in-editor [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  editor:address:editor-data<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  t:address:touch-event<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  row:address:number<span class="Special"> &lt;- </span>get-address editor:address:editor-data/deref, cursor-row:offset
+  row:address:number/deref<span class="Special"> &lt;- </span>get t:address:touch-event/deref, row:offset
+  column:address:number<span class="Special"> &lt;- </span>get-address editor:address:editor-data/deref, cursor-column:offset
+  column:address:number/deref<span class="Special"> &lt;- </span>get t:address:touch-event/deref, column:offset
+  <span class="Comment"># todo: adjust 'cursor' pointer into editor data</span>
+]
+
+<span class="muScenario">scenario</span> editor-handles-empty-event-queue [
+  assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span>
+  assume-console <span class="Constant">[]</span>
+  run [
+    s:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    editor:address:editor-data<span class="Special"> &lt;- </span>new-editor s:address:array:character, screen:address, <span class="Constant">0:literal/top</span>, <span class="Constant">0:literal/left</span>, <span class="Constant">5:literal/right</span>
+    event-loop screen:address, console:address, editor:address:editor-data
+  ]
+  screen-should-contain [
+   <span class="Constant"> .abc       .</span>
+   <span class="Constant"> .          .</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> editor-handles-mouse-clicks [
+  assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span>
+  assume-console [
+    left-click 0, 1
+  ]
+  run [
+    1:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
+    2:address:editor-data<span class="Special"> &lt;- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/top</span>, <span class="Constant">0:literal/left</span>, <span class="Constant">5:literal/right</span>
+    event-loop screen:address, console:address, 2:address:editor-data
+    3:number<span class="Special"> &lt;- </span>get 2:address:editor-data/deref, cursor-row:offset
+    4:number<span class="Special"> &lt;- </span>get 2:address:editor-data/deref, cursor-column:offset
+  ]
+  screen-should-contain [
+   <span class="Constant"> .abc       .</span>
+   <span class="Constant"> .          .</span>
+  ]
+  memory-should-contain [
+    3<span class="Special"> &lt;- </span>0  <span class="Comment"># cursor is at row 0..</span>
+    4<span class="Special"> &lt;- </span>1  <span class="Comment"># ..and column 1</span>
+  ]
+]
+
+<span class="SalientComment">## helpers for drawing editor borders</span>
+
+<span class="muRecipe">recipe</span> draw-box [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  top:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   left:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  <span class="Delimiter">{</span>
-    out?:boolean<span class="Special"> &lt;- </span>lesser-than left:number, <span class="Constant">0:literal</span>
-    <span class="muControl">break-unless</span> out?:boolean
-    left:number<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
-  <span class="Delimiter">}</span>
   bottom:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  <span class="Delimiter">{</span>
-    height:number<span class="Special"> &lt;- </span>screen-height screen:address
-    out?:boolean<span class="Special"> &lt;- </span>greater-or-equal bottom:number, height:number
-    <span class="muControl">break-unless</span> out?:boolean
-    bottom:number<span class="Special"> &lt;- </span>subtract height:number, <span class="Constant">1:literal</span>
-  <span class="Delimiter">}</span>
   right:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  color:number, color-found?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="Delimiter">{</span>
-    width:number<span class="Special"> &lt;- </span>screen-width screen:address
-    out?:boolean<span class="Special"> &lt;- </span>greater-or-equal right:number, width:number
-    <span class="muControl">break-unless</span> out?:boolean
-    right:number<span class="Special"> &lt;- </span>subtract width:number, <span class="Constant">1:literal</span>
+    <span class="Comment"># default color to white</span>
+    <span class="muControl">break-if</span> color-found?:boolean
+    color:number<span class="Special"> &lt;- </span>copy <span class="Constant">245:literal/grey</span>
   <span class="Delimiter">}</span>
-<span class="CommentedCode">#?   print-integer screen:address, bottom:number</span>
-<span class="CommentedCode">#?   print-character screen:address, 32:literal/space</span>
-<span class="CommentedCode">#?   print-integer screen:address, right:number</span>
   <span class="Comment"># top border</span>
+  draw-horizontal screen:address, top:number, left:number, right:number, color:number
+  draw-horizontal screen:address, bottom:number, left:number, right:number, color:number
+  draw-vertical screen:address, left:number, top:number, bottom:number, color:number
+  draw-vertical screen:address, right:number, top:number, bottom:number, color:number
+  draw-top-left screen:address, top:number, left:number, color:number
+  draw-top-right screen:address, top:number, right:number, color:number
+  draw-bottom-left screen:address, bottom:number, left:number, color:number
+  draw-bottom-right screen:address, bottom:number, right:number, color:number
+  <span class="Comment"># position cursor inside box</span>
   move-cursor screen:address, top:number, left:number
-  print-character screen:address, <span class="Constant">9484:literal/down-right</span>, <span class="Constant">245:literal/grey</span>
-  x:number<span class="Special"> &lt;- </span>add left:number, <span class="Constant">1:literal</span>  <span class="Comment"># exclude corner</span>
+  cursor-down screen:address
+  cursor-right screen:address
+]
+
+<span class="muRecipe">recipe</span> draw-horizontal [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  row:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  x:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  right:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  color:number, color-found?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="Delimiter">{</span>
-    continue?:boolean<span class="Special"> &lt;- </span>lesser-than x:number, right:number
-    <span class="muControl">break-unless</span> continue?:boolean
-    print-character screen:address, <span class="Constant">9472:literal/horizontal</span>, <span class="Constant">245:literal/grey</span>
-    x:number<span class="Special"> &lt;- </span>add x:number, <span class="Constant">1:literal</span>
-    <span class="muControl">loop</span>
+    <span class="Comment"># default color to white</span>
+    <span class="muControl">break-if</span> color-found?:boolean
+    color:number<span class="Special"> &lt;- </span>copy <span class="Constant">245:literal/grey</span>
   <span class="Delimiter">}</span>
-  print-character screen:address, <span class="Constant">9488:literal/down-left</span>, <span class="Constant">245:literal/grey</span>
-  <span class="Comment"># bottom border</span>
-  move-cursor screen:address, bottom:number, left:number
-  print-character screen:address, <span class="Constant">9492:literal/up-right</span>, <span class="Constant">245:literal/grey</span>
-  x:number<span class="Special"> &lt;- </span>add left:number, <span class="Constant">1:literal</span>  <span class="Comment"># exclude corner</span>
+  move-cursor screen:address, row:number, x:number
   <span class="Delimiter">{</span>
     continue?:boolean<span class="Special"> &lt;- </span>lesser-than x:number, right:number
     <span class="muControl">break-unless</span> continue?:boolean
-    print-character screen:address, <span class="Constant">9472:literal/horizontal</span>, <span class="Constant">245:literal/grey</span>
+    print-character screen:address, <span class="Constant">9472:literal/horizontal</span>, color:number
     x:number<span class="Special"> &lt;- </span>add x:number, <span class="Constant">1:literal</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  print-character screen:address, <span class="Constant">9496:literal/up-left</span>, <span class="Constant">245:literal/grey</span>
-  <span class="Comment"># left and right borders</span>
-  x:number<span class="Special"> &lt;- </span>add top:number, <span class="Constant">1:literal</span>  <span class="Comment"># exclude corner</span>
+]
+
+<span class="muRecipe">recipe</span> draw-vertical [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  col:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  x:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  bottom:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  color:number, color-found?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Delimiter">{</span>
+    <span class="Comment"># default color to white</span>
+    <span class="muControl">break-if</span> color-found?:boolean
+    color:number<span class="Special"> &lt;- </span>copy <span class="Constant">245:literal/grey</span>
+  <span class="Delimiter">}</span>
   <span class="Delimiter">{</span>
     continue?:boolean<span class="Special"> &lt;- </span>lesser-than x:number, bottom:number
     <span class="muControl">break-unless</span> continue?:boolean
-    move-cursor screen:address, x:number, left:number
-    print-character screen:address, <span class="Constant">9474:literal/vertical</span>, <span class="Constant">245:literal/grey</span>
-    move-cursor screen:address, x:number, right:number
-    print-character screen:address, <span class="Constant">9474:literal/vertical</span>, <span class="Constant">245:literal/grey</span>
+    move-cursor screen:address, x:number, col:number
+    print-character screen:address, <span class="Constant">9474:literal/vertical</span>, color:number
     x:number<span class="Special"> &lt;- </span>add x:number, <span class="Constant">1:literal</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="Comment"># position cursor inside box</span>
+]
+
+<span class="muRecipe">recipe</span> draw-top-left [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  top:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  left:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  color:number, color-found?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Delimiter">{</span>
+    <span class="Comment"># default color to white</span>
+    <span class="muControl">break-if</span> color-found?:boolean
+    color:number<span class="Special"> &lt;- </span>copy <span class="Constant">245:literal/grey</span>
+  <span class="Delimiter">}</span>
   move-cursor screen:address, top:number, left:number
-  cursor-down screen:address
-  cursor-right screen:address
+  print-character screen:address, <span class="Constant">9484:literal/down-right</span>, color:number
+]
+
+<span class="muRecipe">recipe</span> draw-top-right [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  top:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  right:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  color:number, color-found?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Delimiter">{</span>
+    <span class="Comment"># default color to white</span>
+    <span class="muControl">break-if</span> color-found?:boolean
+    color:number<span class="Special"> &lt;- </span>copy <span class="Constant">245:literal/grey</span>
+  <span class="Delimiter">}</span>
+  move-cursor screen:address, top:number, right:number
+  print-character screen:address, <span class="Constant">9488:literal/down-left</span>, color:number
+]
+
+<span class="muRecipe">recipe</span> draw-bottom-left [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  bottom:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  left:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  color:number, color-found?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Delimiter">{</span>
+    <span class="Comment"># default color to white</span>
+    <span class="muControl">break-if</span> color-found?:boolean
+    color:number<span class="Special"> &lt;- </span>copy <span class="Constant">245:literal/grey</span>
+  <span class="Delimiter">}</span>
+  move-cursor screen:address, bottom:number, left:number
+  print-character screen:address, <span class="Constant">9492:literal/up-right</span>, color:number
+]
+
+<span class="muRecipe">recipe</span> draw-bottom-right [
+  <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
+  screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  bottom:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  right:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  color:number, color-found?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Delimiter">{</span>
+    <span class="Comment"># default color to white</span>
+    <span class="muControl">break-if</span> color-found?:boolean
+    color:number<span class="Special"> &lt;- </span>copy <span class="Constant">245:literal/grey</span>
+  <span class="Delimiter">}</span>
+  move-cursor screen:address, bottom:number, right:number
+  print-character screen:address, <span class="Constant">9496:literal/up-left</span>, color:number
 ]
 </pre>
 </body>
diff --git a/html/factorial.mu.html b/html/factorial.mu.html
index 22438340..13e4a6c0 100644
--- a/html/factorial.mu.html
+++ b/html/factorial.mu.html
@@ -12,13 +12,13 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .muScenario { color: #00af00; }
-.Delimiter { color: #c000c0; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+.Delimiter { color: #a04060; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.muControl { color: #804000; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
diff --git a/html/fork.mu.html b/html/fork.mu.html
index 40e645b5..4d6b367c 100644
--- a/html/fork.mu.html
+++ b/html/fork.mu.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
-.muControl { color: #804000; }
+* { font-size: 1.05em; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
diff --git a/html/keyboard.mu.html b/html/keyboard.mu.html
index 9b0e29b3..883ead79 100644
--- a/html/keyboard.mu.html
+++ b/html/keyboard.mu.html
@@ -12,12 +12,12 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Constant { color: #008080; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+* { font-size: 1.05em; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.muControl { color: #804000; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
diff --git a/html/mouse.mu.html b/html/mouse.mu.html
index c4926f24..8987fca6 100644
--- a/html/mouse.mu.html
+++ b/html/mouse.mu.html
@@ -12,11 +12,11 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Comment { color: #8080ff; }
-.Delimiter { color: #c000c0; }
+* { font-size: 1.05em; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.muControl { color: #804000; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
diff --git a/html/repl.mu.html b/html/repl.mu.html
index 2ccd9f9b..87daf87b 100644
--- a/html/repl.mu.html
+++ b/html/repl.mu.html
@@ -12,14 +12,14 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
+* { font-size: 1.05em; }
 .muScenario { color: #00af00; }
-.Delimiter { color: #c000c0; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+.Delimiter { color: #a04060; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
-.muControl { color: #804000; }
+.Comment { color: #9090ff; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
@@ -36,35 +36,36 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muRecipe">recipe</span> main [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
-  switch-to-display
+  open-console
   msg:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[ready! type in an instruction, then hit enter. ctrl-d exits.</span>
 <span class="Constant">]</span>
   <span class="Constant">0:literal/real-screen</span><span class="Special"> &lt;- </span>print-string <span class="Constant">0:literal/real-screen</span>, msg:address:array:character, <span class="Constant">245:literal/grey</span>
-  <span class="Constant">0:literal/real-keyboard</span>, <span class="Constant">0:literal/real-screen</span><span class="Special"> &lt;- </span>color-session <span class="Constant">0:literal/real-keyboard</span>, <span class="Constant">0:literal/real-screen</span>
-<span class="CommentedCode">#?   wait-for-key-from-keyboard #? 1</span>
-  return-to-console
+  <span class="Constant">0:literal/real-console</span>, <span class="Constant">0:literal/real-screen</span><span class="Special"> &lt;- </span>color-session <span class="Constant">0:literal/real-console</span>, <span class="Constant">0:literal/real-screen</span>
+  close-console
 ]
 
 <span class="muRecipe">recipe</span> color-session [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
-  keyboard:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  console:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="Delimiter">{</span>
-    inst:address:array:character, keyboard:address, screen:address<span class="Special"> &lt;- </span>read-instruction keyboard:address, screen:address
+    inst:address:array:character, console:address, screen:address<span class="Special"> &lt;- </span>read-instruction console:address, screen:address
     <span class="muControl">break-unless</span> inst:address:array:character
     run-interactive inst:address:array:character
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> keyboard:address/same-as-ingredient:0, screen:address/same-as-ingredient:1
+  <span class="muControl">reply</span> console:address/same-as-ingredient:0, screen:address/same-as-ingredient:1
 ]
 
-<span class="Comment"># basic keyboard input; just text and enter</span>
+<span class="Comment"># basic console input; just text and enter</span>
 <span class="muScenario">scenario</span> read-instruction1 [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[x &lt;- copy y</span>
+  assume-console [
+    type <span class="Constant">[x &lt;- copy y</span>
 <span class="Constant">]</span>
+  ]
   run [
-    1:address:array:character<span class="Special"> &lt;- </span>read-instruction keyboard:address, screen:address
+    1:address:array:character<span class="Special"> &lt;- </span>read-instruction console:address, screen:address
     2:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[=&gt; ]</span>
     print-string screen:address, 2:address:array:character
     print-string screen:address, 1:address:array:character
@@ -85,15 +86,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="Comment"># Read characters as they're typed at the keyboard, print them to the screen,</span>
+<span class="Comment"># Read characters as they're typed at the console, print them to the screen,</span>
 <span class="Comment"># accumulate them in a string, return the string at the end.</span>
 <span class="Comment"># Most of the complexity is for the printing to screen, to highlight strings</span>
 <span class="Comment"># and comments specially. Especially in the presence of backspacing.</span>
 <span class="muRecipe">recipe</span> read-instruction [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">60:literal</span>
-  k:address:keyboard<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  x:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  result:address:buffer<span class="Special"> &lt;- </span>init-buffer <span class="Constant">10:literal</span>  <span class="Comment"># string to maybe add to</span>
+  console:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  result:address:buffer<span class="Special"> &lt;- </span>new-buffer <span class="Constant">10:literal</span>  <span class="Comment"># string to maybe add to</span>
   trace <span class="Constant">[app]</span>, <span class="Constant">[read-instruction]</span>
   <span class="Comment"># start state machine by calling slurp-regular-characters, which will return</span>
   <span class="Comment"># by calling the complete continuation</span>
@@ -104,7 +105,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   completed?:boolean<span class="Special"> &lt;- </span>greater-than len:number, <span class="Constant">0:literal</span>
   <span class="muControl">jump-if</span> completed?:boolean, <span class="Constant">+completed:label</span>
   <span class="Comment"># Otherwise we're just getting started.</span>
-  result:address:buffer, k:address:keyboard, x:address:screen<span class="Special"> &lt;- </span>slurp-regular-characters result:address:buffer, k:address:keyboard, x:address:screen, complete:continuation
+  result:address:buffer, console:address, screen:address<span class="Special"> &lt;- </span>slurp-regular-characters result:address:buffer, console:address, screen:address, complete:continuation
 <span class="CommentedCode">#?   $print [aaa: ], result:address:buffer #? 1</span>
 <span class="CommentedCode">#?   move-cursor-down-on-display #? 1</span>
   trace <span class="Constant">[error]</span>, <span class="Constant">[slurp-regular-characters should never return normally]</span>
@@ -113,16 +114,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="CommentedCode">#?   $print [bbb: ], result2:address:array:character #? 1</span>
 <span class="CommentedCode">#?   move-cursor-down-on-display #? 1</span>
   trace <span class="Constant">[app]</span>, <span class="Constant">[exiting read-instruction]</span>
-  <span class="muControl">reply</span> result2:address:array:character, k:address:keyboard/same-as-ingredient:0, x:address:screen/same-as-ingredient:1
+  <span class="muControl">reply</span> result2:address:array:character, console:address/same-as-ingredient:0, screen:address/same-as-ingredient:1
 ]
 
-<span class="Comment"># read characters from the keyboard, print them to the screen in *white*.</span>
+<span class="Comment"># read characters from the console, print them to the screen in *white*.</span>
 <span class="Comment"># Transition to other routines for comments and strings.</span>
 <span class="muRecipe">recipe</span> slurp-regular-characters [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   result:address:buffer<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  k:address:keyboard<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  x:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  console:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   complete:continuation<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-regular-characters]</span>
   characters-slurped:number<span class="Special"> &lt;- </span>copy <span class="Constant">0:literal</span>
@@ -134,8 +135,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="CommentedCode">#? ] #? 1</span>
 <span class="CommentedCode">#?     move-cursor-down-on-display #? 1</span>
     <span class="Comment"># read character</span>
-    c:character, k:address:keyboard<span class="Special"> &lt;- </span>wait-for-key k:address:keyboard
-<span class="CommentedCode">#?     print-character x:address:screen, c:character #? 1</span>
+    c:character, console:address found?:boolean<span class="Special"> &lt;- </span>read-key console:address
+    <span class="muControl">loop-unless</span> found?:boolean <span class="Constant">+next-character:label</span>
+<span class="CommentedCode">#?     print-character screen:address, c:character #? 1</span>
 <span class="CommentedCode">#?     move-cursor-down-on-display #? 1</span>
     <span class="Comment"># quit?</span>
     <span class="Delimiter">{</span>
@@ -146,21 +148,21 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="CommentedCode">#?       $print [ctrl-d] #? 1</span>
 <span class="CommentedCode">#?       move-cursor-down-on-display #? 1</span>
       trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-regular-characters: ctrl-d]</span>
-      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2
+      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, console:address/same-as-ingredient:1, screen:address/same-as-ingredient:2
     <span class="Delimiter">}</span>
     <span class="Delimiter">{</span>
       null?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">0:literal/null</span>
       <span class="muControl">break-unless</span> null?:boolean
       trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-regular-characters: null]</span>
-      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2
+      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, console:address/same-as-ingredient:1, screen:address/same-as-ingredient:2
     <span class="Delimiter">}</span>
     <span class="Comment"># comment?</span>
     <span class="Delimiter">{</span>
       comment?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">35:literal/hash</span>
       <span class="muControl">break-unless</span> comment?:boolean
-      print-character x:address:screen, c:character, <span class="Constant">4:literal/blue</span>
+      print-character screen:address, c:character, <span class="Constant">4:literal/blue</span>
       result:address:buffer<span class="Special"> &lt;- </span>buffer-append result:address:buffer, c:character
-      result:address:buffer, k:address:keyboard, x:address:screen<span class="Special"> &lt;- </span>slurp-comment result:address:buffer, k:address:keyboard, x:address:screen, complete:continuation
+      result:address:buffer, console:address, screen:address<span class="Special"> &lt;- </span>slurp-comment result:address:buffer, console:address, screen:address, complete:continuation
       <span class="Comment"># continue appending to this instruction, whether comment ended or was backspaced out of</span>
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
@@ -168,23 +170,23 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Delimiter">{</span>
       string?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">91:literal/open-bracket</span>
       <span class="muControl">break-unless</span> string?:boolean
-      print-character x:address:screen, c:character, <span class="Constant">6:literal/cyan</span>
+      print-character screen:address, c:character, <span class="Constant">6:literal/cyan</span>
       result:address:buffer<span class="Special"> &lt;- </span>buffer-append result:address:buffer, c:character
-      result:address:buffer, _, k:address:keyboard, x:address:screen<span class="Special"> &lt;- </span>slurp-string result:address:buffer, k:address:keyboard, x:address:screen, complete:continuation
+      result:address:buffer, _, console:address, screen:address<span class="Special"> &lt;- </span>slurp-string result:address:buffer, console:address, screen:address, complete:continuation
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
     <span class="Comment"># assignment</span>
     <span class="Delimiter">{</span>
       assign?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">60:literal/less-than</span>
       <span class="muControl">break-unless</span> assign?:boolean
-      print-character x:address:screen, c:character, <span class="Constant">1:literal/red</span>
+      print-character screen:address, c:character, <span class="Constant">1:literal/red</span>
       trace <span class="Constant">[app]</span>, <span class="Constant">[start of assignment: &lt;]</span>
       result:address:buffer<span class="Special"> &lt;- </span>buffer-append result:address:buffer, c:character
-      result:address:buffer, k:address:keyboard, x:address:screen<span class="Special"> &lt;- </span>slurp-assignment result:address:buffer, k:address:keyboard, x:address:screen, complete:continuation
+      result:address:buffer, console:address, screen:address<span class="Special"> &lt;- </span>slurp-assignment result:address:buffer, console:address, screen:address, complete:continuation
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
     <span class="Comment"># print</span>
-    print-character x:address:screen, c:character  <span class="Comment"># default color</span>
+    print-character screen:address, c:character  <span class="Comment"># default color</span>
     <span class="Comment"># append</span>
     result:address:buffer<span class="Special"> &lt;- </span>buffer-append result:address:buffer, c:character
 <span class="CommentedCode">#?     $print [a1 #? 1</span>
@@ -214,7 +216,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="CommentedCode">#?         $print [a6 #? 1</span>
 <span class="CommentedCode">#? ] #? 1</span>
 <span class="CommentedCode">#?         move-cursor-down-on-display #? 1</span>
-        <span class="muControl">reply</span> result:address:buffer, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2
+        <span class="muControl">reply</span> result:address:buffer, console:address/same-as-ingredient:1, screen:address/same-as-ingredient:2
       <span class="Delimiter">}</span>
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
@@ -230,20 +232,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">}</span>
   <span class="Comment"># newline encountered; terminate all recursive calls</span>
 <span class="CommentedCode">#?   xx:address:array:character &lt;- new [completing!] #? 1</span>
-<span class="CommentedCode">#?   print-string x:address:screen, xx:address:array:character #? 1</span>
+<span class="CommentedCode">#?   print-string screen:address, xx:address:array:character #? 1</span>
   trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-regular-characters: newline encountered; unwinding stack]</span>
   <span class="muControl">continue-from</span> complete:continuation
 ]
 
-<span class="Comment"># read characters from keyboard, print them to screen in the comment color.</span>
+<span class="Comment"># read characters from console, print them to screen in the comment color.</span>
 <span class="Comment">#</span>
 <span class="Comment"># Simpler version of slurp-regular-characters; doesn't handle comments or</span>
 <span class="Comment"># strings. Tracks an extra count in case we backspace out of it</span>
 <span class="muRecipe">recipe</span> slurp-comment [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   result:address:buffer<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  k:address:keyboard<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  x:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  console:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   complete:continuation<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-comment]</span>
   <span class="Comment"># use this to track when backspace should reset color</span>
@@ -251,22 +253,23 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">{</span>
 <span class="Constant">    +next-character</span>
     <span class="Comment"># read character</span>
-    c:character, k:address:keyboard<span class="Special"> &lt;- </span>wait-for-key k:address:keyboard
+    c:character, console:address, found?:boolean<span class="Special"> &lt;- </span>read-key console:address
+    <span class="muControl">loop-unless</span> found?:boolean <span class="Constant">+next-character:label</span>
     <span class="Comment"># quit?</span>
     <span class="Delimiter">{</span>
       ctrl-d?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">4:literal/ctrl-d/eof</span>
       <span class="muControl">break-unless</span> ctrl-d?:boolean
       trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-comment: ctrl-d]</span>
-      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2
+      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, console:address/same-as-ingredient:1, screen:address/same-as-ingredient:2
     <span class="Delimiter">}</span>
     <span class="Delimiter">{</span>
       null?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">0:literal/null</span>
       <span class="muControl">break-unless</span> null?:boolean
       trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-comment: null]</span>
-      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2
+      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, console:address/same-as-ingredient:1, screen:address/same-as-ingredient:2
     <span class="Delimiter">}</span>
     <span class="Comment"># print</span>
-    print-character x:address:screen, c:character, <span class="Constant">4:literal/blue</span>
+    print-character screen:address, c:character, <span class="Constant">4:literal/blue</span>
     <span class="Comment"># append</span>
     result:address:buffer<span class="Special"> &lt;- </span>buffer-append result:address:buffer, c:character
     <span class="Comment"># backspace? decrement</span>
@@ -278,7 +281,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
         reset-color?:boolean<span class="Special"> &lt;- </span>lesser-or-equal characters-slurped:number, <span class="Constant">0:literal</span>
         <span class="muControl">break-unless</span> reset-color?:boolean
         trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-comment: too many backspaces; returning]</span>
-        <span class="muControl">reply</span> result:address:buffer, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2
+        <span class="muControl">reply</span> result:address:buffer, console:address/same-as-ingredient:1, screen:address/same-as-ingredient:2
       <span class="Delimiter">}</span>
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
@@ -293,7 +296,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="muControl">continue-from</span> complete:continuation
 ]
 
-<span class="Comment"># read characters from keyboard, print them to screen in the string color and</span>
+<span class="Comment"># read characters from console, print them to screen in the string color and</span>
 <span class="Comment"># accumulate them into a buffer.</span>
 <span class="Comment">#</span>
 <span class="Comment"># Version of slurp-regular-characters that:</span>
@@ -303,8 +306,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muRecipe">recipe</span> slurp-string [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   result:address:buffer<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  k:address:keyboard<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  x:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  console:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   complete:continuation<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   nested-string?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-string]</span>
@@ -313,35 +316,36 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">{</span>
 <span class="Constant">    +next-character</span>
     <span class="Comment"># read character</span>
-    c:character, k:address:keyboard<span class="Special"> &lt;- </span>wait-for-key k:address:keyboard
+    c:character, console:address, found?:boolean<span class="Special"> &lt;- </span>read-key console:address
+    <span class="muControl">loop-unless</span> found?:boolean <span class="Constant">+next-character:label</span>
     <span class="Comment"># quit?</span>
     <span class="Delimiter">{</span>
       ctrl-d?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">4:literal/ctrl-d/eof</span>
       <span class="muControl">break-unless</span> ctrl-d?:boolean
       trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-string: ctrl-d]</span>
-      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, <span class="Constant">0:literal</span>, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2
+      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, <span class="Constant">0:literal</span>, console:address/same-as-ingredient:1, screen:address/same-as-ingredient:2
     <span class="Delimiter">}</span>
     <span class="Delimiter">{</span>
       null?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">0:literal/null</span>
       <span class="muControl">break-unless</span> null?:boolean
       trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-string: null]</span>
-      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, <span class="Constant">0:literal</span>, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2
+      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, <span class="Constant">0:literal</span>, console:address/same-as-ingredient:1, screen:address/same-as-ingredient:2
     <span class="Delimiter">}</span>
     <span class="Comment"># string</span>
     <span class="Delimiter">{</span>
       string?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">91:literal/open-bracket</span>
       <span class="muControl">break-unless</span> string?:boolean
       trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-string: open-bracket encountered; recursing]</span>
-      print-character x:address:screen, c:character, <span class="Constant">6:literal/cyan</span>
+      print-character screen:address, c:character, <span class="Constant">6:literal/cyan</span>
       result:address:buffer<span class="Special"> &lt;- </span>buffer-append result:address:buffer, c:character
       <span class="Comment"># make a recursive call to handle nested strings</span>
-      result:address:buffer, tmp:number, k:address:keyboard, x:address:screen<span class="Special"> &lt;- </span>slurp-string result:address:buffer, k:address:keyboard, x:address:screen, complete:continuation, <span class="Constant">1:literal/nested?</span>
+      result:address:buffer, tmp:number, console:address, screen:address<span class="Special"> &lt;- </span>slurp-string result:address:buffer, console:address, screen:address, complete:continuation, <span class="Constant">1:literal/nested?</span>
       <span class="Comment"># but if we backspace over a completed nested string, handle it in the caller</span>
       characters-slurped:number<span class="Special"> &lt;- </span>add characters-slurped:number, tmp:number, <span class="Constant">1:literal</span>  <span class="Comment"># for the leading '['</span>
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
     <span class="Comment"># print</span>
-    print-character x:address:screen, c:character, <span class="Constant">6:literal/cyan</span>
+    print-character screen:address, c:character, <span class="Constant">6:literal/cyan</span>
     <span class="Comment"># append</span>
     result:address:buffer<span class="Special"> &lt;- </span>buffer-append result:address:buffer, c:character
     <span class="Comment"># backspace? decrement</span>
@@ -353,7 +357,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
         reset-color?:boolean<span class="Special"> &lt;- </span>lesser-or-equal characters-slurped:number, <span class="Constant">0:literal</span>
         <span class="muControl">break-unless</span> reset-color?:boolean
         trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-string: too many backspaces; returning]</span>
-        <span class="muControl">reply</span> result:address:buffer/same-as-ingredient:0, <span class="Constant">0:literal</span>, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2
+        <span class="muControl">reply</span> result:address:buffer/same-as-ingredient:0, <span class="Constant">0:literal</span>, console:address/same-as-ingredient:1, screen:address/same-as-ingredient:2
       <span class="Delimiter">}</span>
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
@@ -367,11 +371,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">{</span>
     <span class="muControl">break-unless</span> nested-string?:boolean
     <span class="Comment"># nested string? return like a normal recipe</span>
-    <span class="muControl">reply</span> result:address:buffer, characters-slurped:number, k:address:keyboard, x:address:screen
+    <span class="muControl">reply</span> result:address:buffer, characters-slurped:number, console:address, screen:address
   <span class="Delimiter">}</span>
   <span class="Comment"># top-level string call? recurse</span>
   trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-string: close-bracket encountered; recursing to regular characters]</span>
-  result:address:buffer, k:address:keyboard, x:address:screen<span class="Special"> &lt;- </span>slurp-regular-characters result:address:buffer, k:address:keyboard, x:address:screen, complete:continuation
+  result:address:buffer, console:address, screen:address<span class="Special"> &lt;- </span>slurp-regular-characters result:address:buffer, console:address, screen:address, complete:continuation
   <span class="Comment"># backspaced back into this string</span>
   trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-string: backspaced back into string; restarting]</span>
   <span class="muControl">jump</span> <span class="Constant">+next-character:label</span>
@@ -380,28 +384,29 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muRecipe">recipe</span> slurp-assignment [
   <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new location:type, <span class="Constant">30:literal</span>
   result:address:buffer<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  k:address:keyboard<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  x:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  console:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  screen:address<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   complete:continuation<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="Delimiter">{</span>
 <span class="Constant">    +next-character</span>
     <span class="Comment"># read character</span>
-    c:character, k:address:keyboard<span class="Special"> &lt;- </span>wait-for-key k:address:keyboard
+    c:character, console:address, found?:boolean<span class="Special"> &lt;- </span>read-key console:address
+    <span class="muControl">loop-unless</span> found?:boolean <span class="Constant">+next-character:label</span>
     <span class="Comment"># quit?</span>
     <span class="Delimiter">{</span>
       ctrl-d?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">4:literal/ctrl-d/eof</span>
       <span class="muControl">break-unless</span> ctrl-d?:boolean
       trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-assignment: ctrl-d]</span>
-      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2
+      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, console:address/same-as-ingredient:1, screen:address/same-as-ingredient:2
     <span class="Delimiter">}</span>
     <span class="Delimiter">{</span>
       null?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">0:literal/null</span>
       <span class="muControl">break-unless</span> null?:boolean
       trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-assignment: null]</span>
-      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2
+      <span class="muControl">reply</span> <span class="Constant">0:literal</span>, console:address/same-as-ingredient:1, screen:address/same-as-ingredient:2
     <span class="Delimiter">}</span>
     <span class="Comment"># print</span>
-    print-character x:address:screen, c:character, <span class="Constant">1:literal/red</span>
+    print-character screen:address, c:character, <span class="Constant">1:literal/red</span>
     trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-assignment: saved one character]</span>
     <span class="Comment"># append</span>
     result:address:buffer<span class="Special"> &lt;- </span>buffer-append result:address:buffer, c:character
@@ -410,11 +415,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       backspace?:boolean<span class="Special"> &lt;- </span>equal c:character, <span class="Constant">8:literal/backspace</span>
       <span class="muControl">break-unless</span> backspace?:boolean
       trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-assignment: backspace; returning]</span>
-      <span class="muControl">reply</span> result:address:buffer/same-as-ingredient:0, k:address:keyboard/same-as-ingredient:1, x:address:screen/same-as-ingredient:2
+      <span class="muControl">reply</span> result:address:buffer/same-as-ingredient:0, console:address/same-as-ingredient:1, screen:address/same-as-ingredient:2
     <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
   trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-assignment: done, recursing to regular characters]</span>
-  result:address:buffer, k:address:keyboard, x:address:screen<span class="Special"> &lt;- </span>slurp-regular-characters result:address:buffer, k:address:keyboard, x:address:screen, complete:continuation
+  result:address:buffer, console:address, screen:address<span class="Special"> &lt;- </span>slurp-regular-characters result:address:buffer, console:address, screen:address, complete:continuation
   <span class="Comment"># backspaced back into this string</span>
   trace <span class="Constant">[app]</span>, <span class="Constant">[slurp-assignment: backspaced back into assignment; restarting]</span>
   <span class="muControl">jump</span> <span class="Constant">+next-character:label</span>
@@ -422,10 +427,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-color-comment [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[# comment</span>
-<span class="Constant">]</span>
+  assume-console [
+    type <span class="Constant">[# comment]</span>
+  ]
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain-in-color <span class="Constant">4:literal/blue</span>, [
    <span class="Constant"> .# comment                     .</span>
@@ -439,11 +445,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-cancel-comment-on-backspace [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[#a««z</span>
-<span class="Constant">]</span>
-  replace-in-keyboard <span class="Constant">171:literal/«</span>, <span class="Constant">8:literal/backspace</span>
+  assume-console [
+    type <span class="Constant">[#a««z]</span>
+  ]
+  backspace:event<span class="Special"> &lt;- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">8:literal/backspace</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span>
+  replace-in-console <span class="Constant">171:literal/«</span>, backspace:event
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain-in-color <span class="Constant">4:literal/blue</span>, [
    <span class="Constant"> .                              .</span>
@@ -457,11 +465,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-cancel-comment-on-backspace2 [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[#ab«««z</span>
-<span class="Constant">]</span>
-  replace-in-keyboard <span class="Constant">171:literal/«</span>, <span class="Constant">8:literal/backspace</span>
+  assume-console [
+    type <span class="Constant">[#ab«««z]</span>
+  ]
+  backspace:event<span class="Special"> &lt;- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">8:literal/backspace</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span>
+  replace-in-console <span class="Constant">171:literal/«</span>, backspace:event
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain-in-color <span class="Constant">4:literal/blue</span>, [
    <span class="Constant"> .                              .</span>
@@ -475,11 +485,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-cancel-comment-on-backspace3 [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[#a«z</span>
-<span class="Constant">]</span>
-  replace-in-keyboard <span class="Constant">171:literal/«</span>, <span class="Constant">8:literal/backspace</span>
+  assume-console [
+    type <span class="Constant">[#a«z]</span>
+  ]
+  backspace:event<span class="Special"> &lt;- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">8:literal/backspace</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span>
+  replace-in-console <span class="Constant">171:literal/«</span>, backspace:event
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain-in-color <span class="Constant">4:literal/blue</span>, [
    <span class="Constant"> .#z                            .</span>
@@ -493,13 +505,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-stop-after-comment [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  <span class="Comment"># keyboard contains comment and then a second line</span>
-  assume-keyboard <span class="Constant">[#abc</span>
-<span class="Constant">3</span>
-<span class="Constant">]</span>
-  replace-in-keyboard <span class="Constant">171:literal/«</span>, <span class="Constant">8:literal/backspace</span>
+  <span class="Comment"># console contains comment and then a second line</span>
+  assume-console [
+    type <span class="Constant">[#abc</span>
+<span class="Constant">3]</span>
+  ]
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   <span class="Comment"># check that read-instruction reads just the comment</span>
   screen-should-contain [
@@ -511,10 +523,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muScenario">scenario</span> read-instruction-color-string [
 <span class="CommentedCode">#?   $start-tracing #? 1</span>
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[abc [string]</span>
-]
+  assume-console [
+    type <span class="Constant">[abc [string]</span>]
+  ]
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain [
    <span class="Constant"> .abc [string]                  .</span>
@@ -532,11 +545,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-color-string-multiline [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[abc [line1</span>
-<span class="Constant">line2]</span>
-]
+  assume-console [
+    type <span class="Constant">[abc [line1</span>
+<span class="Constant">line2]</span>]
+  ]
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain [
    <span class="Constant"> .abc [line1                    .</span>
@@ -557,10 +571,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-color-string-and-comment [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[abc [string]</span>  <span class="Comment"># comment</span>
-]
+  assume-console [
+    type <span class="Constant">[abc [string]</span>  <span class="Comment"># comment]</span>
+  ]
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain [
    <span class="Constant"> .abc [string]  # comment       .</span>
@@ -582,10 +597,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-ignore-comment-inside-string [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[abc [string # not a comment]</span>
-]
+  assume-console [
+    type <span class="Constant">[abc [string # not a comment]</span>]
+  ]
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain [
    <span class="Constant"> .abc [string # not a comment]  .</span>
@@ -607,10 +623,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-ignore-string-inside-comment [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[abc # comment [not a string]</span>
-]
+  assume-console [
+    type <span class="Constant">[abc # comment [not a string]</span>]
+  ]
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain [
    <span class="Constant"> .abc # comment [not a string]  .</span>
@@ -632,11 +649,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-color-string-inside-string [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[abc [string [inner string]</span>]
-]
+  assume-console [
+    type <span class="Constant">[abc [string [inner string]</span>]]
+  ]
   run [
 <span class="CommentedCode">#?     $start-tracing #? 1</span>
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
 <span class="CommentedCode">#?     $stop-tracing #? 1</span>
 <span class="CommentedCode">#?     $browse-trace #? 1</span>
   ]
@@ -656,12 +674,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-cancel-string-on-backspace [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  <span class="Comment"># need to escape the '[' once for 'scenario' and once for 'assume-keyboard'</span>
-  assume-keyboard <span class="Constant">[\\\[a««z</span>
-<span class="Constant">]</span>
-  replace-in-keyboard <span class="Constant">171:literal/«</span>, <span class="Constant">8:literal/backspace</span>
+  assume-console [
+    type <span class="Constant">[(a««z]</span>  <span class="Comment"># '(' is '[' and '«' is backspace</span>
+  ]
+  open-bracket:event<span class="Special"> &lt;- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">91:literal/open-bracket</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span>
+  replace-in-console <span class="Constant">40:literal/open-paren</span>, open-bracket:event
+  backspace:event<span class="Special"> &lt;- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">8:literal/backspace</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span>
+  replace-in-console <span class="Constant">171:literal/«</span>, backspace:event
   run [
-    read-instruction keyboard:address, screen:address
+<span class="CommentedCode">#?     d:address:array:event &lt;- get console:address/deref, data:offset #? 1</span>
+<span class="CommentedCode">#?     $print [a: ], d:address:array:event #? 1</span>
+<span class="CommentedCode">#?     x:number &lt;- length d:address:array:event/deref #? 1</span>
+<span class="CommentedCode">#?     $print [b: ], x:number #? 1</span>
+    read-instruction console:address, screen:address
   ]
   screen-should-contain-in-color <span class="Constant">6:literal/cyan</span>, [
    <span class="Constant"> .                              .</span>
@@ -675,11 +700,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-cancel-string-inside-string-on-backspace [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[[a[b]</span>«««b]
-]
-  replace-in-keyboard <span class="Constant">171:literal/«</span>, <span class="Constant">8:literal/backspace</span>
+  assume-console [
+    type <span class="Constant">[(a[b]</span>«««b)]  <span class="Comment"># '(' is '[' and '«' is backspace</span>
+  ]
+  open-bracket:event<span class="Special"> &lt;- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">91:literal/open-bracket</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span>
+  replace-in-console <span class="Constant">40:literal/open-paren</span>, open-bracket:event
+  close-bracket:event<span class="Special"> &lt;- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">93:literal/close-bracket</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span>
+  replace-in-console <span class="Constant">41:literal/close-paren</span>, close-bracket:event
+  backspace:event<span class="Special"> &lt;- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">8:literal/backspace</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span>
+  replace-in-console <span class="Constant">171:literal/«</span>, backspace:event
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain-in-color <span class="Constant">6:literal/cyan</span>, [
    <span class="Constant"> .[ab]                          .</span>
@@ -693,16 +724,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-backspace-back-into-string [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[[a]</span>«b
-]
-  replace-in-keyboard <span class="Constant">171:literal/«</span>, <span class="Constant">8:literal/backspace</span>
+  assume-console [
+    type <span class="Constant">[[a]</span>«b]  <span class="Comment"># '«' is backspace</span>
+  ]
+  backspace:event<span class="Special"> &lt;- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">8:literal/backspace</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span>
+  replace-in-console <span class="Constant">171:literal/«</span>, backspace:event
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain [
    <span class="Constant"> .\\\[ab                           .</span>
    <span class="Constant"> .                              .</span>
   ]
+<span class="CommentedCode">#?   $print [aaa] #? 1</span>
   screen-should-contain-in-color <span class="Constant">6:literal/cyan</span>, [
    <span class="Constant"> .\\\[ab                           .</span>
    <span class="Constant"> .                              .</span>
@@ -721,10 +755,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-highlight-start-of-assignment [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[a &lt;</span>
-<span class="Constant">]</span>
+  assume-console [
+    type <span class="Constant">[a &lt;]</span>
+  ]
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain [
    <span class="Constant"> .a &lt;                           .</span>
@@ -742,10 +777,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-highlight-assignment [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[a &lt;- b</span>
-<span class="Constant">]</span>
+  assume-console [
+    type <span class="Constant">[a &lt;- b]</span>
+  ]
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain [
    <span class="Constant"> .a &lt;- b                        .</span>
@@ -763,11 +799,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-backspace-over-assignment [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[a &lt;-«</span>
-<span class="Constant">]</span>
-  replace-in-keyboard <span class="Constant">171:literal/«</span>, <span class="Constant">8:literal/backspace</span>
+  assume-console [
+    type <span class="Constant">[a &lt;-«]</span>  <span class="Comment"># '«' is backspace</span>
+  ]
+  backspace:event<span class="Special"> &lt;- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">8:literal/backspace</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span>
+  replace-in-console <span class="Constant">171:literal/«</span>, backspace:event
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain [
    <span class="Constant"> .a &lt;                           .</span>
@@ -785,11 +823,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-assignment-continues-after-backspace [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[a &lt;-«-</span>
-<span class="Constant">]</span>
-  replace-in-keyboard <span class="Constant">171:literal/«</span>, <span class="Constant">8:literal/backspace</span>
+  assume-console [
+    type <span class="Constant">[a &lt;-«-]</span>  <span class="Comment"># '«' is backspace</span>
+  ]
+  backspace:event<span class="Special"> &lt;- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">8:literal/backspace</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span>
+  replace-in-console <span class="Constant">171:literal/«</span>, backspace:event
+<span class="CommentedCode">#?   $print [aaa] #? 1</span>
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
   ]
   screen-should-contain [
    <span class="Constant"> .a &lt;-                          .</span>
@@ -807,11 +848,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> read-instruction-assignment-continues-after-backspace2 [
   assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span>
-  assume-keyboard <span class="Constant">[a &lt;- ««-</span>
-<span class="Constant">]</span>
-  replace-in-keyboard <span class="Constant">171:literal/«</span>, <span class="Constant">8:literal/backspace</span>
+  assume-console [
+    type <span class="Constant">[a &lt;- ««-]</span>  <span class="Comment"># '«' is backspace</span>
+  ]
+  backspace:event<span class="Special"> &lt;- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">8:literal/backspace</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span>
+  replace-in-console <span class="Constant">171:literal/«</span>, backspace:event
   run [
-    read-instruction keyboard:address, screen:address
+    read-instruction console:address, screen:address
 <span class="CommentedCode">#?     $browse-trace #? 1</span>
   ]
   screen-should-contain [
diff --git a/html/screen.mu.html b/html/screen.mu.html
index 9dfa3474..4618548a 100644
--- a/html/screen.mu.html
+++ b/html/screen.mu.html
@@ -12,9 +12,9 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+* { font-size: 1.05em; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
 .muRecipe { color: #ff8700; }
 -->
@@ -34,26 +34,26 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="Comment"># screens.</span>
 
 <span class="muRecipe">recipe</span> main [
-  switch-to-display
+  open-console
   print-character <span class="Constant">0:literal/screen</span>, <span class="Constant">97:literal</span>, <span class="Constant">2:literal/red</span>
   1:number/<span class="Special">raw</span>, 2:number/<span class="Special">raw &lt;- </span>cursor-position <span class="Constant">0:literal/screen</span>
-  wait-for-key <span class="Constant">0:literal/keyboard</span>
+  wait-for-event <span class="Constant">0:literal/console</span>
   clear-screen <span class="Constant">0:literal/screen</span>
   move-cursor <span class="Constant">0:literal/screen</span>, <span class="Constant">0:literal/row</span>, <span class="Constant">4:literal/column</span>
   print-character <span class="Constant">0:literal/screen</span>, <span class="Constant">98:literal</span>
-  wait-for-key <span class="Constant">0:literal/keyboard</span>
+  wait-for-event <span class="Constant">0:literal/console</span>
   move-cursor <span class="Constant">0:literal/screen</span>, <span class="Constant">0:literal/row</span>, <span class="Constant">0:literal/column</span>
   clear-line <span class="Constant">0:literal/screen</span>
-  wait-for-key <span class="Constant">0:literal/keyboard</span>
+  wait-for-event <span class="Constant">0:literal/console</span>
   cursor-down <span class="Constant">0:literal/screen</span>
-  wait-for-key <span class="Constant">0:literal/keyboard</span>
+  wait-for-event <span class="Constant">0:literal/console</span>
   cursor-right <span class="Constant">0:literal/screen</span>
-  wait-for-key <span class="Constant">0:literal/keyboard</span>
+  wait-for-event <span class="Constant">0:literal/console</span>
   cursor-left <span class="Constant">0:literal/screen</span>
-  wait-for-key <span class="Constant">0:literal/keyboard</span>
+  wait-for-event <span class="Constant">0:literal/console</span>
   cursor-up <span class="Constant">0:literal/screen</span>
-  wait-for-key <span class="Constant">0:literal/keyboard</span>
-  return-to-console
+  wait-for-event <span class="Constant">0:literal/console</span>
+  close-console
 ]
 </pre>
 </body>
diff --git a/html/tangle.mu.html b/html/tangle.mu.html
index 4337e012..77714d9f 100644
--- a/html/tangle.mu.html
+++ b/html/tangle.mu.html
@@ -12,12 +12,12 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Delimiter { color: #c000c0; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+* { font-size: 1.05em; }
+.Delimiter { color: #a04060; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
-.muControl { color: #804000; }
+.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 -->
 </style>
diff --git a/html/x.mu.html b/html/x.mu.html
index 8bde79bf..fa874a2d 100644
--- a/html/x.mu.html
+++ b/html/x.mu.html
@@ -12,9 +12,9 @@
 <!--
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1em; }
-.Comment { color: #8080ff; }
-.Constant { color: #008080; }
+* { font-size: 1.05em; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
 .muRecipe { color: #ff8700; }
 -->
diff --git a/update_html b/update_html
index be541212..d374774c 100755
--- a/update_html
+++ b/update_html
@@ -8,3 +8,9 @@ do
 done
 sed -i 's,<title>\~/Desktop/s/mu/,<title>Mu - ,' html/*
 sed -i 's,\.html</title>,</title>,' html/*
+sed -i 's/^\*.*/* { font-size: 1.05em; }/g' html/*
+# tweak contrast
+sed -i 's/^\.Constant.*/.Constant { color: #00a0a0; }/' html/*
+sed -i 's/^\.muControl.*/.muControl { color: #c0a020; }/' html/*
+sed -i 's/^\.Comment.*/.Comment { color: #9090ff; }/' html/*
+sed -i 's/^\.Delimiter.*/.Delimiter { color: #a04060; }/' html/*  # not meant to be read/ can be lower-contrast