summaryrefslogtreecommitdiff
path: root/chapter05
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-10-02 13:04:34 -0700
committerCliff Click <cliffc@acm.org>2026-10-02 13:04:34 -0700
commite4dc3273f201ae741637b626998637cce973546b (patch)
tree7607c1da4378da42549e8142371d95bdca4e06e0 /chapter05
parent6cd01a8d646750748a0af221073de8a7787472ad (diff)
downloadSimple-e4dc3273f201ae741637b626998637cce973546b.tar.gz
Simple-e4dc3273f201ae741637b626998637cce973546b.zip
First pass README updates
Diffstat (limited to 'chapter05')
-rw-r--r--chapter05/README.md37
-rw-r--r--chapter05/docs/05-graph1.json25
-rw-r--r--chapter05/docs/05-graph1.svg348
-rw-r--r--chapter05/docs/05-graph2.json27
-rw-r--r--chapter05/docs/05-graph2.svg354
-rw-r--r--chapter05/docs/05-graph3.json28
-rw-r--r--chapter05/docs/05-graph3.svg343
-rw-r--r--chapter05/docs/05-graph4.json28
-rw-r--r--chapter05/docs/05-graph4.svg343
-rw-r--r--chapter05/docs/05-graph5.json27
-rw-r--r--chapter05/docs/05-graph5.svg318
-rw-r--r--chapter05/docs/05-graph6.json26
-rw-r--r--chapter05/docs/05-graph6.svg293
-rw-r--r--chapter05/docs/05-graph7.json31
-rw-r--r--chapter05/docs/05-graph7.svg409
-rw-r--r--chapter05/docs/05-graph8.json45
-rw-r--r--chapter05/docs/05-graph8.svg618
-rw-r--r--chapter05/docs/05-graph9.json26
-rw-r--r--chapter05/docs/05-graph9.svg291
-rw-r--r--chapter05/docs/Makefile13
20 files changed, 1466 insertions, 2164 deletions
diff --git a/chapter05/README.md b/chapter05/README.md
index 2732066e..f7ff382c 100644
--- a/chapter05/README.md
+++ b/chapter05/README.md
@@ -1,11 +1,14 @@
# Chapter 5: If Statement, Phi, and Region
+[Previous: Chapter 4](../chapter04/README.md) |
+[Next: Chapter 6](../chapter06/README.md)
+
# Table of Contents
1. [Recap](#recap)
2. [New Nodes](#new-nodes)
3. [`IfNode`](#ifnode)
-4. [`PhiNode` ](#phinode)
+4. [`PhiNode`](#phinode)
5. [`RegionNode`](#regionnode)
6. [Pinned data nodes](#we-do-not-associate-a-control-edge-on-every-data-node-in-the-graph)
7. [`Stop` Nodes](#stop-nodes)
@@ -19,9 +22,7 @@
15. [Finally](#finally)
16. [Example 2](#example-2)
17. [Example 3](#example-3)
-18. [Example 3](#example-3)
-19. [More Examples](#more-examples)
-
+18. [More Examples](#more-examples)
You can also read [this chapter](https://github.com/SeaOfNodes/Simple/tree/linear-chapter05) in a linear Git revision history on the [linear](https://github.com/SeaOfNodes/Simple/tree/linear) branch and [compare](https://github.com/SeaOfNodes/Simple/compare/linear-chapter04...linear-chapter05) it to the previous chapter.
@@ -50,7 +51,7 @@ Here is a recap of the nodes introduced in previous chapters:
| Sub | Data | 2 | Subtract a value from another | Two data nodes, the first one is subtracted by the second one | Result of the subtraction |
| Mul | Data | 2 | Multiply two values | Two data nodes without restrictions on the order | Result of the multiplication |
| Div | Data | 2 | Divide a value by another | Two data nodes, the first one is divided by the second one | Result of the division |
-| Minus | Data | 2 | Negate a value | One data node which value is negated | Result of the negation |
+| Minus | Data | 2 | Negate a value | One data node that value is negated | Result of the negation |
| Scope | Symbol Table | 3 | Represents scopes in the graph | Nodes that represent the current value of variables | None |
> A `Proj` is a control node when it projects a control slot: `Proj#0` off `Start`,
@@ -92,7 +93,7 @@ Integer arithmetic likewise retains an integer result type when it cannot fold.
In this Sea of Nodes, there is an embedded Control Flow Graph - and like a
normal CFG there are merge points where two basic blocks flow into one. The
`Region` node takes control from each predecessor control (block) as input and
-produces a merged control as an output.[^2]
+produces a merged control as an output.[^2]
Both `Return` and `If` take control in slot 0. `PhiNode`s need their
corresponding `RegionNode` to know when to merge data values, so again slot 0
@@ -125,7 +126,7 @@ When we parse an `if` statement, the control flow splits at that point. We
must track the names being updated in each part of the `if` statement, and then
merge them at the end. The implementation follows the description in *Combining Analyses, Combining Optimizations*[^4].
-This involves following:
+This involves the following:
1. We create an `IfNode` with the current control token, i.e. the node mapped to
`$ctrl`, and the `if` predicate expression as inputs.
@@ -154,7 +155,7 @@ Implementation is in [`parseIf` method in `Parser`](https://github.com/SeaOfNode
## Operations on ScopeNodes
As explained above, we duplicate ScopeNodes and merge them at a later point. There are some
-subtleties in how this is implemented that is worth going over.
+subtleties in how this is implemented that are worth going over.
### Duplicating a ScopeNode
@@ -175,7 +176,7 @@ At the merge point we merge two ScopeNodes. The goals are:
2) A new Region node is created representing the merged control flow. The phis have this region node as the first input.
3) After the merge is completed, the duplicate is discarded, and its use of each of the nodes is also deleted.
-The merging logic takes advantage of that fact that the two ScopeNodes have the bound nodes in the same order in the list of inputs. This was ensured during duplicating the ScopeNode.
+The merging logic takes advantage of the fact that the two ScopeNodes have the bound nodes in the same order in the list of inputs. This was ensured during duplicating the ScopeNode.
Although only the innermost occurrence of a name can have its binding changed, we scan all the nodes in our input list, and simply ignore ones where the binding has not changed.
For implementation [see `ScopeNode.mergeScopes()`](https://github.com/SeaOfNodes/Simple/blob/main/chapter05/src/main/java/com/seaofnodes/simple/node/ScopeNode.java#L164-L173)
@@ -195,7 +196,7 @@ return a;
### Before Merging
-Following shows the graph just before we merge the two branches of the `if` statement in a `Region` node.
+The following shows the graph just before we merge the two branches of the `if` statement in a `Region` node.
![Graph1](./docs/05-graph1.svg)
@@ -225,7 +226,7 @@ Here is the graph after the `return` statement was parsed and processed.
## Example #2
Consider the following code snippet:
-```java
+```java
int b = 0;
int c = 0;
if (arg == 1) {
@@ -241,16 +242,16 @@ return b;
The value of `b` depends on which path the control flow took.
To resolve this, a Φ (Phi) function is inserted.
-```
+```
b = Phi(Region,2, 1); // values vary
-c = Phi(Region,1, 0); // valuse vary, but dead
+c = Phi(Region,1, 0); // values vary, but dead
```
The `Phi` for `c` will die when the scope where `c` is defined dies. This does
not happen when merging but after the `return`. `return` is using `b` so `b`
stays alive.
-Before, we go ahead and parse down the if statement we duplicate the scope:
+Before we go ahead and parse down the if statement we duplicate the scope:
```java
ScopeNode fScope = _scope.dup();
/* Scope[$ctrl:$ctrl, arg:arg][b:0, c:0]*/
@@ -270,7 +271,7 @@ Notice, this branch modified and set a new value for both symbols currently exis
Now, we set the scope back to where we started (without the modifications that `ifT` made)
```java
-_scope = fScope;
+_scope = fScope;
```
We then will proceed and parse down the second branch of the if statement:
@@ -278,12 +279,12 @@ We then will proceed and parse down the second branch of the if statement:
if (matchx("else")) {
parseStatement();
fScope = _scope;
-
+
/* Scope[$ctrl:False, arg:arg][b:1, c:0]*/
}
```
-This branch modified the values of `b` and `c`. Since the branch arms are also
+The two branches modified `b`; only the true branch modified `c`. Since the branch arms are also
lexical scopes, they cannot introduce new symbols in the current (outer) scope.
This means that the order of the name bindings stayed the same. Excluding the
first control node, we loop through and compare the nodes corresponding to the
@@ -303,7 +304,7 @@ representing this conflict:
## Example #3
-Phi's implement a peephole illustrated in the example:
+Phis implement a peephole illustrated in the example:
```java
int a=arg==2;
diff --git a/chapter05/docs/05-graph1.json b/chapter05/docs/05-graph1.json
new file mode 100644
index 00000000..a2b4a7bd
--- /dev/null
+++ b/chapter05/docs/05-graph1.json
@@ -0,0 +1,25 @@
+{
+ "ver": 1,
+ "comp": "chapter05/docs/05-graph1.svg",
+ "step": 1,
+ "roots": [],
+ "scope": 0,
+ "nodes": [
+ {"id": 1, "label": "Scope", "type": null, "kind": "SCOPE", "edges": [{"idx": 0, "def": 11, "role": "ASSOC", "label": "0: $ctrl"}, {"idx": 1, "def": 10, "role": "ASSOC", "label": "0: arg"}, {"idx": 2, "def": 14, "role": "ASSOC", "label": "1: a"}], "proj": null},
+ {"id": 2, "label": "Start", "type": null, "kind": "CTRL", "edges": [], "proj": null},
+ {"id": 4, "label": "Scope", "type": null, "kind": "SCOPE", "edges": [{"idx": 0, "def": 12, "role": "ASSOC", "label": "0: $ctrl"}, {"idx": 1, "def": 10, "role": "ASSOC", "label": "0: arg"}, {"idx": 2, "def": 16, "role": "ASSOC", "label": "1: a"}], "proj": null},
+ {"id": 6, "label": "$ctrl", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 2, "role": "CTRL", "label": null}], "proj": {"par": 2, "idx": 0}},
+ {"id": 7, "label": "#1", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 8, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 10, "role": "DATA", "label": null}, {"idx": 2, "def": 7, "role": "DATA", "label": null}], "proj": null},
+ {"id": 9, "label": "If", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 6, "role": "CTRL", "label": null}, {"idx": 1, "def": 8, "role": "DATA", "label": null}], "proj": null},
+ {"id": 10, "label": "arg", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 2, "role": "DATA", "label": null}], "proj": {"par": 2, "idx": 1}},
+ {"id": 11, "label": "True", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 9, "role": "CTRL", "label": null}], "proj": {"par": 9, "idx": 0}},
+ {"id": 12, "label": "False", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 9, "role": "CTRL", "label": null}], "proj": {"par": 9, "idx": 1}},
+ {"id": 13, "label": "#2", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 14, "label": "+", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 10, "role": "DATA", "label": null}, {"idx": 2, "def": 13, "role": "DATA", "label": null}], "proj": null},
+ {"id": 15, "label": "#3", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 16, "label": "-", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 10, "role": "DATA", "label": null}, {"idx": 2, "def": 15, "role": "DATA", "label": null}], "proj": null}
+ ],
+ "groups": [
+ ]
+}
diff --git a/chapter05/docs/05-graph1.svg b/chapter05/docs/05-graph1.svg
index efe0a0e8..97813974 100644
--- a/chapter05/docs/05-graph1.svg
+++ b/chapter05/docs/05-graph1.svg
@@ -1,228 +1,120 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Generated by graphviz version 2.43.0 (0)
- -->
-<!-- Title: chapter05 Pages: 1 -->
-<svg width="432pt" height="356pt"
- viewBox="0.00 0.00 432.00 356.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 352)">
-<title>chapter05</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-352 428,-352 428,4 -4,4"/>
-<g id="clust1" class="cluster">
-<title>cluster_Nodes</title>
-<polygon fill="none" stroke="black" points="85,-88 85,-340 415,-340 415,-88 85,-88"/>
-</g>
-<g id="clust2" class="cluster">
-<title>cluster_Scope1_0</title>
-<polygon fill="none" stroke="black" points="8,-8 8,-76 208,-76 208,-8 8,-8"/>
-</g>
-<g id="clust3" class="cluster">
-<title>cluster_Scope1_1</title>
-<polygon fill="none" stroke="black" points="16,-16 16,-68 86,-68 86,-16 16,-16"/>
-</g>
-<g id="clust4" class="cluster">
-<title>cluster_Scope12_0</title>
-<polygon fill="none" stroke="black" points="216,-8 216,-76 416,-76 416,-8 216,-8"/>
-</g>
-<g id="clust5" class="cluster">
-<title>cluster_Scope12_1</title>
-<polygon fill="none" stroke="black" points="224,-16 224,-68 294,-68 294,-16 224,-16"/>
-</g>
-<!-- Start2 -->
-<g id="node1" class="node">
-<title>Start2</title>
-<polygon fill="yellow" stroke="transparent" points="174,-303 174,-328 255,-328 255,-303 174,-303"/>
-<polygon fill="none" stroke="black" points="174,-303 174,-328 255,-328 255,-303 174,-303"/>
-<text text-anchor="start" x="196" y="-311.8" font-family="Times,serif" font-size="14.00">Start</text>
-<polygon fill="none" stroke="black" points="174,-272 174,-303 255,-303 255,-272 174,-272"/>
-<polygon fill="yellow" stroke="transparent" points="179,-277 179,-298 219,-298 219,-277 179,-277"/>
-<polygon fill="none" stroke="black" points="179,-277 179,-298 219,-298 219,-277 179,-277"/>
-<text text-anchor="start" x="182" y="-283.8" font-family="Times,serif" font-size="14.00">$ctrl</text>
-<polygon fill="none" stroke="black" points="219,-277 219,-298 250,-298 250,-277 219,-277"/>
-<text text-anchor="start" x="222" y="-283.8" font-family="Times,serif" font-size="14.00">arg</text>
-</g>
-<!-- Con_7 -->
-<g id="node2" class="node">
-<title>Con_7</title>
-<ellipse fill="none" stroke="black" cx="308" cy="-300" rx="27" ry="18"/>
-<text text-anchor="middle" x="308" y="-296.3" font-family="Times,serif" font-size="14.00">#1</text>
-</g>
-<!-- EQNode8 -->
-<g id="node3" class="node">
-<title>EQNode8</title>
-<ellipse fill="none" stroke="black" cx="245" cy="-214" rx="27" ry="18"/>
-<text text-anchor="middle" x="245" y="-210.3" font-family="Times,serif" font-size="14.00">==</text>
-</g>
-<!-- EQNode8&#45;&gt;Start2 -->
-<g id="edge1" class="edge">
-<title>EQNode8&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M240.7,-231.97C238.58,-241.48 236.3,-253.83 235.4,-265.95"/>
-<polygon fill="black" stroke="black" points="231.9,-265.87 235,-276 238.89,-266.15 231.9,-265.87"/>
-<text text-anchor="middle" x="237.7" y="-234.57" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode8&#45;&gt;Con_7 -->
-<g id="edge2" class="edge">
-<title>EQNode8&#45;&gt;Con_7</title>
-<path fill="none" stroke="black" d="M256.56,-230.41C266.06,-243.08 279.67,-261.23 290.51,-275.68"/>
-<polygon fill="black" stroke="black" points="287.72,-277.79 296.52,-283.69 293.32,-273.59 287.72,-277.79"/>
-<text text-anchor="middle" x="253.56" y="-233.01" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- If9 -->
-<g id="node4" class="node">
-<title>If9</title>
-<polygon fill="yellow" stroke="transparent" points="169,-131 169,-156 263,-156 263,-131 169,-131"/>
-<polygon fill="none" stroke="black" points="169,-131 169,-156 263,-156 263,-131 169,-131"/>
-<text text-anchor="start" x="210.5" y="-139.8" font-family="Times,serif" font-size="14.00">If</text>
-<polygon fill="none" stroke="black" points="169,-100 169,-131 263,-131 263,-100 169,-100"/>
-<polygon fill="yellow" stroke="transparent" points="174,-105 174,-126 214,-126 214,-105 174,-105"/>
-<polygon fill="none" stroke="black" points="174,-105 174,-126 214,-126 214,-105 174,-105"/>
-<text text-anchor="start" x="177" y="-111.8" font-family="Times,serif" font-size="14.00">True</text>
-<polygon fill="yellow" stroke="transparent" points="214,-105 214,-126 258,-126 258,-105 214,-105"/>
-<polygon fill="none" stroke="black" points="214,-105 214,-126 258,-126 258,-105 214,-105"/>
-<text text-anchor="start" x="217" y="-111.8" font-family="Times,serif" font-size="14.00">False</text>
-</g>
-<!-- If9&#45;&gt;Start2 -->
-<g id="edge3" class="edge">
-<title>If9&#45;&gt;Start2:p0</title>
-<path fill="none" stroke="red" d="M210.29,-160.14C205.78,-187.26 200.08,-228.01 199.14,-265.52"/>
-<polygon fill="red" stroke="red" points="195.63,-265.96 199,-276 202.63,-266.05 195.63,-265.96"/>
-<text text-anchor="middle" x="207.29" y="-162.74" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- If9&#45;&gt;EQNode8 -->
-<g id="edge4" class="edge">
-<title>If9&#45;&gt;EQNode8</title>
-<path fill="none" stroke="black" d="M226.8,-160.28C229.78,-168.9 232.97,-178.17 235.85,-186.49"/>
-<polygon fill="black" stroke="black" points="232.58,-187.76 239.16,-196.07 239.2,-185.48 232.58,-187.76"/>
-<text text-anchor="middle" x="223.8" y="-162.88" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Con_13 -->
-<g id="node5" class="node">
-<title>Con_13</title>
-<ellipse fill="none" stroke="black" cx="120" cy="-300" rx="27" ry="18"/>
-<text text-anchor="middle" x="120" y="-296.3" font-family="Times,serif" font-size="14.00">#2</text>
-</g>
-<!-- Add14 -->
-<g id="node6" class="node">
-<title>Add14</title>
-<ellipse fill="none" stroke="black" cx="153" cy="-214" rx="27" ry="18"/>
-<text text-anchor="middle" x="153" y="-210.3" font-family="Times,serif" font-size="14.00">+</text>
-</g>
-<!-- Add14&#45;&gt;Start2 -->
-<g id="edge5" class="edge">
-<title>Add14&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M174.12,-225.69C193.67,-236.17 221.18,-252.54 231.18,-266.44"/>
-<polygon fill="black" stroke="black" points="228.04,-268.01 235,-276 234.54,-265.42 228.04,-268.01"/>
-<text text-anchor="middle" x="171.12" y="-228.29" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Add14&#45;&gt;Con_13 -->
-<g id="edge6" class="edge">
-<title>Add14&#45;&gt;Con_13</title>
-<path fill="none" stroke="black" d="M146.48,-231.6C141.87,-243.33 135.59,-259.3 130.31,-272.76"/>
-<polygon fill="black" stroke="black" points="126.91,-271.85 126.51,-282.44 133.42,-274.41 126.91,-271.85"/>
-<text text-anchor="middle" x="143.48" y="-234.2" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Con_15 -->
-<g id="node7" class="node">
-<title>Con_15</title>
-<ellipse fill="none" stroke="black" cx="380" cy="-300" rx="27" ry="18"/>
-<text text-anchor="middle" x="380" y="-296.3" font-family="Times,serif" font-size="14.00">#3</text>
-</g>
-<!-- Sub16 -->
-<g id="node8" class="node">
-<title>Sub16</title>
-<ellipse fill="none" stroke="black" cx="317" cy="-214" rx="27" ry="18"/>
-<text text-anchor="middle" x="317" y="-210.3" font-family="Times,serif" font-size="14.00">&#45;</text>
-</g>
-<!-- Sub16&#45;&gt;Start2 -->
-<g id="edge7" class="edge">
-<title>Sub16&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M304.31,-229.92C290.9,-245.57 270.14,-269.43 258.76,-280.7"/>
-<polygon fill="black" stroke="black" points="256.56,-277.98 251,-287 260.97,-283.41 256.56,-277.98"/>
-<text text-anchor="middle" x="301.31" y="-232.52" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Sub16&#45;&gt;Con_15 -->
-<g id="edge8" class="edge">
-<title>Sub16&#45;&gt;Con_15</title>
-<path fill="none" stroke="black" d="M328.56,-230.41C338.06,-243.08 351.67,-261.23 362.51,-275.68"/>
-<polygon fill="black" stroke="black" points="359.72,-277.79 368.52,-283.69 365.32,-273.59 359.72,-277.79"/>
-<text text-anchor="middle" x="325.56" y="-233.01" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Scope1_0 -->
-<g id="node9" class="node">
-<title>Scope1_0</title>
-<polygon fill="cyan" stroke="transparent" points="105,-31 105,-52 121,-52 121,-31 105,-31"/>
-<polygon fill="none" stroke="black" points="105,-31 105,-52 121,-52 121,-31 105,-31"/>
-<text text-anchor="start" x="108" y="-37.8" font-family="Times,serif" font-size="14.00">0</text>
-<polygon fill="none" stroke="black" points="121,-31 121,-52 161,-52 161,-31 121,-31"/>
-<text text-anchor="start" x="124" y="-37.8" font-family="Times,serif" font-size="14.00">$ctrl</text>
-<polygon fill="none" stroke="black" points="161,-31 161,-52 192,-52 192,-31 161,-31"/>
-<text text-anchor="start" x="164" y="-37.8" font-family="Times,serif" font-size="14.00">arg</text>
-</g>
-<!-- Scope1_0&#45;&gt;Start2 -->
-<g id="edge10" class="edge">
-<title>Scope1_0:Scope1_0_arg&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="cornflowerblue" stroke-dasharray="5,2" d="M177,-53C177,-72.12 160.6,-70.93 152,-88 122.36,-146.82 79.43,-177.9 117,-232 146.68,-274.74 223.16,-227.66 233.77,-265.81"/>
-<polygon fill="cornflowerblue" stroke="cornflowerblue" points="230.33,-266.49 235,-276 237.28,-265.65 230.33,-266.49"/>
-</g>
-<!-- Scope1_0&#45;&gt;If9 -->
-<g id="edge9" class="edge">
-<title>Scope1_0:Scope1_0_$ctrl&#45;&gt;If9:p0</title>
-<path fill="none" stroke="cornflowerblue" stroke-dasharray="5,2" d="M141,-53C141,-81.73 181.94,-74.1 191.86,-94.03"/>
-<polygon fill="cornflowerblue" stroke="cornflowerblue" points="188.48,-94.96 194,-104 195.32,-93.49 188.48,-94.96"/>
-</g>
-<!-- Scope1_1 -->
-<g id="node10" class="node">
-<title>Scope1_1</title>
-<polygon fill="cyan" stroke="transparent" points="36,-31 36,-52 52,-52 52,-31 36,-31"/>
-<polygon fill="none" stroke="black" points="36,-31 36,-52 52,-52 52,-31 36,-31"/>
-<text text-anchor="start" x="39" y="-37.8" font-family="Times,serif" font-size="14.00">1</text>
-<polygon fill="none" stroke="black" points="52,-31 52,-52 67,-52 67,-31 52,-31"/>
-<text text-anchor="start" x="55" y="-37.8" font-family="Times,serif" font-size="14.00">a</text>
-</g>
-<!-- Scope1_1&#45;&gt;Add14 -->
-<g id="edge11" class="edge">
-<title>Scope1_1:Scope1_1_a&#45;&gt;Add14</title>
-<path fill="none" stroke="cornflowerblue" stroke-dasharray="5,2" d="M60,-53C60,-108.8 102.8,-162.53 130.33,-191.31"/>
-<polygon fill="cornflowerblue" stroke="cornflowerblue" points="128.14,-194.07 137.64,-198.75 133.13,-189.17 128.14,-194.07"/>
-</g>
-<!-- Scope12_0 -->
-<g id="node11" class="node">
-<title>Scope12_0</title>
-<polygon fill="cyan" stroke="transparent" points="313,-31 313,-52 329,-52 329,-31 313,-31"/>
-<polygon fill="none" stroke="black" points="313,-31 313,-52 329,-52 329,-31 313,-31"/>
-<text text-anchor="start" x="316" y="-37.8" font-family="Times,serif" font-size="14.00">0</text>
-<polygon fill="none" stroke="black" points="329,-31 329,-52 369,-52 369,-31 329,-31"/>
-<text text-anchor="start" x="332" y="-37.8" font-family="Times,serif" font-size="14.00">$ctrl</text>
-<polygon fill="none" stroke="black" points="369,-31 369,-52 400,-52 400,-31 369,-31"/>
-<text text-anchor="start" x="372" y="-37.8" font-family="Times,serif" font-size="14.00">arg</text>
-</g>
-<!-- Scope12_0&#45;&gt;Start2 -->
-<g id="edge13" class="edge">
-<title>Scope12_0:Scope12_0_arg&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="cornflowerblue" stroke-dasharray="5,2" d="M385,-53C385,-133.82 402.85,-168.39 353,-232 328.7,-263.01 305.02,-246.51 272,-268 265.41,-272.29 263.77,-278.64 260.39,-282.8"/>
-<polygon fill="cornflowerblue" stroke="cornflowerblue" points="258.7,-279.72 251,-287 261.56,-286.11 258.7,-279.72"/>
-</g>
-<!-- Scope12_0&#45;&gt;If9 -->
-<g id="edge12" class="edge">
-<title>Scope12_0:Scope12_0_$ctrl&#45;&gt;If9:p1</title>
-<path fill="none" stroke="cornflowerblue" stroke-dasharray="5,2" d="M349,-53C349,-98.16 313.19,-112.94 269.13,-114.79"/>
-<polygon fill="cornflowerblue" stroke="cornflowerblue" points="268.93,-111.3 259,-115 269.07,-118.3 268.93,-111.3"/>
-</g>
-<!-- Scope12_1 -->
-<g id="node12" class="node">
-<title>Scope12_1</title>
-<polygon fill="cyan" stroke="transparent" points="244,-31 244,-52 260,-52 260,-31 244,-31"/>
-<polygon fill="none" stroke="black" points="244,-31 244,-52 260,-52 260,-31 244,-31"/>
-<text text-anchor="start" x="247" y="-37.8" font-family="Times,serif" font-size="14.00">1</text>
-<polygon fill="none" stroke="black" points="260,-31 260,-52 275,-52 275,-31 260,-31"/>
-<text text-anchor="start" x="263" y="-37.8" font-family="Times,serif" font-size="14.00">a</text>
-</g>
-<!-- Scope12_1&#45;&gt;Sub16 -->
-<g id="edge14" class="edge">
-<title>Scope12_1:Scope12_1_a&#45;&gt;Sub16</title>
-<path fill="none" stroke="cornflowerblue" stroke-dasharray="5,2" d="M268,-53C268,-69.44 275,-72.33 280,-88 290.77,-121.73 302.19,-160.92 309.45,-186.29"/>
-<polygon fill="cornflowerblue" stroke="cornflowerblue" points="306.09,-187.29 312.2,-195.95 312.83,-185.37 306.09,-187.29"/>
-</g>
-</g>
-</svg>
+<svg aria-label="Compiler graph" width="1006" height="548" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1006 548" style="font-family: sans-serif;"><style>
+ html, body { height:100%; margin:0; font-family:sans-serif; }
+ .viewer { height:100%; display:grid; grid-template-rows:auto minmax(0,1fr) auto; }
+ .source { padding:8px; border-bottom:1px solid #ccc; }
+ #program { width:min(600px,80vw); vertical-align:middle; }
+ #status { margin-top:4px; }
+ #graph { min-height:0; overflow:hidden; position:relative; background:#fafbfc; }
+ #elk { width:100%; height:100%; }
+ #graph svg { display:block; }
+ .tools { display:flex; flex-wrap:wrap; align-items:center; gap:14px; margin-top:8px; font-size:12px; }
+ .hint { color:#616c78; }
+ .ctrl { color:#b63838; } .mem { color:#2867b2; } .data { color:#536477; }
+ .edge { fill:none; stroke-width:1.5; }
+ .edge.CTRL { stroke-width:2; }
+ .edge.ASSOC { stroke-dasharray:4 4; }
+ .edge.PARSER { stroke-dasharray:5 4; }
+ .parser rect { fill:#f6f0ff; stroke:#7956a5; stroke-width:1.5; stroke-dasharray:5 4; }
+ .edge.selected { stroke-width:3.5; }
+ .edge.bundle { stroke-width:4; }
+ .edge.bundle.selected { stroke-width:6; }
+ .edge-hit { fill:none; stroke:transparent; stroke-width:12; vector-effect:non-scaling-stroke; pointer-events:stroke; cursor:pointer; }
+ .edge-jump { fill:transparent; pointer-events:all; cursor:pointer; }
+ .node { cursor:pointer; }
+ .box { stroke:#758191; stroke-width:1; }
+ .node.held .box { stroke-dasharray:5 3; }
+ .node.near .box { stroke:#c18221; stroke-width:2; }
+ .node.focus .box { stroke:#9c4900; stroke-width:3; }
+ .node.selected .box { stroke:#1569b9; stroke-width:3; }
+ .node.folded .box { stroke-width:4; }
+ .node.folding .box { fill:#f4ccd7; }
+ .fold-tag { font-size:9px; font-weight:700; fill:#963751; }
+ .peep-area { fill:#fff3d9; fill-opacity:.8; stroke:#c18221; stroke-width:2; pointer-events:none; }
+ .node.peep-edit .box { stroke:#9c4900; stroke-width:3; }
+ .node.error .box { stroke:#b42318; stroke-width:4; }
+ #event.error { color:#b42318; font-weight:600; white-space:pre-wrap; overflow-wrap:anywhere; }
+ .peep-ghosts { pointer-events:none; }
+ .region-box { stroke:#9da9b8; stroke-width:1.5; }
+ .fold-btn { cursor:pointer; }
+ .fold-btn rect { fill:white; stroke:#596674; }
+ .fold-btn text { font-size:14px; fill:#152330; }
+ .fold-btn:focus rect { stroke:#1569b9; stroke-width:2; }
+ .shortcut { cursor:pointer; }
+ .shortcut path { fill:none; stroke-width:1.5; }
+ .shortcut rect { fill:#fff8ec; stroke:#b63838; stroke-dasharray:3 2; }
+ .shortcut text { font-size:11px; fill:#783030; }
+ .shortcut.selected rect, .shortcut:focus rect { stroke-width:2.5; }
+ .label { font-size:12px; fill:#152330; font-weight:600; }
+ .node-id { font-size:10px; fill:#596674; font-weight:400; }
+ .type { font-size:11px; fill:#455768; }
+ .port { stroke:#536477; stroke-width:1; }
+ .row { stroke:#b6afcf; stroke-width:1; }
+ .bind { font-size:12px; fill:#152330; }
+ .slot { font-size:10px; fill:#364352; paint-order:stroke; stroke:#fafbfc; stroke-width:3; }
+ #detail { position:absolute; top:8px; right:8px; margin:0; padding:12px; max-width:320px;
+ max-height:45%; overflow:auto; white-space:pre-wrap; overflow-wrap:anywhere;
+ background:#fffffff2; border:1px solid #bac5d0; border-radius:4px; font-size:12px; }
+ .controls { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:6px; padding:6px; }
+ .button { color:white; background:black; font-size:20px; min-width:30px; }
+ .button:disabled { background:grey; }
+ .count { font-size:20px; min-width:35px; text-align:center; }
+ #N { width:6ch; }
+ #scrub { width:clamp(120px,35vw,600px); }
+ </style><defs><marker id="arrow-CTRL" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#b63838"/></marker><marker id="arrow-DATA" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#536477"/></marker><marker id="arrow-MEM" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#2867b2"/></marker><marker id="arrow-ASSOC" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#9396a3"/></marker><marker id="arrow-PARSER" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#7956a5"/></marker></defs><rect width="100%" height="100%" fill="rgb(250, 251, 252)"/><g><g class="regions" style="opacity: 1;"/><rect class="peep-area" rx="36" style="opacity: 0;"/><g class="edges"><path class="edge ASSOC" id="e1i0" d="M84,367 C84,391 848.5,364 848.5,388" stroke="#9396a3" marker-start="url(#arrow-ASSOC)" style="opacity: 1;"><title>#1[0] → #11 · ASSOC · 0: $ctrl</title></path><path class="edge ASSOC" id="e1i1" d="M224,115 C224,139 906.5,364 906.5,388" stroke="#9396a3" marker-start="url(#arrow-ASSOC)" style="opacity: 1;"><title>#1[1] → #10 · ASSOC · 0: arg</title></path><path class="edge ASSOC" id="e1i2" d="M376,219 C376,243 958,364 958,388" stroke="#9396a3" marker-start="url(#arrow-ASSOC)" style="opacity: 1;"><title>#1[2] → #14 · ASSOC · 1: a</title></path><path class="edge ASSOC" id="e4i0" d="M204,367 C204,391 848.5,444 848.5,468" stroke="#9396a3" marker-start="url(#arrow-ASSOC)" style="opacity: 1;"><title>#4[0] → #12 · ASSOC · 0: $ctrl</title></path><path class="edge ASSOC" id="e4i1" d="M224,115 C224,139 906.5,444 906.5,468" stroke="#9396a3" marker-start="url(#arrow-ASSOC)" style="opacity: 1;"><title>#4[1] → #10 · ASSOC · 0: arg</title></path><path class="edge ASSOC" id="e4i2" d="M528,219 C528,243 958,444 958,468" stroke="#9396a3" marker-start="url(#arrow-ASSOC)" style="opacity: 1;"><title>#4[2] → #16 · ASSOC · 1: a</title></path><path class="edge DATA" id="e8i1" d="M224,118 L224,166" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#8[1] → #10 · DATA</title></path><path class="edge DATA" id="e8i2" d="M382,118 L382,128 L254,128 L254,166" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#8[2] → #7 · DATA</title></path><path class="edge CTRL" id="e9i0" d="M104,118 L104,270" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#9[0] → #6 · CTRL</title></path><path class="edge DATA" id="e9i1" d="M224,222 L224,232 L184,232 L184,270" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#9[1] → #8 · DATA</title></path><path class="edge DATA" id="e14i1" d="M224,118 L224,138 L376,138 L376,166" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#14[1] → #10 · DATA</title></path><path class="edge DATA" id="e14i2" d="M534,118 L534,128 L406,128 L406,166" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#14[2] → #13 · DATA</title></path><path class="edge DATA" id="e16i1" d="M224,118 L224,138 L528,138 L528,166" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#16[1] → #10 · DATA</title></path><path class="edge DATA" id="e16i2" d="M686,118 L686,128 L558,128 L558,166" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#16[2] → #15 · DATA</title></path></g><g class="edge-hits"/><g class="parser" style="opacity: 1;"/><g class="nodes"><g class="node" id="n1" data-id="1" transform="translate(818,388)" style="opacity: 1;"><path class="box" d="M4,0H160Q164,0 164,4V52Q164,56 160,56H4Q0,56 0,52V4Q0,0 4,0Z" fill="#e5e0ff"/><text class="label" text-anchor="middle" x="82" y="48"><tspan>Scope</tspan><tspan class="node-id">  #1</tspan></text><text class="type" text-anchor="middle" y="35" x="82"/><title>#1 Scope
+Type not computed
+
+[0] → #11 ASSOC 0: $ctrl
+[1] → #10 ASSOC 0: arg
+[2] → #14 ASSOC 1: a</title><line class="row" x1="0" x2="164" y1="30" y2="30"/><line class="row" x1="61" x2="61" y1="0" y2="30"/><line class="row" x1="116" x2="116" y1="0" y2="30"/><text class="bind" x="30.5" y="20" text-anchor="middle">0: $ctrl</text><text class="bind" x="88.5" y="20" text-anchor="middle">0: arg</text><text class="bind" x="140" y="20" text-anchor="middle">1: a</text><circle class="port" cx="30.5" cy="0" r="3" fill="#536477"/><circle class="port" cx="88.5" cy="0" r="3" fill="#536477"/><circle class="port" cx="140" cy="0" r="3" fill="#536477"/><text class="slot" x="30.5" y="-7" text-anchor="middle">0</text><text class="slot" x="88.5" y="-7" text-anchor="middle">1</text><text class="slot" x="140" y="-7" text-anchor="middle">2</text></g><g class="node" id="n2" data-id="2" transform="translate(44,24)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>Start</tspan><tspan class="node-id">  #2</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#2 Start
+Type not computed
+
+</title></g><g class="node" id="n4" data-id="4" transform="translate(818,468)" style="opacity: 1;"><path class="box" d="M4,0H160Q164,0 164,4V52Q164,56 160,56H4Q0,56 0,52V4Q0,0 4,0Z" fill="#e5e0ff"/><text class="label" text-anchor="middle" x="82" y="48"><tspan>Scope</tspan><tspan class="node-id">  #4</tspan></text><text class="type" text-anchor="middle" y="35" x="82"/><title>#4 Scope
+Type not computed
+
+[0] → #12 ASSOC 0: $ctrl
+[1] → #10 ASSOC 0: arg
+[2] → #16 ASSOC 1: a</title><line class="row" x1="0" x2="164" y1="30" y2="30"/><line class="row" x1="61" x2="61" y1="0" y2="30"/><line class="row" x1="116" x2="116" y1="0" y2="30"/><text class="bind" x="30.5" y="20" text-anchor="middle">0: $ctrl</text><text class="bind" x="88.5" y="20" text-anchor="middle">0: arg</text><text class="bind" x="140" y="20" text-anchor="middle">1: a</text><circle class="port" cx="30.5" cy="0" r="3" fill="#536477"/><circle class="port" cx="88.5" cy="0" r="3" fill="#536477"/><circle class="port" cx="140" cy="0" r="3" fill="#536477"/><text class="slot" x="30.5" y="-7" text-anchor="middle">0</text><text class="slot" x="88.5" y="-7" text-anchor="middle">1</text><text class="slot" x="140" y="-7" text-anchor="middle">2</text></g><g class="node" id="n6" data-id="6" transform="translate(44,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>$ctrl</tspan><tspan class="node-id">  #6/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#6 $ctrl
+Projection 0 of #2
+Type not computed
+
+[0] → #2 CTRL</title></g><g class="node" id="n7" data-id="7" transform="translate(322,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#1</tspan><tspan class="node-id">  #7</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#7 #1
+Type not computed
+
+</title></g><g class="node" id="n8" data-id="8" transform="translate(164,172)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #8</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#8 ==
+Type not computed
+
+[0] → — DATA
+[1] → #10 DATA
+[2] → #7 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n9" data-id="9" transform="translate(24,276)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>If</tspan><tspan class="node-id">  #9</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#9 If
+Type not computed
+
+[0] → #6 CTRL
+[1] → #8 DATA</title><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><circle class="port" cx="160" cy="-3" r="3" fill="#536477"/><text class="slot" x="80" y="-10" text-anchor="middle">0</text><text class="slot" x="160" y="-10" text-anchor="middle">1</text></g><g class="node" id="n10" data-id="10" transform="translate(164,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>arg</tspan><tspan class="node-id">  #10/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#10 arg
+Projection 1 of #2
+Type not computed
+
+[0] → #2 DATA</title></g><g class="node" id="n11" data-id="11" transform="translate(24,320)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>True</tspan><tspan class="node-id">  #11/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#11 True
+Projection 0 of #9
+Type not computed
+
+[0] → #9 CTRL</title></g><g class="node" id="n12" data-id="12" transform="translate(144,320)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>False</tspan><tspan class="node-id">  #12/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#12 False
+Projection 1 of #9
+Type not computed
+
+[0] → #9 CTRL</title></g><g class="node" id="n13" data-id="13" transform="translate(474,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#2</tspan><tspan class="node-id">  #13</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#13 #2
+Type not computed
+
+</title></g><g class="node" id="n14" data-id="14" transform="translate(316,172)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>+</tspan><tspan class="node-id">  #14</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#14 +
+Type not computed
+
+[0] → — DATA
+[1] → #10 DATA
+[2] → #13 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n15" data-id="15" transform="translate(626,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#3</tspan><tspan class="node-id">  #15</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#15 #3
+Type not computed
+
+</title></g><g class="node" id="n16" data-id="16" transform="translate(468,172)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>-</tspan><tspan class="node-id">  #16</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#16 -
+Type not computed
+
+[0] → — DATA
+[1] → #10 DATA
+[2] → #15 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g></g><g class="region-heads" style="opacity: 1;"/><g class="shortcuts" style="opacity: 1;"/><g class="peep-ghosts" pointer-events="none"/></g></svg>
diff --git a/chapter05/docs/05-graph2.json b/chapter05/docs/05-graph2.json
new file mode 100644
index 00000000..5980da2b
--- /dev/null
+++ b/chapter05/docs/05-graph2.json
@@ -0,0 +1,27 @@
+{
+ "ver": 1,
+ "comp": "chapter05/docs/05-graph2.svg",
+ "step": 1,
+ "roots": [],
+ "scope": 0,
+ "nodes": [
+ {"id": 1, "label": "Scope", "type": null, "kind": "SCOPE", "edges": [{"idx": 0, "def": 17, "role": "ASSOC", "label": "0: $ctrl"}, {"idx": 1, "def": 5, "role": "ASSOC", "label": "0: arg"}, {"idx": 2, "def": 18, "role": "ASSOC", "label": "1: a"}], "proj": null},
+ {"id": 2, "label": "Start", "type": null, "kind": "CTRL", "edges": [], "proj": null},
+ {"id": 4, "label": "$ctrl", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 2, "role": "CTRL", "label": null}], "proj": {"par": 2, "idx": 0}},
+ {"id": 5, "label": "arg", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 2, "role": "DATA", "label": null}], "proj": {"par": 2, "idx": 1}},
+ {"id": 6, "label": "True", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 9, "role": "CTRL", "label": null}], "proj": {"par": 9, "idx": 0}},
+ {"id": 7, "label": "#1", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 8, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 5, "role": "DATA", "label": null}, {"idx": 2, "def": 7, "role": "DATA", "label": null}], "proj": null},
+ {"id": 9, "label": "If", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 4, "role": "CTRL", "label": null}, {"idx": 1, "def": 8, "role": "DATA", "label": null}], "proj": null},
+ {"id": 10, "label": "False", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 9, "role": "CTRL", "label": null}], "proj": {"par": 9, "idx": 1}},
+ {"id": 13, "label": "#2", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 14, "label": "+", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 5, "role": "DATA", "label": null}, {"idx": 2, "def": 13, "role": "DATA", "label": null}], "proj": null},
+ {"id": 15, "label": "#3", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 16, "label": "-", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 5, "role": "DATA", "label": null}, {"idx": 2, "def": 15, "role": "DATA", "label": null}], "proj": null},
+ {"id": 17, "label": "Region", "type": null, "kind": "REGION", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 6, "role": "CTRL", "label": null}, {"idx": 2, "def": 10, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 18, "label": "φ_a", "type": null, "kind": "PHI", "edges": [{"idx": 0, "def": 17, "role": "ASSOC", "label": null}, {"idx": 1, "def": 14, "role": "DATA", "label": null}, {"idx": 2, "def": 16, "role": "DATA", "label": null}], "proj": null}
+ ],
+ "groups": [
+ {"id": 9, "par": 0, "nodes": [6, 8, 9, 10, 14, 16, 17, 18]}
+ ]
+}
diff --git a/chapter05/docs/05-graph2.svg b/chapter05/docs/05-graph2.svg
index d5e48a9e..bd06978a 100644
--- a/chapter05/docs/05-graph2.svg
+++ b/chapter05/docs/05-graph2.svg
@@ -1,229 +1,125 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Generated by graphviz version 2.43.0 (0)
- -->
-<!-- Title: chapter05 Pages: 1 -->
-<svg width="343pt" height="428pt"
- viewBox="0.00 0.00 343.03 428.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 424)">
-<title>chapter05</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-424 339.03,-424 339.03,4 -4,4"/>
-<g id="clust1" class="cluster">
-<title>cluster_Nodes</title>
-<polygon fill="none" stroke="black" points="8,-88 8,-412 282,-412 282,-88 8,-88"/>
-</g>
-<g id="clust3" class="cluster">
-<title>cluster_Scope1_0</title>
-<polygon fill="none" stroke="black" points="67,-8 67,-76 267,-76 267,-8 67,-8"/>
-</g>
-<g id="clust4" class="cluster">
-<title>cluster_Scope1_1</title>
-<polygon fill="none" stroke="black" points="75,-16 75,-68 145,-68 145,-16 75,-16"/>
-</g>
-<!-- Start2 -->
-<g id="node1" class="node">
-<title>Start2</title>
-<polygon fill="yellow" stroke="transparent" points="113,-375 113,-400 194,-400 194,-375 113,-375"/>
-<polygon fill="none" stroke="black" points="113,-375 113,-400 194,-400 194,-375 113,-375"/>
-<text text-anchor="start" x="135" y="-383.8" font-family="Times,serif" font-size="14.00">Start</text>
-<polygon fill="none" stroke="black" points="113,-344 113,-375 194,-375 194,-344 113,-344"/>
-<polygon fill="yellow" stroke="transparent" points="118,-349 118,-370 158,-370 158,-349 118,-349"/>
-<polygon fill="none" stroke="black" points="118,-349 118,-370 158,-370 158,-349 118,-349"/>
-<text text-anchor="start" x="121" y="-355.8" font-family="Times,serif" font-size="14.00">$ctrl</text>
-<polygon fill="none" stroke="black" points="158,-349 158,-370 189,-370 189,-349 158,-349"/>
-<text text-anchor="start" x="161" y="-355.8" font-family="Times,serif" font-size="14.00">arg</text>
-</g>
-<!-- Con_7 -->
-<g id="node2" class="node">
-<title>Con_7</title>
-<ellipse fill="none" stroke="black" cx="247" cy="-372" rx="27" ry="18"/>
-<text text-anchor="middle" x="247" y="-368.3" font-family="Times,serif" font-size="14.00">#1</text>
-</g>
-<!-- EQNode8 -->
-<g id="node3" class="node">
-<title>EQNode8</title>
-<ellipse fill="none" stroke="black" cx="247" cy="-286" rx="27" ry="18"/>
-<text text-anchor="middle" x="247" y="-282.3" font-family="Times,serif" font-size="14.00">==</text>
-</g>
-<!-- EQNode8&#45;&gt;Start2 -->
-<g id="edge1" class="edge">
-<title>EQNode8&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M236.57,-302.62C225.76,-318.5 208.98,-342.28 198.26,-353.17"/>
-<polygon fill="black" stroke="black" points="196.15,-350.37 190,-359 200.19,-356.09 196.15,-350.37"/>
-<text text-anchor="middle" x="233.57" y="-305.22" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode8&#45;&gt;Con_7 -->
-<g id="edge2" class="edge">
-<title>EQNode8&#45;&gt;Con_7</title>
-<path fill="none" stroke="black" d="M247,-304.4C247,-315.74 247,-330.77 247,-343.68"/>
-<polygon fill="black" stroke="black" points="243.5,-343.9 247,-353.9 250.5,-343.9 243.5,-343.9"/>
-<text text-anchor="middle" x="244" y="-307" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- If9 -->
-<g id="node4" class="node">
-<title>If9</title>
-<polygon fill="yellow" stroke="transparent" points="172,-203 172,-228 266,-228 266,-203 172,-203"/>
-<polygon fill="none" stroke="black" points="172,-203 172,-228 266,-228 266,-203 172,-203"/>
-<text text-anchor="start" x="213.5" y="-211.8" font-family="Times,serif" font-size="14.00">If</text>
-<polygon fill="none" stroke="black" points="172,-172 172,-203 266,-203 266,-172 172,-172"/>
-<polygon fill="yellow" stroke="transparent" points="177,-177 177,-198 217,-198 217,-177 177,-177"/>
-<polygon fill="none" stroke="black" points="177,-177 177,-198 217,-198 217,-177 177,-177"/>
-<text text-anchor="start" x="180" y="-183.8" font-family="Times,serif" font-size="14.00">True</text>
-<polygon fill="yellow" stroke="transparent" points="217,-177 217,-198 261,-198 261,-177 217,-177"/>
-<polygon fill="none" stroke="black" points="217,-177 217,-198 261,-198 261,-177 217,-177"/>
-<text text-anchor="start" x="220" y="-183.8" font-family="Times,serif" font-size="14.00">False</text>
-</g>
-<!-- If9&#45;&gt;Start2 -->
-<g id="edge3" class="edge">
-<title>If9&#45;&gt;Start2:p0</title>
-<path fill="none" stroke="red" d="M210.31,-232.18C203.59,-253.4 193.07,-281.57 179,-304 166.9,-323.28 145.68,-322.25 139.64,-338.02"/>
-<polygon fill="red" stroke="red" points="136.17,-337.56 138,-348 143.08,-338.7 136.17,-337.56"/>
-<text text-anchor="middle" x="207.31" y="-234.78" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- If9&#45;&gt;EQNode8 -->
-<g id="edge4" class="edge">
-<title>If9&#45;&gt;EQNode8</title>
-<path fill="none" stroke="black" d="M229.43,-232.28C232.3,-240.9 235.39,-250.17 238.16,-258.49"/>
-<polygon fill="black" stroke="black" points="234.87,-259.69 241.36,-268.07 241.51,-257.48 234.87,-259.69"/>
-<text text-anchor="middle" x="226.43" y="-234.88" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Con_13 -->
-<g id="node5" class="node">
-<title>Con_13</title>
-<ellipse fill="none" stroke="black" cx="135" cy="-286" rx="27" ry="18"/>
-<text text-anchor="middle" x="135" y="-282.3" font-family="Times,serif" font-size="14.00">#2</text>
-</g>
-<!-- Add14 -->
-<g id="node6" class="node">
-<title>Add14</title>
-<ellipse fill="none" stroke="black" cx="119" cy="-200" rx="27" ry="18"/>
-<text text-anchor="middle" x="119" y="-196.3" font-family="Times,serif" font-size="14.00">+</text>
-</g>
-<!-- Add14&#45;&gt;Start2 -->
-<g id="edge5" class="edge">
-<title>Add14&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M134.23,-215.02C146.68,-227.55 163.4,-247.1 171,-268 181.92,-298.04 175.64,-309.96 174.25,-337.87"/>
-<polygon fill="black" stroke="black" points="170.75,-337.92 174,-348 177.75,-338.09 170.75,-337.92"/>
-<text text-anchor="middle" x="131.23" y="-217.62" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Add14&#45;&gt;Con_13 -->
-<g id="edge6" class="edge">
-<title>Add14&#45;&gt;Con_13</title>
-<path fill="none" stroke="black" d="M122.24,-218C124.43,-229.5 127.37,-244.93 129.87,-258.08"/>
-<polygon fill="black" stroke="black" points="126.46,-258.86 131.77,-268.03 133.33,-257.55 126.46,-258.86"/>
-<text text-anchor="middle" x="119.24" y="-220.6" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Con_15 -->
-<g id="node7" class="node">
-<title>Con_15</title>
-<ellipse fill="none" stroke="black" cx="43" cy="-286" rx="27" ry="18"/>
-<text text-anchor="middle" x="43" y="-282.3" font-family="Times,serif" font-size="14.00">#3</text>
-</g>
-<!-- Sub16 -->
-<g id="node8" class="node">
-<title>Sub16</title>
-<ellipse fill="none" stroke="black" cx="47" cy="-200" rx="27" ry="18"/>
-<text text-anchor="middle" x="47" y="-196.3" font-family="Times,serif" font-size="14.00">&#45;</text>
-</g>
-<!-- Sub16&#45;&gt;Start2 -->
-<g id="edge7" class="edge">
-<title>Sub16&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M54.69,-217.49C67.53,-244.81 92.56,-297.14 99,-304 122.77,-329.31 164.37,-313.46 172.57,-338.01"/>
-<polygon fill="black" stroke="black" points="169.12,-338.6 174,-348 176.05,-337.61 169.12,-338.6"/>
-<text text-anchor="middle" x="51.69" y="-220.09" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Sub16&#45;&gt;Con_15 -->
-<g id="edge8" class="edge">
-<title>Sub16&#45;&gt;Con_15</title>
-<path fill="none" stroke="black" d="M46.19,-218C45.65,-229.31 44.93,-244.42 44.31,-257.43"/>
-<polygon fill="black" stroke="black" points="40.8,-257.58 43.82,-267.74 47.79,-257.92 40.8,-257.58"/>
-<text text-anchor="middle" x="43.19" y="-220.6" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Region17 -->
-<g id="node9" class="node">
-<title>Region17</title>
-<polygon fill="yellow" stroke="black" points="232,-132 166,-132 166,-96 232,-96 232,-132"/>
-<text text-anchor="middle" x="199" y="-110.3" font-family="Times,serif" font-size="14.00">Region</text>
-</g>
-<!-- Region17&#45;&gt;If9 -->
-<g id="edge9" class="edge">
-<title>Region17&#45;&gt;If9:p0</title>
-<path fill="none" stroke="red" d="M198.14,-132.09C197.72,-141.54 197.27,-153.77 197.08,-165.68"/>
-<polygon fill="red" stroke="red" points="193.58,-165.97 197,-176 200.58,-166.03 193.58,-165.97"/>
-<text text-anchor="middle" x="195.14" y="-134.69" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Region17&#45;&gt;If9 -->
-<g id="edge10" class="edge">
-<title>Region17&#45;&gt;If9:p1</title>
-<path fill="none" stroke="red" d="M217.83,-132.05C226.1,-141.05 234.63,-152.92 237.76,-165.89"/>
-<polygon fill="red" stroke="red" points="234.31,-166.5 239,-176 241.25,-165.65 234.31,-166.5"/>
-<text text-anchor="middle" x="214.83" y="-134.65" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a18 -->
-<g id="node10" class="node">
-<title>Phi_a18</title>
-<ellipse fill="lightyellow" stroke="black" cx="119" cy="-114" rx="27" ry="18"/>
-<text text-anchor="middle" x="119" y="-110.3" font-family="Times,serif" font-size="14.00">φ_a</text>
-</g>
-<!-- Phi_a18&#45;&gt;Add14 -->
-<g id="edge12" class="edge">
-<title>Phi_a18&#45;&gt;Add14</title>
-<path fill="none" stroke="black" d="M119,-132.4C119,-143.74 119,-158.77 119,-171.68"/>
-<polygon fill="black" stroke="black" points="115.5,-171.9 119,-181.9 122.5,-171.9 115.5,-171.9"/>
-<text text-anchor="middle" x="116" y="-135" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Phi_a18&#45;&gt;Sub16 -->
-<g id="edge13" class="edge">
-<title>Phi_a18&#45;&gt;Sub16</title>
-<path fill="none" stroke="black" d="M106.13,-130.02C95.07,-142.92 78.96,-161.71 66.35,-176.42"/>
-<polygon fill="black" stroke="black" points="63.61,-174.24 59.76,-184.11 68.93,-178.8 63.61,-174.24"/>
-<text text-anchor="middle" x="103.13" y="-132.62" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a18&#45;&gt;Region17 -->
-<g id="edge11" class="edge">
-<title>Phi_a18&#45;&gt;Region17</title>
-<path fill="none" stroke="black" stroke-dasharray="1,5" d="M146.19,-114C149.39,-114 152.58,-114 155.78,-114"/>
-<polygon fill="black" stroke="black" points="155.99,-117.5 165.99,-114 155.99,-110.5 155.99,-117.5"/>
-<text text-anchor="middle" x="149.19" y="-107.6" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Scope1_0 -->
-<g id="node11" class="node">
-<title>Scope1_0</title>
-<polygon fill="cyan" stroke="transparent" points="164,-31 164,-52 180,-52 180,-31 164,-31"/>
-<polygon fill="none" stroke="black" points="164,-31 164,-52 180,-52 180,-31 164,-31"/>
-<text text-anchor="start" x="167" y="-37.8" font-family="Times,serif" font-size="14.00">0</text>
-<polygon fill="none" stroke="black" points="180,-31 180,-52 220,-52 220,-31 180,-31"/>
-<text text-anchor="start" x="183" y="-37.8" font-family="Times,serif" font-size="14.00">$ctrl</text>
-<polygon fill="none" stroke="black" points="220,-31 220,-52 251,-52 251,-31 220,-31"/>
-<text text-anchor="start" x="223" y="-37.8" font-family="Times,serif" font-size="14.00">arg</text>
-</g>
-<!-- Scope1_0&#45;&gt;Start2 -->
-<g id="edge15" class="edge">
-<title>Scope1_0:Scope1_0_arg&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="cornflowerblue" stroke-dasharray="5,2" d="M252,-41C369.7,-41 344.88,-203.88 283,-304 264.19,-334.43 240.54,-319.81 211,-340 204.51,-344.44 202.84,-350.75 199.44,-354.86"/>
-<polygon fill="cornflowerblue" stroke="cornflowerblue" points="197.75,-351.78 190,-359 200.56,-358.19 197.75,-351.78"/>
-</g>
-<!-- Scope1_0&#45;&gt;Region17 -->
-<g id="edge14" class="edge">
-<title>Scope1_0:Scope1_0_$ctrl&#45;&gt;Region17</title>
-<path fill="none" stroke="cornflowerblue" stroke-dasharray="5,2" d="M200,-53C200,-63.75 199.84,-75.58 199.64,-85.87"/>
-<polygon fill="cornflowerblue" stroke="cornflowerblue" points="196.14,-85.86 199.44,-95.93 203.14,-86.01 196.14,-85.86"/>
-</g>
-<!-- Scope1_1 -->
-<g id="node12" class="node">
-<title>Scope1_1</title>
-<polygon fill="cyan" stroke="transparent" points="95,-31 95,-52 111,-52 111,-31 95,-31"/>
-<polygon fill="none" stroke="black" points="95,-31 95,-52 111,-52 111,-31 95,-31"/>
-<text text-anchor="start" x="98" y="-37.8" font-family="Times,serif" font-size="14.00">1</text>
-<polygon fill="none" stroke="black" points="111,-31 111,-52 126,-52 126,-31 111,-31"/>
-<text text-anchor="start" x="114" y="-37.8" font-family="Times,serif" font-size="14.00">a</text>
-</g>
-<!-- Scope1_1&#45;&gt;Phi_a18 -->
-<g id="edge16" class="edge">
-<title>Scope1_1:Scope1_1_a&#45;&gt;Phi_a18</title>
-<path fill="none" stroke="cornflowerblue" stroke-dasharray="5,2" d="M119,-53C119,-63.75 119,-75.58 119,-85.87"/>
-<polygon fill="cornflowerblue" stroke="cornflowerblue" points="115.5,-85.93 119,-95.93 122.5,-85.93 115.5,-85.93"/>
-</g>
-</g>
-</svg>
+<svg aria-label="Compiler graph" width="996" height="631" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 996 631" style="font-family: sans-serif;"><style>
+ html, body { height:100%; margin:0; font-family:sans-serif; }
+ .viewer { height:100%; display:grid; grid-template-rows:auto minmax(0,1fr) auto; }
+ .source { padding:8px; border-bottom:1px solid #ccc; }
+ #program { width:min(600px,80vw); vertical-align:middle; }
+ #status { margin-top:4px; }
+ #graph { min-height:0; overflow:hidden; position:relative; background:#fafbfc; }
+ #elk { width:100%; height:100%; }
+ #graph svg { display:block; }
+ .tools { display:flex; flex-wrap:wrap; align-items:center; gap:14px; margin-top:8px; font-size:12px; }
+ .hint { color:#616c78; }
+ .ctrl { color:#b63838; } .mem { color:#2867b2; } .data { color:#536477; }
+ .edge { fill:none; stroke-width:1.5; }
+ .edge.CTRL { stroke-width:2; }
+ .edge.ASSOC { stroke-dasharray:4 4; }
+ .edge.PARSER { stroke-dasharray:5 4; }
+ .parser rect { fill:#f6f0ff; stroke:#7956a5; stroke-width:1.5; stroke-dasharray:5 4; }
+ .edge.selected { stroke-width:3.5; }
+ .edge.bundle { stroke-width:4; }
+ .edge.bundle.selected { stroke-width:6; }
+ .edge-hit { fill:none; stroke:transparent; stroke-width:12; vector-effect:non-scaling-stroke; pointer-events:stroke; cursor:pointer; }
+ .edge-jump { fill:transparent; pointer-events:all; cursor:pointer; }
+ .node { cursor:pointer; }
+ .box { stroke:#758191; stroke-width:1; }
+ .node.held .box { stroke-dasharray:5 3; }
+ .node.near .box { stroke:#c18221; stroke-width:2; }
+ .node.focus .box { stroke:#9c4900; stroke-width:3; }
+ .node.selected .box { stroke:#1569b9; stroke-width:3; }
+ .node.folded .box { stroke-width:4; }
+ .node.folding .box { fill:#f4ccd7; }
+ .fold-tag { font-size:9px; font-weight:700; fill:#963751; }
+ .peep-area { fill:#fff3d9; fill-opacity:.8; stroke:#c18221; stroke-width:2; pointer-events:none; }
+ .node.peep-edit .box { stroke:#9c4900; stroke-width:3; }
+ .node.error .box { stroke:#b42318; stroke-width:4; }
+ #event.error { color:#b42318; font-weight:600; white-space:pre-wrap; overflow-wrap:anywhere; }
+ .peep-ghosts { pointer-events:none; }
+ .region-box { stroke:#9da9b8; stroke-width:1.5; }
+ .fold-btn { cursor:pointer; }
+ .fold-btn rect { fill:white; stroke:#596674; }
+ .fold-btn text { font-size:14px; fill:#152330; }
+ .fold-btn:focus rect { stroke:#1569b9; stroke-width:2; }
+ .shortcut { cursor:pointer; }
+ .shortcut path { fill:none; stroke-width:1.5; }
+ .shortcut rect { fill:#fff8ec; stroke:#b63838; stroke-dasharray:3 2; }
+ .shortcut text { font-size:11px; fill:#783030; }
+ .shortcut.selected rect, .shortcut:focus rect { stroke-width:2.5; }
+ .label { font-size:12px; fill:#152330; font-weight:600; }
+ .node-id { font-size:10px; fill:#596674; font-weight:400; }
+ .type { font-size:11px; fill:#455768; }
+ .port { stroke:#536477; stroke-width:1; }
+ .row { stroke:#b6afcf; stroke-width:1; }
+ .bind { font-size:12px; fill:#152330; }
+ .slot { font-size:10px; fill:#364352; paint-order:stroke; stroke:#fafbfc; stroke-width:3; }
+ #detail { position:absolute; top:8px; right:8px; margin:0; padding:12px; max-width:320px;
+ max-height:45%; overflow:auto; white-space:pre-wrap; overflow-wrap:anywhere;
+ background:#fffffff2; border:1px solid #bac5d0; border-radius:4px; font-size:12px; }
+ .controls { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:6px; padding:6px; }
+ .button { color:white; background:black; font-size:20px; min-width:30px; }
+ .button:disabled { background:grey; }
+ .count { font-size:20px; min-width:35px; text-align:center; }
+ #N { width:6ch; }
+ #scrub { width:clamp(120px,35vw,600px); }
+ </style><defs><marker id="arrow-CTRL" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#b63838"/></marker><marker id="arrow-DATA" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#536477"/></marker><marker id="arrow-MEM" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#2867b2"/></marker><marker id="arrow-ASSOC" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#9396a3"/></marker><marker id="arrow-PARSER" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#7956a5"/></marker></defs><rect width="100%" height="100%" fill="rgb(250, 251, 252)"/><g><g class="regions" style="opacity: 1;"><g class="region" transform="translate(144,171)"><rect class="region-box" rx="8" width="574" height="374" fill="#f2f7ef"/></g></g><rect class="peep-area" rx="36" style="opacity: 0;"/><g class="edges"><path class="edge ASSOC" id="e1i0" d="M306,530 C306,554 838.5,527 838.5,551" stroke="#9396a3" marker-start="url(#arrow-ASSOC)" style="opacity: 1;"><title>#1[0] → #17 · ASSOC · 0: $ctrl</title></path><path class="edge ASSOC" id="e1i1" d="M356,115 C356,139 896.5,527 896.5,551" stroke="#9396a3" marker-start="url(#arrow-ASSOC)" style="opacity: 1;"><title>#1[1] → #5 · ASSOC · 0: arg</title></path><path class="edge ASSOC" id="e1i2" d="M458,530 C458,554 948,527 948,551" stroke="#9396a3" marker-start="url(#arrow-ASSOC)" style="opacity: 1;"><title>#1[2] → #18 · ASSOC · 1: a</title></path><path class="edge DATA" id="e8i1" d="M356,118 L356,128 L307,128 L307,225" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#8[1] → #5 · DATA</title></path><path class="edge DATA" id="e8i2" d="M84,118 L84,128 L226,128 L226,215 L337,215 L337,225" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#8[2] → #7 · DATA</title></path><path class="edge CTRL" id="e9i0" d="M236,118 L236,329" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#9[0] → #4 · CTRL</title></path><path class="edge DATA" id="e9i1" d="M307,281 L307,291 L316,291 L316,329" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#9[1] → #8 · DATA</title></path><path class="edge DATA" id="e14i1" d="M356,118 L356,128 L494,128 L494,343.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#14[1] → #5 · DATA</title></path><path class="edge DATA" id="e14i2" d="M524,118 L524,343.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#14[2] → #13 · DATA</title></path><path class="edge DATA" id="e16i1" d="M356,118 L356,128 L513,128 L513,291 L646,291 L646,343.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#16[1] → #5 · DATA</title></path><path class="edge DATA" id="e16i2" d="M676,118 L676,343.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#16[2] → #15 · DATA</title></path><path class="edge CTRL" id="e17i1" d="M216,429 L216,439 L306,439 L306,477" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#17[1] → #6 · CTRL</title></path><path class="edge CTRL" id="e17i2" d="M336,429 L336,477" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#17[2] → #10 · CTRL</title></path><path class="edge DATA" id="e18i1" d="M494,399.66666666666663 L494,439 L438,439 L438,477" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#18[1] → #14 · DATA</title></path><path class="edge DATA" id="e18i2" d="M646,399.66666666666663 L646,449 L478,449 L478,477" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#18[2] → #16 · DATA</title></path></g><g class="edge-hits"/><g class="parser" style="opacity: 1;"/><g class="nodes"><g class="node" id="n1" data-id="1" transform="translate(808,551)" style="opacity: 1;"><path class="box" d="M4,0H160Q164,0 164,4V52Q164,56 160,56H4Q0,56 0,52V4Q0,0 4,0Z" fill="#e5e0ff"/><text class="label" text-anchor="middle" x="82" y="48"><tspan>Scope</tspan><tspan class="node-id">  #1</tspan></text><text class="type" text-anchor="middle" y="35" x="82"/><title>#1 Scope
+Type not computed
+
+[0] → #17 ASSOC 0: $ctrl
+[1] → #5 ASSOC 0: arg
+[2] → #18 ASSOC 1: a</title><line class="row" x1="0" x2="164" y1="30" y2="30"/><line class="row" x1="61" x2="61" y1="0" y2="30"/><line class="row" x1="116" x2="116" y1="0" y2="30"/><text class="bind" x="30.5" y="20" text-anchor="middle">0: $ctrl</text><text class="bind" x="88.5" y="20" text-anchor="middle">0: arg</text><text class="bind" x="140" y="20" text-anchor="middle">1: a</text><circle class="port" cx="30.5" cy="0" r="3" fill="#536477"/><circle class="port" cx="88.5" cy="0" r="3" fill="#536477"/><circle class="port" cx="140" cy="0" r="3" fill="#536477"/><text class="slot" x="30.5" y="-7" text-anchor="middle">0</text><text class="slot" x="88.5" y="-7" text-anchor="middle">1</text><text class="slot" x="140" y="-7" text-anchor="middle">2</text></g><g class="node" id="n2" data-id="2" transform="translate(176,24)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>Start</tspan><tspan class="node-id">  #2</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#2 Start
+Type not computed
+
+</title></g><g class="node" id="n4" data-id="4" transform="translate(176,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>$ctrl</tspan><tspan class="node-id">  #4/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#4 $ctrl
+Projection 0 of #2
+Type not computed
+
+[0] → #2 CTRL</title></g><g class="node" id="n5" data-id="5" transform="translate(296,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>arg</tspan><tspan class="node-id">  #5/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#5 arg
+Projection 1 of #2
+Type not computed
+
+[0] → #2 DATA</title></g><g class="node" id="n6" data-id="6" transform="translate(156,379)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>True</tspan><tspan class="node-id">  #6/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#6 True
+Projection 0 of #9
+Type not computed
+
+[0] → #9 CTRL</title></g><g class="node" id="n7" data-id="7" transform="translate(24,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#1</tspan><tspan class="node-id">  #7</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#7 #1
+Type not computed
+
+</title></g><g class="node" id="n8" data-id="8" transform="translate(247,231)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #8</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#8 ==
+Type not computed
+
+[0] → — DATA
+[1] → #5 DATA
+[2] → #7 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n9" data-id="9" transform="translate(156,335)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>If</tspan><tspan class="node-id">  #9</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#9 If
+Type not computed
+
+[0] → #4 CTRL
+[1] → #8 DATA</title><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><circle class="port" cx="160" cy="-3" r="3" fill="#536477"/><text class="slot" x="80" y="-10" text-anchor="middle">0</text><text class="slot" x="160" y="-10" text-anchor="middle">1</text></g><g class="node" id="n10" data-id="10" transform="translate(276,379)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>False</tspan><tspan class="node-id">  #10/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#10 False
+Projection 1 of #9
+Type not computed
+
+[0] → #9 CTRL</title></g><g class="node" id="n13" data-id="13" transform="translate(464,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#2</tspan><tspan class="node-id">  #13</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#13 #2
+Type not computed
+
+</title></g><g class="node" id="n14" data-id="14" transform="translate(434,349.66666666666663)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>+</tspan><tspan class="node-id">  #14</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#14 +
+Type not computed
+
+[0] → — DATA
+[1] → #5 DATA
+[2] → #13 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n15" data-id="15" transform="translate(616,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#3</tspan><tspan class="node-id">  #15</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#15 #3
+Type not computed
+
+</title></g><g class="node" id="n16" data-id="16" transform="translate(586,349.66666666666663)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>-</tspan><tspan class="node-id">  #16</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#16 -
+Type not computed
+
+[0] → — DATA
+[1] → #5 DATA
+[2] → #15 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n17" data-id="17" transform="translate(246,483)" style="opacity: 1;"><path class="box" d="M12,0H108L120,44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Region</tspan><tspan class="node-id">  #17</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#17 Region
+Type not computed
+
+[0] → — DATA
+[1] → #6 CTRL
+[2] → #10 CTRL</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n18" data-id="18" transform="translate(398,483)" style="opacity: 1;"><path class="box" d="M12,0H108L120,22L108,44H12L0,22Z" fill="#f5e4fa"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>φ_a</tspan><tspan class="node-id">  #18</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#18 φ_a
+Type not computed
+
+[0] → #17 ASSOC
+[1] → #14 DATA
+[2] → #16 DATA</title><circle class="port" cx="-3" cy="22" r="3" fill="#536477"/><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><path class="reg" fill="none" stroke="#b63838" d="M-3,22H-18m4,-3l-4,3l4,3"><title>[0] → #17</title></path><text class="slot" x="-10" y="15" text-anchor="middle">0</text><text class="slot" x="40" y="-10" text-anchor="middle">1</text><text class="slot" x="80" y="-10" text-anchor="middle">2</text></g></g><g class="region-heads" style="opacity: 1;"><g class="region-head" transform="translate(144,171)"><text class="label" x="26" y="17"><tspan>If</tspan><tspan class="node-id">  #9</tspan></text><title>If · 8 nodes</title><g class="fold-btn" role="button" tabindex="0" transform="translate(4,4)" aria-label="Fold region #9"><rect width="16" height="16" rx="2"/><text x="8" y="12" text-anchor="middle">−</text><title>Fold region</title></g></g></g><g class="shortcuts" style="opacity: 1;"/><g class="peep-ghosts" pointer-events="none"/></g></svg>
diff --git a/chapter05/docs/05-graph3.json b/chapter05/docs/05-graph3.json
new file mode 100644
index 00000000..16d74821
--- /dev/null
+++ b/chapter05/docs/05-graph3.json
@@ -0,0 +1,28 @@
+{
+ "ver": 1,
+ "comp": "chapter05/docs/05-graph3.svg",
+ "step": 1,
+ "roots": [],
+ "scope": 0,
+ "nodes": [
+ {"id": 1, "label": "$ctrl", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 2, "role": "CTRL", "label": null}], "proj": {"par": 2, "idx": 0}},
+ {"id": 2, "label": "Start", "type": null, "kind": "CTRL", "edges": [], "proj": null},
+ {"id": 3, "label": "Stop", "type": null, "kind": "STOP", "edges": [{"idx": 0, "def": 19, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 4, "label": "arg", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 2, "role": "DATA", "label": null}], "proj": {"par": 2, "idx": 1}},
+ {"id": 5, "label": "True", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 9, "role": "CTRL", "label": null}], "proj": {"par": 9, "idx": 0}},
+ {"id": 6, "label": "False", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 9, "role": "CTRL", "label": null}], "proj": {"par": 9, "idx": 1}},
+ {"id": 7, "label": "#1", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 8, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 4, "role": "DATA", "label": null}, {"idx": 2, "def": 7, "role": "DATA", "label": null}], "proj": null},
+ {"id": 9, "label": "If", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 1, "role": "CTRL", "label": null}, {"idx": 1, "def": 8, "role": "DATA", "label": null}], "proj": null},
+ {"id": 13, "label": "#2", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 14, "label": "+", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 4, "role": "DATA", "label": null}, {"idx": 2, "def": 13, "role": "DATA", "label": null}], "proj": null},
+ {"id": 15, "label": "#3", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 16, "label": "-", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 4, "role": "DATA", "label": null}, {"idx": 2, "def": 15, "role": "DATA", "label": null}], "proj": null},
+ {"id": 17, "label": "Region", "type": null, "kind": "REGION", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 5, "role": "CTRL", "label": null}, {"idx": 2, "def": 6, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 18, "label": "φ_a", "type": null, "kind": "PHI", "edges": [{"idx": 0, "def": 17, "role": "ASSOC", "label": null}, {"idx": 1, "def": 14, "role": "DATA", "label": null}, {"idx": 2, "def": 16, "role": "DATA", "label": null}], "proj": null},
+ {"id": 19, "label": "Return", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 17, "role": "CTRL", "label": null}, {"idx": 1, "def": 18, "role": "DATA", "label": null}], "proj": null}
+ ],
+ "groups": [
+ {"id": 9, "par": 0, "nodes": [5, 6, 8, 9, 14, 16, 17, 18]}
+ ]
+}
diff --git a/chapter05/docs/05-graph3.svg b/chapter05/docs/05-graph3.svg
index 855fdc2c..50255072 100644
--- a/chapter05/docs/05-graph3.svg
+++ b/chapter05/docs/05-graph3.svg
@@ -1,216 +1,127 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Generated by graphviz version 2.43.0 (0)
- -->
-<!-- Title: chapter05 Pages: 1 -->
-<svg width="298pt" height="492pt"
- viewBox="0.00 0.00 298.00 492.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 488)">
-<title>chapter05</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-488 294,-488 294,4 -4,4"/>
-<g id="clust1" class="cluster">
-<title>cluster_Nodes</title>
-<polygon fill="none" stroke="black" points="8,-8 8,-476 282,-476 282,-8 8,-8"/>
-</g>
-<!-- Start2 -->
-<g id="node1" class="node">
-<title>Start2</title>
-<polygon fill="yellow" stroke="transparent" points="113,-439 113,-464 194,-464 194,-439 113,-439"/>
-<polygon fill="none" stroke="black" points="113,-439 113,-464 194,-464 194,-439 113,-439"/>
-<text text-anchor="start" x="135" y="-447.8" font-family="Times,serif" font-size="14.00">Start</text>
-<polygon fill="none" stroke="black" points="113,-408 113,-439 194,-439 194,-408 113,-408"/>
-<polygon fill="yellow" stroke="transparent" points="118,-413 118,-434 158,-434 158,-413 118,-413"/>
-<polygon fill="none" stroke="black" points="118,-413 118,-434 158,-434 158,-413 118,-413"/>
-<text text-anchor="start" x="121" y="-419.8" font-family="Times,serif" font-size="14.00">$ctrl</text>
-<polygon fill="none" stroke="black" points="158,-413 158,-434 189,-434 189,-413 158,-413"/>
-<text text-anchor="start" x="161" y="-419.8" font-family="Times,serif" font-size="14.00">arg</text>
-</g>
-<!-- Stop3 -->
-<g id="node2" class="node">
-<title>Stop3</title>
-<polygon fill="yellow" stroke="black" points="185,-52 131,-52 131,-16 185,-16 185,-52"/>
-<text text-anchor="middle" x="158" y="-30.3" font-family="Times,serif" font-size="14.00">Stop</text>
-</g>
-<!-- Return19 -->
-<g id="node12" class="node">
-<title>Return19</title>
-<polygon fill="yellow" stroke="black" points="191,-124 125,-124 125,-88 191,-88 191,-124"/>
-<text text-anchor="middle" x="158" y="-102.3" font-family="Times,serif" font-size="14.00">Return</text>
-</g>
-<!-- Stop3&#45;&gt;Return19 -->
-<g id="edge1" class="edge">
-<title>Stop3&#45;&gt;Return19</title>
-<path fill="none" stroke="red" d="M158,-52.3C158,-60.02 158,-69.29 158,-77.89"/>
-<polygon fill="red" stroke="red" points="154.5,-77.9 158,-87.9 161.5,-77.9 154.5,-77.9"/>
-<text text-anchor="middle" x="155" y="-54.9" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Con_7 -->
-<g id="node3" class="node">
-<title>Con_7</title>
-<ellipse fill="none" stroke="black" cx="247" cy="-436" rx="27" ry="18"/>
-<text text-anchor="middle" x="247" y="-432.3" font-family="Times,serif" font-size="14.00">#1</text>
-</g>
-<!-- EQNode8 -->
-<g id="node4" class="node">
-<title>EQNode8</title>
-<ellipse fill="none" stroke="black" cx="247" cy="-350" rx="27" ry="18"/>
-<text text-anchor="middle" x="247" y="-346.3" font-family="Times,serif" font-size="14.00">==</text>
-</g>
-<!-- EQNode8&#45;&gt;Start2 -->
-<g id="edge2" class="edge">
-<title>EQNode8&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M236.57,-366.62C225.76,-382.5 208.98,-406.28 198.26,-417.17"/>
-<polygon fill="black" stroke="black" points="196.15,-414.37 190,-423 200.19,-420.09 196.15,-414.37"/>
-<text text-anchor="middle" x="233.57" y="-369.22" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode8&#45;&gt;Con_7 -->
-<g id="edge3" class="edge">
-<title>EQNode8&#45;&gt;Con_7</title>
-<path fill="none" stroke="black" d="M247,-368.4C247,-379.74 247,-394.77 247,-407.68"/>
-<polygon fill="black" stroke="black" points="243.5,-407.9 247,-417.9 250.5,-407.9 243.5,-407.9"/>
-<text text-anchor="middle" x="244" y="-371" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- If9 -->
-<g id="node5" class="node">
-<title>If9</title>
-<polygon fill="yellow" stroke="transparent" points="172,-267 172,-292 266,-292 266,-267 172,-267"/>
-<polygon fill="none" stroke="black" points="172,-267 172,-292 266,-292 266,-267 172,-267"/>
-<text text-anchor="start" x="213.5" y="-275.8" font-family="Times,serif" font-size="14.00">If</text>
-<polygon fill="none" stroke="black" points="172,-236 172,-267 266,-267 266,-236 172,-236"/>
-<polygon fill="yellow" stroke="transparent" points="177,-241 177,-262 217,-262 217,-241 177,-241"/>
-<polygon fill="none" stroke="black" points="177,-241 177,-262 217,-262 217,-241 177,-241"/>
-<text text-anchor="start" x="180" y="-247.8" font-family="Times,serif" font-size="14.00">True</text>
-<polygon fill="yellow" stroke="transparent" points="217,-241 217,-262 261,-262 261,-241 217,-241"/>
-<polygon fill="none" stroke="black" points="217,-241 217,-262 261,-262 261,-241 217,-241"/>
-<text text-anchor="start" x="220" y="-247.8" font-family="Times,serif" font-size="14.00">False</text>
-</g>
-<!-- If9&#45;&gt;Start2 -->
-<g id="edge4" class="edge">
-<title>If9&#45;&gt;Start2:p0</title>
-<path fill="none" stroke="red" d="M210.31,-296.18C203.59,-317.4 193.07,-345.57 179,-368 166.9,-387.28 145.68,-386.25 139.64,-402.02"/>
-<polygon fill="red" stroke="red" points="136.17,-401.56 138,-412 143.08,-402.7 136.17,-401.56"/>
-<text text-anchor="middle" x="207.31" y="-298.78" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- If9&#45;&gt;EQNode8 -->
-<g id="edge5" class="edge">
-<title>If9&#45;&gt;EQNode8</title>
-<path fill="none" stroke="black" d="M229.43,-296.28C232.3,-304.9 235.39,-314.17 238.16,-322.49"/>
-<polygon fill="black" stroke="black" points="234.87,-323.69 241.36,-332.07 241.51,-321.48 234.87,-323.69"/>
-<text text-anchor="middle" x="226.43" y="-298.88" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Con_13 -->
-<g id="node6" class="node">
-<title>Con_13</title>
-<ellipse fill="none" stroke="black" cx="43" cy="-350" rx="27" ry="18"/>
-<text text-anchor="middle" x="43" y="-346.3" font-family="Times,serif" font-size="14.00">#2</text>
-</g>
-<!-- Add14 -->
-<g id="node7" class="node">
-<title>Add14</title>
-<ellipse fill="none" stroke="black" cx="47" cy="-264" rx="27" ry="18"/>
-<text text-anchor="middle" x="47" y="-260.3" font-family="Times,serif" font-size="14.00">+</text>
-</g>
-<!-- Add14&#45;&gt;Start2 -->
-<g id="edge6" class="edge">
-<title>Add14&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M54.69,-281.49C67.53,-308.81 92.56,-361.14 99,-368 122.77,-393.31 164.37,-377.46 172.57,-402.01"/>
-<polygon fill="black" stroke="black" points="169.12,-402.6 174,-412 176.05,-401.61 169.12,-402.6"/>
-<text text-anchor="middle" x="51.69" y="-284.09" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Add14&#45;&gt;Con_13 -->
-<g id="edge7" class="edge">
-<title>Add14&#45;&gt;Con_13</title>
-<path fill="none" stroke="black" d="M46.19,-282C45.65,-293.31 44.93,-308.42 44.31,-321.43"/>
-<polygon fill="black" stroke="black" points="40.8,-321.58 43.82,-331.74 47.79,-321.92 40.8,-321.58"/>
-<text text-anchor="middle" x="43.19" y="-284.6" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Con_15 -->
-<g id="node8" class="node">
-<title>Con_15</title>
-<ellipse fill="none" stroke="black" cx="135" cy="-350" rx="27" ry="18"/>
-<text text-anchor="middle" x="135" y="-346.3" font-family="Times,serif" font-size="14.00">#3</text>
-</g>
-<!-- Sub16 -->
-<g id="node9" class="node">
-<title>Sub16</title>
-<ellipse fill="none" stroke="black" cx="119" cy="-264" rx="27" ry="18"/>
-<text text-anchor="middle" x="119" y="-260.3" font-family="Times,serif" font-size="14.00">&#45;</text>
-</g>
-<!-- Sub16&#45;&gt;Start2 -->
-<g id="edge8" class="edge">
-<title>Sub16&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M134.23,-279.02C146.68,-291.55 163.4,-311.1 171,-332 181.92,-362.04 175.64,-373.96 174.25,-401.87"/>
-<polygon fill="black" stroke="black" points="170.75,-401.92 174,-412 177.75,-402.09 170.75,-401.92"/>
-<text text-anchor="middle" x="131.23" y="-281.62" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Sub16&#45;&gt;Con_15 -->
-<g id="edge9" class="edge">
-<title>Sub16&#45;&gt;Con_15</title>
-<path fill="none" stroke="black" d="M122.24,-282C124.43,-293.5 127.37,-308.93 129.87,-322.08"/>
-<polygon fill="black" stroke="black" points="126.46,-322.86 131.77,-332.03 133.33,-321.55 126.46,-322.86"/>
-<text text-anchor="middle" x="119.24" y="-284.6" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Region17 -->
-<g id="node10" class="node">
-<title>Region17</title>
-<polygon fill="yellow" stroke="black" points="230,-196 164,-196 164,-160 230,-160 230,-196"/>
-<text text-anchor="middle" x="197" y="-174.3" font-family="Times,serif" font-size="14.00">Region</text>
-</g>
-<!-- Region17&#45;&gt;If9 -->
-<g id="edge10" class="edge">
-<title>Region17&#45;&gt;If9:p0</title>
-<path fill="none" stroke="red" d="M197,-196.09C197,-205.55 197,-217.77 197,-229.69"/>
-<polygon fill="red" stroke="red" points="193.5,-230 197,-240 200.5,-230 193.5,-230"/>
-<text text-anchor="middle" x="194" y="-198.69" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Region17&#45;&gt;If9 -->
-<g id="edge11" class="edge">
-<title>Region17&#45;&gt;If9:p1</title>
-<path fill="none" stroke="red" d="M217.02,-196.12C225.64,-205.06 234.48,-216.84 237.71,-229.84"/>
-<polygon fill="red" stroke="red" points="234.27,-230.52 239,-240 241.22,-229.64 234.27,-230.52"/>
-<text text-anchor="middle" x="214.02" y="-198.72" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a18 -->
-<g id="node11" class="node">
-<title>Phi_a18</title>
-<ellipse fill="lightyellow" stroke="black" cx="119" cy="-178" rx="27" ry="18"/>
-<text text-anchor="middle" x="119" y="-174.3" font-family="Times,serif" font-size="14.00">φ_a</text>
-</g>
-<!-- Phi_a18&#45;&gt;Add14 -->
-<g id="edge13" class="edge">
-<title>Phi_a18&#45;&gt;Add14</title>
-<path fill="none" stroke="black" d="M106.13,-194.02C95.07,-206.92 78.96,-225.71 66.35,-240.42"/>
-<polygon fill="black" stroke="black" points="63.61,-238.24 59.76,-248.11 68.93,-242.8 63.61,-238.24"/>
-<text text-anchor="middle" x="103.13" y="-196.62" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Phi_a18&#45;&gt;Sub16 -->
-<g id="edge14" class="edge">
-<title>Phi_a18&#45;&gt;Sub16</title>
-<path fill="none" stroke="black" d="M119,-196.4C119,-207.74 119,-222.77 119,-235.68"/>
-<polygon fill="black" stroke="black" points="115.5,-235.9 119,-245.9 122.5,-235.9 115.5,-235.9"/>
-<text text-anchor="middle" x="116" y="-199" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a18&#45;&gt;Region17 -->
-<g id="edge12" class="edge">
-<title>Phi_a18&#45;&gt;Region17</title>
-<path fill="none" stroke="black" stroke-dasharray="1,5" d="M146.12,-178C148.58,-178 151.04,-178 153.5,-178"/>
-<polygon fill="black" stroke="black" points="153.61,-181.5 163.61,-178 153.61,-174.5 153.61,-181.5"/>
-<text text-anchor="middle" x="149.12" y="-171.6" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Return19&#45;&gt;Region17 -->
-<g id="edge15" class="edge">
-<title>Return19&#45;&gt;Region17</title>
-<path fill="none" stroke="red" d="M167.64,-124.3C172.13,-132.36 177.56,-142.11 182.52,-151.02"/>
-<polygon fill="red" stroke="red" points="179.55,-152.86 187.47,-159.9 185.66,-149.46 179.55,-152.86"/>
-<text text-anchor="middle" x="164.64" y="-126.9" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Return19&#45;&gt;Phi_a18 -->
-<g id="edge16" class="edge">
-<title>Return19&#45;&gt;Phi_a18</title>
-<path fill="none" stroke="black" d="M148.36,-124.3C143.69,-132.68 138,-142.9 132.87,-152.1"/>
-<polygon fill="black" stroke="black" points="129.8,-150.42 127.99,-160.86 135.92,-153.82 129.8,-150.42"/>
-<text text-anchor="middle" x="145.36" y="-126.9" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-</g>
-</svg>
+<svg aria-label="Compiler graph" width="760" height="752" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 752" style="font-family: sans-serif;"><style>
+ html, body { height:100%; margin:0; font-family:sans-serif; }
+ .viewer { height:100%; display:grid; grid-template-rows:auto minmax(0,1fr) auto; }
+ .source { padding:8px; border-bottom:1px solid #ccc; }
+ #program { width:min(600px,80vw); vertical-align:middle; }
+ #status { margin-top:4px; }
+ #graph { min-height:0; overflow:hidden; position:relative; background:#fafbfc; }
+ #elk { width:100%; height:100%; }
+ #graph svg { display:block; }
+ .tools { display:flex; flex-wrap:wrap; align-items:center; gap:14px; margin-top:8px; font-size:12px; }
+ .hint { color:#616c78; }
+ .ctrl { color:#b63838; } .mem { color:#2867b2; } .data { color:#536477; }
+ .edge { fill:none; stroke-width:1.5; }
+ .edge.CTRL { stroke-width:2; }
+ .edge.ASSOC { stroke-dasharray:4 4; }
+ .edge.PARSER { stroke-dasharray:5 4; }
+ .parser rect { fill:#f6f0ff; stroke:#7956a5; stroke-width:1.5; stroke-dasharray:5 4; }
+ .edge.selected { stroke-width:3.5; }
+ .edge.bundle { stroke-width:4; }
+ .edge.bundle.selected { stroke-width:6; }
+ .edge-hit { fill:none; stroke:transparent; stroke-width:12; vector-effect:non-scaling-stroke; pointer-events:stroke; cursor:pointer; }
+ .edge-jump { fill:transparent; pointer-events:all; cursor:pointer; }
+ .node { cursor:pointer; }
+ .box { stroke:#758191; stroke-width:1; }
+ .node.held .box { stroke-dasharray:5 3; }
+ .node.near .box { stroke:#c18221; stroke-width:2; }
+ .node.focus .box { stroke:#9c4900; stroke-width:3; }
+ .node.selected .box { stroke:#1569b9; stroke-width:3; }
+ .node.folded .box { stroke-width:4; }
+ .node.folding .box { fill:#f4ccd7; }
+ .fold-tag { font-size:9px; font-weight:700; fill:#963751; }
+ .peep-area { fill:#fff3d9; fill-opacity:.8; stroke:#c18221; stroke-width:2; pointer-events:none; }
+ .node.peep-edit .box { stroke:#9c4900; stroke-width:3; }
+ .node.error .box { stroke:#b42318; stroke-width:4; }
+ #event.error { color:#b42318; font-weight:600; white-space:pre-wrap; overflow-wrap:anywhere; }
+ .peep-ghosts { pointer-events:none; }
+ .region-box { stroke:#9da9b8; stroke-width:1.5; }
+ .fold-btn { cursor:pointer; }
+ .fold-btn rect { fill:white; stroke:#596674; }
+ .fold-btn text { font-size:14px; fill:#152330; }
+ .fold-btn:focus rect { stroke:#1569b9; stroke-width:2; }
+ .shortcut { cursor:pointer; }
+ .shortcut path { fill:none; stroke-width:1.5; }
+ .shortcut rect { fill:#fff8ec; stroke:#b63838; stroke-dasharray:3 2; }
+ .shortcut text { font-size:11px; fill:#783030; }
+ .shortcut.selected rect, .shortcut:focus rect { stroke-width:2.5; }
+ .label { font-size:12px; fill:#152330; font-weight:600; }
+ .node-id { font-size:10px; fill:#596674; font-weight:400; }
+ .type { font-size:11px; fill:#455768; }
+ .port { stroke:#536477; stroke-width:1; }
+ .row { stroke:#b6afcf; stroke-width:1; }
+ .bind { font-size:12px; fill:#152330; }
+ .slot { font-size:10px; fill:#364352; paint-order:stroke; stroke:#fafbfc; stroke-width:3; }
+ #detail { position:absolute; top:8px; right:8px; margin:0; padding:12px; max-width:320px;
+ max-height:45%; overflow:auto; white-space:pre-wrap; overflow-wrap:anywhere;
+ background:#fffffff2; border:1px solid #bac5d0; border-radius:4px; font-size:12px; }
+ .controls { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:6px; padding:6px; }
+ .button { color:white; background:black; font-size:20px; min-width:30px; }
+ .button:disabled { background:grey; }
+ .count { font-size:20px; min-width:35px; text-align:center; }
+ #N { width:6ch; }
+ #scrub { width:clamp(120px,35vw,600px); }
+ </style><defs><marker id="arrow-CTRL" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#b63838"/></marker><marker id="arrow-DATA" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#536477"/></marker><marker id="arrow-MEM" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#2867b2"/></marker><marker id="arrow-ASSOC" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#9396a3"/></marker><marker id="arrow-PARSER" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#7956a5"/></marker></defs><rect width="100%" height="100%" fill="rgb(250, 251, 252)"/><g><g class="regions" style="opacity: 1;"><g class="region" transform="translate(144,171)"><rect class="region-box" rx="8" width="574" height="374" fill="#f2f7ef"/></g></g><rect class="peep-area" rx="36" style="opacity: 0;"/><g class="edges"><path class="edge CTRL" id="e3i0" d="M326,651 C326,675 380,678 380,702" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#3[0] → #19 · CTRL</title></path><path class="edge DATA" id="e8i1" d="M356,118 L356,128 L307,128 L307,225" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#8[1] → #4 · DATA</title></path><path class="edge DATA" id="e8i2" d="M84,118 L84,128 L226,128 L226,215 L337,215 L337,225" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#8[2] → #7 · DATA</title></path><path class="edge CTRL" id="e9i0" d="M236,118 L236,329" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#9[0] → #1 · CTRL</title></path><path class="edge DATA" id="e9i1" d="M307,281 L307,291 L316,291 L316,329" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#9[1] → #8 · DATA</title></path><path class="edge DATA" id="e14i1" d="M356,118 L356,128 L494,128 L494,343.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#14[1] → #4 · DATA</title></path><path class="edge DATA" id="e14i2" d="M524,118 L524,343.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#14[2] → #13 · DATA</title></path><path class="edge DATA" id="e16i1" d="M356,118 L356,128 L513,128 L513,291 L646,291 L646,343.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#16[1] → #4 · DATA</title></path><path class="edge DATA" id="e16i2" d="M676,118 L676,343.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#16[2] → #15 · DATA</title></path><path class="edge CTRL" id="e17i1" d="M216,429 L216,439 L306,439 L306,477" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#17[1] → #5 · CTRL</title></path><path class="edge CTRL" id="e17i2" d="M336,429 L336,477" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#17[2] → #6 · CTRL</title></path><path class="edge DATA" id="e18i1" d="M494,399.66666666666663 L494,439 L438,439 L438,477" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#18[1] → #14 · DATA</title></path><path class="edge DATA" id="e18i2" d="M646,399.66666666666663 L646,449 L478,449 L478,477" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#18[2] → #16 · DATA</title></path><path class="edge CTRL" id="e19i0" d="M306,533 L306,598" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#19[0] → #17 · CTRL</title></path><path class="edge DATA" id="e19i1" d="M458,533 L458,560 L346,560 L346,598" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#19[1] → #18 · DATA</title></path></g><g class="edge-hits"/><g class="parser" style="opacity: 1;"/><g class="nodes"><g class="node" id="n1" data-id="1" transform="translate(176,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>$ctrl</tspan><tspan class="node-id">  #1/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#1 $ctrl
+Projection 0 of #2
+Type not computed
+
+[0] → #2 CTRL</title></g><g class="node" id="n2" data-id="2" transform="translate(176,24)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>Start</tspan><tspan class="node-id">  #2</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#2 Start
+Type not computed
+
+</title></g><g class="node" id="n3" data-id="3" transform="translate(344,702)" style="opacity: 1;"><path class="box" d="M0,0H72V26H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="36" y="17"><tspan>Stop</tspan><tspan class="node-id">  #3</tspan></text><text class="type" text-anchor="middle" y="35" x="36"/><title>#3 Stop
+Type not computed
+
+[0] → #19 CTRL</title><circle class="port" cx="36" cy="0" r="3" fill="#536477"/><text class="slot" x="36" y="-7" text-anchor="middle">0</text></g><g class="node" id="n4" data-id="4" transform="translate(296,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>arg</tspan><tspan class="node-id">  #4/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#4 arg
+Projection 1 of #2
+Type not computed
+
+[0] → #2 DATA</title></g><g class="node" id="n5" data-id="5" transform="translate(156,379)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>True</tspan><tspan class="node-id">  #5/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#5 True
+Projection 0 of #9
+Type not computed
+
+[0] → #9 CTRL</title></g><g class="node" id="n6" data-id="6" transform="translate(276,379)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>False</tspan><tspan class="node-id">  #6/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#6 False
+Projection 1 of #9
+Type not computed
+
+[0] → #9 CTRL</title></g><g class="node" id="n7" data-id="7" transform="translate(24,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#1</tspan><tspan class="node-id">  #7</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#7 #1
+Type not computed
+
+</title></g><g class="node" id="n8" data-id="8" transform="translate(247,231)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #8</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#8 ==
+Type not computed
+
+[0] → — DATA
+[1] → #4 DATA
+[2] → #7 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n9" data-id="9" transform="translate(156,335)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>If</tspan><tspan class="node-id">  #9</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#9 If
+Type not computed
+
+[0] → #1 CTRL
+[1] → #8 DATA</title><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><circle class="port" cx="160" cy="-3" r="3" fill="#536477"/><text class="slot" x="80" y="-10" text-anchor="middle">0</text><text class="slot" x="160" y="-10" text-anchor="middle">1</text></g><g class="node" id="n13" data-id="13" transform="translate(464,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#2</tspan><tspan class="node-id">  #13</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#13 #2
+Type not computed
+
+</title></g><g class="node" id="n14" data-id="14" transform="translate(434,349.66666666666663)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>+</tspan><tspan class="node-id">  #14</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#14 +
+Type not computed
+
+[0] → — DATA
+[1] → #4 DATA
+[2] → #13 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n15" data-id="15" transform="translate(616,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#3</tspan><tspan class="node-id">  #15</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#15 #3
+Type not computed
+
+</title></g><g class="node" id="n16" data-id="16" transform="translate(586,349.66666666666663)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>-</tspan><tspan class="node-id">  #16</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#16 -
+Type not computed
+
+[0] → — DATA
+[1] → #4 DATA
+[2] → #15 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n17" data-id="17" transform="translate(246,483)" style="opacity: 1;"><path class="box" d="M12,0H108L120,44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Region</tspan><tspan class="node-id">  #17</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#17 Region
+Type not computed
+
+[0] → — DATA
+[1] → #5 CTRL
+[2] → #6 CTRL</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n18" data-id="18" transform="translate(398,483)" style="opacity: 1;"><path class="box" d="M12,0H108L120,22L108,44H12L0,22Z" fill="#f5e4fa"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>φ_a</tspan><tspan class="node-id">  #18</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#18 φ_a
+Type not computed
+
+[0] → #17 ASSOC
+[1] → #14 DATA
+[2] → #16 DATA</title><circle class="port" cx="-3" cy="22" r="3" fill="#536477"/><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><path class="reg" fill="none" stroke="#b63838" d="M-3,22H-18m4,-3l-4,3l4,3"><title>[0] → #17</title></path><text class="slot" x="-10" y="15" text-anchor="middle">0</text><text class="slot" x="40" y="-10" text-anchor="middle">1</text><text class="slot" x="80" y="-10" text-anchor="middle">2</text></g><g class="node" id="n19" data-id="19" transform="translate(266,604)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Return</tspan><tspan class="node-id">  #19</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#19 Return
+Type not computed
+
+[0] → #17 CTRL
+[1] → #18 DATA</title><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><text class="slot" x="40" y="-10" text-anchor="middle">0</text><text class="slot" x="80" y="-10" text-anchor="middle">1</text></g></g><g class="region-heads" style="opacity: 1;"><g class="region-head" transform="translate(144,171)"><text class="label" x="26" y="17"><tspan>If</tspan><tspan class="node-id">  #9</tspan></text><title>If · 8 nodes</title><g class="fold-btn" role="button" tabindex="0" transform="translate(4,4)" aria-label="Fold region #9"><rect width="16" height="16" rx="2"/><text x="8" y="12" text-anchor="middle">−</text><title>Fold region</title></g></g></g><g class="shortcuts" style="opacity: 1;"/><g class="peep-ghosts" pointer-events="none"/></g></svg>
diff --git a/chapter05/docs/05-graph4.json b/chapter05/docs/05-graph4.json
new file mode 100644
index 00000000..36527f8d
--- /dev/null
+++ b/chapter05/docs/05-graph4.json
@@ -0,0 +1,28 @@
+{
+ "ver": 1,
+ "comp": "chapter05/docs/05-graph4.svg",
+ "step": 1,
+ "roots": [],
+ "scope": 0,
+ "nodes": [
+ {"id": 1, "label": "$ctrl", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 2, "role": "CTRL", "label": null}], "proj": {"par": 2, "idx": 0}},
+ {"id": 2, "label": "Start", "type": null, "kind": "CTRL", "edges": [], "proj": null},
+ {"id": 3, "label": "Stop", "type": null, "kind": "STOP", "edges": [{"idx": 0, "def": 18, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 4, "label": "arg", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 2, "role": "DATA", "label": null}], "proj": {"par": 2, "idx": 1}},
+ {"id": 5, "label": "True", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 10, "role": "CTRL", "label": null}], "proj": {"par": 10, "idx": 0}},
+ {"id": 6, "label": "#2", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 7, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 4, "role": "DATA", "label": null}, {"idx": 2, "def": 6, "role": "DATA", "label": null}], "proj": null},
+ {"id": 8, "label": "#1", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 9, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 4, "role": "DATA", "label": null}, {"idx": 2, "def": 8, "role": "DATA", "label": null}], "proj": null},
+ {"id": 10, "label": "If", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 1, "role": "CTRL", "label": null}, {"idx": 1, "def": 9, "role": "DATA", "label": null}], "proj": null},
+ {"id": 11, "label": "False", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 10, "role": "CTRL", "label": null}], "proj": {"par": 10, "idx": 1}},
+ {"id": 14, "label": "#3", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 15, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 4, "role": "DATA", "label": null}, {"idx": 2, "def": 14, "role": "DATA", "label": null}], "proj": null},
+ {"id": 16, "label": "Region", "type": null, "kind": "REGION", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 5, "role": "CTRL", "label": null}, {"idx": 2, "def": 11, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 17, "label": "φ_a", "type": null, "kind": "PHI", "edges": [{"idx": 0, "def": 16, "role": "ASSOC", "label": null}, {"idx": 1, "def": 15, "role": "DATA", "label": null}, {"idx": 2, "def": 7, "role": "DATA", "label": null}], "proj": null},
+ {"id": 18, "label": "Return", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 16, "role": "CTRL", "label": null}, {"idx": 1, "def": 17, "role": "DATA", "label": null}], "proj": null}
+ ],
+ "groups": [
+ {"id": 10, "par": 0, "nodes": [5, 7, 9, 10, 11, 15, 16, 17]}
+ ]
+}
diff --git a/chapter05/docs/05-graph4.svg b/chapter05/docs/05-graph4.svg
index 3fcee500..58f0cb18 100644
--- a/chapter05/docs/05-graph4.svg
+++ b/chapter05/docs/05-graph4.svg
@@ -1,216 +1,127 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Generated by graphviz version 2.43.0 (0)
- -->
-<!-- Title: chapter05 Pages: 1 -->
-<svg width="298pt" height="492pt"
- viewBox="0.00 0.00 298.00 492.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 488)">
-<title>chapter05</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-488 294,-488 294,4 -4,4"/>
-<g id="clust1" class="cluster">
-<title>cluster_Nodes</title>
-<polygon fill="none" stroke="black" points="8,-8 8,-476 282,-476 282,-8 8,-8"/>
-</g>
-<!-- Start2 -->
-<g id="node1" class="node">
-<title>Start2</title>
-<polygon fill="yellow" stroke="transparent" points="113,-439 113,-464 194,-464 194,-439 113,-439"/>
-<polygon fill="none" stroke="black" points="113,-439 113,-464 194,-464 194,-439 113,-439"/>
-<text text-anchor="start" x="135" y="-447.8" font-family="Times,serif" font-size="14.00">Start</text>
-<polygon fill="none" stroke="black" points="113,-408 113,-439 194,-439 194,-408 113,-408"/>
-<polygon fill="yellow" stroke="transparent" points="118,-413 118,-434 158,-434 158,-413 118,-413"/>
-<polygon fill="none" stroke="black" points="118,-413 118,-434 158,-434 158,-413 118,-413"/>
-<text text-anchor="start" x="121" y="-419.8" font-family="Times,serif" font-size="14.00">$ctrl</text>
-<polygon fill="none" stroke="black" points="158,-413 158,-434 189,-434 189,-413 158,-413"/>
-<text text-anchor="start" x="161" y="-419.8" font-family="Times,serif" font-size="14.00">arg</text>
-</g>
-<!-- Stop3 -->
-<g id="node2" class="node">
-<title>Stop3</title>
-<polygon fill="yellow" stroke="black" points="185,-52 131,-52 131,-16 185,-16 185,-52"/>
-<text text-anchor="middle" x="158" y="-30.3" font-family="Times,serif" font-size="14.00">Stop</text>
-</g>
-<!-- Return18 -->
-<g id="node12" class="node">
-<title>Return18</title>
-<polygon fill="yellow" stroke="black" points="191,-124 125,-124 125,-88 191,-88 191,-124"/>
-<text text-anchor="middle" x="158" y="-102.3" font-family="Times,serif" font-size="14.00">Return</text>
-</g>
-<!-- Stop3&#45;&gt;Return18 -->
-<g id="edge1" class="edge">
-<title>Stop3&#45;&gt;Return18</title>
-<path fill="none" stroke="red" d="M158,-52.3C158,-60.02 158,-69.29 158,-77.89"/>
-<polygon fill="red" stroke="red" points="154.5,-77.9 158,-87.9 161.5,-77.9 154.5,-77.9"/>
-<text text-anchor="middle" x="155" y="-54.9" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Con_6 -->
-<g id="node3" class="node">
-<title>Con_6</title>
-<ellipse fill="none" stroke="black" cx="43" cy="-350" rx="27" ry="18"/>
-<text text-anchor="middle" x="43" y="-346.3" font-family="Times,serif" font-size="14.00">#2</text>
-</g>
-<!-- EQNode7 -->
-<g id="node4" class="node">
-<title>EQNode7</title>
-<ellipse fill="none" stroke="black" cx="47" cy="-264" rx="27" ry="18"/>
-<text text-anchor="middle" x="47" y="-260.3" font-family="Times,serif" font-size="14.00">==</text>
-</g>
-<!-- EQNode7&#45;&gt;Start2 -->
-<g id="edge2" class="edge">
-<title>EQNode7&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M54.69,-281.49C67.53,-308.81 92.56,-361.14 99,-368 122.77,-393.31 164.37,-377.46 172.57,-402.01"/>
-<polygon fill="black" stroke="black" points="169.12,-402.6 174,-412 176.05,-401.61 169.12,-402.6"/>
-<text text-anchor="middle" x="51.69" y="-284.09" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode7&#45;&gt;Con_6 -->
-<g id="edge3" class="edge">
-<title>EQNode7&#45;&gt;Con_6</title>
-<path fill="none" stroke="black" d="M46.19,-282C45.65,-293.31 44.93,-308.42 44.31,-321.43"/>
-<polygon fill="black" stroke="black" points="40.8,-321.58 43.82,-331.74 47.79,-321.92 40.8,-321.58"/>
-<text text-anchor="middle" x="43.19" y="-284.6" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Con_8 -->
-<g id="node5" class="node">
-<title>Con_8</title>
-<ellipse fill="none" stroke="black" cx="247" cy="-436" rx="27" ry="18"/>
-<text text-anchor="middle" x="247" y="-432.3" font-family="Times,serif" font-size="14.00">#1</text>
-</g>
-<!-- EQNode9 -->
-<g id="node6" class="node">
-<title>EQNode9</title>
-<ellipse fill="none" stroke="black" cx="247" cy="-350" rx="27" ry="18"/>
-<text text-anchor="middle" x="247" y="-346.3" font-family="Times,serif" font-size="14.00">==</text>
-</g>
-<!-- EQNode9&#45;&gt;Start2 -->
-<g id="edge4" class="edge">
-<title>EQNode9&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M236.57,-366.62C225.76,-382.5 208.98,-406.28 198.26,-417.17"/>
-<polygon fill="black" stroke="black" points="196.15,-414.37 190,-423 200.19,-420.09 196.15,-414.37"/>
-<text text-anchor="middle" x="233.57" y="-369.22" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode9&#45;&gt;Con_8 -->
-<g id="edge5" class="edge">
-<title>EQNode9&#45;&gt;Con_8</title>
-<path fill="none" stroke="black" d="M247,-368.4C247,-379.74 247,-394.77 247,-407.68"/>
-<polygon fill="black" stroke="black" points="243.5,-407.9 247,-417.9 250.5,-407.9 243.5,-407.9"/>
-<text text-anchor="middle" x="244" y="-371" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- If10 -->
-<g id="node7" class="node">
-<title>If10</title>
-<polygon fill="yellow" stroke="transparent" points="172,-267 172,-292 266,-292 266,-267 172,-267"/>
-<polygon fill="none" stroke="black" points="172,-267 172,-292 266,-292 266,-267 172,-267"/>
-<text text-anchor="start" x="213.5" y="-275.8" font-family="Times,serif" font-size="14.00">If</text>
-<polygon fill="none" stroke="black" points="172,-236 172,-267 266,-267 266,-236 172,-236"/>
-<polygon fill="yellow" stroke="transparent" points="177,-241 177,-262 217,-262 217,-241 177,-241"/>
-<polygon fill="none" stroke="black" points="177,-241 177,-262 217,-262 217,-241 177,-241"/>
-<text text-anchor="start" x="180" y="-247.8" font-family="Times,serif" font-size="14.00">True</text>
-<polygon fill="yellow" stroke="transparent" points="217,-241 217,-262 261,-262 261,-241 217,-241"/>
-<polygon fill="none" stroke="black" points="217,-241 217,-262 261,-262 261,-241 217,-241"/>
-<text text-anchor="start" x="220" y="-247.8" font-family="Times,serif" font-size="14.00">False</text>
-</g>
-<!-- If10&#45;&gt;Start2 -->
-<g id="edge6" class="edge">
-<title>If10&#45;&gt;Start2:p0</title>
-<path fill="none" stroke="red" d="M210.31,-296.18C203.59,-317.4 193.07,-345.57 179,-368 166.9,-387.28 145.68,-386.25 139.64,-402.02"/>
-<polygon fill="red" stroke="red" points="136.17,-401.56 138,-412 143.08,-402.7 136.17,-401.56"/>
-<text text-anchor="middle" x="207.31" y="-298.78" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- If10&#45;&gt;EQNode9 -->
-<g id="edge7" class="edge">
-<title>If10&#45;&gt;EQNode9</title>
-<path fill="none" stroke="black" d="M229.43,-296.28C232.3,-304.9 235.39,-314.17 238.16,-322.49"/>
-<polygon fill="black" stroke="black" points="234.87,-323.69 241.36,-332.07 241.51,-321.48 234.87,-323.69"/>
-<text text-anchor="middle" x="226.43" y="-298.88" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Con_14 -->
-<g id="node8" class="node">
-<title>Con_14</title>
-<ellipse fill="none" stroke="black" cx="135" cy="-350" rx="27" ry="18"/>
-<text text-anchor="middle" x="135" y="-346.3" font-family="Times,serif" font-size="14.00">#3</text>
-</g>
-<!-- EQNode15 -->
-<g id="node9" class="node">
-<title>EQNode15</title>
-<ellipse fill="none" stroke="black" cx="119" cy="-264" rx="27" ry="18"/>
-<text text-anchor="middle" x="119" y="-260.3" font-family="Times,serif" font-size="14.00">==</text>
-</g>
-<!-- EQNode15&#45;&gt;Start2 -->
-<g id="edge8" class="edge">
-<title>EQNode15&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M134.23,-279.02C146.68,-291.55 163.4,-311.1 171,-332 181.92,-362.04 175.64,-373.96 174.25,-401.87"/>
-<polygon fill="black" stroke="black" points="170.75,-401.92 174,-412 177.75,-402.09 170.75,-401.92"/>
-<text text-anchor="middle" x="131.23" y="-281.62" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode15&#45;&gt;Con_14 -->
-<g id="edge9" class="edge">
-<title>EQNode15&#45;&gt;Con_14</title>
-<path fill="none" stroke="black" d="M122.24,-282C124.43,-293.5 127.37,-308.93 129.87,-322.08"/>
-<polygon fill="black" stroke="black" points="126.46,-322.86 131.77,-332.03 133.33,-321.55 126.46,-322.86"/>
-<text text-anchor="middle" x="119.24" y="-284.6" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Region16 -->
-<g id="node10" class="node">
-<title>Region16</title>
-<polygon fill="yellow" stroke="black" points="230,-196 164,-196 164,-160 230,-160 230,-196"/>
-<text text-anchor="middle" x="197" y="-174.3" font-family="Times,serif" font-size="14.00">Region</text>
-</g>
-<!-- Region16&#45;&gt;If10 -->
-<g id="edge10" class="edge">
-<title>Region16&#45;&gt;If10:p0</title>
-<path fill="none" stroke="red" d="M197,-196.09C197,-205.55 197,-217.77 197,-229.69"/>
-<polygon fill="red" stroke="red" points="193.5,-230 197,-240 200.5,-230 193.5,-230"/>
-<text text-anchor="middle" x="194" y="-198.69" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Region16&#45;&gt;If10 -->
-<g id="edge11" class="edge">
-<title>Region16&#45;&gt;If10:p1</title>
-<path fill="none" stroke="red" d="M217.02,-196.12C225.64,-205.06 234.48,-216.84 237.71,-229.84"/>
-<polygon fill="red" stroke="red" points="234.27,-230.52 239,-240 241.22,-229.64 234.27,-230.52"/>
-<text text-anchor="middle" x="214.02" y="-198.72" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a17 -->
-<g id="node11" class="node">
-<title>Phi_a17</title>
-<ellipse fill="lightyellow" stroke="black" cx="119" cy="-178" rx="27" ry="18"/>
-<text text-anchor="middle" x="119" y="-174.3" font-family="Times,serif" font-size="14.00">φ_a</text>
-</g>
-<!-- Phi_a17&#45;&gt;EQNode7 -->
-<g id="edge14" class="edge">
-<title>Phi_a17&#45;&gt;EQNode7</title>
-<path fill="none" stroke="black" d="M106.13,-194.02C95.07,-206.92 78.96,-225.71 66.35,-240.42"/>
-<polygon fill="black" stroke="black" points="63.61,-238.24 59.76,-248.11 68.93,-242.8 63.61,-238.24"/>
-<text text-anchor="middle" x="103.13" y="-196.62" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a17&#45;&gt;EQNode15 -->
-<g id="edge13" class="edge">
-<title>Phi_a17&#45;&gt;EQNode15</title>
-<path fill="none" stroke="black" d="M119,-196.4C119,-207.74 119,-222.77 119,-235.68"/>
-<polygon fill="black" stroke="black" points="115.5,-235.9 119,-245.9 122.5,-235.9 115.5,-235.9"/>
-<text text-anchor="middle" x="116" y="-199" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Phi_a17&#45;&gt;Region16 -->
-<g id="edge12" class="edge">
-<title>Phi_a17&#45;&gt;Region16</title>
-<path fill="none" stroke="black" stroke-dasharray="1,5" d="M146.12,-178C148.58,-178 151.04,-178 153.5,-178"/>
-<polygon fill="black" stroke="black" points="153.61,-181.5 163.61,-178 153.61,-174.5 153.61,-181.5"/>
-<text text-anchor="middle" x="149.12" y="-171.6" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Return18&#45;&gt;Region16 -->
-<g id="edge15" class="edge">
-<title>Return18&#45;&gt;Region16</title>
-<path fill="none" stroke="red" d="M167.64,-124.3C172.13,-132.36 177.56,-142.11 182.52,-151.02"/>
-<polygon fill="red" stroke="red" points="179.55,-152.86 187.47,-159.9 185.66,-149.46 179.55,-152.86"/>
-<text text-anchor="middle" x="164.64" y="-126.9" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Return18&#45;&gt;Phi_a17 -->
-<g id="edge16" class="edge">
-<title>Return18&#45;&gt;Phi_a17</title>
-<path fill="none" stroke="black" d="M148.36,-124.3C143.69,-132.68 138,-142.9 132.87,-152.1"/>
-<polygon fill="black" stroke="black" points="129.8,-150.42 127.99,-160.86 135.92,-153.82 129.8,-150.42"/>
-<text text-anchor="middle" x="145.36" y="-126.9" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-</g>
-</svg>
+<svg aria-label="Compiler graph" width="760" height="752" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 752" style="font-family: sans-serif;"><style>
+ html, body { height:100%; margin:0; font-family:sans-serif; }
+ .viewer { height:100%; display:grid; grid-template-rows:auto minmax(0,1fr) auto; }
+ .source { padding:8px; border-bottom:1px solid #ccc; }
+ #program { width:min(600px,80vw); vertical-align:middle; }
+ #status { margin-top:4px; }
+ #graph { min-height:0; overflow:hidden; position:relative; background:#fafbfc; }
+ #elk { width:100%; height:100%; }
+ #graph svg { display:block; }
+ .tools { display:flex; flex-wrap:wrap; align-items:center; gap:14px; margin-top:8px; font-size:12px; }
+ .hint { color:#616c78; }
+ .ctrl { color:#b63838; } .mem { color:#2867b2; } .data { color:#536477; }
+ .edge { fill:none; stroke-width:1.5; }
+ .edge.CTRL { stroke-width:2; }
+ .edge.ASSOC { stroke-dasharray:4 4; }
+ .edge.PARSER { stroke-dasharray:5 4; }
+ .parser rect { fill:#f6f0ff; stroke:#7956a5; stroke-width:1.5; stroke-dasharray:5 4; }
+ .edge.selected { stroke-width:3.5; }
+ .edge.bundle { stroke-width:4; }
+ .edge.bundle.selected { stroke-width:6; }
+ .edge-hit { fill:none; stroke:transparent; stroke-width:12; vector-effect:non-scaling-stroke; pointer-events:stroke; cursor:pointer; }
+ .edge-jump { fill:transparent; pointer-events:all; cursor:pointer; }
+ .node { cursor:pointer; }
+ .box { stroke:#758191; stroke-width:1; }
+ .node.held .box { stroke-dasharray:5 3; }
+ .node.near .box { stroke:#c18221; stroke-width:2; }
+ .node.focus .box { stroke:#9c4900; stroke-width:3; }
+ .node.selected .box { stroke:#1569b9; stroke-width:3; }
+ .node.folded .box { stroke-width:4; }
+ .node.folding .box { fill:#f4ccd7; }
+ .fold-tag { font-size:9px; font-weight:700; fill:#963751; }
+ .peep-area { fill:#fff3d9; fill-opacity:.8; stroke:#c18221; stroke-width:2; pointer-events:none; }
+ .node.peep-edit .box { stroke:#9c4900; stroke-width:3; }
+ .node.error .box { stroke:#b42318; stroke-width:4; }
+ #event.error { color:#b42318; font-weight:600; white-space:pre-wrap; overflow-wrap:anywhere; }
+ .peep-ghosts { pointer-events:none; }
+ .region-box { stroke:#9da9b8; stroke-width:1.5; }
+ .fold-btn { cursor:pointer; }
+ .fold-btn rect { fill:white; stroke:#596674; }
+ .fold-btn text { font-size:14px; fill:#152330; }
+ .fold-btn:focus rect { stroke:#1569b9; stroke-width:2; }
+ .shortcut { cursor:pointer; }
+ .shortcut path { fill:none; stroke-width:1.5; }
+ .shortcut rect { fill:#fff8ec; stroke:#b63838; stroke-dasharray:3 2; }
+ .shortcut text { font-size:11px; fill:#783030; }
+ .shortcut.selected rect, .shortcut:focus rect { stroke-width:2.5; }
+ .label { font-size:12px; fill:#152330; font-weight:600; }
+ .node-id { font-size:10px; fill:#596674; font-weight:400; }
+ .type { font-size:11px; fill:#455768; }
+ .port { stroke:#536477; stroke-width:1; }
+ .row { stroke:#b6afcf; stroke-width:1; }
+ .bind { font-size:12px; fill:#152330; }
+ .slot { font-size:10px; fill:#364352; paint-order:stroke; stroke:#fafbfc; stroke-width:3; }
+ #detail { position:absolute; top:8px; right:8px; margin:0; padding:12px; max-width:320px;
+ max-height:45%; overflow:auto; white-space:pre-wrap; overflow-wrap:anywhere;
+ background:#fffffff2; border:1px solid #bac5d0; border-radius:4px; font-size:12px; }
+ .controls { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:6px; padding:6px; }
+ .button { color:white; background:black; font-size:20px; min-width:30px; }
+ .button:disabled { background:grey; }
+ .count { font-size:20px; min-width:35px; text-align:center; }
+ #N { width:6ch; }
+ #scrub { width:clamp(120px,35vw,600px); }
+ </style><defs><marker id="arrow-CTRL" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#b63838"/></marker><marker id="arrow-DATA" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#536477"/></marker><marker id="arrow-MEM" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#2867b2"/></marker><marker id="arrow-ASSOC" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#9396a3"/></marker><marker id="arrow-PARSER" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#7956a5"/></marker></defs><rect width="100%" height="100%" fill="rgb(250, 251, 252)"/><g><g class="regions" style="opacity: 1;"><g class="region" transform="translate(144,171)"><rect class="region-box" rx="8" width="574" height="374" fill="#f2f7ef"/></g></g><rect class="peep-area" rx="36" style="opacity: 0;"/><g class="edges"><path class="edge CTRL" id="e3i0" d="M326,651 C326,675 380,678 380,702" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#3[0] → #18 · CTRL</title></path><path class="edge DATA" id="e7i1" d="M356,118 L356,128 L513,128 L513,291 L646,291 L646,343.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#7[1] → #4 · DATA</title></path><path class="edge DATA" id="e7i2" d="M676,118 L676,343.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#7[2] → #6 · DATA</title></path><path class="edge DATA" id="e9i1" d="M356,118 L356,128 L307,128 L307,225" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#9[1] → #4 · DATA</title></path><path class="edge DATA" id="e9i2" d="M84,118 L84,128 L226,128 L226,215 L337,215 L337,225" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#9[2] → #8 · DATA</title></path><path class="edge CTRL" id="e10i0" d="M236,118 L236,329" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#10[0] → #1 · CTRL</title></path><path class="edge DATA" id="e10i1" d="M307,281 L307,291 L316,291 L316,329" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#10[1] → #9 · DATA</title></path><path class="edge DATA" id="e15i1" d="M356,118 L356,128 L494,128 L494,343.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#15[1] → #4 · DATA</title></path><path class="edge DATA" id="e15i2" d="M524,118 L524,343.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#15[2] → #14 · DATA</title></path><path class="edge CTRL" id="e16i1" d="M216,429 L216,439 L306,439 L306,477" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#16[1] → #5 · CTRL</title></path><path class="edge CTRL" id="e16i2" d="M336,429 L336,477" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#16[2] → #11 · CTRL</title></path><path class="edge DATA" id="e17i1" d="M494,399.66666666666663 L494,439 L438,439 L438,477" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#17[1] → #15 · DATA</title></path><path class="edge DATA" id="e17i2" d="M646,399.66666666666663 L646,449 L478,449 L478,477" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#17[2] → #7 · DATA</title></path><path class="edge CTRL" id="e18i0" d="M306,533 L306,598" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#18[0] → #16 · CTRL</title></path><path class="edge DATA" id="e18i1" d="M458,533 L458,560 L346,560 L346,598" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#18[1] → #17 · DATA</title></path></g><g class="edge-hits"/><g class="parser" style="opacity: 1;"/><g class="nodes"><g class="node" id="n1" data-id="1" transform="translate(176,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>$ctrl</tspan><tspan class="node-id">  #1/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#1 $ctrl
+Projection 0 of #2
+Type not computed
+
+[0] → #2 CTRL</title></g><g class="node" id="n2" data-id="2" transform="translate(176,24)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>Start</tspan><tspan class="node-id">  #2</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#2 Start
+Type not computed
+
+</title></g><g class="node" id="n3" data-id="3" transform="translate(344,702)" style="opacity: 1;"><path class="box" d="M0,0H72V26H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="36" y="17"><tspan>Stop</tspan><tspan class="node-id">  #3</tspan></text><text class="type" text-anchor="middle" y="35" x="36"/><title>#3 Stop
+Type not computed
+
+[0] → #18 CTRL</title><circle class="port" cx="36" cy="0" r="3" fill="#536477"/><text class="slot" x="36" y="-7" text-anchor="middle">0</text></g><g class="node" id="n4" data-id="4" transform="translate(296,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>arg</tspan><tspan class="node-id">  #4/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#4 arg
+Projection 1 of #2
+Type not computed
+
+[0] → #2 DATA</title></g><g class="node" id="n5" data-id="5" transform="translate(156,379)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>True</tspan><tspan class="node-id">  #5/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#5 True
+Projection 0 of #10
+Type not computed
+
+[0] → #10 CTRL</title></g><g class="node" id="n6" data-id="6" transform="translate(616,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#2</tspan><tspan class="node-id">  #6</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#6 #2
+Type not computed
+
+</title></g><g class="node" id="n7" data-id="7" transform="translate(586,349.66666666666663)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #7</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#7 ==
+Type not computed
+
+[0] → — DATA
+[1] → #4 DATA
+[2] → #6 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n8" data-id="8" transform="translate(24,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#1</tspan><tspan class="node-id">  #8</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#8 #1
+Type not computed
+
+</title></g><g class="node" id="n9" data-id="9" transform="translate(247,231)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #9</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#9 ==
+Type not computed
+
+[0] → — DATA
+[1] → #4 DATA
+[2] → #8 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n10" data-id="10" transform="translate(156,335)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>If</tspan><tspan class="node-id">  #10</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#10 If
+Type not computed
+
+[0] → #1 CTRL
+[1] → #9 DATA</title><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><circle class="port" cx="160" cy="-3" r="3" fill="#536477"/><text class="slot" x="80" y="-10" text-anchor="middle">0</text><text class="slot" x="160" y="-10" text-anchor="middle">1</text></g><g class="node" id="n11" data-id="11" transform="translate(276,379)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>False</tspan><tspan class="node-id">  #11/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#11 False
+Projection 1 of #10
+Type not computed
+
+[0] → #10 CTRL</title></g><g class="node" id="n14" data-id="14" transform="translate(464,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#3</tspan><tspan class="node-id">  #14</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#14 #3
+Type not computed
+
+</title></g><g class="node" id="n15" data-id="15" transform="translate(434,349.66666666666663)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #15</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#15 ==
+Type not computed
+
+[0] → — DATA
+[1] → #4 DATA
+[2] → #14 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n16" data-id="16" transform="translate(246,483)" style="opacity: 1;"><path class="box" d="M12,0H108L120,44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Region</tspan><tspan class="node-id">  #16</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#16 Region
+Type not computed
+
+[0] → — DATA
+[1] → #5 CTRL
+[2] → #11 CTRL</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n17" data-id="17" transform="translate(398,483)" style="opacity: 1;"><path class="box" d="M12,0H108L120,22L108,44H12L0,22Z" fill="#f5e4fa"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>φ_a</tspan><tspan class="node-id">  #17</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#17 φ_a
+Type not computed
+
+[0] → #16 ASSOC
+[1] → #15 DATA
+[2] → #7 DATA</title><circle class="port" cx="-3" cy="22" r="3" fill="#536477"/><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><path class="reg" fill="none" stroke="#b63838" d="M-3,22H-18m4,-3l-4,3l4,3"><title>[0] → #16</title></path><text class="slot" x="-10" y="15" text-anchor="middle">0</text><text class="slot" x="40" y="-10" text-anchor="middle">1</text><text class="slot" x="80" y="-10" text-anchor="middle">2</text></g><g class="node" id="n18" data-id="18" transform="translate(266,604)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Return</tspan><tspan class="node-id">  #18</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#18 Return
+Type not computed
+
+[0] → #16 CTRL
+[1] → #17 DATA</title><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><text class="slot" x="40" y="-10" text-anchor="middle">0</text><text class="slot" x="80" y="-10" text-anchor="middle">1</text></g></g><g class="region-heads" style="opacity: 1;"><g class="region-head" transform="translate(144,171)"><text class="label" x="26" y="17"><tspan>If</tspan><tspan class="node-id">  #10</tspan></text><title>If · 8 nodes</title><g class="fold-btn" role="button" tabindex="0" transform="translate(4,4)" aria-label="Fold region #10"><rect width="16" height="16" rx="2"/><text x="8" y="12" text-anchor="middle">−</text><title>Fold region</title></g></g></g><g class="shortcuts" style="opacity: 1;"/><g class="peep-ghosts" pointer-events="none"/></g></svg>
diff --git a/chapter05/docs/05-graph5.json b/chapter05/docs/05-graph5.json
new file mode 100644
index 00000000..b9dc070b
--- /dev/null
+++ b/chapter05/docs/05-graph5.json
@@ -0,0 +1,27 @@
+{
+ "ver": 1,
+ "comp": "chapter05/docs/05-graph5.svg",
+ "step": 1,
+ "roots": [],
+ "scope": 0,
+ "nodes": [
+ {"id": 1, "label": "$ctrl", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 2, "role": "CTRL", "label": null}], "proj": {"par": 2, "idx": 0}},
+ {"id": 2, "label": "Start", "type": null, "kind": "CTRL", "edges": [], "proj": null},
+ {"id": 3, "label": "Stop", "type": null, "kind": "STOP", "edges": [{"idx": 0, "def": 21, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 4, "label": "arg", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 2, "role": "DATA", "label": null}], "proj": {"par": 2, "idx": 1}},
+ {"id": 5, "label": "True", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 10, "role": "CTRL", "label": null}], "proj": {"par": 10, "idx": 0}},
+ {"id": 6, "label": "#2", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 7, "label": "False", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 10, "role": "CTRL", "label": null}], "proj": {"par": 10, "idx": 1}},
+ {"id": 8, "label": "#1", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 9, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 4, "role": "DATA", "label": null}, {"idx": 2, "def": 8, "role": "DATA", "label": null}], "proj": null},
+ {"id": 10, "label": "If", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 1, "role": "CTRL", "label": null}, {"idx": 1, "def": 9, "role": "DATA", "label": null}], "proj": null},
+ {"id": 14, "label": "#3", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 16, "label": "Region", "type": null, "kind": "REGION", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 5, "role": "CTRL", "label": null}, {"idx": 2, "def": 7, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 19, "label": "φ_a", "type": null, "kind": "PHI", "edges": [{"idx": 0, "def": 16, "role": "ASSOC", "label": null}, {"idx": 1, "def": 14, "role": "DATA", "label": null}, {"idx": 2, "def": 6, "role": "DATA", "label": null}], "proj": null},
+ {"id": 20, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 4, "role": "DATA", "label": null}, {"idx": 2, "def": 19, "role": "DATA", "label": null}], "proj": null},
+ {"id": 21, "label": "Return", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 16, "role": "CTRL", "label": null}, {"idx": 1, "def": 20, "role": "DATA", "label": null}], "proj": null}
+ ],
+ "groups": [
+ {"id": 10, "par": 0, "nodes": [5, 7, 9, 10, 16, 19]}
+ ]
+}
diff --git a/chapter05/docs/05-graph5.svg b/chapter05/docs/05-graph5.svg
index 4f6fa4bd..4d137bda 100644
--- a/chapter05/docs/05-graph5.svg
+++ b/chapter05/docs/05-graph5.svg
@@ -1,196 +1,122 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Generated by graphviz version 2.43.0 (0)
- -->
-<!-- Title: chapter05 Pages: 1 -->
-<svg width="314pt" height="564pt"
- viewBox="0.00 0.00 314.00 564.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 560)">
-<title>chapter05</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-560 310,-560 310,4 -4,4"/>
-<g id="clust1" class="cluster">
-<title>cluster_Nodes</title>
-<polygon fill="none" stroke="black" points="8,-8 8,-548 298,-548 298,-8 8,-8"/>
-</g>
-<!-- Start2 -->
-<g id="node1" class="node">
-<title>Start2</title>
-<polygon fill="yellow" stroke="transparent" points="97,-511 97,-536 178,-536 178,-511 97,-511"/>
-<polygon fill="none" stroke="black" points="97,-511 97,-536 178,-536 178,-511 97,-511"/>
-<text text-anchor="start" x="119" y="-519.8" font-family="Times,serif" font-size="14.00">Start</text>
-<polygon fill="none" stroke="black" points="97,-480 97,-511 178,-511 178,-480 97,-480"/>
-<polygon fill="yellow" stroke="transparent" points="102,-485 102,-506 142,-506 142,-485 102,-485"/>
-<polygon fill="none" stroke="black" points="102,-485 102,-506 142,-506 142,-485 102,-485"/>
-<text text-anchor="start" x="105" y="-491.8" font-family="Times,serif" font-size="14.00">$ctrl</text>
-<polygon fill="none" stroke="black" points="142,-485 142,-506 173,-506 173,-485 142,-485"/>
-<text text-anchor="start" x="145" y="-491.8" font-family="Times,serif" font-size="14.00">arg</text>
-</g>
-<!-- Stop3 -->
-<g id="node2" class="node">
-<title>Stop3</title>
-<polygon fill="yellow" stroke="black" points="148,-52 94,-52 94,-16 148,-16 148,-52"/>
-<text text-anchor="middle" x="121" y="-30.3" font-family="Times,serif" font-size="14.00">Stop</text>
-</g>
-<!-- Return21 -->
-<g id="node11" class="node">
-<title>Return21</title>
-<polygon fill="yellow" stroke="black" points="154,-124 88,-124 88,-88 154,-88 154,-124"/>
-<text text-anchor="middle" x="121" y="-102.3" font-family="Times,serif" font-size="14.00">Return</text>
-</g>
-<!-- Stop3&#45;&gt;Return21 -->
-<g id="edge1" class="edge">
-<title>Stop3&#45;&gt;Return21</title>
-<path fill="none" stroke="red" d="M121,-52.3C121,-60.02 121,-69.29 121,-77.89"/>
-<polygon fill="red" stroke="red" points="117.5,-77.9 121,-87.9 124.5,-77.9 117.5,-77.9"/>
-<text text-anchor="middle" x="118" y="-54.9" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Con_6 -->
-<g id="node3" class="node">
-<title>Con_6</title>
-<ellipse fill="none" stroke="black" cx="263" cy="-336" rx="27" ry="18"/>
-<text text-anchor="middle" x="263" y="-332.3" font-family="Times,serif" font-size="14.00">#2</text>
-</g>
-<!-- Con_8 -->
-<g id="node4" class="node">
-<title>Con_8</title>
-<ellipse fill="none" stroke="black" cx="43" cy="-508" rx="27" ry="18"/>
-<text text-anchor="middle" x="43" y="-504.3" font-family="Times,serif" font-size="14.00">#1</text>
-</g>
-<!-- EQNode9 -->
-<g id="node5" class="node">
-<title>EQNode9</title>
-<ellipse fill="none" stroke="black" cx="71" cy="-422" rx="27" ry="18"/>
-<text text-anchor="middle" x="71" y="-418.3" font-family="Times,serif" font-size="14.00">==</text>
-</g>
-<!-- EQNode9&#45;&gt;Start2 -->
-<g id="edge2" class="edge">
-<title>EQNode9&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M92.51,-433.05C113.44,-443.41 143.59,-460.03 154.16,-474.46"/>
-<polygon fill="black" stroke="black" points="151.02,-476.03 158,-484 157.51,-473.42 151.02,-476.03"/>
-<text text-anchor="middle" x="89.51" y="-435.65" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode9&#45;&gt;Con_8 -->
-<g id="edge3" class="edge">
-<title>EQNode9&#45;&gt;Con_8</title>
-<path fill="none" stroke="black" d="M65.33,-440C61.44,-451.69 56.19,-467.44 51.76,-480.73"/>
-<polygon fill="black" stroke="black" points="48.4,-479.72 48.56,-490.31 55.04,-481.93 48.4,-479.72"/>
-<text text-anchor="middle" x="62.33" y="-442.6" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- If10 -->
-<g id="node6" class="node">
-<title>If10</title>
-<polygon fill="yellow" stroke="transparent" points="24,-339 24,-364 118,-364 118,-339 24,-339"/>
-<polygon fill="none" stroke="black" points="24,-339 24,-364 118,-364 118,-339 24,-339"/>
-<text text-anchor="start" x="65.5" y="-347.8" font-family="Times,serif" font-size="14.00">If</text>
-<polygon fill="none" stroke="black" points="24,-308 24,-339 118,-339 118,-308 24,-308"/>
-<polygon fill="yellow" stroke="transparent" points="29,-313 29,-334 69,-334 69,-313 29,-313"/>
-<polygon fill="none" stroke="black" points="29,-313 29,-334 69,-334 69,-313 29,-313"/>
-<text text-anchor="start" x="32" y="-319.8" font-family="Times,serif" font-size="14.00">True</text>
-<polygon fill="yellow" stroke="transparent" points="69,-313 69,-334 113,-334 113,-313 69,-313"/>
-<polygon fill="none" stroke="black" points="69,-313 69,-334 113,-334 113,-313 69,-313"/>
-<text text-anchor="start" x="72" y="-319.8" font-family="Times,serif" font-size="14.00">False</text>
-</g>
-<!-- If10&#45;&gt;Start2 -->
-<g id="edge4" class="edge">
-<title>If10&#45;&gt;Start2:p0</title>
-<path fill="none" stroke="red" d="M90.29,-368.12C96.41,-379.12 102.69,-391.8 107,-404 117.81,-434.65 121.3,-445.6 121.9,-473.74"/>
-<polygon fill="red" stroke="red" points="118.4,-474.03 122,-484 125.4,-473.97 118.4,-474.03"/>
-<text text-anchor="middle" x="87.29" y="-370.72" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- If10&#45;&gt;EQNode9 -->
-<g id="edge5" class="edge">
-<title>If10&#45;&gt;EQNode9</title>
-<path fill="none" stroke="black" d="M71,-368.28C71,-376.58 71,-385.48 71,-393.56"/>
-<polygon fill="black" stroke="black" points="67.5,-393.6 71,-403.6 74.5,-393.6 67.5,-393.6"/>
-<text text-anchor="middle" x="68" y="-370.88" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Con_14 -->
-<g id="node7" class="node">
-<title>Con_14</title>
-<ellipse fill="none" stroke="black" cx="191" cy="-336" rx="27" ry="18"/>
-<text text-anchor="middle" x="191" y="-332.3" font-family="Times,serif" font-size="14.00">#3</text>
-</g>
-<!-- Region16 -->
-<g id="node8" class="node">
-<title>Region16</title>
-<polygon fill="yellow" stroke="black" points="125,-268 59,-268 59,-232 125,-232 125,-268"/>
-<text text-anchor="middle" x="92" y="-246.3" font-family="Times,serif" font-size="14.00">Region</text>
-</g>
-<!-- Region16&#45;&gt;If10 -->
-<g id="edge6" class="edge">
-<title>Region16&#45;&gt;If10:p0</title>
-<path fill="none" stroke="red" d="M71.51,-268.03C62.68,-276.94 53.63,-288.71 50.32,-301.78"/>
-<polygon fill="red" stroke="red" points="46.81,-301.63 49,-312 53.75,-302.53 46.81,-301.63"/>
-<text text-anchor="middle" x="68.51" y="-270.63" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Region16&#45;&gt;If10 -->
-<g id="edge7" class="edge">
-<title>Region16&#45;&gt;If10:p1</title>
-<path fill="none" stroke="red" d="M91.57,-268.09C91.36,-277.55 91.13,-289.77 91.04,-301.69"/>
-<polygon fill="red" stroke="red" points="87.54,-301.99 91,-312 94.54,-302.01 87.54,-301.99"/>
-<text text-anchor="middle" x="88.57" y="-270.69" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a19 -->
-<g id="node9" class="node">
-<title>Phi_a19</title>
-<ellipse fill="lightyellow" stroke="black" cx="191" cy="-250" rx="27" ry="18"/>
-<text text-anchor="middle" x="191" y="-246.3" font-family="Times,serif" font-size="14.00">φ_a</text>
-</g>
-<!-- Phi_a19&#45;&gt;Con_6 -->
-<g id="edge10" class="edge">
-<title>Phi_a19&#45;&gt;Con_6</title>
-<path fill="none" stroke="black" d="M203.87,-266.02C214.93,-278.92 231.04,-297.71 243.65,-312.42"/>
-<polygon fill="black" stroke="black" points="241.07,-314.8 250.24,-320.11 246.39,-310.24 241.07,-314.8"/>
-<text text-anchor="middle" x="200.87" y="-268.62" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a19&#45;&gt;Con_14 -->
-<g id="edge9" class="edge">
-<title>Phi_a19&#45;&gt;Con_14</title>
-<path fill="none" stroke="black" d="M191,-268.4C191,-279.74 191,-294.77 191,-307.68"/>
-<polygon fill="black" stroke="black" points="187.5,-307.9 191,-317.9 194.5,-307.9 187.5,-307.9"/>
-<text text-anchor="middle" x="188" y="-271" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Phi_a19&#45;&gt;Region16 -->
-<g id="edge8" class="edge">
-<title>Phi_a19&#45;&gt;Region16</title>
-<path fill="none" stroke="black" stroke-dasharray="1,5" d="M163.78,-250C154.35,-250 144.92,-250 135.49,-250"/>
-<polygon fill="black" stroke="black" points="135.26,-246.5 125.26,-250 135.26,-253.5 135.26,-246.5"/>
-<text text-anchor="middle" x="160.78" y="-243.6" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- EQNode20 -->
-<g id="node10" class="node">
-<title>EQNode20</title>
-<ellipse fill="none" stroke="black" cx="145" cy="-178" rx="27" ry="18"/>
-<text text-anchor="middle" x="145" y="-174.3" font-family="Times,serif" font-size="14.00">==</text>
-</g>
-<!-- EQNode20&#45;&gt;Start2 -->
-<g id="edge11" class="edge">
-<title>EQNode20&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M145.93,-196.36C148.75,-249.2 157.02,-408.5 157.92,-473.67"/>
-<polygon fill="black" stroke="black" points="154.42,-474.03 158,-484 161.42,-473.97 154.42,-474.03"/>
-<text text-anchor="middle" x="142.93" y="-198.96" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode20&#45;&gt;Phi_a19 -->
-<g id="edge12" class="edge">
-<title>EQNode20&#45;&gt;Phi_a19</title>
-<path fill="none" stroke="black" d="M155.44,-194.88C161.2,-203.66 168.48,-214.74 174.96,-224.58"/>
-<polygon fill="black" stroke="black" points="172.19,-226.74 180.6,-233.18 178.04,-222.9 172.19,-226.74"/>
-<text text-anchor="middle" x="152.44" y="-197.48" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Return21&#45;&gt;Region16 -->
-<g id="edge13" class="edge">
-<title>Return21&#45;&gt;Region16</title>
-<path fill="none" stroke="red" d="M116.96,-124.15C114.56,-134.51 111.51,-147.99 109,-160 104.69,-180.66 100.23,-204.11 96.96,-221.75"/>
-<polygon fill="red" stroke="red" points="93.46,-221.44 95.09,-231.9 100.34,-222.7 93.46,-221.44"/>
-<text text-anchor="middle" x="113.96" y="-126.75" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Return21&#45;&gt;EQNode20 -->
-<g id="edge14" class="edge">
-<title>Return21&#45;&gt;EQNode20</title>
-<path fill="none" stroke="black" d="M126.93,-124.3C129.68,-132.3 132.99,-141.98 136.03,-150.85"/>
-<polygon fill="black" stroke="black" points="132.75,-152.05 139.3,-160.38 139.37,-149.78 132.75,-152.05"/>
-<text text-anchor="middle" x="123.93" y="-126.9" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-</g>
-</svg>
+<svg aria-label="Compiler graph" width="793" height="838" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 793 838" style="font-family: sans-serif;"><style>
+ html, body { height:100%; margin:0; font-family:sans-serif; }
+ .viewer { height:100%; display:grid; grid-template-rows:auto minmax(0,1fr) auto; }
+ .source { padding:8px; border-bottom:1px solid #ccc; }
+ #program { width:min(600px,80vw); vertical-align:middle; }
+ #status { margin-top:4px; }
+ #graph { min-height:0; overflow:hidden; position:relative; background:#fafbfc; }
+ #elk { width:100%; height:100%; }
+ #graph svg { display:block; }
+ .tools { display:flex; flex-wrap:wrap; align-items:center; gap:14px; margin-top:8px; font-size:12px; }
+ .hint { color:#616c78; }
+ .ctrl { color:#b63838; } .mem { color:#2867b2; } .data { color:#536477; }
+ .edge { fill:none; stroke-width:1.5; }
+ .edge.CTRL { stroke-width:2; }
+ .edge.ASSOC { stroke-dasharray:4 4; }
+ .edge.PARSER { stroke-dasharray:5 4; }
+ .parser rect { fill:#f6f0ff; stroke:#7956a5; stroke-width:1.5; stroke-dasharray:5 4; }
+ .edge.selected { stroke-width:3.5; }
+ .edge.bundle { stroke-width:4; }
+ .edge.bundle.selected { stroke-width:6; }
+ .edge-hit { fill:none; stroke:transparent; stroke-width:12; vector-effect:non-scaling-stroke; pointer-events:stroke; cursor:pointer; }
+ .edge-jump { fill:transparent; pointer-events:all; cursor:pointer; }
+ .node { cursor:pointer; }
+ .box { stroke:#758191; stroke-width:1; }
+ .node.held .box { stroke-dasharray:5 3; }
+ .node.near .box { stroke:#c18221; stroke-width:2; }
+ .node.focus .box { stroke:#9c4900; stroke-width:3; }
+ .node.selected .box { stroke:#1569b9; stroke-width:3; }
+ .node.folded .box { stroke-width:4; }
+ .node.folding .box { fill:#f4ccd7; }
+ .fold-tag { font-size:9px; font-weight:700; fill:#963751; }
+ .peep-area { fill:#fff3d9; fill-opacity:.8; stroke:#c18221; stroke-width:2; pointer-events:none; }
+ .node.peep-edit .box { stroke:#9c4900; stroke-width:3; }
+ .node.error .box { stroke:#b42318; stroke-width:4; }
+ #event.error { color:#b42318; font-weight:600; white-space:pre-wrap; overflow-wrap:anywhere; }
+ .peep-ghosts { pointer-events:none; }
+ .region-box { stroke:#9da9b8; stroke-width:1.5; }
+ .fold-btn { cursor:pointer; }
+ .fold-btn rect { fill:white; stroke:#596674; }
+ .fold-btn text { font-size:14px; fill:#152330; }
+ .fold-btn:focus rect { stroke:#1569b9; stroke-width:2; }
+ .shortcut { cursor:pointer; }
+ .shortcut path { fill:none; stroke-width:1.5; }
+ .shortcut rect { fill:#fff8ec; stroke:#b63838; stroke-dasharray:3 2; }
+ .shortcut text { font-size:11px; fill:#783030; }
+ .shortcut.selected rect, .shortcut:focus rect { stroke-width:2.5; }
+ .label { font-size:12px; fill:#152330; font-weight:600; }
+ .node-id { font-size:10px; fill:#596674; font-weight:400; }
+ .type { font-size:11px; fill:#455768; }
+ .port { stroke:#536477; stroke-width:1; }
+ .row { stroke:#b6afcf; stroke-width:1; }
+ .bind { font-size:12px; fill:#152330; }
+ .slot { font-size:10px; fill:#364352; paint-order:stroke; stroke:#fafbfc; stroke-width:3; }
+ #detail { position:absolute; top:8px; right:8px; margin:0; padding:12px; max-width:320px;
+ max-height:45%; overflow:auto; white-space:pre-wrap; overflow-wrap:anywhere;
+ background:#fffffff2; border:1px solid #bac5d0; border-radius:4px; font-size:12px; }
+ .controls { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:6px; padding:6px; }
+ .button { color:white; background:black; font-size:20px; min-width:30px; }
+ .button:disabled { background:grey; }
+ .count { font-size:20px; min-width:35px; text-align:center; }
+ #N { width:6ch; }
+ #scrub { width:clamp(120px,35vw,600px); }
+ </style><defs><marker id="arrow-CTRL" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#b63838"/></marker><marker id="arrow-DATA" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#536477"/></marker><marker id="arrow-MEM" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#2867b2"/></marker><marker id="arrow-ASSOC" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#9396a3"/></marker><marker id="arrow-PARSER" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#7956a5"/></marker></defs><rect width="100%" height="100%" fill="rgb(250, 251, 252)"/><g><g class="regions" style="opacity: 1;"><g class="region" transform="translate(35,173)"><rect class="region-box" rx="8" width="360" height="354" fill="#f2f7ef"/></g></g><rect class="peep-area" rx="36" style="opacity: 0;"/><g class="edges"><path class="edge CTRL" id="e3i0" d="M191,737 C191,761 396.5,764 396.5,788" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#3[0] → #21 · CTRL</title></path><path class="edge DATA" id="e9i1" d="M247,118 L247,128 L207,128 L207,207" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#9[1] → #4 · DATA</title></path><path class="edge DATA" id="e9i2" d="M405,118 L405,138 L237,138 L237,207" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#9[2] → #8 · DATA</title></path><path class="edge CTRL" id="e10i0" d="M127,118 L127,311" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#10[0] → #1 · CTRL</title></path><path class="edge DATA" id="e10i1" d="M207,263 L207,311" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#10[1] → #9 · DATA</title></path><path class="edge CTRL" id="e16i1" d="M107,411 L107,421 L171,421 L171,459" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#16[1] → #5 · CTRL</title></path><path class="edge CTRL" id="e16i2" d="M227,411 L227,421 L201,421 L201,459" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#16[2] → #7 · CTRL</title></path><path class="edge DATA" id="e19i1" d="M557,118 L557,148 L303,148 L303,459" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#19[1] → #14 · DATA</title></path><path class="edge DATA" id="e19i2" d="M709,118 L709,158 L343,158 L343,459" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#19[2] → #6 · DATA</title></path><path class="edge DATA" id="e20i1" d="M247,118 L247,128 L24,128 L24,542 L242,542 L242,580" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#20[1] → #4 · DATA</title></path><path class="edge DATA" id="e20i2" d="M323,515 L323,542 L272,542 L272,580" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#20[2] → #19 · DATA</title></path><path class="edge CTRL" id="e21i0" d="M171,515 L171,684" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#21[0] → #16 · CTRL</title></path><path class="edge DATA" id="e21i1" d="M242,636 L242,646 L211,646 L211,684" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#21[1] → #20 · DATA</title></path></g><g class="edge-hits"/><g class="parser" style="opacity: 1;"/><g class="nodes"><g class="node" id="n1" data-id="1" transform="translate(67,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>$ctrl</tspan><tspan class="node-id">  #1/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#1 $ctrl
+Projection 0 of #2
+Type not computed
+
+[0] → #2 CTRL</title></g><g class="node" id="n2" data-id="2" transform="translate(67,24)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>Start</tspan><tspan class="node-id">  #2</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#2 Start
+Type not computed
+
+</title></g><g class="node" id="n3" data-id="3" transform="translate(360.5,788)" style="opacity: 1;"><path class="box" d="M0,0H72V26H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="36" y="17"><tspan>Stop</tspan><tspan class="node-id">  #3</tspan></text><text class="type" text-anchor="middle" y="35" x="36"/><title>#3 Stop
+Type not computed
+
+[0] → #21 CTRL</title><circle class="port" cx="36" cy="0" r="3" fill="#536477"/><text class="slot" x="36" y="-7" text-anchor="middle">0</text></g><g class="node" id="n4" data-id="4" transform="translate(187,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>arg</tspan><tspan class="node-id">  #4/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#4 arg
+Projection 1 of #2
+Type not computed
+
+[0] → #2 DATA</title></g><g class="node" id="n5" data-id="5" transform="translate(47,361)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>True</tspan><tspan class="node-id">  #5/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#5 True
+Projection 0 of #10
+Type not computed
+
+[0] → #10 CTRL</title></g><g class="node" id="n6" data-id="6" transform="translate(649,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#2</tspan><tspan class="node-id">  #6</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#6 #2
+Type not computed
+
+</title></g><g class="node" id="n7" data-id="7" transform="translate(167,361)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>False</tspan><tspan class="node-id">  #7/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#7 False
+Projection 1 of #10
+Type not computed
+
+[0] → #10 CTRL</title></g><g class="node" id="n8" data-id="8" transform="translate(345,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#1</tspan><tspan class="node-id">  #8</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#8 #1
+Type not computed
+
+</title></g><g class="node" id="n9" data-id="9" transform="translate(147,213)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #9</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#9 ==
+Type not computed
+
+[0] → — DATA
+[1] → #4 DATA
+[2] → #8 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n10" data-id="10" transform="translate(47,317)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>If</tspan><tspan class="node-id">  #10</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#10 If
+Type not computed
+
+[0] → #1 CTRL
+[1] → #9 DATA</title><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><circle class="port" cx="160" cy="-3" r="3" fill="#536477"/><text class="slot" x="80" y="-10" text-anchor="middle">0</text><text class="slot" x="160" y="-10" text-anchor="middle">1</text></g><g class="node" id="n14" data-id="14" transform="translate(497,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#3</tspan><tspan class="node-id">  #14</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#14 #3
+Type not computed
+
+</title></g><g class="node" id="n16" data-id="16" transform="translate(111,465)" style="opacity: 1;"><path class="box" d="M12,0H108L120,44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Region</tspan><tspan class="node-id">  #16</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#16 Region
+Type not computed
+
+[0] → — DATA
+[1] → #5 CTRL
+[2] → #7 CTRL</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n19" data-id="19" transform="translate(263,465)" style="opacity: 1;"><path class="box" d="M12,0H108L120,22L108,44H12L0,22Z" fill="#f5e4fa"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>φ_a</tspan><tspan class="node-id">  #19</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#19 φ_a
+Type not computed
+
+[0] → #16 ASSOC
+[1] → #14 DATA
+[2] → #6 DATA</title><circle class="port" cx="-3" cy="22" r="3" fill="#536477"/><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><path class="reg" fill="none" stroke="#b63838" d="M-3,22H-18m4,-3l-4,3l4,3"><title>[0] → #16</title></path><text class="slot" x="-10" y="15" text-anchor="middle">0</text><text class="slot" x="40" y="-10" text-anchor="middle">1</text><text class="slot" x="80" y="-10" text-anchor="middle">2</text></g><g class="node" id="n20" data-id="20" transform="translate(182,586)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #20</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#20 ==
+Type not computed
+
+[0] → — DATA
+[1] → #4 DATA
+[2] → #19 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n21" data-id="21" transform="translate(131,690)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Return</tspan><tspan class="node-id">  #21</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#21 Return
+Type not computed
+
+[0] → #16 CTRL
+[1] → #20 DATA</title><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><text class="slot" x="40" y="-10" text-anchor="middle">0</text><text class="slot" x="80" y="-10" text-anchor="middle">1</text></g></g><g class="region-heads" style="opacity: 1;"><g class="region-head" transform="translate(35,173)"><text class="label" x="26" y="17"><tspan>If</tspan><tspan class="node-id">  #10</tspan></text><title>If · 6 nodes</title><g class="fold-btn" role="button" tabindex="0" transform="translate(4,4)" aria-label="Fold region #10"><rect width="16" height="16" rx="2"/><text x="8" y="12" text-anchor="middle">−</text><title>Fold region</title></g></g></g><g class="shortcuts" style="opacity: 1;"/><g class="peep-ghosts" pointer-events="none"/></g></svg>
diff --git a/chapter05/docs/05-graph6.json b/chapter05/docs/05-graph6.json
new file mode 100644
index 00000000..1039bb08
--- /dev/null
+++ b/chapter05/docs/05-graph6.json
@@ -0,0 +1,26 @@
+{
+ "ver": 1,
+ "comp": "chapter05/docs/05-graph6.svg",
+ "step": 1,
+ "roots": [],
+ "scope": 0,
+ "nodes": [
+ {"id": 1, "label": "$ctrl", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 2, "role": "CTRL", "label": null}], "proj": {"par": 2, "idx": 0}},
+ {"id": 2, "label": "Start", "type": null, "kind": "CTRL", "edges": [], "proj": null},
+ {"id": 3, "label": "Stop", "type": null, "kind": "STOP", "edges": [{"idx": 0, "def": 19, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 4, "label": "arg", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 2, "role": "DATA", "label": null}], "proj": {"par": 2, "idx": 1}},
+ {"id": 5, "label": "True", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 10, "role": "CTRL", "label": null}], "proj": {"par": 10, "idx": 0}},
+ {"id": 6, "label": "#3", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 7, "label": "False", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 10, "role": "CTRL", "label": null}], "proj": {"par": 10, "idx": 1}},
+ {"id": 8, "label": "#1", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 9, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 4, "role": "DATA", "label": null}, {"idx": 2, "def": 8, "role": "DATA", "label": null}], "proj": null},
+ {"id": 10, "label": "If", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 1, "role": "CTRL", "label": null}, {"idx": 1, "def": 9, "role": "DATA", "label": null}], "proj": null},
+ {"id": 15, "label": "#4", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 16, "label": "Region", "type": null, "kind": "REGION", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 5, "role": "CTRL", "label": null}, {"idx": 2, "def": 7, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 17, "label": "φ_c", "type": null, "kind": "PHI", "edges": [{"idx": 0, "def": 16, "role": "ASSOC", "label": null}, {"idx": 1, "def": 15, "role": "DATA", "label": null}, {"idx": 2, "def": 6, "role": "DATA", "label": null}], "proj": null},
+ {"id": 19, "label": "Return", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 16, "role": "CTRL", "label": null}, {"idx": 1, "def": 17, "role": "DATA", "label": null}], "proj": null}
+ ],
+ "groups": [
+ {"id": 10, "par": 0, "nodes": [5, 7, 9, 10, 16, 17]}
+ ]
+}
diff --git a/chapter05/docs/05-graph6.svg b/chapter05/docs/05-graph6.svg
index 71527d7f..831a6a07 100644
--- a/chapter05/docs/05-graph6.svg
+++ b/chapter05/docs/05-graph6.svg
@@ -1,176 +1,117 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Generated by graphviz version 2.43.0 (0)
- -->
-<!-- Title: chapter05 Pages: 1 -->
-<svg width="294pt" height="492pt"
- viewBox="0.00 0.00 294.00 492.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 488)">
-<title>chapter05</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-488 290,-488 290,4 -4,4"/>
-<g id="clust1" class="cluster">
-<title>cluster_Nodes</title>
-<polygon fill="none" stroke="black" points="8,-8 8,-476 278,-476 278,-8 8,-8"/>
-</g>
-<!-- Start2 -->
-<g id="node1" class="node">
-<title>Start2</title>
-<polygon fill="yellow" stroke="transparent" points="109,-439 109,-464 190,-464 190,-439 109,-439"/>
-<polygon fill="none" stroke="black" points="109,-439 109,-464 190,-464 190,-439 109,-439"/>
-<text text-anchor="start" x="131" y="-447.8" font-family="Times,serif" font-size="14.00">Start</text>
-<polygon fill="none" stroke="black" points="109,-408 109,-439 190,-439 190,-408 109,-408"/>
-<polygon fill="yellow" stroke="transparent" points="114,-413 114,-434 154,-434 154,-413 114,-413"/>
-<polygon fill="none" stroke="black" points="114,-413 114,-434 154,-434 154,-413 114,-413"/>
-<text text-anchor="start" x="117" y="-419.8" font-family="Times,serif" font-size="14.00">$ctrl</text>
-<polygon fill="none" stroke="black" points="154,-413 154,-434 185,-434 185,-413 154,-413"/>
-<text text-anchor="start" x="157" y="-419.8" font-family="Times,serif" font-size="14.00">arg</text>
-</g>
-<!-- Stop3 -->
-<g id="node2" class="node">
-<title>Stop3</title>
-<polygon fill="yellow" stroke="black" points="181,-52 127,-52 127,-16 181,-16 181,-52"/>
-<text text-anchor="middle" x="154" y="-30.3" font-family="Times,serif" font-size="14.00">Stop</text>
-</g>
-<!-- Return19 -->
-<g id="node10" class="node">
-<title>Return19</title>
-<polygon fill="yellow" stroke="black" points="187,-124 121,-124 121,-88 187,-88 187,-124"/>
-<text text-anchor="middle" x="154" y="-102.3" font-family="Times,serif" font-size="14.00">Return</text>
-</g>
-<!-- Stop3&#45;&gt;Return19 -->
-<g id="edge1" class="edge">
-<title>Stop3&#45;&gt;Return19</title>
-<path fill="none" stroke="red" d="M154,-52.3C154,-60.02 154,-69.29 154,-77.89"/>
-<polygon fill="red" stroke="red" points="150.5,-77.9 154,-87.9 157.5,-77.9 150.5,-77.9"/>
-<text text-anchor="middle" x="151" y="-54.9" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Con_6 -->
-<g id="node3" class="node">
-<title>Con_6</title>
-<ellipse fill="none" stroke="black" cx="43" cy="-264" rx="27" ry="18"/>
-<text text-anchor="middle" x="43" y="-260.3" font-family="Times,serif" font-size="14.00">#3</text>
-</g>
-<!-- Con_8 -->
-<g id="node4" class="node">
-<title>Con_8</title>
-<ellipse fill="none" stroke="black" cx="243" cy="-436" rx="27" ry="18"/>
-<text text-anchor="middle" x="243" y="-432.3" font-family="Times,serif" font-size="14.00">#1</text>
-</g>
-<!-- EQNode9 -->
-<g id="node5" class="node">
-<title>EQNode9</title>
-<ellipse fill="none" stroke="black" cx="215" cy="-350" rx="27" ry="18"/>
-<text text-anchor="middle" x="215" y="-346.3" font-family="Times,serif" font-size="14.00">==</text>
-</g>
-<!-- EQNode9&#45;&gt;Start2 -->
-<g id="edge2" class="edge">
-<title>EQNode9&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M197.73,-364.01C187.32,-373.17 175.33,-386.49 171.36,-401.73"/>
-<polygon fill="black" stroke="black" points="167.84,-401.63 170,-412 174.78,-402.54 167.84,-401.63"/>
-<text text-anchor="middle" x="194.73" y="-366.61" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode9&#45;&gt;Con_8 -->
-<g id="edge3" class="edge">
-<title>EQNode9&#45;&gt;Con_8</title>
-<path fill="none" stroke="black" d="M220.67,-368C224.56,-379.69 229.81,-395.44 234.24,-408.73"/>
-<polygon fill="black" stroke="black" points="230.96,-409.93 237.44,-418.31 237.6,-407.72 230.96,-409.93"/>
-<text text-anchor="middle" x="217.67" y="-370.6" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- If10 -->
-<g id="node6" class="node">
-<title>If10</title>
-<polygon fill="yellow" stroke="transparent" points="168,-267 168,-292 262,-292 262,-267 168,-267"/>
-<polygon fill="none" stroke="black" points="168,-267 168,-292 262,-292 262,-267 168,-267"/>
-<text text-anchor="start" x="209.5" y="-275.8" font-family="Times,serif" font-size="14.00">If</text>
-<polygon fill="none" stroke="black" points="168,-236 168,-267 262,-267 262,-236 168,-236"/>
-<polygon fill="yellow" stroke="transparent" points="173,-241 173,-262 213,-262 213,-241 173,-241"/>
-<polygon fill="none" stroke="black" points="173,-241 173,-262 213,-262 213,-241 173,-241"/>
-<text text-anchor="start" x="176" y="-247.8" font-family="Times,serif" font-size="14.00">True</text>
-<polygon fill="yellow" stroke="transparent" points="213,-241 213,-262 257,-262 257,-241 213,-241"/>
-<polygon fill="none" stroke="black" points="213,-241 213,-262 257,-262 257,-241 213,-241"/>
-<text text-anchor="start" x="216" y="-247.8" font-family="Times,serif" font-size="14.00">False</text>
-</g>
-<!-- If10&#45;&gt;Start2 -->
-<g id="edge4" class="edge">
-<title>If10&#45;&gt;Start2:p0</title>
-<path fill="none" stroke="red" d="M185.76,-296.14C164.32,-322.05 138.32,-361.17 134.48,-401.9"/>
-<polygon fill="red" stroke="red" points="130.98,-401.84 134,-412 137.97,-402.18 130.98,-401.84"/>
-<text text-anchor="middle" x="182.76" y="-298.74" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- If10&#45;&gt;EQNode9 -->
-<g id="edge5" class="edge">
-<title>If10&#45;&gt;EQNode9</title>
-<path fill="none" stroke="black" d="M215,-296.28C215,-304.58 215,-313.48 215,-321.56"/>
-<polygon fill="black" stroke="black" points="211.5,-321.6 215,-331.6 218.5,-321.6 211.5,-321.6"/>
-<text text-anchor="middle" x="212" y="-298.88" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Con_15 -->
-<g id="node7" class="node">
-<title>Con_15</title>
-<ellipse fill="none" stroke="black" cx="115" cy="-264" rx="27" ry="18"/>
-<text text-anchor="middle" x="115" y="-260.3" font-family="Times,serif" font-size="14.00">#4</text>
-</g>
-<!-- Region16 -->
-<g id="node8" class="node">
-<title>Region16</title>
-<polygon fill="yellow" stroke="black" points="226,-196 160,-196 160,-160 226,-160 226,-196"/>
-<text text-anchor="middle" x="193" y="-174.3" font-family="Times,serif" font-size="14.00">Region</text>
-</g>
-<!-- Region16&#45;&gt;If10 -->
-<g id="edge6" class="edge">
-<title>Region16&#45;&gt;If10:p0</title>
-<path fill="none" stroke="red" d="M193,-196.09C193,-205.55 193,-217.77 193,-229.69"/>
-<polygon fill="red" stroke="red" points="189.5,-230 193,-240 196.5,-230 189.5,-230"/>
-<text text-anchor="middle" x="190" y="-198.69" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Region16&#45;&gt;If10 -->
-<g id="edge7" class="edge">
-<title>Region16&#45;&gt;If10:p1</title>
-<path fill="none" stroke="red" d="M213.02,-196.12C221.64,-205.06 230.48,-216.84 233.71,-229.84"/>
-<polygon fill="red" stroke="red" points="230.27,-230.52 235,-240 237.22,-229.64 230.27,-230.52"/>
-<text text-anchor="middle" x="210.02" y="-198.72" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_c17 -->
-<g id="node9" class="node">
-<title>Phi_c17</title>
-<ellipse fill="lightyellow" stroke="black" cx="115" cy="-178" rx="27" ry="18"/>
-<text text-anchor="middle" x="115" y="-174.3" font-family="Times,serif" font-size="14.00">φ_c</text>
-</g>
-<!-- Phi_c17&#45;&gt;Con_6 -->
-<g id="edge10" class="edge">
-<title>Phi_c17&#45;&gt;Con_6</title>
-<path fill="none" stroke="black" d="M102.13,-194.02C91.07,-206.92 74.96,-225.71 62.35,-240.42"/>
-<polygon fill="black" stroke="black" points="59.61,-238.24 55.76,-248.11 64.93,-242.8 59.61,-238.24"/>
-<text text-anchor="middle" x="99.13" y="-196.62" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_c17&#45;&gt;Con_15 -->
-<g id="edge9" class="edge">
-<title>Phi_c17&#45;&gt;Con_15</title>
-<path fill="none" stroke="black" d="M115,-196.4C115,-207.74 115,-222.77 115,-235.68"/>
-<polygon fill="black" stroke="black" points="111.5,-235.9 115,-245.9 118.5,-235.9 111.5,-235.9"/>
-<text text-anchor="middle" x="112" y="-199" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Phi_c17&#45;&gt;Region16 -->
-<g id="edge8" class="edge">
-<title>Phi_c17&#45;&gt;Region16</title>
-<path fill="none" stroke="black" stroke-dasharray="1,5" d="M142.12,-178C144.58,-178 147.04,-178 149.5,-178"/>
-<polygon fill="black" stroke="black" points="149.61,-181.5 159.61,-178 149.61,-174.5 149.61,-181.5"/>
-<text text-anchor="middle" x="145.12" y="-171.6" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Return19&#45;&gt;Region16 -->
-<g id="edge11" class="edge">
-<title>Return19&#45;&gt;Region16</title>
-<path fill="none" stroke="red" d="M163.64,-124.3C168.13,-132.36 173.56,-142.11 178.52,-151.02"/>
-<polygon fill="red" stroke="red" points="175.55,-152.86 183.47,-159.9 181.66,-149.46 175.55,-152.86"/>
-<text text-anchor="middle" x="160.64" y="-126.9" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Return19&#45;&gt;Phi_c17 -->
-<g id="edge12" class="edge">
-<title>Return19&#45;&gt;Phi_c17</title>
-<path fill="none" stroke="black" d="M144.36,-124.3C139.69,-132.68 134,-142.9 128.87,-152.1"/>
-<polygon fill="black" stroke="black" points="125.8,-150.42 123.99,-160.86 131.92,-153.82 125.8,-150.42"/>
-<text text-anchor="middle" x="141.36" y="-126.9" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-</g>
-</svg>
+<svg aria-label="Compiler graph" width="782" height="734" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 782 734" style="font-family: sans-serif;"><style>
+ html, body { height:100%; margin:0; font-family:sans-serif; }
+ .viewer { height:100%; display:grid; grid-template-rows:auto minmax(0,1fr) auto; }
+ .source { padding:8px; border-bottom:1px solid #ccc; }
+ #program { width:min(600px,80vw); vertical-align:middle; }
+ #status { margin-top:4px; }
+ #graph { min-height:0; overflow:hidden; position:relative; background:#fafbfc; }
+ #elk { width:100%; height:100%; }
+ #graph svg { display:block; }
+ .tools { display:flex; flex-wrap:wrap; align-items:center; gap:14px; margin-top:8px; font-size:12px; }
+ .hint { color:#616c78; }
+ .ctrl { color:#b63838; } .mem { color:#2867b2; } .data { color:#536477; }
+ .edge { fill:none; stroke-width:1.5; }
+ .edge.CTRL { stroke-width:2; }
+ .edge.ASSOC { stroke-dasharray:4 4; }
+ .edge.PARSER { stroke-dasharray:5 4; }
+ .parser rect { fill:#f6f0ff; stroke:#7956a5; stroke-width:1.5; stroke-dasharray:5 4; }
+ .edge.selected { stroke-width:3.5; }
+ .edge.bundle { stroke-width:4; }
+ .edge.bundle.selected { stroke-width:6; }
+ .edge-hit { fill:none; stroke:transparent; stroke-width:12; vector-effect:non-scaling-stroke; pointer-events:stroke; cursor:pointer; }
+ .edge-jump { fill:transparent; pointer-events:all; cursor:pointer; }
+ .node { cursor:pointer; }
+ .box { stroke:#758191; stroke-width:1; }
+ .node.held .box { stroke-dasharray:5 3; }
+ .node.near .box { stroke:#c18221; stroke-width:2; }
+ .node.focus .box { stroke:#9c4900; stroke-width:3; }
+ .node.selected .box { stroke:#1569b9; stroke-width:3; }
+ .node.folded .box { stroke-width:4; }
+ .node.folding .box { fill:#f4ccd7; }
+ .fold-tag { font-size:9px; font-weight:700; fill:#963751; }
+ .peep-area { fill:#fff3d9; fill-opacity:.8; stroke:#c18221; stroke-width:2; pointer-events:none; }
+ .node.peep-edit .box { stroke:#9c4900; stroke-width:3; }
+ .node.error .box { stroke:#b42318; stroke-width:4; }
+ #event.error { color:#b42318; font-weight:600; white-space:pre-wrap; overflow-wrap:anywhere; }
+ .peep-ghosts { pointer-events:none; }
+ .region-box { stroke:#9da9b8; stroke-width:1.5; }
+ .fold-btn { cursor:pointer; }
+ .fold-btn rect { fill:white; stroke:#596674; }
+ .fold-btn text { font-size:14px; fill:#152330; }
+ .fold-btn:focus rect { stroke:#1569b9; stroke-width:2; }
+ .shortcut { cursor:pointer; }
+ .shortcut path { fill:none; stroke-width:1.5; }
+ .shortcut rect { fill:#fff8ec; stroke:#b63838; stroke-dasharray:3 2; }
+ .shortcut text { font-size:11px; fill:#783030; }
+ .shortcut.selected rect, .shortcut:focus rect { stroke-width:2.5; }
+ .label { font-size:12px; fill:#152330; font-weight:600; }
+ .node-id { font-size:10px; fill:#596674; font-weight:400; }
+ .type { font-size:11px; fill:#455768; }
+ .port { stroke:#536477; stroke-width:1; }
+ .row { stroke:#b6afcf; stroke-width:1; }
+ .bind { font-size:12px; fill:#152330; }
+ .slot { font-size:10px; fill:#364352; paint-order:stroke; stroke:#fafbfc; stroke-width:3; }
+ #detail { position:absolute; top:8px; right:8px; margin:0; padding:12px; max-width:320px;
+ max-height:45%; overflow:auto; white-space:pre-wrap; overflow-wrap:anywhere;
+ background:#fffffff2; border:1px solid #bac5d0; border-radius:4px; font-size:12px; }
+ .controls { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:6px; padding:6px; }
+ .button { color:white; background:black; font-size:20px; min-width:30px; }
+ .button:disabled { background:grey; }
+ .count { font-size:20px; min-width:35px; text-align:center; }
+ #N { width:6ch; }
+ #scrub { width:clamp(120px,35vw,600px); }
+ </style><defs><marker id="arrow-CTRL" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#b63838"/></marker><marker id="arrow-DATA" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#536477"/></marker><marker id="arrow-MEM" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#2867b2"/></marker><marker id="arrow-ASSOC" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#9396a3"/></marker><marker id="arrow-PARSER" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#7956a5"/></marker></defs><rect width="100%" height="100%" fill="rgb(250, 251, 252)"/><g><g class="regions" style="opacity: 1;"><g class="region" transform="translate(24,173)"><rect class="region-box" rx="8" width="360" height="354" fill="#f2f7ef"/></g></g><rect class="peep-area" rx="36" style="opacity: 0;"/><g class="edges"><path class="edge CTRL" id="e3i0" d="M180,633 C180,657 391,660 391,684" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#3[0] → #19 · CTRL</title></path><path class="edge DATA" id="e9i1" d="M236,118 L236,128 L196,128 L196,207" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#9[1] → #4 · DATA</title></path><path class="edge DATA" id="e9i2" d="M394,118 L394,138 L226,138 L226,207" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#9[2] → #8 · DATA</title></path><path class="edge CTRL" id="e10i0" d="M116,118 L116,311" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#10[0] → #1 · CTRL</title></path><path class="edge DATA" id="e10i1" d="M196,263 L196,311" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#10[1] → #9 · DATA</title></path><path class="edge CTRL" id="e16i1" d="M96,411 L96,421 L160,421 L160,459" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#16[1] → #5 · CTRL</title></path><path class="edge CTRL" id="e16i2" d="M216,411 L216,421 L190,421 L190,459" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#16[2] → #7 · CTRL</title></path><path class="edge DATA" id="e17i1" d="M546,118 L546,148 L292,148 L292,459" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#17[1] → #15 · DATA</title></path><path class="edge DATA" id="e17i2" d="M698,118 L698,158 L332,158 L332,459" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#17[2] → #6 · DATA</title></path><path class="edge CTRL" id="e19i0" d="M160,515 L160,580" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#19[0] → #16 · CTRL</title></path><path class="edge DATA" id="e19i1" d="M312,515 L312,542 L200,542 L200,580" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#19[1] → #17 · DATA</title></path></g><g class="edge-hits"/><g class="parser" style="opacity: 1;"/><g class="nodes"><g class="node" id="n1" data-id="1" transform="translate(56,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>$ctrl</tspan><tspan class="node-id">  #1/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#1 $ctrl
+Projection 0 of #2
+Type not computed
+
+[0] → #2 CTRL</title></g><g class="node" id="n2" data-id="2" transform="translate(56,24)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>Start</tspan><tspan class="node-id">  #2</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#2 Start
+Type not computed
+
+</title></g><g class="node" id="n3" data-id="3" transform="translate(355,684)" style="opacity: 1;"><path class="box" d="M0,0H72V26H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="36" y="17"><tspan>Stop</tspan><tspan class="node-id">  #3</tspan></text><text class="type" text-anchor="middle" y="35" x="36"/><title>#3 Stop
+Type not computed
+
+[0] → #19 CTRL</title><circle class="port" cx="36" cy="0" r="3" fill="#536477"/><text class="slot" x="36" y="-7" text-anchor="middle">0</text></g><g class="node" id="n4" data-id="4" transform="translate(176,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>arg</tspan><tspan class="node-id">  #4/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#4 arg
+Projection 1 of #2
+Type not computed
+
+[0] → #2 DATA</title></g><g class="node" id="n5" data-id="5" transform="translate(36,361)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>True</tspan><tspan class="node-id">  #5/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#5 True
+Projection 0 of #10
+Type not computed
+
+[0] → #10 CTRL</title></g><g class="node" id="n6" data-id="6" transform="translate(638,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#3</tspan><tspan class="node-id">  #6</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#6 #3
+Type not computed
+
+</title></g><g class="node" id="n7" data-id="7" transform="translate(156,361)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>False</tspan><tspan class="node-id">  #7/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#7 False
+Projection 1 of #10
+Type not computed
+
+[0] → #10 CTRL</title></g><g class="node" id="n8" data-id="8" transform="translate(334,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#1</tspan><tspan class="node-id">  #8</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#8 #1
+Type not computed
+
+</title></g><g class="node" id="n9" data-id="9" transform="translate(136,213)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #9</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#9 ==
+Type not computed
+
+[0] → — DATA
+[1] → #4 DATA
+[2] → #8 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n10" data-id="10" transform="translate(36,317)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>If</tspan><tspan class="node-id">  #10</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#10 If
+Type not computed
+
+[0] → #1 CTRL
+[1] → #9 DATA</title><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><circle class="port" cx="160" cy="-3" r="3" fill="#536477"/><text class="slot" x="80" y="-10" text-anchor="middle">0</text><text class="slot" x="160" y="-10" text-anchor="middle">1</text></g><g class="node" id="n15" data-id="15" transform="translate(486,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#4</tspan><tspan class="node-id">  #15</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#15 #4
+Type not computed
+
+</title></g><g class="node" id="n16" data-id="16" transform="translate(100,465)" style="opacity: 1;"><path class="box" d="M12,0H108L120,44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Region</tspan><tspan class="node-id">  #16</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#16 Region
+Type not computed
+
+[0] → — DATA
+[1] → #5 CTRL
+[2] → #7 CTRL</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n17" data-id="17" transform="translate(252,465)" style="opacity: 1;"><path class="box" d="M12,0H108L120,22L108,44H12L0,22Z" fill="#f5e4fa"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>φ_c</tspan><tspan class="node-id">  #17</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#17 φ_c
+Type not computed
+
+[0] → #16 ASSOC
+[1] → #15 DATA
+[2] → #6 DATA</title><circle class="port" cx="-3" cy="22" r="3" fill="#536477"/><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><path class="reg" fill="none" stroke="#b63838" d="M-3,22H-18m4,-3l-4,3l4,3"><title>[0] → #16</title></path><text class="slot" x="-10" y="15" text-anchor="middle">0</text><text class="slot" x="40" y="-10" text-anchor="middle">1</text><text class="slot" x="80" y="-10" text-anchor="middle">2</text></g><g class="node" id="n19" data-id="19" transform="translate(120,586)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Return</tspan><tspan class="node-id">  #19</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#19 Return
+Type not computed
+
+[0] → #16 CTRL
+[1] → #17 DATA</title><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><text class="slot" x="40" y="-10" text-anchor="middle">0</text><text class="slot" x="80" y="-10" text-anchor="middle">1</text></g></g><g class="region-heads" style="opacity: 1;"><g class="region-head" transform="translate(24,173)"><text class="label" x="26" y="17"><tspan>If</tspan><tspan class="node-id">  #10</tspan></text><title>If · 6 nodes</title><g class="fold-btn" role="button" tabindex="0" transform="translate(4,4)" aria-label="Fold region #10"><rect width="16" height="16" rx="2"/><text x="8" y="12" text-anchor="middle">−</text><title>Fold region</title></g></g></g><g class="shortcuts" style="opacity: 1;"/><g class="peep-ghosts" pointer-events="none"/></g></svg>
diff --git a/chapter05/docs/05-graph7.json b/chapter05/docs/05-graph7.json
new file mode 100644
index 00000000..df6cf547
--- /dev/null
+++ b/chapter05/docs/05-graph7.json
@@ -0,0 +1,31 @@
+{
+ "ver": 1,
+ "comp": "chapter05/docs/05-graph7.svg",
+ "step": 1,
+ "roots": [],
+ "scope": 0,
+ "nodes": [
+ {"id": 1, "label": "$ctrl", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 2, "role": "CTRL", "label": null}], "proj": {"par": 2, "idx": 0}},
+ {"id": 2, "label": "Start", "type": null, "kind": "CTRL", "edges": [], "proj": null},
+ {"id": 3, "label": "Stop", "type": null, "kind": "STOP", "edges": [{"idx": 0, "def": 51, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 4, "label": "arg", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 2, "role": "DATA", "label": null}], "proj": {"par": 2, "idx": 1}},
+ {"id": 5, "label": "True", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 12, "role": "CTRL", "label": null}], "proj": {"par": 12, "idx": 0}},
+ {"id": 6, "label": "False", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 12, "role": "CTRL", "label": null}], "proj": {"par": 12, "idx": 1}},
+ {"id": 10, "label": "#1", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 11, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 4, "role": "DATA", "label": null}, {"idx": 2, "def": 10, "role": "DATA", "label": null}], "proj": null},
+ {"id": 12, "label": "If", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 1, "role": "CTRL", "label": null}, {"idx": 1, "def": 11, "role": "DATA", "label": null}], "proj": null},
+ {"id": 19, "label": "#2", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 20, "label": "*", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 4, "role": "DATA", "label": null}, {"idx": 2, "def": 19, "role": "DATA", "label": null}], "proj": null},
+ {"id": 31, "label": "Region", "type": null, "kind": "REGION", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 5, "role": "CTRL", "label": null}, {"idx": 2, "def": 6, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 37, "label": "φ_b", "type": null, "kind": "PHI", "edges": [{"idx": 0, "def": 31, "role": "ASSOC", "label": null}, {"idx": 1, "def": 20, "role": "DATA", "label": null}, {"idx": 2, "def": 4, "role": "DATA", "label": null}], "proj": null},
+ {"id": 42, "label": "+", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 37, "role": "DATA", "label": null}, {"idx": 2, "def": 4, "role": "DATA", "label": null}], "proj": null},
+ {"id": 46, "label": "#4", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 48, "label": "#5", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 49, "label": "φ_ab", "type": null, "kind": "PHI", "edges": [{"idx": 0, "def": 31, "role": "ASSOC", "label": null}, {"idx": 1, "def": 46, "role": "DATA", "label": null}, {"idx": 2, "def": 48, "role": "DATA", "label": null}], "proj": null},
+ {"id": 50, "label": "+", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 42, "role": "DATA", "label": null}, {"idx": 2, "def": 49, "role": "DATA", "label": null}], "proj": null},
+ {"id": 51, "label": "Return", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 31, "role": "CTRL", "label": null}, {"idx": 1, "def": 50, "role": "DATA", "label": null}], "proj": null}
+ ],
+ "groups": [
+ {"id": 12, "par": 0, "nodes": [5, 6, 11, 12, 20, 31, 37, 49]}
+ ]
+}
diff --git a/chapter05/docs/05-graph7.svg b/chapter05/docs/05-graph7.svg
index 8ba5ebd6..4ef44b41 100644
--- a/chapter05/docs/05-graph7.svg
+++ b/chapter05/docs/05-graph7.svg
@@ -1,269 +1,140 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Generated by graphviz version 2.43.0 (0)
- -->
-<!-- Title: chapter05 Pages: 1 -->
-<svg width="386pt" height="636pt"
- viewBox="0.00 0.00 386.00 636.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 632)">
-<title>chapter05</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-632 382,-632 382,4 -4,4"/>
-<g id="clust1" class="cluster">
-<title>cluster_Nodes</title>
-<polygon fill="none" stroke="black" points="8,-8 8,-620 370,-620 370,-8 8,-8"/>
-</g>
-<!-- Start2 -->
-<g id="node1" class="node">
-<title>Start2</title>
-<polygon fill="yellow" stroke="transparent" points="187,-583 187,-608 268,-608 268,-583 187,-583"/>
-<polygon fill="none" stroke="black" points="187,-583 187,-608 268,-608 268,-583 187,-583"/>
-<text text-anchor="start" x="209" y="-591.8" font-family="Times,serif" font-size="14.00">Start</text>
-<polygon fill="none" stroke="black" points="187,-552 187,-583 268,-583 268,-552 187,-552"/>
-<polygon fill="yellow" stroke="transparent" points="192,-557 192,-578 232,-578 232,-557 192,-557"/>
-<polygon fill="none" stroke="black" points="192,-557 192,-578 232,-578 232,-557 192,-557"/>
-<text text-anchor="start" x="195" y="-563.8" font-family="Times,serif" font-size="14.00">$ctrl</text>
-<polygon fill="none" stroke="black" points="232,-557 232,-578 263,-578 263,-557 232,-557"/>
-<text text-anchor="start" x="235" y="-563.8" font-family="Times,serif" font-size="14.00">arg</text>
-</g>
-<!-- Stop3 -->
-<g id="node2" class="node">
-<title>Stop3</title>
-<polygon fill="yellow" stroke="black" points="230,-52 176,-52 176,-16 230,-16 230,-52"/>
-<text text-anchor="middle" x="203" y="-30.3" font-family="Times,serif" font-size="14.00">Stop</text>
-</g>
-<!-- Return51 -->
-<g id="node13" class="node">
-<title>Return51</title>
-<polygon fill="yellow" stroke="black" points="236,-124 170,-124 170,-88 236,-88 236,-124"/>
-<text text-anchor="middle" x="203" y="-102.3" font-family="Times,serif" font-size="14.00">Return</text>
-</g>
-<!-- Stop3&#45;&gt;Return51 -->
-<g id="edge1" class="edge">
-<title>Stop3&#45;&gt;Return51</title>
-<path fill="none" stroke="red" d="M203,-52.3C203,-60.02 203,-69.29 203,-77.89"/>
-<polygon fill="red" stroke="red" points="199.5,-77.9 203,-87.9 206.5,-77.9 199.5,-77.9"/>
-<text text-anchor="middle" x="200" y="-54.9" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Phi_b37 -->
-<g id="node3" class="node">
-<title>Phi_b37</title>
-<ellipse fill="lightyellow" stroke="black" cx="63" cy="-322" rx="27.1" ry="18"/>
-<text text-anchor="middle" x="63" y="-318.3" font-family="Times,serif" font-size="14.00">φ_b</text>
-</g>
-<!-- Phi_b37&#45;&gt;Start2 -->
-<g id="edge4" class="edge">
-<title>Phi_b37&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M50.14,-338.15C37.78,-354.08 20.49,-380.46 17,-407"/>
-<text text-anchor="middle" x="47.14" y="-340.75" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Mul20 -->
-<g id="node14" class="node">
-<title>Mul20</title>
-<ellipse fill="none" stroke="black" cx="63" cy="-408" rx="27" ry="18"/>
-<text text-anchor="middle" x="63" y="-404.3" font-family="Times,serif" font-size="14.00">*</text>
-</g>
-<!-- Phi_b37&#45;&gt;Mul20 -->
-<g id="edge3" class="edge">
-<title>Phi_b37&#45;&gt;Mul20</title>
-<path fill="none" stroke="black" d="M63,-340.4C63,-351.74 63,-366.77 63,-379.68"/>
-<polygon fill="black" stroke="black" points="59.5,-379.9 63,-389.9 66.5,-379.9 59.5,-379.9"/>
-<text text-anchor="middle" x="60" y="-343" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Region31 -->
-<g id="node15" class="node">
-<title>Region31</title>
-<polygon fill="yellow" stroke="black" points="287,-340 221,-340 221,-304 287,-304 287,-340"/>
-<text text-anchor="middle" x="254" y="-318.3" font-family="Times,serif" font-size="14.00">Region</text>
-</g>
-<!-- Phi_b37&#45;&gt;Region31 -->
-<g id="edge2" class="edge">
-<title>Phi_b37&#45;&gt;Region31</title>
-<path fill="none" stroke="black" stroke-dasharray="1,5" d="M83.07,-309.47C97.9,-300.98 118.92,-290.52 139,-286 166.75,-279.76 175.89,-277.4 203,-286 210.99,-288.54 218.81,-292.83 225.83,-297.58"/>
-<polygon fill="black" stroke="black" points="224.11,-300.66 234.24,-303.75 228.25,-295.01 224.11,-300.66"/>
-<text text-anchor="middle" x="80.07" y="-303.07" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Con_10 -->
-<g id="node4" class="node">
-<title>Con_10</title>
-<ellipse fill="none" stroke="black" cx="321" cy="-580" rx="27" ry="18"/>
-<text text-anchor="middle" x="321" y="-576.3" font-family="Times,serif" font-size="14.00">#1</text>
-</g>
-<!-- Add42 -->
-<g id="node5" class="node">
-<title>Add42</title>
-<ellipse fill="none" stroke="black" cx="63" cy="-250" rx="27" ry="18"/>
-<text text-anchor="middle" x="63" y="-246.3" font-family="Times,serif" font-size="14.00">+</text>
-</g>
-<!-- Add42&#45;&gt;Start2 -->
-<g id="edge6" class="edge">
-<title>Add42&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M49.72,-266.09C41.69,-276.12 32.07,-289.98 27,-304 11.37,-347.26 22.99,-361.4 17,-407"/>
-<path fill="none" stroke="black" d="M17,-409C11.54,-445.93 0.41,-459.55 17,-493"/>
-<path fill="none" stroke="black" d="M17,-495C20.89,-502.85 19.85,-506.92 27,-512 102.92,-565.95 228.75,-471 246.01,-537.97"/>
-<polygon fill="black" stroke="black" points="242.59,-538.7 247.67,-548 249.49,-537.56 242.59,-538.7"/>
-<text text-anchor="middle" x="46.72" y="-268.69" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Add42&#45;&gt;Phi_b37 -->
-<g id="edge5" class="edge">
-<title>Add42&#45;&gt;Phi_b37</title>
-<path fill="none" stroke="black" d="M63,-268.3C63,-276.02 63,-285.29 63,-293.89"/>
-<polygon fill="black" stroke="black" points="59.5,-293.9 63,-303.9 66.5,-293.9 59.5,-293.9"/>
-<text text-anchor="middle" x="60" y="-270.9" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode11 -->
-<g id="node6" class="node">
-<title>EQNode11</title>
-<ellipse fill="none" stroke="black" cx="307" cy="-494" rx="27" ry="18"/>
-<text text-anchor="middle" x="307" y="-490.3" font-family="Times,serif" font-size="14.00">==</text>
-</g>
-<!-- EQNode11&#45;&gt;Start2 -->
-<g id="edge7" class="edge">
-<title>EQNode11&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M300.78,-511.7C294.25,-528.15 283.48,-552.23 273.01,-562.3"/>
-<polygon fill="black" stroke="black" points="271.25,-559.27 264,-567 274.49,-565.48 271.25,-559.27"/>
-<text text-anchor="middle" x="297.78" y="-514.3" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode11&#45;&gt;Con_10 -->
-<g id="edge8" class="edge">
-<title>EQNode11&#45;&gt;Con_10</title>
-<path fill="none" stroke="black" d="M309.83,-512C311.75,-523.5 314.32,-538.93 316.51,-552.08"/>
-<polygon fill="black" stroke="black" points="313.07,-552.74 318.17,-562.03 319.98,-551.59 313.07,-552.74"/>
-<text text-anchor="middle" x="306.83" y="-514.6" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- If12 -->
-<g id="node7" class="node">
-<title>If12</title>
-<polygon fill="yellow" stroke="transparent" points="260,-411 260,-436 354,-436 354,-411 260,-411"/>
-<polygon fill="none" stroke="black" points="260,-411 260,-436 354,-436 354,-411 260,-411"/>
-<text text-anchor="start" x="301.5" y="-419.8" font-family="Times,serif" font-size="14.00">If</text>
-<polygon fill="none" stroke="black" points="260,-380 260,-411 354,-411 354,-380 260,-380"/>
-<polygon fill="yellow" stroke="transparent" points="265,-385 265,-406 305,-406 305,-385 265,-385"/>
-<polygon fill="none" stroke="black" points="265,-385 265,-406 305,-406 305,-385 265,-385"/>
-<text text-anchor="start" x="268" y="-391.8" font-family="Times,serif" font-size="14.00">True</text>
-<polygon fill="yellow" stroke="transparent" points="305,-385 305,-406 349,-406 349,-385 305,-385"/>
-<polygon fill="none" stroke="black" points="305,-385 305,-406 349,-406 349,-385 305,-385"/>
-<text text-anchor="start" x="308" y="-391.8" font-family="Times,serif" font-size="14.00">False</text>
-</g>
-<!-- If12&#45;&gt;Start2 -->
-<g id="edge9" class="edge">
-<title>If12&#45;&gt;Start2:p0</title>
-<path fill="none" stroke="red" d="M271.9,-440.02C246.84,-465.46 216.84,-504 212.53,-545.87"/>
-<polygon fill="red" stroke="red" points="209.02,-545.83 212,-556 216.01,-546.2 209.02,-545.83"/>
-<text text-anchor="middle" x="268.9" y="-442.62" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- If12&#45;&gt;EQNode11 -->
-<g id="edge10" class="edge">
-<title>If12&#45;&gt;EQNode11</title>
-<path fill="none" stroke="black" d="M307,-440.28C307,-448.58 307,-457.48 307,-465.56"/>
-<polygon fill="black" stroke="black" points="303.5,-465.6 307,-475.6 310.5,-465.6 303.5,-465.6"/>
-<text text-anchor="middle" x="304" y="-442.88" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Con_46 -->
-<g id="node8" class="node">
-<title>Con_46</title>
-<ellipse fill="none" stroke="black" cx="135" cy="-408" rx="27" ry="18"/>
-<text text-anchor="middle" x="135" y="-404.3" font-family="Times,serif" font-size="14.00">#4</text>
-</g>
-<!-- Con_48 -->
-<g id="node9" class="node">
-<title>Con_48</title>
-<ellipse fill="none" stroke="black" cx="207" cy="-408" rx="27" ry="18"/>
-<text text-anchor="middle" x="207" y="-404.3" font-family="Times,serif" font-size="14.00">#5</text>
-</g>
-<!-- Phi_ab49 -->
-<g id="node10" class="node">
-<title>Phi_ab49</title>
-<ellipse fill="lightyellow" stroke="black" cx="171" cy="-322" rx="32.49" ry="18"/>
-<text text-anchor="middle" x="171" y="-318.3" font-family="Times,serif" font-size="14.00">φ_ab</text>
-</g>
-<!-- Phi_ab49&#45;&gt;Con_46 -->
-<g id="edge12" class="edge">
-<title>Phi_ab49&#45;&gt;Con_46</title>
-<path fill="none" stroke="black" d="M163.89,-339.6C158.81,-351.45 151.88,-367.62 146.08,-381.15"/>
-<polygon fill="black" stroke="black" points="142.82,-379.87 142.1,-390.44 149.25,-382.63 142.82,-379.87"/>
-<text text-anchor="middle" x="160.89" y="-342.2" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Phi_ab49&#45;&gt;Con_48 -->
-<g id="edge13" class="edge">
-<title>Phi_ab49&#45;&gt;Con_48</title>
-<path fill="none" stroke="black" d="M178.11,-339.6C183.19,-351.45 190.12,-367.62 195.92,-381.15"/>
-<polygon fill="black" stroke="black" points="192.75,-382.63 199.9,-390.44 199.18,-379.87 192.75,-382.63"/>
-<text text-anchor="middle" x="175.11" y="-342.2" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_ab49&#45;&gt;Region31 -->
-<g id="edge11" class="edge">
-<title>Phi_ab49&#45;&gt;Region31</title>
-<path fill="none" stroke="black" stroke-dasharray="1,5" d="M203.75,-322C206.03,-322 208.32,-322 210.6,-322"/>
-<polygon fill="black" stroke="black" points="210.63,-325.5 220.63,-322 210.63,-318.5 210.63,-325.5"/>
-<text text-anchor="middle" x="206.75" y="-315.6" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Add50 -->
-<g id="node11" class="node">
-<title>Add50</title>
-<ellipse fill="none" stroke="black" cx="171" cy="-178" rx="27" ry="18"/>
-<text text-anchor="middle" x="171" y="-174.3" font-family="Times,serif" font-size="14.00">+</text>
-</g>
-<!-- Add50&#45;&gt;Add42 -->
-<g id="edge14" class="edge">
-<title>Add50&#45;&gt;Add42</title>
-<path fill="none" stroke="black" d="M152.19,-191.19C135,-202.33 109.38,-218.94 90.01,-231.5"/>
-<polygon fill="black" stroke="black" points="88.08,-228.57 81.6,-236.95 91.89,-234.44 88.08,-228.57"/>
-<text text-anchor="middle" x="149.19" y="-193.79" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Add50&#45;&gt;Phi_ab49 -->
-<g id="edge15" class="edge">
-<title>Add50&#45;&gt;Phi_ab49</title>
-<path fill="none" stroke="black" d="M171,-196.13C171,-220.33 171,-264.79 171,-293.61"/>
-<polygon fill="black" stroke="black" points="167.5,-293.81 171,-303.81 174.5,-293.81 167.5,-293.81"/>
-<text text-anchor="middle" x="168" y="-198.73" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Con_19 -->
-<g id="node12" class="node">
-<title>Con_19</title>
-<ellipse fill="none" stroke="black" cx="63" cy="-494" rx="27" ry="18"/>
-<text text-anchor="middle" x="63" y="-490.3" font-family="Times,serif" font-size="14.00">#2</text>
-</g>
-<!-- Return51&#45;&gt;Add50 -->
-<g id="edge17" class="edge">
-<title>Return51&#45;&gt;Add50</title>
-<path fill="none" stroke="black" d="M195.09,-124.3C191.39,-132.39 186.91,-142.19 182.83,-151.13"/>
-<polygon fill="black" stroke="black" points="179.57,-149.83 178.6,-160.38 185.94,-152.74 179.57,-149.83"/>
-<text text-anchor="middle" x="192.09" y="-126.9" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Return51&#45;&gt;Region31 -->
-<g id="edge16" class="edge">
-<title>Return51&#45;&gt;Region31</title>
-<path fill="none" stroke="red" d="M207.09,-124.15C215.93,-161.25 236.89,-249.19 247.54,-293.9"/>
-<polygon fill="red" stroke="red" points="244.17,-294.85 249.89,-303.77 250.98,-293.23 244.17,-294.85"/>
-<text text-anchor="middle" x="204.09" y="-126.75" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Mul20&#45;&gt;Start2 -->
-<g id="edge18" class="edge">
-<title>Mul20&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M46.66,-422.5C28.85,-438.94 4.44,-467.68 17,-493"/>
-<text text-anchor="middle" x="43.66" y="-425.1" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Mul20&#45;&gt;Con_19 -->
-<g id="edge19" class="edge">
-<title>Mul20&#45;&gt;Con_19</title>
-<path fill="none" stroke="black" d="M63,-426.4C63,-437.74 63,-452.77 63,-465.68"/>
-<polygon fill="black" stroke="black" points="59.5,-465.9 63,-475.9 66.5,-465.9 59.5,-465.9"/>
-<text text-anchor="middle" x="60" y="-429" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Region31&#45;&gt;If12 -->
-<g id="edge20" class="edge">
-<title>Region31&#45;&gt;If12:p0</title>
-<path fill="none" stroke="red" d="M268.23,-340.25C274.66,-349.42 281.38,-361.37 283.93,-373.89"/>
-<polygon fill="red" stroke="red" points="280.47,-374.42 285,-384 287.43,-373.69 280.47,-374.42"/>
-<text text-anchor="middle" x="265.23" y="-342.85" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Region31&#45;&gt;If12 -->
-<g id="edge21" class="edge">
-<title>Region31&#45;&gt;If12:p1</title>
-<path fill="none" stroke="red" d="M287.08,-335.84C303.38,-344.18 320.59,-356.74 325.57,-373.96"/>
-<polygon fill="red" stroke="red" points="322.13,-374.59 327,-384 329.06,-373.61 322.13,-374.59"/>
-<text text-anchor="middle" x="290.08" y="-329.44" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-</g>
-</svg>
+<svg aria-label="Compiler graph" width="902" height="942" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 902 942" style="font-family: sans-serif;"><style>
+ html, body { height:100%; margin:0; font-family:sans-serif; }
+ .viewer { height:100%; display:grid; grid-template-rows:auto minmax(0,1fr) auto; }
+ .source { padding:8px; border-bottom:1px solid #ccc; }
+ #program { width:min(600px,80vw); vertical-align:middle; }
+ #status { margin-top:4px; }
+ #graph { min-height:0; overflow:hidden; position:relative; background:#fafbfc; }
+ #elk { width:100%; height:100%; }
+ #graph svg { display:block; }
+ .tools { display:flex; flex-wrap:wrap; align-items:center; gap:14px; margin-top:8px; font-size:12px; }
+ .hint { color:#616c78; }
+ .ctrl { color:#b63838; } .mem { color:#2867b2; } .data { color:#536477; }
+ .edge { fill:none; stroke-width:1.5; }
+ .edge.CTRL { stroke-width:2; }
+ .edge.ASSOC { stroke-dasharray:4 4; }
+ .edge.PARSER { stroke-dasharray:5 4; }
+ .parser rect { fill:#f6f0ff; stroke:#7956a5; stroke-width:1.5; stroke-dasharray:5 4; }
+ .edge.selected { stroke-width:3.5; }
+ .edge.bundle { stroke-width:4; }
+ .edge.bundle.selected { stroke-width:6; }
+ .edge-hit { fill:none; stroke:transparent; stroke-width:12; vector-effect:non-scaling-stroke; pointer-events:stroke; cursor:pointer; }
+ .edge-jump { fill:transparent; pointer-events:all; cursor:pointer; }
+ .node { cursor:pointer; }
+ .box { stroke:#758191; stroke-width:1; }
+ .node.held .box { stroke-dasharray:5 3; }
+ .node.near .box { stroke:#c18221; stroke-width:2; }
+ .node.focus .box { stroke:#9c4900; stroke-width:3; }
+ .node.selected .box { stroke:#1569b9; stroke-width:3; }
+ .node.folded .box { stroke-width:4; }
+ .node.folding .box { fill:#f4ccd7; }
+ .fold-tag { font-size:9px; font-weight:700; fill:#963751; }
+ .peep-area { fill:#fff3d9; fill-opacity:.8; stroke:#c18221; stroke-width:2; pointer-events:none; }
+ .node.peep-edit .box { stroke:#9c4900; stroke-width:3; }
+ .node.error .box { stroke:#b42318; stroke-width:4; }
+ #event.error { color:#b42318; font-weight:600; white-space:pre-wrap; overflow-wrap:anywhere; }
+ .peep-ghosts { pointer-events:none; }
+ .region-box { stroke:#9da9b8; stroke-width:1.5; }
+ .fold-btn { cursor:pointer; }
+ .fold-btn rect { fill:white; stroke:#596674; }
+ .fold-btn text { font-size:14px; fill:#152330; }
+ .fold-btn:focus rect { stroke:#1569b9; stroke-width:2; }
+ .shortcut { cursor:pointer; }
+ .shortcut path { fill:none; stroke-width:1.5; }
+ .shortcut rect { fill:#fff8ec; stroke:#b63838; stroke-dasharray:3 2; }
+ .shortcut text { font-size:11px; fill:#783030; }
+ .shortcut.selected rect, .shortcut:focus rect { stroke-width:2.5; }
+ .label { font-size:12px; fill:#152330; font-weight:600; }
+ .node-id { font-size:10px; fill:#596674; font-weight:400; }
+ .type { font-size:11px; fill:#455768; }
+ .port { stroke:#536477; stroke-width:1; }
+ .row { stroke:#b6afcf; stroke-width:1; }
+ .bind { font-size:12px; fill:#152330; }
+ .slot { font-size:10px; fill:#364352; paint-order:stroke; stroke:#fafbfc; stroke-width:3; }
+ #detail { position:absolute; top:8px; right:8px; margin:0; padding:12px; max-width:320px;
+ max-height:45%; overflow:auto; white-space:pre-wrap; overflow-wrap:anywhere;
+ background:#fffffff2; border:1px solid #bac5d0; border-radius:4px; font-size:12px; }
+ .controls { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:6px; padding:6px; }
+ .button { color:white; background:black; font-size:20px; min-width:30px; }
+ .button:disabled { background:grey; }
+ .count { font-size:20px; min-width:35px; text-align:center; }
+ #N { width:6ch; }
+ #scrub { width:clamp(120px,35vw,600px); }
+ </style><defs><marker id="arrow-CTRL" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#b63838"/></marker><marker id="arrow-DATA" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#536477"/></marker><marker id="arrow-MEM" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#2867b2"/></marker><marker id="arrow-ASSOC" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#9396a3"/></marker><marker id="arrow-PARSER" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#7956a5"/></marker></defs><rect width="100%" height="100%" fill="rgb(250, 251, 252)"/><g><g class="regions" style="opacity: 1;"><g class="region" transform="translate(144,173)"><rect class="region-box" rx="8" width="538" height="354" fill="#f2f7ef"/></g></g><rect class="peep-area" rx="36" style="opacity: 0;"/><g class="edges"><path class="edge CTRL" id="e3i0" d="M326,841 C326,865 451,868 451,892" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#3[0] → #51 · CTRL</title></path><path class="edge DATA" id="e11i1" d="M356,118 L356,148 L316,148 L316,207" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#11[1] → #4 · DATA</title></path><path class="edge DATA" id="e11i2" d="M84,118 L84,158 L346,158 L346,207" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#11[2] → #10 · DATA</title></path><path class="edge CTRL" id="e12i0" d="M236,118 L236,311" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#12[0] → #1 · CTRL</title></path><path class="edge DATA" id="e12i1" d="M316,263 L316,311" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#12[1] → #11 · DATA</title></path><path class="edge DATA" id="e20i1" d="M356,118 L356,148 L494,148 L494,325.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#20[1] → #4 · DATA</title></path><path class="edge DATA" id="e20i2" d="M514,118 L514,128 L524,128 L524,325.66666666666663" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#20[2] → #19 · DATA</title></path><path class="edge CTRL" id="e31i1" d="M216,411 L216,421 L306,421 L306,459" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#31[1] → #5 · CTRL</title></path><path class="edge CTRL" id="e31i2" d="M336,411 L336,459" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#31[2] → #6 · CTRL</title></path><path class="edge DATA" id="e37i1" d="M494,381.66666666666663 L494,421 L438,421 L438,459" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#37[1] → #20 · DATA</title></path><path class="edge DATA" id="e37i2" d="M356,118 L356,148 L564,148 L564,431 L478,431 L478,459" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#37[2] → #4 · DATA</title></path><path class="edge DATA" id="e42i1" d="M458,515 L458,542 L540,542 L540,580" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#42[1] → #37 · DATA</title></path><path class="edge DATA" id="e42i2" d="M356,118 L356,148 L692,148 L692,542 L570,542 L570,580" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#42[2] → #4 · DATA</title></path><path class="edge DATA" id="e49i1" d="M666,118 L666,128 L590,128 L590,459" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#49[1] → #46 · DATA</title></path><path class="edge DATA" id="e49i2" d="M818,118 L818,138 L630,138 L630,459" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#49[2] → #48 · DATA</title></path><path class="edge DATA" id="e50i1" d="M540,636 L540,684" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#50[1] → #42 · DATA</title></path><path class="edge DATA" id="e50i2" d="M610,515 L610,646 L570,646 L570,684" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#50[2] → #49 · DATA</title></path><path class="edge CTRL" id="e51i0" d="M306,515 L306,788" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#51[0] → #31 · CTRL</title></path><path class="edge DATA" id="e51i1" d="M540,740 L540,750 L346,750 L346,788" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#51[1] → #50 · DATA</title></path></g><g class="edge-hits"/><g class="parser" style="opacity: 1;"/><g class="nodes"><g class="node" id="n1" data-id="1" transform="translate(176,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>$ctrl</tspan><tspan class="node-id">  #1/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#1 $ctrl
+Projection 0 of #2
+Type not computed
+
+[0] → #2 CTRL</title></g><g class="node" id="n2" data-id="2" transform="translate(176,24)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>Start</tspan><tspan class="node-id">  #2</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#2 Start
+Type not computed
+
+</title></g><g class="node" id="n3" data-id="3" transform="translate(415,892)" style="opacity: 1;"><path class="box" d="M0,0H72V26H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="36" y="17"><tspan>Stop</tspan><tspan class="node-id">  #3</tspan></text><text class="type" text-anchor="middle" y="35" x="36"/><title>#3 Stop
+Type not computed
+
+[0] → #51 CTRL</title><circle class="port" cx="36" cy="0" r="3" fill="#536477"/><text class="slot" x="36" y="-7" text-anchor="middle">0</text></g><g class="node" id="n4" data-id="4" transform="translate(296,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>arg</tspan><tspan class="node-id">  #4/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#4 arg
+Projection 1 of #2
+Type not computed
+
+[0] → #2 DATA</title></g><g class="node" id="n5" data-id="5" transform="translate(156,361)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>True</tspan><tspan class="node-id">  #5/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#5 True
+Projection 0 of #12
+Type not computed
+
+[0] → #12 CTRL</title></g><g class="node" id="n6" data-id="6" transform="translate(276,361)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>False</tspan><tspan class="node-id">  #6/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#6 False
+Projection 1 of #12
+Type not computed
+
+[0] → #12 CTRL</title></g><g class="node" id="n10" data-id="10" transform="translate(24,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#1</tspan><tspan class="node-id">  #10</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#10 #1
+Type not computed
+
+</title></g><g class="node" id="n11" data-id="11" transform="translate(256,213)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #11</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#11 ==
+Type not computed
+
+[0] → — DATA
+[1] → #4 DATA
+[2] → #10 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n12" data-id="12" transform="translate(156,317)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>If</tspan><tspan class="node-id">  #12</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#12 If
+Type not computed
+
+[0] → #1 CTRL
+[1] → #11 DATA</title><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><circle class="port" cx="160" cy="-3" r="3" fill="#536477"/><text class="slot" x="80" y="-10" text-anchor="middle">0</text><text class="slot" x="160" y="-10" text-anchor="middle">1</text></g><g class="node" id="n19" data-id="19" transform="translate(454,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#2</tspan><tspan class="node-id">  #19</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#19 #2
+Type not computed
+
+</title></g><g class="node" id="n20" data-id="20" transform="translate(434,331.66666666666663)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>*</tspan><tspan class="node-id">  #20</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#20 *
+Type not computed
+
+[0] → — DATA
+[1] → #4 DATA
+[2] → #19 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n31" data-id="31" transform="translate(246,465)" style="opacity: 1;"><path class="box" d="M12,0H108L120,44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Region</tspan><tspan class="node-id">  #31</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#31 Region
+Type not computed
+
+[0] → — DATA
+[1] → #5 CTRL
+[2] → #6 CTRL</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n37" data-id="37" transform="translate(398,465)" style="opacity: 1;"><path class="box" d="M12,0H108L120,22L108,44H12L0,22Z" fill="#f5e4fa"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>φ_b</tspan><tspan class="node-id">  #37</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#37 φ_b
+Type not computed
+
+[0] → #31 ASSOC
+[1] → #20 DATA
+[2] → #4 DATA</title><circle class="port" cx="-3" cy="22" r="3" fill="#536477"/><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><path class="reg" fill="none" stroke="#b63838" d="M-3,22H-18m4,-3l-4,3l4,3"><title>[0] → #31</title></path><text class="slot" x="-10" y="15" text-anchor="middle">0</text><text class="slot" x="40" y="-10" text-anchor="middle">1</text><text class="slot" x="80" y="-10" text-anchor="middle">2</text></g><g class="node" id="n42" data-id="42" transform="translate(480,586)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>+</tspan><tspan class="node-id">  #42</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#42 +
+Type not computed
+
+[0] → — DATA
+[1] → #37 DATA
+[2] → #4 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n46" data-id="46" transform="translate(606,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#4</tspan><tspan class="node-id">  #46</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#46 #4
+Type not computed
+
+</title></g><g class="node" id="n48" data-id="48" transform="translate(758,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#5</tspan><tspan class="node-id">  #48</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#48 #5
+Type not computed
+
+</title></g><g class="node" id="n49" data-id="49" transform="translate(550,465)" style="opacity: 1;"><path class="box" d="M12,0H108L120,22L108,44H12L0,22Z" fill="#f5e4fa"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>φ_ab</tspan><tspan class="node-id">  #49</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#49 φ_ab
+Type not computed
+
+[0] → #31 ASSOC
+[1] → #46 DATA
+[2] → #48 DATA</title><circle class="port" cx="-3" cy="22" r="3" fill="#536477"/><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><path class="reg" fill="none" stroke="#b63838" d="M-3,22H-18m4,-3l-4,3l4,3"><title>[0] → #31</title></path><text class="slot" x="-10" y="15" text-anchor="middle">0</text><text class="slot" x="40" y="-10" text-anchor="middle">1</text><text class="slot" x="80" y="-10" text-anchor="middle">2</text></g><g class="node" id="n50" data-id="50" transform="translate(480,690)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>+</tspan><tspan class="node-id">  #50</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#50 +
+Type not computed
+
+[0] → — DATA
+[1] → #42 DATA
+[2] → #49 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n51" data-id="51" transform="translate(266,794)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Return</tspan><tspan class="node-id">  #51</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#51 Return
+Type not computed
+
+[0] → #31 CTRL
+[1] → #50 DATA</title><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><text class="slot" x="40" y="-10" text-anchor="middle">0</text><text class="slot" x="80" y="-10" text-anchor="middle">1</text></g></g><g class="region-heads" style="opacity: 1;"><g class="region-head" transform="translate(144,173)"><text class="label" x="26" y="17"><tspan>If</tspan><tspan class="node-id">  #12</tspan></text><title>If · 8 nodes</title><g class="fold-btn" role="button" tabindex="0" transform="translate(4,4)" aria-label="Fold region #12"><rect width="16" height="16" rx="2"/><text x="8" y="12" text-anchor="middle">−</text><title>Fold region</title></g></g></g><g class="shortcuts" style="opacity: 1;"/><g class="peep-ghosts" pointer-events="none"/></g></svg>
diff --git a/chapter05/docs/05-graph8.json b/chapter05/docs/05-graph8.json
new file mode 100644
index 00000000..887d1e8a
--- /dev/null
+++ b/chapter05/docs/05-graph8.json
@@ -0,0 +1,45 @@
+{
+ "ver": 1,
+ "comp": "chapter05/docs/05-graph8.svg",
+ "step": 1,
+ "roots": [],
+ "scope": 0,
+ "nodes": [
+ {"id": 1, "label": "Scope", "type": null, "kind": "SCOPE", "edges": [{"idx": 0, "def": 0, "role": "ASSOC", "label": "0: $ctrl"}, {"idx": 1, "def": 6, "role": "ASSOC", "label": "0: arg"}, {"idx": 2, "def": 34, "role": "ASSOC", "label": "1: a"}], "proj": null},
+ {"id": 2, "label": "Start", "type": null, "kind": "CTRL", "edges": [], "proj": null},
+ {"id": 3, "label": "Stop", "type": null, "kind": "STOP", "edges": [{"idx": 0, "def": 35, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 5, "label": "$ctrl", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 2, "role": "CTRL", "label": null}], "proj": {"par": 2, "idx": 0}},
+ {"id": 6, "label": "arg", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 2, "role": "DATA", "label": null}], "proj": {"par": 2, "idx": 1}},
+ {"id": 7, "label": "#1", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 8, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 6, "role": "DATA", "label": null}, {"idx": 2, "def": 7, "role": "DATA", "label": null}], "proj": null},
+ {"id": 9, "label": "If", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 5, "role": "CTRL", "label": null}, {"idx": 1, "def": 8, "role": "DATA", "label": null}], "proj": null},
+ {"id": 10, "label": "True", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 9, "role": "CTRL", "label": null}], "proj": {"par": 9, "idx": 0}},
+ {"id": 11, "label": "False", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 9, "role": "CTRL", "label": null}], "proj": {"par": 9, "idx": 1}},
+ {"id": 12, "label": "True", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 15, "role": "CTRL", "label": null}], "proj": {"par": 15, "idx": 0}},
+ {"id": 13, "label": "#2", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 14, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 6, "role": "DATA", "label": null}, {"idx": 2, "def": 13, "role": "DATA", "label": null}], "proj": null},
+ {"id": 15, "label": "If", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 10, "role": "CTRL", "label": null}, {"idx": 1, "def": 14, "role": "DATA", "label": null}], "proj": null},
+ {"id": 16, "label": "False", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 15, "role": "CTRL", "label": null}], "proj": {"par": 15, "idx": 1}},
+ {"id": 17, "label": "True", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 25, "role": "CTRL", "label": null}], "proj": {"par": 25, "idx": 0}},
+ {"id": 18, "label": "False", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 25, "role": "CTRL", "label": null}], "proj": {"par": 25, "idx": 1}},
+ {"id": 19, "label": "#2", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 20, "label": "#3", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 21, "label": "Region", "type": null, "kind": "REGION", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 12, "role": "CTRL", "label": null}, {"idx": 2, "def": 16, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 22, "label": "φ_a", "type": null, "kind": "PHI", "edges": [{"idx": 0, "def": 21, "role": "ASSOC", "label": null}, {"idx": 1, "def": 19, "role": "DATA", "label": null}, {"idx": 2, "def": 20, "role": "DATA", "label": null}], "proj": null},
+ {"id": 23, "label": "#3", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 24, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 6, "role": "DATA", "label": null}, {"idx": 2, "def": 23, "role": "DATA", "label": null}], "proj": null},
+ {"id": 25, "label": "If", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 11, "role": "CTRL", "label": null}, {"idx": 1, "def": 24, "role": "DATA", "label": null}], "proj": null},
+ {"id": 29, "label": "#4", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 30, "label": "#5", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 31, "label": "Region", "type": null, "kind": "REGION", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 17, "role": "CTRL", "label": null}, {"idx": 2, "def": 18, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 32, "label": "φ_a", "type": null, "kind": "PHI", "edges": [{"idx": 0, "def": 31, "role": "ASSOC", "label": null}, {"idx": 1, "def": 29, "role": "DATA", "label": null}, {"idx": 2, "def": 30, "role": "DATA", "label": null}], "proj": null},
+ {"id": 33, "label": "Region", "type": null, "kind": "REGION", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 21, "role": "CTRL", "label": null}, {"idx": 2, "def": 31, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 34, "label": "φ_a", "type": null, "kind": "PHI", "edges": [{"idx": 0, "def": 33, "role": "ASSOC", "label": null}, {"idx": 1, "def": 22, "role": "DATA", "label": null}, {"idx": 2, "def": 32, "role": "DATA", "label": null}], "proj": null},
+ {"id": 35, "label": "Return", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 33, "role": "CTRL", "label": null}, {"idx": 1, "def": 34, "role": "DATA", "label": null}], "proj": null}
+ ],
+ "groups": [
+ {"id": 9, "par": 0, "nodes": [8, 9, 10, 11, 33, 34]},
+ {"id": 15, "par": 9, "nodes": [12, 14, 15, 16, 21, 22]},
+ {"id": 25, "par": 9, "nodes": [17, 18, 24, 25, 31, 32]}
+ ]
+}
diff --git a/chapter05/docs/05-graph8.svg b/chapter05/docs/05-graph8.svg
index e5310db4..bf0f8aa0 100644
--- a/chapter05/docs/05-graph8.svg
+++ b/chapter05/docs/05-graph8.svg
@@ -1,430 +1,188 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Generated by graphviz version 2.43.0 (0)
- -->
-<!-- Title: chapter05 Pages: 1 -->
-<svg width="774pt" height="664pt"
- viewBox="0.00 0.00 774.00 664.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 660)">
-<title>chapter05</title>
-<polygon fill="white" stroke="transparent" points="-4,4 -4,-660 770,-660 770,4 -4,4"/>
-<g id="clust1" class="cluster">
-<title>cluster_Nodes</title>
-<polygon fill="none" stroke="black" points="8,-8 8,-648 550,-648 550,-8 8,-8"/>
-</g>
-<g id="clust5" class="cluster">
-<title>cluster_Scope1_0</title>
-<polygon fill="none" stroke="black" points="558,-72 558,-140 758,-140 758,-72 558,-72"/>
-</g>
-<g id="clust6" class="cluster">
-<title>cluster_Scope1_1</title>
-<polygon fill="none" stroke="black" points="566,-80 566,-132 636,-132 636,-80 566,-80"/>
-</g>
-<!-- Start2 -->
-<g id="node1" class="node">
-<title>Start2</title>
-<polygon fill="yellow" stroke="transparent" points="190,-611 190,-636 271,-636 271,-611 190,-611"/>
-<polygon fill="none" stroke="black" points="190,-611 190,-636 271,-636 271,-611 190,-611"/>
-<text text-anchor="start" x="212" y="-619.8" font-family="Times,serif" font-size="14.00">Start</text>
-<polygon fill="none" stroke="black" points="190,-580 190,-611 271,-611 271,-580 190,-580"/>
-<polygon fill="yellow" stroke="transparent" points="195,-585 195,-606 235,-606 235,-585 195,-585"/>
-<polygon fill="none" stroke="black" points="195,-585 195,-606 235,-606 235,-585 195,-585"/>
-<text text-anchor="start" x="198" y="-591.8" font-family="Times,serif" font-size="14.00">$ctrl</text>
-<polygon fill="none" stroke="black" points="235,-585 235,-606 266,-606 266,-585 235,-585"/>
-<text text-anchor="start" x="238" y="-591.8" font-family="Times,serif" font-size="14.00">arg</text>
-</g>
-<!-- Stop3 -->
-<g id="node2" class="node">
-<title>Stop3</title>
-<polygon fill="yellow" stroke="black" points="286,-52 232,-52 232,-16 286,-16 286,-52"/>
-<text text-anchor="middle" x="259" y="-30.3" font-family="Times,serif" font-size="14.00">Stop</text>
-</g>
-<!-- Return35 -->
-<g id="node22" class="node">
-<title>Return35</title>
-<polygon fill="yellow" stroke="black" points="292,-124 226,-124 226,-88 292,-88 292,-124"/>
-<text text-anchor="middle" x="259" y="-102.3" font-family="Times,serif" font-size="14.00">Return</text>
-</g>
-<!-- Stop3&#45;&gt;Return35 -->
-<g id="edge1" class="edge">
-<title>Stop3&#45;&gt;Return35</title>
-<path fill="none" stroke="red" d="M259,-52.3C259,-60.02 259,-69.29 259,-77.89"/>
-<polygon fill="red" stroke="red" points="255.5,-77.9 259,-87.9 262.5,-77.9 255.5,-77.9"/>
-<text text-anchor="middle" x="256" y="-54.9" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Con_7 -->
-<g id="node3" class="node">
-<title>Con_7</title>
-<ellipse fill="none" stroke="black" cx="136" cy="-608" rx="27" ry="18"/>
-<text text-anchor="middle" x="136" y="-604.3" font-family="Times,serif" font-size="14.00">#1</text>
-</g>
-<!-- EQNode8 -->
-<g id="node4" class="node">
-<title>EQNode8</title>
-<ellipse fill="none" stroke="black" cx="169" cy="-522" rx="27" ry="18"/>
-<text text-anchor="middle" x="169" y="-518.3" font-family="Times,serif" font-size="14.00">==</text>
-</g>
-<!-- EQNode8&#45;&gt;Start2 -->
-<g id="edge2" class="edge">
-<title>EQNode8&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M190.12,-533.69C209.67,-544.17 237.18,-560.54 247.18,-574.44"/>
-<polygon fill="black" stroke="black" points="244.04,-576.01 251,-584 250.54,-573.42 244.04,-576.01"/>
-<text text-anchor="middle" x="187.12" y="-536.29" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode8&#45;&gt;Con_7 -->
-<g id="edge3" class="edge">
-<title>EQNode8&#45;&gt;Con_7</title>
-<path fill="none" stroke="black" d="M162.48,-539.6C157.87,-551.33 151.59,-567.3 146.31,-580.76"/>
-<polygon fill="black" stroke="black" points="142.91,-579.85 142.51,-590.44 149.42,-582.41 142.91,-579.85"/>
-<text text-anchor="middle" x="159.48" y="-542.2" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- If9 -->
-<g id="node5" class="node">
-<title>If9</title>
-<polygon fill="yellow" stroke="transparent" points="124,-439 124,-464 218,-464 218,-439 124,-439"/>
-<polygon fill="none" stroke="black" points="124,-439 124,-464 218,-464 218,-439 124,-439"/>
-<text text-anchor="start" x="165.5" y="-447.8" font-family="Times,serif" font-size="14.00">If</text>
-<polygon fill="none" stroke="black" points="124,-408 124,-439 218,-439 218,-408 124,-408"/>
-<polygon fill="yellow" stroke="transparent" points="129,-413 129,-434 169,-434 169,-413 129,-413"/>
-<polygon fill="none" stroke="black" points="129,-413 129,-434 169,-434 169,-413 129,-413"/>
-<text text-anchor="start" x="132" y="-419.8" font-family="Times,serif" font-size="14.00">True</text>
-<polygon fill="yellow" stroke="transparent" points="169,-413 169,-434 213,-434 213,-413 169,-413"/>
-<polygon fill="none" stroke="black" points="169,-413 169,-434 213,-434 213,-413 169,-413"/>
-<text text-anchor="start" x="172" y="-419.8" font-family="Times,serif" font-size="14.00">False</text>
-</g>
-<!-- If9&#45;&gt;Start2 -->
-<g id="edge4" class="edge">
-<title>If9&#45;&gt;Start2:p0</title>
-<path fill="none" stroke="red" d="M189.59,-468.09C195.4,-479.09 201.26,-491.78 205,-504 214.42,-534.78 214.99,-545.9 215,-573.83"/>
-<polygon fill="red" stroke="red" points="211.5,-574 215,-584 218.5,-574 211.5,-574"/>
-<text text-anchor="middle" x="186.59" y="-470.69" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- If9&#45;&gt;EQNode8 -->
-<g id="edge5" class="edge">
-<title>If9&#45;&gt;EQNode8</title>
-<path fill="none" stroke="black" d="M170.26,-468.28C170.06,-476.58 169.85,-485.48 169.65,-493.56"/>
-<polygon fill="black" stroke="black" points="166.15,-493.51 169.41,-503.6 173.15,-493.68 166.15,-493.51"/>
-<text text-anchor="middle" x="167.26" y="-470.88" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Con_13 -->
-<g id="node6" class="node">
-<title>Con_13</title>
-<ellipse fill="none" stroke="black" cx="71" cy="-522" rx="27" ry="18"/>
-<text text-anchor="middle" x="71" y="-518.3" font-family="Times,serif" font-size="14.00">#2</text>
-</g>
-<!-- EQNode14 -->
-<g id="node7" class="node">
-<title>EQNode14</title>
-<ellipse fill="none" stroke="black" cx="71" cy="-436" rx="27" ry="18"/>
-<text text-anchor="middle" x="71" y="-432.3" font-family="Times,serif" font-size="14.00">==</text>
-</g>
-<!-- EQNode14&#45;&gt;Start2 -->
-<g id="edge6" class="edge">
-<title>EQNode14&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M79.96,-453.18C95.23,-480.56 125.41,-533.7 133,-540 173.12,-573.31 240.9,-534.16 249.98,-573.92"/>
-<polygon fill="black" stroke="black" points="246.51,-574.4 251,-584 253.48,-573.7 246.51,-574.4"/>
-<text text-anchor="middle" x="76.96" y="-455.78" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode14&#45;&gt;Con_13 -->
-<g id="edge7" class="edge">
-<title>EQNode14&#45;&gt;Con_13</title>
-<path fill="none" stroke="black" d="M71,-454.4C71,-465.74 71,-480.77 71,-493.68"/>
-<polygon fill="black" stroke="black" points="67.5,-493.9 71,-503.9 74.5,-493.9 67.5,-493.9"/>
-<text text-anchor="middle" x="68" y="-457" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- If15 -->
-<g id="node8" class="node">
-<title>If15</title>
-<polygon fill="yellow" stroke="transparent" points="24,-339 24,-364 118,-364 118,-339 24,-339"/>
-<polygon fill="none" stroke="black" points="24,-339 24,-364 118,-364 118,-339 24,-339"/>
-<text text-anchor="start" x="65.5" y="-347.8" font-family="Times,serif" font-size="14.00">If</text>
-<polygon fill="none" stroke="black" points="24,-308 24,-339 118,-339 118,-308 24,-308"/>
-<polygon fill="yellow" stroke="transparent" points="29,-313 29,-334 69,-334 69,-313 29,-313"/>
-<polygon fill="none" stroke="black" points="29,-313 29,-334 69,-334 69,-313 29,-313"/>
-<text text-anchor="start" x="32" y="-319.8" font-family="Times,serif" font-size="14.00">True</text>
-<polygon fill="yellow" stroke="transparent" points="69,-313 69,-334 113,-334 113,-313 69,-313"/>
-<polygon fill="none" stroke="black" points="69,-313 69,-334 113,-334 113,-313 69,-313"/>
-<text text-anchor="start" x="72" y="-319.8" font-family="Times,serif" font-size="14.00">False</text>
-</g>
-<!-- If15&#45;&gt;If9 -->
-<g id="edge8" class="edge">
-<title>If15&#45;&gt;If9:p0</title>
-<path fill="none" stroke="red" d="M88.21,-368.05C98.39,-385.75 110.98,-406.4 119.78,-416.61"/>
-<polygon fill="red" stroke="red" points="117.96,-419.62 128,-423 122.25,-414.1 117.96,-419.62"/>
-<text text-anchor="middle" x="85.21" y="-370.65" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- If15&#45;&gt;EQNode14 -->
-<g id="edge9" class="edge">
-<title>If15&#45;&gt;EQNode14</title>
-<path fill="none" stroke="black" d="M71,-368.01C71,-380.76 71,-395.4 71,-407.73"/>
-<polygon fill="black" stroke="black" points="67.5,-407.87 71,-417.87 74.5,-407.87 67.5,-407.87"/>
-<text text-anchor="middle" x="68" y="-370.61" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Con_19 -->
-<g id="node9" class="node">
-<title>Con_19</title>
-<ellipse fill="none" stroke="black" cx="443" cy="-336" rx="27" ry="18"/>
-<text text-anchor="middle" x="443" y="-332.3" font-family="Times,serif" font-size="14.00">#2</text>
-</g>
-<!-- Con_20 -->
-<g id="node10" class="node">
-<title>Con_20</title>
-<ellipse fill="none" stroke="black" cx="515" cy="-336" rx="27" ry="18"/>
-<text text-anchor="middle" x="515" y="-332.3" font-family="Times,serif" font-size="14.00">#3</text>
-</g>
-<!-- Region21 -->
-<g id="node11" class="node">
-<title>Region21</title>
-<polygon fill="yellow" stroke="black" points="147,-268 81,-268 81,-232 147,-232 147,-268"/>
-<text text-anchor="middle" x="114" y="-246.3" font-family="Times,serif" font-size="14.00">Region</text>
-</g>
-<!-- Region21&#45;&gt;If15 -->
-<g id="edge10" class="edge">
-<title>Region21&#45;&gt;If15:p0</title>
-<path fill="none" stroke="red" d="M80.74,-267.13C67.62,-275.57 54.67,-287.24 50.44,-301.92"/>
-<polygon fill="red" stroke="red" points="46.94,-301.61 49,-312 53.87,-302.59 46.94,-301.61"/>
-<text text-anchor="middle" x="77.74" y="-260.73" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Region21&#45;&gt;If15 -->
-<g id="edge11" class="edge">
-<title>Region21&#45;&gt;If15:p1</title>
-<path fill="none" stroke="red" d="M103.71,-268.24C98.93,-277.52 93.86,-289.54 91.87,-301.76"/>
-<polygon fill="red" stroke="red" points="88.36,-301.74 91,-312 95.34,-302.33 88.36,-301.74"/>
-<text text-anchor="middle" x="100.71" y="-270.84" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a22 -->
-<g id="node12" class="node">
-<title>Phi_a22</title>
-<ellipse fill="lightyellow" stroke="black" cx="407" cy="-250" rx="27" ry="18"/>
-<text text-anchor="middle" x="407" y="-246.3" font-family="Times,serif" font-size="14.00">φ_a</text>
-</g>
-<!-- Phi_a22&#45;&gt;Con_19 -->
-<g id="edge13" class="edge">
-<title>Phi_a22&#45;&gt;Con_19</title>
-<path fill="none" stroke="black" d="M414.11,-267.6C419.19,-279.45 426.12,-295.62 431.92,-309.15"/>
-<polygon fill="black" stroke="black" points="428.75,-310.63 435.9,-318.44 435.18,-307.87 428.75,-310.63"/>
-<text text-anchor="middle" x="411.11" y="-270.2" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Phi_a22&#45;&gt;Con_20 -->
-<g id="edge14" class="edge">
-<title>Phi_a22&#45;&gt;Con_20</title>
-<path fill="none" stroke="black" d="M425.04,-263.7C439.78,-274.21 461.03,-289.69 479,-304 483.17,-307.32 487.52,-310.94 491.71,-314.49"/>
-<polygon fill="black" stroke="black" points="489.59,-317.28 499.45,-321.15 494.15,-311.98 489.59,-317.28"/>
-<text text-anchor="middle" x="422.04" y="-266.3" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a22&#45;&gt;Region21 -->
-<g id="edge12" class="edge">
-<title>Phi_a22&#45;&gt;Region21</title>
-<path fill="none" stroke="black" stroke-dasharray="1,5" d="M386.5,-238C370.6,-229.42 347.68,-218.6 326,-214 265.57,-201.18 247.16,-199.97 187,-214 175.19,-216.75 163.08,-221.71 152.22,-227.08"/>
-<polygon fill="black" stroke="black" points="150.28,-224.14 143.03,-231.86 153.51,-230.35 150.28,-224.14"/>
-<text text-anchor="middle" x="383.5" y="-231.6" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Con_23 -->
-<g id="node13" class="node">
-<title>Con_23</title>
-<ellipse fill="none" stroke="black" cx="297" cy="-522" rx="27" ry="18"/>
-<text text-anchor="middle" x="297" y="-518.3" font-family="Times,serif" font-size="14.00">#3</text>
-</g>
-<!-- EQNode24 -->
-<g id="node14" class="node">
-<title>EQNode24</title>
-<ellipse fill="none" stroke="black" cx="271" cy="-436" rx="27" ry="18"/>
-<text text-anchor="middle" x="271" y="-432.3" font-family="Times,serif" font-size="14.00">==</text>
-</g>
-<!-- EQNode24&#45;&gt;Start2 -->
-<g id="edge15" class="edge">
-<title>EQNode24&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="black" d="M267.14,-454.1C261.74,-479.48 252.43,-528.98 251.15,-573.9"/>
-<polygon fill="black" stroke="black" points="247.65,-573.95 251,-584 254.65,-574.05 247.65,-573.95"/>
-<text text-anchor="middle" x="264.14" y="-456.7" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- EQNode24&#45;&gt;Con_23 -->
-<g id="edge16" class="edge">
-<title>EQNode24&#45;&gt;Con_23</title>
-<path fill="none" stroke="black" d="M276.26,-454C279.88,-465.69 284.76,-481.44 288.87,-494.73"/>
-<polygon fill="black" stroke="black" points="285.53,-495.8 291.84,-504.31 292.22,-493.73 285.53,-495.8"/>
-<text text-anchor="middle" x="273.26" y="-456.6" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- If25 -->
-<g id="node15" class="node">
-<title>If25</title>
-<polygon fill="yellow" stroke="transparent" points="152,-339 152,-364 246,-364 246,-339 152,-339"/>
-<polygon fill="none" stroke="black" points="152,-339 152,-364 246,-364 246,-339 152,-339"/>
-<text text-anchor="start" x="193.5" y="-347.8" font-family="Times,serif" font-size="14.00">If</text>
-<polygon fill="none" stroke="black" points="152,-308 152,-339 246,-339 246,-308 152,-308"/>
-<polygon fill="yellow" stroke="transparent" points="157,-313 157,-334 197,-334 197,-313 157,-313"/>
-<polygon fill="none" stroke="black" points="157,-313 157,-334 197,-334 197,-313 157,-313"/>
-<text text-anchor="start" x="160" y="-319.8" font-family="Times,serif" font-size="14.00">True</text>
-<polygon fill="yellow" stroke="transparent" points="197,-313 197,-334 241,-334 241,-313 197,-313"/>
-<polygon fill="none" stroke="black" points="197,-313 197,-334 241,-334 241,-313 197,-313"/>
-<text text-anchor="start" x="200" y="-319.8" font-family="Times,serif" font-size="14.00">False</text>
-</g>
-<!-- If25&#45;&gt;If9 -->
-<g id="edge17" class="edge">
-<title>If25&#45;&gt;If9:p1</title>
-<path fill="none" stroke="red" d="M194.16,-368.3C192.87,-378.58 191.7,-390.29 191.23,-401.68"/>
-<polygon fill="red" stroke="red" points="187.72,-401.93 191,-412 194.72,-402.08 187.72,-401.93"/>
-<text text-anchor="middle" x="191.16" y="-370.9" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- If25&#45;&gt;EQNode24 -->
-<g id="edge18" class="edge">
-<title>If25&#45;&gt;EQNode24</title>
-<path fill="none" stroke="black" d="M221.78,-368.01C232.02,-381.95 243.93,-398.15 253.46,-411.12"/>
-<polygon fill="black" stroke="black" points="250.89,-413.54 259.63,-419.53 256.53,-409.39 250.89,-413.54"/>
-<text text-anchor="middle" x="218.78" y="-370.61" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Con_29 -->
-<g id="node16" class="node">
-<title>Con_29</title>
-<ellipse fill="none" stroke="black" cx="299" cy="-336" rx="27" ry="18"/>
-<text text-anchor="middle" x="299" y="-332.3" font-family="Times,serif" font-size="14.00">#4</text>
-</g>
-<!-- Con_30 -->
-<g id="node17" class="node">
-<title>Con_30</title>
-<ellipse fill="none" stroke="black" cx="371" cy="-336" rx="27" ry="18"/>
-<text text-anchor="middle" x="371" y="-332.3" font-family="Times,serif" font-size="14.00">#5</text>
-</g>
-<!-- Region31 -->
-<g id="node18" class="node">
-<title>Region31</title>
-<polygon fill="yellow" stroke="black" points="253,-268 187,-268 187,-232 253,-232 253,-268"/>
-<text text-anchor="middle" x="220" y="-246.3" font-family="Times,serif" font-size="14.00">Region</text>
-</g>
-<!-- Region31&#45;&gt;If25 -->
-<g id="edge19" class="edge">
-<title>Region31&#45;&gt;If25:p0</title>
-<path fill="none" stroke="red" d="M199.51,-268.03C190.68,-276.94 181.63,-288.71 178.32,-301.78"/>
-<polygon fill="red" stroke="red" points="174.81,-301.63 177,-312 181.75,-302.53 174.81,-301.63"/>
-<text text-anchor="middle" x="196.51" y="-270.63" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Region31&#45;&gt;If25 -->
-<g id="edge20" class="edge">
-<title>Region31&#45;&gt;If25:p1</title>
-<path fill="none" stroke="red" d="M219.57,-268.09C219.36,-277.55 219.13,-289.77 219.04,-301.69"/>
-<polygon fill="red" stroke="red" points="215.54,-301.99 219,-312 222.54,-302.01 215.54,-301.99"/>
-<text text-anchor="middle" x="216.57" y="-270.69" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a32 -->
-<g id="node19" class="node">
-<title>Phi_a32</title>
-<ellipse fill="lightyellow" stroke="black" cx="299" cy="-250" rx="27" ry="18"/>
-<text text-anchor="middle" x="299" y="-246.3" font-family="Times,serif" font-size="14.00">φ_a</text>
-</g>
-<!-- Phi_a32&#45;&gt;Con_29 -->
-<g id="edge22" class="edge">
-<title>Phi_a32&#45;&gt;Con_29</title>
-<path fill="none" stroke="black" d="M299,-268.4C299,-279.74 299,-294.77 299,-307.68"/>
-<polygon fill="black" stroke="black" points="295.5,-307.9 299,-317.9 302.5,-307.9 295.5,-307.9"/>
-<text text-anchor="middle" x="296" y="-271" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Phi_a32&#45;&gt;Con_30 -->
-<g id="edge23" class="edge">
-<title>Phi_a32&#45;&gt;Con_30</title>
-<path fill="none" stroke="black" d="M311.87,-266.02C322.93,-278.92 339.04,-297.71 351.65,-312.42"/>
-<polygon fill="black" stroke="black" points="349.07,-314.8 358.24,-320.11 354.39,-310.24 349.07,-314.8"/>
-<text text-anchor="middle" x="308.87" y="-268.62" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a32&#45;&gt;Region31 -->
-<g id="edge21" class="edge">
-<title>Phi_a32&#45;&gt;Region31</title>
-<path fill="none" stroke="black" stroke-dasharray="1,5" d="M271.7,-250C268.88,-250 266.06,-250 263.23,-250"/>
-<polygon fill="black" stroke="black" points="263.02,-246.5 253.02,-250 263.02,-253.5 263.02,-246.5"/>
-<text text-anchor="middle" x="268.7" y="-243.6" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Region33 -->
-<g id="node20" class="node">
-<title>Region33</title>
-<polygon fill="yellow" stroke="black" points="253,-196 187,-196 187,-160 253,-160 253,-196"/>
-<text text-anchor="middle" x="220" y="-174.3" font-family="Times,serif" font-size="14.00">Region</text>
-</g>
-<!-- Region33&#45;&gt;Region21 -->
-<g id="edge24" class="edge">
-<title>Region33&#45;&gt;Region21</title>
-<path fill="none" stroke="red" d="M194.07,-196.12C180.34,-205.19 163.29,-216.45 148.46,-226.24"/>
-<polygon fill="red" stroke="red" points="146.45,-223.38 140.03,-231.81 150.3,-229.22 146.45,-223.38"/>
-<text text-anchor="middle" x="191.07" y="-198.72" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Region33&#45;&gt;Region31 -->
-<g id="edge25" class="edge">
-<title>Region33&#45;&gt;Region31</title>
-<path fill="none" stroke="red" d="M220,-196.3C220,-204.02 220,-213.29 220,-221.89"/>
-<polygon fill="red" stroke="red" points="216.5,-221.9 220,-231.9 223.5,-221.9 216.5,-221.9"/>
-<text text-anchor="middle" x="217" y="-198.9" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a34 -->
-<g id="node21" class="node">
-<title>Phi_a34</title>
-<ellipse fill="lightyellow" stroke="black" cx="299" cy="-178" rx="27" ry="18"/>
-<text text-anchor="middle" x="299" y="-174.3" font-family="Times,serif" font-size="14.00">φ_a</text>
-</g>
-<!-- Phi_a34&#45;&gt;Phi_a22 -->
-<g id="edge27" class="edge">
-<title>Phi_a34&#45;&gt;Phi_a22</title>
-<path fill="none" stroke="black" d="M317.81,-191.19C335,-202.33 360.62,-218.94 379.99,-231.5"/>
-<polygon fill="black" stroke="black" points="378.11,-234.44 388.4,-236.95 381.92,-228.57 378.11,-234.44"/>
-<text text-anchor="middle" x="314.81" y="-193.79" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Phi_a34&#45;&gt;Phi_a32 -->
-<g id="edge28" class="edge">
-<title>Phi_a34&#45;&gt;Phi_a32</title>
-<path fill="none" stroke="black" d="M299,-196.3C299,-204.02 299,-213.29 299,-221.89"/>
-<polygon fill="black" stroke="black" points="295.5,-221.9 299,-231.9 302.5,-221.9 295.5,-221.9"/>
-<text text-anchor="middle" x="296" y="-198.9" font-family="Helvetica,sans-Serif" font-size="8.00">2</text>
-</g>
-<!-- Phi_a34&#45;&gt;Region33 -->
-<g id="edge26" class="edge">
-<title>Phi_a34&#45;&gt;Region33</title>
-<path fill="none" stroke="black" stroke-dasharray="1,5" d="M271.7,-178C268.88,-178 266.06,-178 263.23,-178"/>
-<polygon fill="black" stroke="black" points="263.02,-174.5 253.02,-178 263.02,-181.5 263.02,-174.5"/>
-<text text-anchor="middle" x="268.7" y="-171.6" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Return35&#45;&gt;Region33 -->
-<g id="edge29" class="edge">
-<title>Return35&#45;&gt;Region33</title>
-<path fill="none" stroke="red" d="M249.36,-124.3C244.87,-132.36 239.44,-142.11 234.48,-151.02"/>
-<polygon fill="red" stroke="red" points="231.34,-149.46 229.53,-159.9 237.45,-152.86 231.34,-149.46"/>
-<text text-anchor="middle" x="246.36" y="-126.9" font-family="Helvetica,sans-Serif" font-size="8.00">0</text>
-</g>
-<!-- Return35&#45;&gt;Phi_a34 -->
-<g id="edge30" class="edge">
-<title>Return35&#45;&gt;Phi_a34</title>
-<path fill="none" stroke="black" d="M268.89,-124.3C273.68,-132.68 279.52,-142.9 284.77,-152.1"/>
-<polygon fill="black" stroke="black" points="281.77,-153.91 289.77,-160.86 287.85,-150.44 281.77,-153.91"/>
-<text text-anchor="middle" x="265.89" y="-126.9" font-family="Helvetica,sans-Serif" font-size="8.00">1</text>
-</g>
-<!-- Scope1_0 -->
-<g id="node23" class="node">
-<title>Scope1_0</title>
-<polygon fill="cyan" stroke="transparent" points="655,-95 655,-116 671,-116 671,-95 655,-95"/>
-<polygon fill="none" stroke="black" points="655,-95 655,-116 671,-116 671,-95 655,-95"/>
-<text text-anchor="start" x="658" y="-101.8" font-family="Times,serif" font-size="14.00">0</text>
-<polygon fill="none" stroke="black" points="671,-95 671,-116 711,-116 711,-95 671,-95"/>
-<text text-anchor="start" x="674" y="-101.8" font-family="Times,serif" font-size="14.00">$ctrl</text>
-<polygon fill="none" stroke="black" points="711,-95 711,-116 742,-116 742,-95 711,-95"/>
-<text text-anchor="start" x="714" y="-101.8" font-family="Times,serif" font-size="14.00">arg</text>
-</g>
-<!-- Scope1_0&#45;&gt;Start2 -->
-<g id="edge31" class="edge">
-<title>Scope1_0:Scope1_0_arg&#45;&gt;Start2:p1</title>
-<path fill="none" stroke="cornflowerblue" stroke-dasharray="5,2" d="M727,-117C727,-185.37 648,-180.63 648,-249 648,-249 648,-249 648,-437 648,-525.53 378.1,-590.44 277.07,-594.77"/>
-<polygon fill="cornflowerblue" stroke="cornflowerblue" points="276.92,-591.27 267,-595 277.08,-598.27 276.92,-591.27"/>
-</g>
-<!-- Scope1_1 -->
-<g id="node24" class="node">
-<title>Scope1_1</title>
-<polygon fill="cyan" stroke="transparent" points="586,-95 586,-116 602,-116 602,-95 586,-95"/>
-<polygon fill="none" stroke="black" points="586,-95 586,-116 602,-116 602,-95 586,-95"/>
-<text text-anchor="start" x="589" y="-101.8" font-family="Times,serif" font-size="14.00">1</text>
-<polygon fill="none" stroke="black" points="602,-95 602,-116 617,-116 617,-95 602,-95"/>
-<text text-anchor="start" x="605" y="-101.8" font-family="Times,serif" font-size="14.00">a</text>
-</g>
-<!-- Scope1_1&#45;&gt;Phi_a34 -->
-<g id="edge32" class="edge">
-<title>Scope1_1:Scope1_1_a&#45;&gt;Phi_a34</title>
-<path fill="none" stroke="cornflowerblue" stroke-dasharray="5,2" d="M610,-117C610,-172.18 418.84,-177.72 336.26,-177.53"/>
-<polygon fill="cornflowerblue" stroke="cornflowerblue" points="336.07,-174.03 326.06,-177.48 336.04,-181.03 336.07,-174.03"/>
-</g>
-</g>
-</svg>
+<svg aria-label="Compiler graph" width="1594" height="1208" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1594 1208" style="font-family: sans-serif;"><style>
+ html, body { height:100%; margin:0; font-family:sans-serif; }
+ .viewer { height:100%; display:grid; grid-template-rows:auto minmax(0,1fr) auto; }
+ .source { padding:8px; border-bottom:1px solid #ccc; }
+ #program { width:min(600px,80vw); vertical-align:middle; }
+ #status { margin-top:4px; }
+ #graph { min-height:0; overflow:hidden; position:relative; background:#fafbfc; }
+ #elk { width:100%; height:100%; }
+ #graph svg { display:block; }
+ .tools { display:flex; flex-wrap:wrap; align-items:center; gap:14px; margin-top:8px; font-size:12px; }
+ .hint { color:#616c78; }
+ .ctrl { color:#b63838; } .mem { color:#2867b2; } .data { color:#536477; }
+ .edge { fill:none; stroke-width:1.5; }
+ .edge.CTRL { stroke-width:2; }
+ .edge.ASSOC { stroke-dasharray:4 4; }
+ .edge.PARSER { stroke-dasharray:5 4; }
+ .parser rect { fill:#f6f0ff; stroke:#7956a5; stroke-width:1.5; stroke-dasharray:5 4; }
+ .edge.selected { stroke-width:3.5; }
+ .edge.bundle { stroke-width:4; }
+ .edge.bundle.selected { stroke-width:6; }
+ .edge-hit { fill:none; stroke:transparent; stroke-width:12; vector-effect:non-scaling-stroke; pointer-events:stroke; cursor:pointer; }
+ .edge-jump { fill:transparent; pointer-events:all; cursor:pointer; }
+ .node { cursor:pointer; }
+ .box { stroke:#758191; stroke-width:1; }
+ .node.held .box { stroke-dasharray:5 3; }
+ .node.near .box { stroke:#c18221; stroke-width:2; }
+ .node.focus .box { stroke:#9c4900; stroke-width:3; }
+ .node.selected .box { stroke:#1569b9; stroke-width:3; }
+ .node.folded .box { stroke-width:4; }
+ .node.folding .box { fill:#f4ccd7; }
+ .fold-tag { font-size:9px; font-weight:700; fill:#963751; }
+ .peep-area { fill:#fff3d9; fill-opacity:.8; stroke:#c18221; stroke-width:2; pointer-events:none; }
+ .node.peep-edit .box { stroke:#9c4900; stroke-width:3; }
+ .node.error .box { stroke:#b42318; stroke-width:4; }
+ #event.error { color:#b42318; font-weight:600; white-space:pre-wrap; overflow-wrap:anywhere; }
+ .peep-ghosts { pointer-events:none; }
+ .region-box { stroke:#9da9b8; stroke-width:1.5; }
+ .fold-btn { cursor:pointer; }
+ .fold-btn rect { fill:white; stroke:#596674; }
+ .fold-btn text { font-size:14px; fill:#152330; }
+ .fold-btn:focus rect { stroke:#1569b9; stroke-width:2; }
+ .shortcut { cursor:pointer; }
+ .shortcut path { fill:none; stroke-width:1.5; }
+ .shortcut rect { fill:#fff8ec; stroke:#b63838; stroke-dasharray:3 2; }
+ .shortcut text { font-size:11px; fill:#783030; }
+ .shortcut.selected rect, .shortcut:focus rect { stroke-width:2.5; }
+ .label { font-size:12px; fill:#152330; font-weight:600; }
+ .node-id { font-size:10px; fill:#596674; font-weight:400; }
+ .type { font-size:11px; fill:#455768; }
+ .port { stroke:#536477; stroke-width:1; }
+ .row { stroke:#b6afcf; stroke-width:1; }
+ .bind { font-size:12px; fill:#152330; }
+ .slot { font-size:10px; fill:#364352; paint-order:stroke; stroke:#fafbfc; stroke-width:3; }
+ #detail { position:absolute; top:8px; right:8px; margin:0; padding:12px; max-width:320px;
+ max-height:45%; overflow:auto; white-space:pre-wrap; overflow-wrap:anywhere;
+ background:#fffffff2; border:1px solid #bac5d0; border-radius:4px; font-size:12px; }
+ .controls { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:6px; padding:6px; }
+ .button { color:white; background:black; font-size:20px; min-width:30px; }
+ .button:disabled { background:grey; }
+ .count { font-size:20px; min-width:35px; text-align:center; }
+ #N { width:6ch; }
+ #scrub { width:clamp(120px,35vw,600px); }
+ </style><defs><marker id="arrow-CTRL" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#b63838"/></marker><marker id="arrow-DATA" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#536477"/></marker><marker id="arrow-MEM" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#2867b2"/></marker><marker id="arrow-ASSOC" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#9396a3"/></marker><marker id="arrow-PARSER" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#7956a5"/></marker></defs><rect width="100%" height="100%" fill="rgb(250, 251, 252)"/><g><g class="regions" style="opacity: 1;"><g class="region" transform="translate(61,193)"><rect class="region-box" rx="8" width="826" height="808" fill="#f2f7ef"/></g><g class="region" transform="translate(73,506)"><rect class="region-box" rx="8" width="410" height="374" fill="#f2f7ef"/></g><g class="region" transform="translate(515,511.7142857142857)"><rect class="region-box" rx="8" width="360" height="354" fill="#f2f7ef"/></g></g><rect class="peep-area" rx="36" style="opacity: 0;"/><g class="edges"><path class="edge ASSOC" id="e1i1" d="M356,115 C356,139 1494.5,0 1494.5,24" stroke="#9396a3" marker-start="url(#arrow-ASSOC)" style="opacity: 1;"><title>#1[1] → #6 · ASSOC · 0: arg</title></path><path class="edge ASSOC" id="e1i2" d="M431,986 C431,1010 1546,0 1546,24" stroke="#9396a3" marker-start="url(#arrow-ASSOC)" style="opacity: 1;"><title>#1[2] → #34 · ASSOC · 1: a</title></path><path class="edge CTRL" id="e3i0" d="M299,1107 C299,1131 797,1134 797,1158" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#3[0] → #35 · CTRL</title></path><path class="edge DATA" id="e8i1" d="M356,118 L356,128 L342,128 L342,247" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#8[1] → #6 · DATA</title></path><path class="edge DATA" id="e8i2" d="M514,118 L514,128 L422,128 L422,237 L372,237 L372,247" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#8[2] → #7 · DATA</title></path><path class="edge CTRL" id="e9i0" d="M236,118 L236,351" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#9[0] → #5 · CTRL</title></path><path class="edge DATA" id="e9i1" d="M342,303 L342,313 L316,313 L316,351" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#9[1] → #8 · DATA</title></path><path class="edge DATA" id="e14i1" d="M356,118 L356,128 L247,128 L247,313 L145,313 L145,560" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#14[1] → #6 · DATA</title></path><path class="edge DATA" id="e14i2" d="M84,118 L84,128 L134,128 L134,461 L135,461 L135,550 L175,550 L175,560" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#14[2] → #13 · DATA</title></path><path class="edge CTRL" id="e15i0" d="M216,451 L216,461 L215,461 L215,664" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#15[0] → #10 · CTRL</title></path><path class="edge DATA" id="e15i1" d="M145,616 L145,626 L295,626 L295,664" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#15[1] → #14 · DATA</title></path><path class="edge CTRL" id="e21i1" d="M195,764 L195,774 L259,774 L259,812" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#21[1] → #12 · CTRL</title></path><path class="edge CTRL" id="e21i2" d="M315,764 L315,774 L289,774 L289,812" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#21[2] → #16 · CTRL</title></path><path class="edge DATA" id="e22i1" d="M666,118 L666,138 L432,138 L432,471 L391,471 L391,812" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#22[1] → #19 · DATA</title></path><path class="edge DATA" id="e22i2" d="M818,118 L818,148 L443,148 L443,481 L431,481 L431,812" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#22[2] → #20 · DATA</title></path><path class="edge DATA" id="e24i1" d="M356,118 L356,128 L412,128 L412,461 L687,461 L687,545.7142857142858" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#24[1] → #6 · DATA</title></path><path class="edge DATA" id="e24i2" d="M970,118 L970,158 L717,158 L717,545.7142857142858" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#24[2] → #23 · DATA</title></path><path class="edge CTRL" id="e25i0" d="M336,451 L336,491 L607,491 L607,649.7142857142858" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#25[0] → #11 · CTRL</title></path><path class="edge DATA" id="e25i1" d="M687,601.7142857142858 L687,649.7142857142858" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#25[1] → #24 · DATA</title></path><path class="edge CTRL" id="e31i1" d="M587,749.7142857142858 L587,759.7142857142858 L651,759.7142857142858 L651,797.7142857142858" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#31[1] → #17 · CTRL</title></path><path class="edge CTRL" id="e31i2" d="M707,749.7142857142858 L707,759.7142857142858 L681,759.7142857142858 L681,797.7142857142858" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#31[2] → #18 · CTRL</title></path><path class="edge DATA" id="e32i1" d="M1122,118 L1122,168 L783,168 L783,797.7142857142858" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#32[1] → #29 · DATA</title></path><path class="edge DATA" id="e32i2" d="M1274,118 L1274,178 L823,178 L823,797.7142857142858" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#32[2] → #30 · DATA</title></path><path class="edge CTRL" id="e33i1" d="M259,868 L259,895 L279,895 L279,933" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#33[1] → #21 · CTRL</title></path><path class="edge CTRL" id="e33i2" d="M651,853.7142857142858 L651,895 L309,895 L309,933" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#33[2] → #31 · CTRL</title></path><path class="edge DATA" id="e34i1" d="M411,868 L411,933" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#34[1] → #22 · DATA</title></path><path class="edge DATA" id="e34i2" d="M803,853.7142857142858 L803,905 L451,905 L451,933" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#34[2] → #32 · DATA</title></path><path class="edge CTRL" id="e35i0" d="M279,989 L279,1054" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#35[0] → #33 · CTRL</title></path><path class="edge DATA" id="e35i1" d="M431,989 L431,1016 L319,1016 L319,1054" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#35[1] → #34 · DATA</title></path></g><g class="edge-hits"/><g class="parser" style="opacity: 1;"/><g class="nodes"><g class="node" id="n1" data-id="1" transform="translate(1406,24)" style="opacity: 1;"><path class="box" d="M4,0H160Q164,0 164,4V52Q164,56 160,56H4Q0,56 0,52V4Q0,0 4,0Z" fill="#e5e0ff"/><text class="label" text-anchor="middle" x="82" y="48"><tspan>Scope</tspan><tspan class="node-id">  #1</tspan></text><text class="type" text-anchor="middle" y="35" x="82"/><title>#1 Scope
+Type not computed
+
+[0] → — ASSOC 0: $ctrl
+[1] → #6 ASSOC 0: arg
+[2] → #34 ASSOC 1: a</title><line class="row" x1="0" x2="164" y1="30" y2="30"/><line class="row" x1="61" x2="61" y1="0" y2="30"/><line class="row" x1="116" x2="116" y1="0" y2="30"/><text class="bind" x="30.5" y="20" text-anchor="middle">0: $ctrl</text><text class="bind" x="88.5" y="20" text-anchor="middle">0: arg</text><text class="bind" x="140" y="20" text-anchor="middle">1: a</text><circle class="port" cx="30.5" cy="0" r="3" fill="white"/><circle class="port" cx="88.5" cy="0" r="3" fill="#536477"/><circle class="port" cx="140" cy="0" r="3" fill="#536477"/><text class="slot" x="30.5" y="-7" text-anchor="middle">0</text><text class="slot" x="88.5" y="-7" text-anchor="middle">1</text><text class="slot" x="140" y="-7" text-anchor="middle">2</text></g><g class="node" id="n2" data-id="2" transform="translate(176,24)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>Start</tspan><tspan class="node-id">  #2</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#2 Start
+Type not computed
+
+</title></g><g class="node" id="n3" data-id="3" transform="translate(761,1158)" style="opacity: 1;"><path class="box" d="M0,0H72V26H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="36" y="17"><tspan>Stop</tspan><tspan class="node-id">  #3</tspan></text><text class="type" text-anchor="middle" y="35" x="36"/><title>#3 Stop
+Type not computed
+
+[0] → #35 CTRL</title><circle class="port" cx="36" cy="0" r="3" fill="#536477"/><text class="slot" x="36" y="-7" text-anchor="middle">0</text></g><g class="node" id="n5" data-id="5" transform="translate(176,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>$ctrl</tspan><tspan class="node-id">  #5/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#5 $ctrl
+Projection 0 of #2
+Type not computed
+
+[0] → #2 CTRL</title></g><g class="node" id="n6" data-id="6" transform="translate(296,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>arg</tspan><tspan class="node-id">  #6/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#6 arg
+Projection 1 of #2
+Type not computed
+
+[0] → #2 DATA</title></g><g class="node" id="n7" data-id="7" transform="translate(454,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#1</tspan><tspan class="node-id">  #7</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#7 #1
+Type not computed
+
+</title></g><g class="node" id="n8" data-id="8" transform="translate(282,253)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #8</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#8 ==
+Type not computed
+
+[0] → — DATA
+[1] → #6 DATA
+[2] → #7 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n9" data-id="9" transform="translate(156,357)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>If</tspan><tspan class="node-id">  #9</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#9 If
+Type not computed
+
+[0] → #5 CTRL
+[1] → #8 DATA</title><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><circle class="port" cx="160" cy="-3" r="3" fill="#536477"/><text class="slot" x="80" y="-10" text-anchor="middle">0</text><text class="slot" x="160" y="-10" text-anchor="middle">1</text></g><g class="node" id="n10" data-id="10" transform="translate(156,401)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>True</tspan><tspan class="node-id">  #10/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#10 True
+Projection 0 of #9
+Type not computed
+
+[0] → #9 CTRL</title></g><g class="node" id="n11" data-id="11" transform="translate(276,401)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>False</tspan><tspan class="node-id">  #11/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#11 False
+Projection 1 of #9
+Type not computed
+
+[0] → #9 CTRL</title></g><g class="node" id="n12" data-id="12" transform="translate(135,714)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>True</tspan><tspan class="node-id">  #12/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#12 True
+Projection 0 of #15
+Type not computed
+
+[0] → #15 CTRL</title></g><g class="node" id="n13" data-id="13" transform="translate(24,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#2</tspan><tspan class="node-id">  #13</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#13 #2
+Type not computed
+
+</title></g><g class="node" id="n14" data-id="14" transform="translate(85,566)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #14</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#14 ==
+Type not computed
+
+[0] → — DATA
+[1] → #6 DATA
+[2] → #13 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n15" data-id="15" transform="translate(135,670)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>If</tspan><tspan class="node-id">  #15</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#15 If
+Type not computed
+
+[0] → #10 CTRL
+[1] → #14 DATA</title><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><circle class="port" cx="160" cy="-3" r="3" fill="#536477"/><text class="slot" x="80" y="-10" text-anchor="middle">0</text><text class="slot" x="160" y="-10" text-anchor="middle">1</text></g><g class="node" id="n16" data-id="16" transform="translate(255,714)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>False</tspan><tspan class="node-id">  #16/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#16 False
+Projection 1 of #15
+Type not computed
+
+[0] → #15 CTRL</title></g><g class="node" id="n17" data-id="17" transform="translate(527,699.7142857142858)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>True</tspan><tspan class="node-id">  #17/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#17 True
+Projection 0 of #25
+Type not computed
+
+[0] → #25 CTRL</title></g><g class="node" id="n18" data-id="18" transform="translate(647,699.7142857142858)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>False</tspan><tspan class="node-id">  #18/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#18 False
+Projection 1 of #25
+Type not computed
+
+[0] → #25 CTRL</title></g><g class="node" id="n19" data-id="19" transform="translate(606,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#2</tspan><tspan class="node-id">  #19</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#19 #2
+Type not computed
+
+</title></g><g class="node" id="n20" data-id="20" transform="translate(758,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#3</tspan><tspan class="node-id">  #20</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#20 #3
+Type not computed
+
+</title></g><g class="node" id="n21" data-id="21" transform="translate(199,818)" style="opacity: 1;"><path class="box" d="M12,0H108L120,44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Region</tspan><tspan class="node-id">  #21</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#21 Region
+Type not computed
+
+[0] → — DATA
+[1] → #12 CTRL
+[2] → #16 CTRL</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n22" data-id="22" transform="translate(351,818)" style="opacity: 1;"><path class="box" d="M12,0H108L120,22L108,44H12L0,22Z" fill="#f5e4fa"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>φ_a</tspan><tspan class="node-id">  #22</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#22 φ_a
+Type not computed
+
+[0] → #21 ASSOC
+[1] → #19 DATA
+[2] → #20 DATA</title><circle class="port" cx="-3" cy="22" r="3" fill="#536477"/><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><path class="reg" fill="none" stroke="#b63838" d="M-3,22H-18m4,-3l-4,3l4,3"><title>[0] → #21</title></path><text class="slot" x="-10" y="15" text-anchor="middle">0</text><text class="slot" x="40" y="-10" text-anchor="middle">1</text><text class="slot" x="80" y="-10" text-anchor="middle">2</text></g><g class="node" id="n23" data-id="23" transform="translate(910,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#3</tspan><tspan class="node-id">  #23</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#23 #3
+Type not computed
+
+</title></g><g class="node" id="n24" data-id="24" transform="translate(627,551.7142857142858)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #24</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#24 ==
+Type not computed
+
+[0] → — DATA
+[1] → #6 DATA
+[2] → #23 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n25" data-id="25" transform="translate(527,655.7142857142858)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>If</tspan><tspan class="node-id">  #25</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#25 If
+Type not computed
+
+[0] → #11 CTRL
+[1] → #24 DATA</title><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><circle class="port" cx="160" cy="-3" r="3" fill="#536477"/><text class="slot" x="80" y="-10" text-anchor="middle">0</text><text class="slot" x="160" y="-10" text-anchor="middle">1</text></g><g class="node" id="n29" data-id="29" transform="translate(1062,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#4</tspan><tspan class="node-id">  #29</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#29 #4
+Type not computed
+
+</title></g><g class="node" id="n30" data-id="30" transform="translate(1214,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>#5</tspan><tspan class="node-id">  #30</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#30 #5
+Type not computed
+
+</title></g><g class="node" id="n31" data-id="31" transform="translate(591,803.7142857142858)" style="opacity: 1;"><path class="box" d="M12,0H108L120,44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Region</tspan><tspan class="node-id">  #31</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#31 Region
+Type not computed
+
+[0] → — DATA
+[1] → #17 CTRL
+[2] → #18 CTRL</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n32" data-id="32" transform="translate(743,803.7142857142858)" style="opacity: 1;"><path class="box" d="M12,0H108L120,22L108,44H12L0,22Z" fill="#f5e4fa"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>φ_a</tspan><tspan class="node-id">  #32</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#32 φ_a
+Type not computed
+
+[0] → #31 ASSOC
+[1] → #29 DATA
+[2] → #30 DATA</title><circle class="port" cx="-3" cy="22" r="3" fill="#536477"/><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><path class="reg" fill="none" stroke="#b63838" d="M-3,22H-18m4,-3l-4,3l4,3"><title>[0] → #31</title></path><text class="slot" x="-10" y="15" text-anchor="middle">0</text><text class="slot" x="40" y="-10" text-anchor="middle">1</text><text class="slot" x="80" y="-10" text-anchor="middle">2</text></g><g class="node" id="n33" data-id="33" transform="translate(219,939)" style="opacity: 1;"><path class="box" d="M12,0H108L120,44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Region</tspan><tspan class="node-id">  #33</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#33 Region
+Type not computed
+
+[0] → — DATA
+[1] → #21 CTRL
+[2] → #31 CTRL</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n34" data-id="34" transform="translate(371,939)" style="opacity: 1;"><path class="box" d="M12,0H108L120,22L108,44H12L0,22Z" fill="#f5e4fa"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>φ_a</tspan><tspan class="node-id">  #34</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#34 φ_a
+Type not computed
+
+[0] → #33 ASSOC
+[1] → #22 DATA
+[2] → #32 DATA</title><circle class="port" cx="-3" cy="22" r="3" fill="#536477"/><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><path class="reg" fill="none" stroke="#b63838" d="M-3,22H-18m4,-3l-4,3l4,3"><title>[0] → #33</title></path><text class="slot" x="-10" y="15" text-anchor="middle">0</text><text class="slot" x="40" y="-10" text-anchor="middle">1</text><text class="slot" x="80" y="-10" text-anchor="middle">2</text></g><g class="node" id="n35" data-id="35" transform="translate(239,1060)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Return</tspan><tspan class="node-id">  #35</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#35 Return
+Type not computed
+
+[0] → #33 CTRL
+[1] → #34 DATA</title><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><text class="slot" x="40" y="-10" text-anchor="middle">0</text><text class="slot" x="80" y="-10" text-anchor="middle">1</text></g></g><g class="region-heads" style="opacity: 1;"><g class="region-head" transform="translate(61,193)"><text class="label" x="26" y="17"><tspan>If</tspan><tspan class="node-id">  #9</tspan></text><title>If · 18 nodes</title><g class="fold-btn" role="button" tabindex="0" transform="translate(4,4)" aria-label="Fold region #9"><rect width="16" height="16" rx="2"/><text x="8" y="12" text-anchor="middle">−</text><title>Fold region</title></g></g><g class="region-head" transform="translate(73,506)"><text class="label" x="26" y="17"><tspan>If</tspan><tspan class="node-id">  #15</tspan></text><title>If · 6 nodes</title><g class="fold-btn" role="button" tabindex="0" transform="translate(4,4)" aria-label="Fold region #15"><rect width="16" height="16" rx="2"/><text x="8" y="12" text-anchor="middle">−</text><title>Fold region</title></g></g><g class="region-head" transform="translate(515,511.7142857142857)"><text class="label" x="26" y="17"><tspan>If</tspan><tspan class="node-id">  #25</tspan></text><title>If · 6 nodes</title><g class="fold-btn" role="button" tabindex="0" transform="translate(4,4)" aria-label="Fold region #25"><rect width="16" height="16" rx="2"/><text x="8" y="12" text-anchor="middle">−</text><title>Fold region</title></g></g></g><g class="shortcuts" style="opacity: 1;"/><g class="peep-ghosts" pointer-events="none"/></g></svg>
diff --git a/chapter05/docs/05-graph9.json b/chapter05/docs/05-graph9.json
new file mode 100644
index 00000000..deb1b540
--- /dev/null
+++ b/chapter05/docs/05-graph9.json
@@ -0,0 +1,26 @@
+{
+ "ver": 1,
+ "comp": "chapter05/docs/05-graph9.svg",
+ "step": 1,
+ "roots": [],
+ "scope": 0,
+ "nodes": [
+ {"id": 1, "label": "$ctrl", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 2, "role": "CTRL", "label": null}], "proj": {"par": 2, "idx": 0}},
+ {"id": 2, "label": "Start", "type": null, "kind": "CTRL", "edges": [], "proj": null},
+ {"id": 3, "label": "Stop", "type": null, "kind": "STOP", "edges": [{"idx": 0, "def": 20, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 4, "label": "arg", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 2, "role": "DATA", "label": null}], "proj": {"par": 2, "idx": 1}},
+ {"id": 5, "label": "True", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 10, "role": "CTRL", "label": null}], "proj": {"par": 10, "idx": 0}},
+ {"id": 6, "label": "False", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 10, "role": "CTRL", "label": null}], "proj": {"par": 10, "idx": 1}},
+ {"id": 8, "label": "1", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 9, "label": "==", "type": null, "kind": "DATA", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 4, "role": "DATA", "label": null}, {"idx": 2, "def": 8, "role": "DATA", "label": null}], "proj": null},
+ {"id": 10, "label": "If", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 1, "role": "CTRL", "label": null}, {"idx": 1, "def": 9, "role": "DATA", "label": null}], "proj": null},
+ {"id": 14, "label": "2", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 16, "label": "1", "type": null, "kind": "DATA", "edges": [], "proj": null},
+ {"id": 17, "label": "Region", "type": null, "kind": "REGION", "edges": [{"idx": 0, "def": 0, "role": "DATA", "label": null}, {"idx": 1, "def": 5, "role": "CTRL", "label": null}, {"idx": 2, "def": 6, "role": "CTRL", "label": null}], "proj": null},
+ {"id": 18, "label": "φ_b", "type": null, "kind": "PHI", "edges": [{"idx": 0, "def": 17, "role": "ASSOC", "label": null}, {"idx": 1, "def": 14, "role": "DATA", "label": null}, {"idx": 2, "def": 16, "role": "DATA", "label": null}], "proj": null},
+ {"id": 20, "label": "Return", "type": null, "kind": "CTRL", "edges": [{"idx": 0, "def": 17, "role": "CTRL", "label": null}, {"idx": 1, "def": 18, "role": "DATA", "label": null}], "proj": null}
+ ],
+ "groups": [
+ {"id": 10, "par": 0, "nodes": [5, 6, 9, 10, 17, 18]}
+ ]
+}
diff --git a/chapter05/docs/05-graph9.svg b/chapter05/docs/05-graph9.svg
index dff4d63f..cc52c5bd 100644
--- a/chapter05/docs/05-graph9.svg
+++ b/chapter05/docs/05-graph9.svg
@@ -1,174 +1,117 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Generated by graphviz version 2.40.1 (20161225.0304)
- -->
-<!-- Title: chapter05 Pages: 1 -->
-<svg width="277pt" height="496pt" viewBox="0.00 0.00 277.00 496.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 492)">
-<title>chapter05</title>
-<polygon fill="#ffffff" stroke="transparent" points="-4,4 -4,-492 273,-492 273,4 -4,4"/>
-<g id="clust1" class="cluster">
-<title>cluster_Nodes</title>
-<polygon fill="none" stroke="#000000" points="8,-8 8,-480 261,-480 261,-8 8,-8"/>
-</g>
-<!-- Start2 -->
-<g id="node1" class="node">
-<title>Start2</title>
-<polygon fill="#ffff00" stroke="transparent" points="109,-442 109,-468 173,-468 173,-442 109,-442"/>
-<polygon fill="none" stroke="#000000" points="109,-442 109,-468 173,-468 173,-442 109,-442"/>
-<text text-anchor="start" x="127.7805" y="-450.4" font-family="Times,serif" font-size="14.00" fill="#000000">Start</text>
-<polygon fill="none" stroke="#000000" points="109,-410 109,-442 173,-442 173,-410 109,-410"/>
-<polygon fill="#ffff00" stroke="transparent" points="114,-415 114,-437 145,-437 145,-415 114,-415"/>
-<polygon fill="none" stroke="#000000" points="114,-415 114,-437 145,-437 145,-415 114,-415"/>
-<text text-anchor="start" x="116.6718" y="-421.4" font-family="Times,serif" font-size="14.00" fill="#000000">$ctrl</text>
-<polygon fill="none" stroke="#000000" points="145,-415 145,-437 168,-437 168,-415 145,-415"/>
-<text text-anchor="start" x="147.5624" y="-421.4" font-family="Times,serif" font-size="14.00" fill="#000000">arg</text>
-</g>
-<!-- Stop3 -->
-<g id="node2" class="node">
-<title>Stop3</title>
-<polygon fill="#ffff00" stroke="#000000" points="179,-52 125,-52 125,-16 179,-16 179,-52"/>
-<text text-anchor="middle" x="152" y="-29.8" font-family="Times,serif" font-size="14.00" fill="#000000">Stop</text>
-</g>
-<!-- Return20 -->
-<g id="node10" class="node">
-<title>Return20</title>
-<polygon fill="#ffff00" stroke="#000000" points="179.1025,-124 124.8975,-124 124.8975,-88 179.1025,-88 179.1025,-124"/>
-<text text-anchor="middle" x="152" y="-101.8" font-family="Times,serif" font-size="14.00" fill="#000000">Return</text>
-</g>
-<!-- Stop3&#45;&gt;Return20 -->
-<g id="edge1" class="edge">
-<title>Stop3-&gt;Return20</title>
-<path fill="none" stroke="#ff0000" d="M152,-52.1686C152,-59.869 152,-69.0257 152,-77.5834"/>
-<polygon fill="#ff0000" stroke="#ff0000" points="148.5001,-77.5867 152,-87.5867 155.5001,-77.5868 148.5001,-77.5867"/>
-<text text-anchor="middle" x="149.7764" y="-54.5686" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#000000">0</text>
-</g>
-<!-- Con_8 -->
-<g id="node3" class="node">
-<title>Con_8</title>
-<ellipse fill="none" stroke="#000000" cx="226" cy="-439" rx="27" ry="18"/>
-<text text-anchor="middle" x="226" y="-434.8" font-family="Times,serif" font-size="14.00" fill="#000000">1</text>
-</g>
-<!-- EQ9 -->
-<g id="node4" class="node">
-<title>EQ9</title>
-<ellipse fill="none" stroke="#000000" cx="207" cy="-352" rx="27" ry="18"/>
-<text text-anchor="middle" x="207" y="-347.8" font-family="Times,serif" font-size="14.00" fill="#000000">==</text>
-</g>
-<!-- EQ9&#45;&gt;Start2 -->
-<g id="edge2" class="edge">
-<title>EQ9-&gt;Start2:p1</title>
-<path fill="none" stroke="#000000" d="M188.0971,-364.9135C176.261,-374.4033 162.483,-388.4885 158.2807,-405.0084"/>
-<polygon fill="#000000" stroke="#000000" points="154.7998,-404.6361 157,-415 161.743,-405.5261 154.7998,-404.6361"/>
-<text text-anchor="middle" x="190.3207" y="-367.3135" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#000000">1</text>
-</g>
-<!-- EQ9&#45;&gt;Con_8 -->
-<g id="edge3" class="edge">
-<title>EQ9-&gt;Con_8</title>
-<path fill="none" stroke="#000000" d="M210.9368,-370.0265C213.5098,-381.8082 216.9235,-397.4393 219.8505,-410.8419"/>
-<polygon fill="#000000" stroke="#000000" points="216.5151,-411.9737 222.0682,-420.9966 223.3539,-410.4801 216.5151,-411.9737"/>
-<text text-anchor="middle" x="208.7132" y="-372.4265" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#000000">2</text>
-</g>
-<!-- If10 -->
-<g id="node5" class="node">
-<title>If10</title>
-<polygon fill="#ffff00" stroke="transparent" points="169,-268 169,-294 246,-294 246,-268 169,-268"/>
-<polygon fill="none" stroke="#000000" points="169,-268 169,-294 246,-294 246,-268 169,-268"/>
-<text text-anchor="start" x="202.8394" y="-276.4" font-family="Times,serif" font-size="14.00" fill="#000000">If</text>
-<polygon fill="none" stroke="#000000" points="169,-236 169,-268 246,-268 246,-236 169,-236"/>
-<polygon fill="#ffff00" stroke="transparent" points="174,-241 174,-263 206,-263 206,-241 174,-241"/>
-<polygon fill="none" stroke="#000000" points="174,-241 174,-263 206,-263 206,-241 174,-241"/>
-<text text-anchor="start" x="176.7861" y="-247.4" font-family="Times,serif" font-size="14.00" fill="#000000">True</text>
-<polygon fill="#ffff00" stroke="transparent" points="206,-241 206,-263 241,-263 241,-241 206,-241"/>
-<polygon fill="none" stroke="#000000" points="206,-241 206,-263 241,-263 241,-241 206,-241"/>
-<text text-anchor="start" x="208.7265" y="-247.4" font-family="Times,serif" font-size="14.00" fill="#000000">False</text>
-</g>
-<!-- If10&#45;&gt;Start2 -->
-<g id="edge4" class="edge">
-<title>If10-&gt;Start2:p0</title>
-<path fill="none" stroke="#ff0000" d="M177.9557,-298.2089C157.4684,-324.8446 133.0529,-364.3668 129.4523,-404.9472"/>
-<polygon fill="#ff0000" stroke="#ff0000" points="125.9531,-404.8528 129,-415 132.946,-405.1674 125.9531,-404.8528"/>
-<text text-anchor="middle" x="175.7321" y="-300.6089" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#000000">0</text>
-</g>
-<!-- If10&#45;&gt;EQ9 -->
-<g id="edge5" class="edge">
-<title>If10-&gt;EQ9</title>
-<path fill="none" stroke="#000000" d="M207,-298.3877C207,-306.7839 207,-315.7123 207,-323.8253"/>
-<polygon fill="#000000" stroke="#000000" points="203.5001,-323.9075 207,-333.9075 210.5001,-323.9075 203.5001,-323.9075"/>
-<text text-anchor="middle" x="204.7764" y="-300.7877" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#000000">1</text>
-</g>
-<!-- Con_14 -->
-<g id="node6" class="node">
-<title>Con_14</title>
-<ellipse fill="none" stroke="#000000" cx="43" cy="-265" rx="27" ry="18"/>
-<text text-anchor="middle" x="43" y="-260.8" font-family="Times,serif" font-size="14.00" fill="#000000">2</text>
-</g>
-<!-- Con_16 -->
-<g id="node7" class="node">
-<title>Con_16</title>
-<ellipse fill="none" stroke="#000000" cx="115" cy="-265" rx="27" ry="18"/>
-<text text-anchor="middle" x="115" y="-260.8" font-family="Times,serif" font-size="14.00" fill="#000000">1</text>
-</g>
-<!-- Region17 -->
-<g id="node8" class="node">
-<title>Region17</title>
-<polygon fill="#ffff00" stroke="#000000" points="217.4435,-196 160.5565,-196 160.5565,-160 217.4435,-160 217.4435,-196"/>
-<text text-anchor="middle" x="189" y="-173.8" font-family="Times,serif" font-size="14.00" fill="#000000">Region</text>
-</g>
-<!-- Region17&#45;&gt;If10 -->
-<g id="edge6" class="edge">
-<title>Region17-&gt;If10:p0</title>
-<path fill="none" stroke="#ff0000" d="M189.4415,-196.1943C189.6508,-206.0242 189.874,-218.6285 189.9616,-230.8706"/>
-<polygon fill="#ff0000" stroke="#ff0000" points="186.462,-231.0134 190,-241 193.4619,-230.9868 186.462,-231.0134"/>
-<text text-anchor="middle" x="187.2179" y="-198.5943" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#000000">1</text>
-</g>
-<!-- Region17&#45;&gt;If10 -->
-<g id="edge7" class="edge">
-<title>Region17-&gt;If10:p1</title>
-<path fill="none" stroke="#ff0000" d="M205.4751,-196.1305C212.7091,-205.5926 220.1774,-217.8998 222.9129,-230.93"/>
-<polygon fill="#ff0000" stroke="#ff0000" points="219.4469,-231.4334 224,-241 226.4064,-230.6821 219.4469,-231.4334"/>
-<text text-anchor="middle" x="203.2515" y="-198.5305" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#000000">2</text>
-</g>
-<!-- Phi_b18 -->
-<g id="node9" class="node">
-<title>Phi_b18</title>
-<ellipse fill="#ffffe0" stroke="#000000" cx="115" cy="-178" rx="27" ry="18"/>
-<text text-anchor="middle" x="115" y="-173.8" font-family="Times,serif" font-size="14.00" fill="#000000">φ_b</text>
-</g>
-<!-- Phi_b18&#45;&gt;Con_14 -->
-<g id="edge9" class="edge">
-<title>Phi_b18-&gt;Con_14</title>
-<path fill="none" stroke="#000000" d="M101.7941,-193.9571C90.8328,-207.202 75.0821,-226.2341 62.6416,-241.2664"/>
-<polygon fill="#000000" stroke="#000000" points="59.8015,-239.2086 56.1222,-249.144 65.1943,-243.6716 59.8015,-239.2086"/>
-<text text-anchor="middle" x="99.5705" y="-196.3571" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#000000">1</text>
-</g>
-<!-- Phi_b18&#45;&gt;Con_16 -->
-<g id="edge10" class="edge">
-<title>Phi_b18-&gt;Con_16</title>
-<path fill="none" stroke="#000000" d="M115,-196.0265C115,-207.8082 115,-223.4393 115,-236.8419"/>
-<polygon fill="#000000" stroke="#000000" points="111.5001,-236.9966 115,-246.9966 118.5001,-236.9967 111.5001,-236.9966"/>
-<text text-anchor="middle" x="112.7764" y="-198.4265" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#000000">2</text>
-</g>
-<!-- Phi_b18&#45;&gt;Region17 -->
-<g id="edge8" class="edge">
-<title>Phi_b18-&gt;Region17</title>
-<path fill="none" stroke="#000000" stroke-dasharray="1,5" d="M142.1719,-178C144.9348,-178 147.6977,-178 150.4605,-178"/>
-<polygon fill="#000000" stroke="#000000" points="150.4641,-181.5001 160.4641,-178 150.4641,-174.5001 150.4641,-181.5001"/>
-<text text-anchor="middle" x="144.3955" y="-170.8" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#000000">0</text>
-</g>
-<!-- Return20&#45;&gt;Region17 -->
-<g id="edge11" class="edge">
-<title>Return20-&gt;Region17</title>
-<path fill="none" stroke="#ff0000" d="M161.3367,-124.1686C165.4243,-132.1229 170.3104,-141.631 174.8309,-150.4277"/>
-<polygon fill="#ff0000" stroke="#ff0000" points="171.8539,-152.2922 179.5376,-159.5867 178.0799,-149.0926 171.8539,-152.2922"/>
-<text text-anchor="middle" x="159.1131" y="-126.5686" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#000000">0</text>
-</g>
-<!-- Return20&#45;&gt;Phi_b18 -->
-<g id="edge12" class="edge">
-<title>Return20-&gt;Phi_b18</title>
-<path fill="none" stroke="#000000" d="M142.6633,-124.1686C138.4051,-132.4549 133.2804,-142.4273 128.6051,-151.5252"/>
-<polygon fill="#000000" stroke="#000000" points="125.4085,-150.0882 123.9508,-160.5823 131.6345,-153.2877 125.4085,-150.0882"/>
-<text text-anchor="middle" x="140.4397" y="-126.5686" font-family="Helvetica,sans-Serif" font-size="8.00" fill="#000000">1</text>
-</g>
-</g>
-</svg> \ No newline at end of file
+<svg aria-label="Compiler graph" width="782" height="734" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 782 734" style="font-family: sans-serif;"><style>
+ html, body { height:100%; margin:0; font-family:sans-serif; }
+ .viewer { height:100%; display:grid; grid-template-rows:auto minmax(0,1fr) auto; }
+ .source { padding:8px; border-bottom:1px solid #ccc; }
+ #program { width:min(600px,80vw); vertical-align:middle; }
+ #status { margin-top:4px; }
+ #graph { min-height:0; overflow:hidden; position:relative; background:#fafbfc; }
+ #elk { width:100%; height:100%; }
+ #graph svg { display:block; }
+ .tools { display:flex; flex-wrap:wrap; align-items:center; gap:14px; margin-top:8px; font-size:12px; }
+ .hint { color:#616c78; }
+ .ctrl { color:#b63838; } .mem { color:#2867b2; } .data { color:#536477; }
+ .edge { fill:none; stroke-width:1.5; }
+ .edge.CTRL { stroke-width:2; }
+ .edge.ASSOC { stroke-dasharray:4 4; }
+ .edge.PARSER { stroke-dasharray:5 4; }
+ .parser rect { fill:#f6f0ff; stroke:#7956a5; stroke-width:1.5; stroke-dasharray:5 4; }
+ .edge.selected { stroke-width:3.5; }
+ .edge.bundle { stroke-width:4; }
+ .edge.bundle.selected { stroke-width:6; }
+ .edge-hit { fill:none; stroke:transparent; stroke-width:12; vector-effect:non-scaling-stroke; pointer-events:stroke; cursor:pointer; }
+ .edge-jump { fill:transparent; pointer-events:all; cursor:pointer; }
+ .node { cursor:pointer; }
+ .box { stroke:#758191; stroke-width:1; }
+ .node.held .box { stroke-dasharray:5 3; }
+ .node.near .box { stroke:#c18221; stroke-width:2; }
+ .node.focus .box { stroke:#9c4900; stroke-width:3; }
+ .node.selected .box { stroke:#1569b9; stroke-width:3; }
+ .node.folded .box { stroke-width:4; }
+ .node.folding .box { fill:#f4ccd7; }
+ .fold-tag { font-size:9px; font-weight:700; fill:#963751; }
+ .peep-area { fill:#fff3d9; fill-opacity:.8; stroke:#c18221; stroke-width:2; pointer-events:none; }
+ .node.peep-edit .box { stroke:#9c4900; stroke-width:3; }
+ .node.error .box { stroke:#b42318; stroke-width:4; }
+ #event.error { color:#b42318; font-weight:600; white-space:pre-wrap; overflow-wrap:anywhere; }
+ .peep-ghosts { pointer-events:none; }
+ .region-box { stroke:#9da9b8; stroke-width:1.5; }
+ .fold-btn { cursor:pointer; }
+ .fold-btn rect { fill:white; stroke:#596674; }
+ .fold-btn text { font-size:14px; fill:#152330; }
+ .fold-btn:focus rect { stroke:#1569b9; stroke-width:2; }
+ .shortcut { cursor:pointer; }
+ .shortcut path { fill:none; stroke-width:1.5; }
+ .shortcut rect { fill:#fff8ec; stroke:#b63838; stroke-dasharray:3 2; }
+ .shortcut text { font-size:11px; fill:#783030; }
+ .shortcut.selected rect, .shortcut:focus rect { stroke-width:2.5; }
+ .label { font-size:12px; fill:#152330; font-weight:600; }
+ .node-id { font-size:10px; fill:#596674; font-weight:400; }
+ .type { font-size:11px; fill:#455768; }
+ .port { stroke:#536477; stroke-width:1; }
+ .row { stroke:#b6afcf; stroke-width:1; }
+ .bind { font-size:12px; fill:#152330; }
+ .slot { font-size:10px; fill:#364352; paint-order:stroke; stroke:#fafbfc; stroke-width:3; }
+ #detail { position:absolute; top:8px; right:8px; margin:0; padding:12px; max-width:320px;
+ max-height:45%; overflow:auto; white-space:pre-wrap; overflow-wrap:anywhere;
+ background:#fffffff2; border:1px solid #bac5d0; border-radius:4px; font-size:12px; }
+ .controls { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:6px; padding:6px; }
+ .button { color:white; background:black; font-size:20px; min-width:30px; }
+ .button:disabled { background:grey; }
+ .count { font-size:20px; min-width:35px; text-align:center; }
+ #N { width:6ch; }
+ #scrub { width:clamp(120px,35vw,600px); }
+ </style><defs><marker id="arrow-CTRL" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#b63838"/></marker><marker id="arrow-DATA" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#536477"/></marker><marker id="arrow-MEM" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#2867b2"/></marker><marker id="arrow-ASSOC" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#9396a3"/></marker><marker id="arrow-PARSER" viewBox="0 -4 8 8" refX="8" refY="0" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,-4L8,0L0,4Z" fill="#7956a5"/></marker></defs><rect width="100%" height="100%" fill="rgb(250, 251, 252)"/><g><g class="regions" style="opacity: 1;"><g class="region" transform="translate(24,173)"><rect class="region-box" rx="8" width="360" height="354" fill="#f2f7ef"/></g></g><rect class="peep-area" rx="36" style="opacity: 0;"/><g class="edges"><path class="edge CTRL" id="e3i0" d="M180,633 C180,657 391,660 391,684" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#3[0] → #20 · CTRL</title></path><path class="edge DATA" id="e9i1" d="M236,118 L236,128 L196,128 L196,207" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#9[1] → #4 · DATA</title></path><path class="edge DATA" id="e9i2" d="M394,118 L394,138 L226,138 L226,207" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#9[2] → #8 · DATA</title></path><path class="edge CTRL" id="e10i0" d="M116,118 L116,311" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#10[0] → #1 · CTRL</title></path><path class="edge DATA" id="e10i1" d="M196,263 L196,311" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#10[1] → #9 · DATA</title></path><path class="edge CTRL" id="e17i1" d="M96,411 L96,421 L160,421 L160,459" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#17[1] → #5 · CTRL</title></path><path class="edge CTRL" id="e17i2" d="M216,411 L216,421 L190,421 L190,459" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#17[2] → #6 · CTRL</title></path><path class="edge DATA" id="e18i1" d="M546,118 L546,148 L292,148 L292,459" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#18[1] → #14 · DATA</title></path><path class="edge DATA" id="e18i2" d="M698,118 L698,158 L332,158 L332,459" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#18[2] → #16 · DATA</title></path><path class="edge CTRL" id="e20i0" d="M160,515 L160,580" stroke="#b63838" marker-start="url(#arrow-CTRL)" style="opacity: 1;"><title>#20[0] → #17 · CTRL</title></path><path class="edge DATA" id="e20i1" d="M312,515 L312,542 L200,542 L200,580" stroke="#536477" marker-start="url(#arrow-DATA)" style="opacity: 1;"><title>#20[1] → #18 · DATA</title></path></g><g class="edge-hits"/><g class="parser" style="opacity: 1;"/><g class="nodes"><g class="node" id="n1" data-id="1" transform="translate(56,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>$ctrl</tspan><tspan class="node-id">  #1/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#1 $ctrl
+Projection 0 of #2
+Type not computed
+
+[0] → #2 CTRL</title></g><g class="node" id="n2" data-id="2" transform="translate(56,24)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>Start</tspan><tspan class="node-id">  #2</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#2 Start
+Type not computed
+
+</title></g><g class="node" id="n3" data-id="3" transform="translate(355,684)" style="opacity: 1;"><path class="box" d="M0,0H72V26H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="36" y="17"><tspan>Stop</tspan><tspan class="node-id">  #3</tspan></text><text class="type" text-anchor="middle" y="35" x="36"/><title>#3 Stop
+Type not computed
+
+[0] → #20 CTRL</title><circle class="port" cx="36" cy="0" r="3" fill="#536477"/><text class="slot" x="36" y="-7" text-anchor="middle">0</text></g><g class="node" id="n4" data-id="4" transform="translate(176,68)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>arg</tspan><tspan class="node-id">  #4/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#4 arg
+Projection 1 of #2
+Type not computed
+
+[0] → #2 DATA</title></g><g class="node" id="n5" data-id="5" transform="translate(36,361)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>True</tspan><tspan class="node-id">  #5/0</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#5 True
+Projection 0 of #10
+Type not computed
+
+[0] → #10 CTRL</title></g><g class="node" id="n6" data-id="6" transform="translate(156,361)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>False</tspan><tspan class="node-id">  #6/1</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#6 False
+Projection 1 of #10
+Type not computed
+
+[0] → #10 CTRL</title></g><g class="node" id="n8" data-id="8" transform="translate(334,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>1</tspan><tspan class="node-id">  #8</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#8 1
+Type not computed
+
+</title></g><g class="node" id="n9" data-id="9" transform="translate(136,213)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>==</tspan><tspan class="node-id">  #9</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#9 ==
+Type not computed
+
+[0] → — DATA
+[1] → #4 DATA
+[2] → #8 DATA</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n10" data-id="10" transform="translate(36,317)" style="opacity: 1;"><path class="box" d="M0,0H240V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="120" y="18"><tspan>If</tspan><tspan class="node-id">  #10</tspan></text><text class="type" text-anchor="middle" y="35" x="120"/><title>#10 If
+Type not computed
+
+[0] → #1 CTRL
+[1] → #9 DATA</title><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><circle class="port" cx="160" cy="-3" r="3" fill="#536477"/><text class="slot" x="80" y="-10" text-anchor="middle">0</text><text class="slot" x="160" y="-10" text-anchor="middle">1</text></g><g class="node" id="n14" data-id="14" transform="translate(486,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>2</tspan><tspan class="node-id">  #14</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#14 2
+Type not computed
+
+</title></g><g class="node" id="n16" data-id="16" transform="translate(638,68)" style="opacity: 1;"><path class="box" d="M14,0H106Q120,0 120,14V30Q120,44 106,44H14Q0,44 0,30V14Q0,0 14,0Z" fill="#edf3f7"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>1</tspan><tspan class="node-id">  #16</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#16 1
+Type not computed
+
+</title></g><g class="node" id="n17" data-id="17" transform="translate(100,465)" style="opacity: 1;"><path class="box" d="M12,0H108L120,44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Region</tspan><tspan class="node-id">  #17</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#17 Region
+Type not computed
+
+[0] → — DATA
+[1] → #5 CTRL
+[2] → #6 CTRL</title><circle class="port" cx="30" cy="-3" r="3" fill="white"/><circle class="port" cx="60" cy="-3" r="3" fill="#536477"/><circle class="port" cx="90" cy="-3" r="3" fill="#536477"/><text class="slot" x="30" y="-10" text-anchor="middle">0</text><text class="slot" x="60" y="-10" text-anchor="middle">1</text><text class="slot" x="90" y="-10" text-anchor="middle">2</text></g><g class="node" id="n18" data-id="18" transform="translate(252,465)" style="opacity: 1;"><path class="box" d="M12,0H108L120,22L108,44H12L0,22Z" fill="#f5e4fa"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>φ_b</tspan><tspan class="node-id">  #18</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#18 φ_b
+Type not computed
+
+[0] → #17 ASSOC
+[1] → #14 DATA
+[2] → #16 DATA</title><circle class="port" cx="-3" cy="22" r="3" fill="#536477"/><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><path class="reg" fill="none" stroke="#b63838" d="M-3,22H-18m4,-3l-4,3l4,3"><title>[0] → #17</title></path><text class="slot" x="-10" y="15" text-anchor="middle">0</text><text class="slot" x="40" y="-10" text-anchor="middle">1</text><text class="slot" x="80" y="-10" text-anchor="middle">2</text></g><g class="node" id="n20" data-id="20" transform="translate(120,586)" style="opacity: 1;"><path class="box" d="M0,0H120V44H0Z" fill="#fff1c4"/><text class="label" text-anchor="middle" x="60" y="18"><tspan>Return</tspan><tspan class="node-id">  #20</tspan></text><text class="type" text-anchor="middle" y="35" x="60"/><title>#20 Return
+Type not computed
+
+[0] → #17 CTRL
+[1] → #18 DATA</title><circle class="port" cx="40" cy="-3" r="3" fill="#536477"/><circle class="port" cx="80" cy="-3" r="3" fill="#536477"/><text class="slot" x="40" y="-10" text-anchor="middle">0</text><text class="slot" x="80" y="-10" text-anchor="middle">1</text></g></g><g class="region-heads" style="opacity: 1;"><g class="region-head" transform="translate(24,173)"><text class="label" x="26" y="17"><tspan>If</tspan><tspan class="node-id">  #10</tspan></text><title>If · 6 nodes</title><g class="fold-btn" role="button" tabindex="0" transform="translate(4,4)" aria-label="Fold region #10"><rect width="16" height="16" rx="2"/><text x="8" y="12" text-anchor="middle">−</text><title>Fold region</title></g></g></g><g class="shortcuts" style="opacity: 1;"/><g class="peep-ghosts" pointer-events="none"/></g></svg>
diff --git a/chapter05/docs/Makefile b/chapter05/docs/Makefile
index 12659b8f..6fa0f057 100644
--- a/chapter05/docs/Makefile
+++ b/chapter05/docs/Makefile
@@ -1,12 +1 @@
-GV := $(wildcard *.gv)
-SVG := $(patsubst %.gv,%.svg,$(GV))
-
-.PHONY: all
-all: $(SVG)
-
-%.svg: %.gv
- dot -Tsvg $< > $@
-
-.PHONY: clean
-clean:
- @rm -f $(SVG)
+include ../../graph/docs.mk