summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@gmail.com>2021-03-11 20:15:47 -0800
committerIrene Knapp <ireneista@gmail.com>2021-03-11 20:15:47 -0800
commit86990efcf8fa63decb05f462d745b95e4992dc77 (patch)
tree46990fd1c749ccca0b6477650973d83174e5e264
parenta159d4dd29491a1eb88163e63ceb41a903dc47b6 (diff)
refactor everything into smaller modules; move to using async-std; make the read loop async. some stuff doesn't work yet but it needed to be done and this is as clean a state as it's likely to get in, so we're committing it as a base to build on.
-rw-r--r--Cargo.lock460
-rw-r--r--Cargo.nix1685
-rw-r--r--Cargo.toml6
-rw-r--r--src/error.rs33
-rw-r--r--src/main.rs61
-rw-r--r--src/path.rs21
-rw-r--r--src/path/error.rs28
-rw-r--r--src/path/prelude.rs5
-rw-r--r--src/prelude.rs5
-rw-r--r--src/result.rs2
-rw-r--r--src/terminal.rs216
-rw-r--r--src/terminal/decoding.rs151
-rw-r--r--src/terminal/error.rs14
-rw-r--r--src/terminal/prelude.rs4
14 files changed, 2507 insertions, 184 deletions
diff --git a/Cargo.lock b/Cargo.lock
index c775fd3..b6d2c4d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -31,6 +31,124 @@ dependencies = [
 ]
 
 [[package]]
+name = "async-channel"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59740d83946db6a5af71ae25ddf9562c2b176b2ca42cf99a455f09f4a220d6b9"
+dependencies = [
+ "concurrent-queue",
+ "event-listener",
+ "futures-core",
+]
+
+[[package]]
+name = "async-executor"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb877970c7b440ead138f6321a3b5395d6061183af779340b65e20c0fede9146"
+dependencies = [
+ "async-task",
+ "concurrent-queue",
+ "fastrand",
+ "futures-lite",
+ "once_cell",
+ "vec-arena",
+]
+
+[[package]]
+name = "async-global-executor"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9586ec52317f36de58453159d48351bc244bc24ced3effc1fce22f3d48664af6"
+dependencies = [
+ "async-channel",
+ "async-executor",
+ "async-io",
+ "async-mutex",
+ "blocking",
+ "futures-lite",
+ "num_cpus",
+ "once_cell",
+]
+
+[[package]]
+name = "async-io"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9315f8f07556761c3e48fec2e6b276004acf426e6dc068b2c2251854d65ee0fd"
+dependencies = [
+ "concurrent-queue",
+ "fastrand",
+ "futures-lite",
+ "libc",
+ "log",
+ "nb-connect",
+ "once_cell",
+ "parking",
+ "polling",
+ "vec-arena",
+ "waker-fn",
+ "winapi",
+]
+
+[[package]]
+name = "async-lock"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1996609732bde4a9988bc42125f55f2af5f3c36370e27c778d5191a4a1b63bfb"
+dependencies = [
+ "event-listener",
+]
+
+[[package]]
+name = "async-mutex"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e"
+dependencies = [
+ "event-listener",
+]
+
+[[package]]
+name = "async-std"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9f06685bad74e0570f5213741bea82158279a4103d988e57bfada11ad230341"
+dependencies = [
+ "async-channel",
+ "async-global-executor",
+ "async-io",
+ "async-lock",
+ "crossbeam-utils 0.8.1",
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-lite",
+ "gloo-timers",
+ "kv-log-macro",
+ "log",
+ "memchr",
+ "num_cpus",
+ "once_cell",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+ "wasm-bindgen-futures",
+]
+
+[[package]]
+name = "async-task"
+version = "4.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0"
+
+[[package]]
+name = "atomic-waker"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a"
+
+[[package]]
 name = "atty"
 version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -107,6 +225,26 @@ dependencies = [
 ]
 
 [[package]]
+name = "blocking"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5e170dbede1f740736619b776d7251cb1b9095c435c34d8ca9f57fcd2f335e9"
+dependencies = [
+ "async-channel",
+ "async-task",
+ "atomic-waker",
+ "fastrand",
+ "futures-lite",
+ "once_cell",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f07aa6688c702439a1be0307b6a94dffe1168569e45b9500c1372bc580740d59"
+
+[[package]]
 name = "byte-tools"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -119,6 +257,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
 
 [[package]]
+name = "cache-padded"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
+
+[[package]]
 name = "cc"
 version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -137,6 +281,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
+name = "concurrent-queue"
+version = "1.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
+dependencies = [
+ "cache-padded",
+]
+
+[[package]]
 name = "constant_time_eq"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -154,6 +307,17 @@ dependencies = [
 ]
 
 [[package]]
+name = "crossbeam-utils"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
+dependencies = [
+ "autocfg",
+ "cfg-if 1.0.0",
+ "lazy_static",
+]
+
+[[package]]
 name = "diff"
 version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -207,18 +371,69 @@ dependencies = [
 ]
 
 [[package]]
+name = "event-listener"
+version = "2.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59"
+
+[[package]]
 name = "fake-simd"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
 
 [[package]]
+name = "fastrand"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca5faf057445ce5c9d4329e382b2ce7ca38550ef3b73a5348362d5f24e0c7fe3"
+dependencies = [
+ "instant",
+]
+
+[[package]]
 name = "fixedbitset"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
 
 [[package]]
+name = "futures-channel"
+version = "0.3.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2d31b7ec7efab6eefc7c57233bb10b847986139d88cc2f5a02a1ae6871a1846"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79e5145dde8da7d1b3892dad07a9c98fc04bc39892b1ecc9692cf53e2b780a65"
+
+[[package]]
+name = "futures-io"
+version = "0.3.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28be053525281ad8259d47e4de5de657b25e7bac113458555bb4b70bc6870500"
+
+[[package]]
+name = "futures-lite"
+version = "1.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4481d0cd0de1d204a4fa55e7d45f07b1d958abcb06714b3446438e2eff695fb"
+dependencies = [
+ "fastrand",
+ "futures-core",
+ "futures-io",
+ "memchr",
+ "parking",
+ "pin-project-lite",
+ "waker-fn",
+]
+
+[[package]]
 name = "generic-array"
 version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -239,6 +454,19 @@ dependencies = [
 ]
 
 [[package]]
+name = "gloo-timers"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
 name = "hashbrown"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -264,6 +492,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "instant"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
 name = "itertools"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -273,6 +510,24 @@ dependencies = [
 ]
 
 [[package]]
+name = "js-sys"
+version = "0.3.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5cfb73131c35423a367daf8cbd24100af0d077668c8c2943f0e7dd775fef0f65"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "kv-log-macro"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
+dependencies = [
+ "log",
+]
+
+[[package]]
 name = "lalrpop"
 version = "0.19.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -334,6 +589,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
 
 [[package]]
+name = "nb-connect"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8123a81538e457d44b933a02faf885d3fe8408806b23fa700e8f01c6c3a98998"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
 name = "new_debug_unreachable"
 version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -352,12 +617,34 @@ dependencies = [
 ]
 
 [[package]]
+name = "num_cpus"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
+dependencies = [
+ "hermit-abi",
+ "libc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
+
+[[package]]
 name = "opaque-debug"
 version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
 
 [[package]]
+name = "parking"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
+
+[[package]]
 name = "petgraph"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -377,6 +664,51 @@ dependencies = [
 ]
 
 [[package]]
+name = "pin-project"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95b70b68509f17aa2857863b6fa00bf21fc93674c7a8893de2f469f6aa7ca2f2"
+dependencies = [
+ "pin-project-internal",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "caa25a6393f22ce819b0f50e0be89287292fda8d425be38ee0ca14c4931d9e71"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "polling"
+version = "2.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2a7bc6b2a29e632e45451c941832803a18cce6781db04de8a04696cdca8bde4"
+dependencies = [
+ "cfg-if 0.1.10",
+ "libc",
+ "log",
+ "wepoll-sys",
+ "winapi",
+]
+
+[[package]]
 name = "precomputed-hash"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -444,7 +776,7 @@ dependencies = [
  "base64",
  "blake2b_simd",
  "constant_time_eq",
- "crossbeam-utils",
+ "crossbeam-utils 0.7.2",
 ]
 
 [[package]]
@@ -483,9 +815,32 @@ dependencies = [
 name = "shell"
 version = "0.1.0"
 dependencies = [
+ "async-std",
  "lalrpop",
  "lalrpop-util",
  "nix",
+ "pin-project",
+ "pin-utils",
+ "signal-hook",
+]
+
+[[package]]
+name = "signal-hook"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "780f5e3fe0c66f67197236097d89de1e86216f1f6fdeaf47c442f854ab46c240"
+dependencies = [
+ "libc",
+ "signal-hook-registry",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6"
+dependencies = [
+ "libc",
 ]
 
 [[package]]
@@ -495,6 +850,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
 
 [[package]]
+name = "slab"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
+
+[[package]]
 name = "string_cache"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -557,12 +918,109 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
 
 [[package]]
+name = "vec-arena"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eafc1b9b2dfc6f5529177b62cf806484db55b32dc7c9658a118e11bbeb33061d"
+
+[[package]]
+name = "waker-fn"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
+
+[[package]]
 name = "wasi"
 version = "0.9.0+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
 
 [[package]]
+name = "wasm-bindgen"
+version = "0.2.70"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55c0f7123de74f0dab9b7d00fd614e7b19349cd1e2f5252bbe9b1754b59433be"
+dependencies = [
+ "cfg-if 1.0.0",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.70"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7bc45447f0d4573f3d65720f636bbcc3dd6ce920ed704670118650bcd47764c7"
+dependencies = [
+ "bumpalo",
+ "lazy_static",
+ "log",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3de431a2910c86679c34283a33f66f4e4abd7e0aec27b6669060148872aadf94"
+dependencies = [
+ "cfg-if 1.0.0",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.70"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b8853882eef39593ad4174dd26fc9865a64e84026d223f63bb2c42affcbba2c"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.70"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4133b5e7f2a531fa413b3a1695e925038a05a71cf67e87dafa295cb645a01385"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.70"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd4945e4943ae02d15c13962b38a5b1e81eadd4b71214eee75af64a4d6a4fd64"
+
+[[package]]
+name = "web-sys"
+version = "0.3.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c40dc691fc48003eba817c38da7113c15698142da971298003cac3ef175680b3"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "wepoll-sys"
+version = "3.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fcb14dea929042224824779fbc82d9fab8d2e6d3cbc0ac404de8edf489e77ff"
+dependencies = [
+ "cc",
+]
+
+[[package]]
 name = "winapi"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.nix b/Cargo.nix
index 0e39dd2..35566b5 100644
--- a/Cargo.nix
+++ b/Cargo.nix
@@ -136,6 +136,366 @@ rec {
         ];
         
       };
+      "async-channel" = rec {
+        crateName = "async-channel";
+        version = "1.5.1";
+        edition = "2018";
+        sha256 = "1ffn42ig82az8ndgjb545imifarcavwxs9dff6psbdkdjj1hsx2r";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "concurrent-queue";
+            packageId = "concurrent-queue";
+          }
+          {
+            name = "event-listener";
+            packageId = "event-listener";
+          }
+          {
+            name = "futures-core";
+            packageId = "futures-core";
+          }
+        ];
+        
+      };
+      "async-executor" = rec {
+        crateName = "async-executor";
+        version = "1.4.0";
+        edition = "2018";
+        sha256 = "0ilivvzc082ynr096xxghc8hdmlmacxilcpn738ylh5lqxq7k1zb";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "async-task";
+            packageId = "async-task";
+          }
+          {
+            name = "concurrent-queue";
+            packageId = "concurrent-queue";
+          }
+          {
+            name = "fastrand";
+            packageId = "fastrand";
+          }
+          {
+            name = "futures-lite";
+            packageId = "futures-lite";
+          }
+          {
+            name = "once_cell";
+            packageId = "once_cell";
+          }
+          {
+            name = "vec-arena";
+            packageId = "vec-arena";
+          }
+        ];
+        
+      };
+      "async-global-executor" = rec {
+        crateName = "async-global-executor";
+        version = "2.0.2";
+        edition = "2018";
+        sha256 = "1xjacr43sbz2zk0zygpd9k14n95wa61x8n9i8mcdwdkz659fr1lm";
+        authors = [
+          "Marc-Antoine Perennou <Marc-Antoine@Perennou.com>"
+        ];
+        dependencies = [
+          {
+            name = "async-channel";
+            packageId = "async-channel";
+          }
+          {
+            name = "async-executor";
+            packageId = "async-executor";
+          }
+          {
+            name = "async-io";
+            packageId = "async-io";
+            optional = true;
+          }
+          {
+            name = "async-mutex";
+            packageId = "async-mutex";
+          }
+          {
+            name = "blocking";
+            packageId = "blocking";
+          }
+          {
+            name = "futures-lite";
+            packageId = "futures-lite";
+          }
+          {
+            name = "num_cpus";
+            packageId = "num_cpus";
+          }
+          {
+            name = "once_cell";
+            packageId = "once_cell";
+          }
+        ];
+        features = {
+          "default" = [ "async-io" ];
+          "tokio" = [ "tokio-crate" ];
+          "tokio02" = [ "tokio02-crate" ];
+          "tokio03" = [ "tokio03-crate" ];
+        };
+        resolvedDefaultFeatures = [ "async-io" "default" ];
+      };
+      "async-io" = rec {
+        crateName = "async-io";
+        version = "1.3.1";
+        edition = "2018";
+        sha256 = "1zg0bvb58615qar6ih3ddr1cyjh0fsrfdhpy90z1qxjnfpqgh5ck";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "concurrent-queue";
+            packageId = "concurrent-queue";
+          }
+          {
+            name = "fastrand";
+            packageId = "fastrand";
+          }
+          {
+            name = "futures-lite";
+            packageId = "futures-lite";
+          }
+          {
+            name = "libc";
+            packageId = "libc";
+            target = { target, features }: target."unix";
+          }
+          {
+            name = "log";
+            packageId = "log";
+          }
+          {
+            name = "nb-connect";
+            packageId = "nb-connect";
+          }
+          {
+            name = "once_cell";
+            packageId = "once_cell";
+          }
+          {
+            name = "parking";
+            packageId = "parking";
+          }
+          {
+            name = "polling";
+            packageId = "polling";
+          }
+          {
+            name = "vec-arena";
+            packageId = "vec-arena";
+          }
+          {
+            name = "waker-fn";
+            packageId = "waker-fn";
+          }
+          {
+            name = "winapi";
+            packageId = "winapi";
+            target = { target, features }: target."windows";
+            features = [ "winsock2" ];
+          }
+        ];
+        
+      };
+      "async-lock" = rec {
+        crateName = "async-lock";
+        version = "2.3.0";
+        edition = "2018";
+        sha256 = "1yrvnshs94aiimvprqkhcg1z7x9abzsja8f4ifcakr5x6abn15hr";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "event-listener";
+            packageId = "event-listener";
+          }
+        ];
+        
+      };
+      "async-mutex" = rec {
+        crateName = "async-mutex";
+        version = "1.4.0";
+        edition = "2018";
+        sha256 = "0vhmsscqx48dmxw0yir6az0pbwcq6qjvcv2f43vdpn95vd9bi7a7";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "event-listener";
+            packageId = "event-listener";
+          }
+        ];
+        
+      };
+      "async-std" = rec {
+        crateName = "async-std";
+        version = "1.9.0";
+        edition = "2018";
+        sha256 = "0h834fni3npsggjqin8386d2fn11m2z42dr1ymq0aknppa2ndw6r";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+          "Yoshua Wuyts <yoshuawuyts@gmail.com>"
+          "Friedel Ziegelmayer <me@dignifiedquire.com>"
+          "Contributors to async-std"
+        ];
+        dependencies = [
+          {
+            name = "async-channel";
+            packageId = "async-channel";
+            optional = true;
+          }
+          {
+            name = "async-global-executor";
+            packageId = "async-global-executor";
+            optional = true;
+            target = { target, features }: (!(target."os" == "unknown"));
+            features = [ "async-io" ];
+          }
+          {
+            name = "async-io";
+            packageId = "async-io";
+            optional = true;
+            target = { target, features }: (!(target."os" == "unknown"));
+          }
+          {
+            name = "async-lock";
+            packageId = "async-lock";
+            optional = true;
+          }
+          {
+            name = "crossbeam-utils";
+            packageId = "crossbeam-utils 0.8.1";
+            optional = true;
+          }
+          {
+            name = "futures-channel";
+            packageId = "futures-channel";
+            optional = true;
+            target = { target, features }: (target."arch" == "wasm32");
+          }
+          {
+            name = "futures-core";
+            packageId = "futures-core";
+            optional = true;
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "futures-io";
+            packageId = "futures-io";
+            optional = true;
+          }
+          {
+            name = "futures-lite";
+            packageId = "futures-lite";
+            optional = true;
+            target = { target, features }: (!(target."os" == "unknown"));
+          }
+          {
+            name = "gloo-timers";
+            packageId = "gloo-timers";
+            optional = true;
+            target = { target, features }: (target."arch" == "wasm32");
+            features = [ "futures" ];
+          }
+          {
+            name = "kv-log-macro";
+            packageId = "kv-log-macro";
+            optional = true;
+          }
+          {
+            name = "log";
+            packageId = "log";
+            optional = true;
+            features = [ "kv_unstable" ];
+          }
+          {
+            name = "memchr";
+            packageId = "memchr";
+            optional = true;
+          }
+          {
+            name = "num_cpus";
+            packageId = "num_cpus";
+            optional = true;
+          }
+          {
+            name = "once_cell";
+            packageId = "once_cell";
+            optional = true;
+          }
+          {
+            name = "pin-project-lite";
+            packageId = "pin-project-lite";
+            optional = true;
+          }
+          {
+            name = "pin-utils";
+            packageId = "pin-utils";
+            optional = true;
+          }
+          {
+            name = "slab";
+            packageId = "slab";
+            optional = true;
+          }
+          {
+            name = "wasm-bindgen-futures";
+            packageId = "wasm-bindgen-futures";
+            optional = true;
+            target = { target, features }: (target."arch" == "wasm32");
+          }
+        ];
+        features = {
+          "alloc" = [ "futures-core/alloc" "pin-project-lite" ];
+          "attributes" = [ "async-attributes" ];
+          "default" = [ "std" "async-global-executor" "async-io" "futures-lite" "kv-log-macro" "log" "num_cpus" "pin-project-lite" "gloo-timers" ];
+          "docs" = [ "attributes" "unstable" "default" ];
+          "std" = [ "alloc" "crossbeam-utils" "futures-core/std" "futures-io" "memchr" "once_cell" "pin-utils" "slab" "wasm-bindgen-futures" "futures-channel" "async-channel" "async-lock" ];
+          "tokio02" = [ "async-global-executor/tokio02" ];
+          "tokio03" = [ "async-global-executor/tokio03" ];
+          "tokio1" = [ "async-global-executor/tokio" ];
+          "unstable" = [ "std" "async-io" "async-process" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "async-channel" "async-global-executor" "async-io" "async-lock" "crossbeam-utils" "default" "futures-channel" "futures-core" "futures-io" "futures-lite" "gloo-timers" "kv-log-macro" "log" "memchr" "num_cpus" "once_cell" "pin-project-lite" "pin-utils" "slab" "std" "wasm-bindgen-futures" ];
+      };
+      "async-task" = rec {
+        crateName = "async-task";
+        version = "4.0.3";
+        edition = "2018";
+        sha256 = "1w0a1c8jim6s5bvcyiiwg9m4bdv3xnd4hbjm97ndgmphmgg32679";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        features = {
+          "default" = [ "std" ];
+        };
+        resolvedDefaultFeatures = [ "default" "std" ];
+      };
+      "atomic-waker" = rec {
+        crateName = "atomic-waker";
+        version = "1.0.0";
+        edition = "2018";
+        sha256 = "0ansiq5vlw684fhks2x4a4is2rqlbv50q5mi8x0fxxvx5q2p8lq6";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        
+      };
       "atty" = rec {
         crateName = "atty";
         version = "0.2.14";
@@ -225,6 +585,18 @@ rec {
         };
         resolvedDefaultFeatures = [ "std" ];
       };
+      "bitflags" = rec {
+        crateName = "bitflags";
+        version = "1.2.1";
+        edition = "2015";
+        sha256 = "14qnd5nq8p2almk79m4m8ydqhd413yaxsyjp5xd19g3mikzf47fg";
+        authors = [
+          "The Rust Project Developers"
+        ];
+        features = {
+        };
+        resolvedDefaultFeatures = [ "default" ];
+      };
       "blake2b_simd" = rec {
         crateName = "blake2b_simd";
         version = "0.5.10";
@@ -298,6 +670,54 @@ rec {
         ];
         
       };
+      "blocking" = rec {
+        crateName = "blocking";
+        version = "1.0.2";
+        edition = "2018";
+        sha256 = "1s9myg9gqmwzrbc38p23bh4vkc8w4pbpddqrcrrl1xz1xpdp1qf5";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "async-channel";
+            packageId = "async-channel";
+          }
+          {
+            name = "async-task";
+            packageId = "async-task";
+          }
+          {
+            name = "atomic-waker";
+            packageId = "atomic-waker";
+          }
+          {
+            name = "fastrand";
+            packageId = "fastrand";
+          }
+          {
+            name = "futures-lite";
+            packageId = "futures-lite";
+          }
+          {
+            name = "once_cell";
+            packageId = "once_cell";
+          }
+        ];
+        
+      };
+      "bumpalo" = rec {
+        crateName = "bumpalo";
+        version = "3.5.0";
+        edition = "2018";
+        sha256 = "0n8dfj0caarpq409anz4d62idqgz9nlvc1q3pshkj93hiilacyph";
+        authors = [
+          "Nick Fitzgerald <fitzgen@gmail.com>"
+        ];
+        features = {
+        };
+        resolvedDefaultFeatures = [ "default" ];
+      };
       "byte-tools" = rec {
         crateName = "byte-tools";
         version = "0.3.1";
@@ -321,7 +741,30 @@ rec {
         };
         resolvedDefaultFeatures = [ "default" "std" ];
       };
-      "cfg-if" = rec {
+      "cache-padded" = rec {
+        crateName = "cache-padded";
+        version = "1.1.1";
+        edition = "2018";
+        sha256 = "1fkdwv9vjazm6fs3s5v56mm4carwswdmw8fcwm9ygrcvihcya6k3";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        
+      };
+      "cc" = rec {
+        crateName = "cc";
+        version = "1.0.66";
+        edition = "2018";
+        crateBin = [];
+        sha256 = "0j7d7h4n81z5f22l3v8ggjvvw8m64636nlaqax4x1y44da1rc12c";
+        authors = [
+          "Alex Crichton <alex@alexcrichton.com>"
+        ];
+        features = {
+          "parallel" = [ "jobserver" ];
+        };
+      };
+      "cfg-if 0.1.10" = rec {
         crateName = "cfg-if";
         version = "0.1.10";
         edition = "2018";
@@ -333,6 +776,34 @@ rec {
           "rustc-dep-of-std" = [ "core" "compiler_builtins" ];
         };
       };
+      "cfg-if 1.0.0" = rec {
+        crateName = "cfg-if";
+        version = "1.0.0";
+        edition = "2018";
+        sha256 = "1za0vb97n4brpzpv8lsbnzmq5r8f2b0cpqqr0sy8h5bn751xxwds";
+        authors = [
+          "Alex Crichton <alex@alexcrichton.com>"
+        ];
+        features = {
+          "rustc-dep-of-std" = [ "core" "compiler_builtins" ];
+        };
+      };
+      "concurrent-queue" = rec {
+        crateName = "concurrent-queue";
+        version = "1.2.2";
+        edition = "2018";
+        sha256 = "18w6hblcjjk9d0my3657ra1zdj79gwfjmzvc0b3985g01dahgv9h";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "cache-padded";
+            packageId = "cache-padded";
+          }
+        ];
+        
+      };
       "constant_time_eq" = rec {
         crateName = "constant_time_eq";
         version = "0.1.5";
@@ -343,7 +814,7 @@ rec {
         ];
         
       };
-      "crossbeam-utils" = rec {
+      "crossbeam-utils 0.7.2" = rec {
         crateName = "crossbeam-utils";
         version = "0.7.2";
         edition = "2015";
@@ -354,7 +825,38 @@ rec {
         dependencies = [
           {
             name = "cfg-if";
-            packageId = "cfg-if";
+            packageId = "cfg-if 0.1.10";
+          }
+          {
+            name = "lazy_static";
+            packageId = "lazy_static";
+            optional = true;
+          }
+        ];
+        buildDependencies = [
+          {
+            name = "autocfg";
+            packageId = "autocfg";
+          }
+        ];
+        features = {
+          "default" = [ "std" ];
+          "std" = [ "lazy_static" ];
+        };
+        resolvedDefaultFeatures = [ "default" "lazy_static" "std" ];
+      };
+      "crossbeam-utils 0.8.1" = rec {
+        crateName = "crossbeam-utils";
+        version = "0.8.1";
+        edition = "2018";
+        sha256 = "13fvrqlap7bgvlnpqr5gjcxdhx1jv99pkfg5xdlq5xcy30g6vn82";
+        authors = [
+          "The Crossbeam Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "cfg-if";
+            packageId = "cfg-if 1.0.0";
           }
           {
             name = "lazy_static";
@@ -492,6 +994,16 @@ rec {
           "persistent" = [ "dogged" ];
         };
       };
+      "event-listener" = rec {
+        crateName = "event-listener";
+        version = "2.5.1";
+        edition = "2018";
+        sha256 = "0ndyp41pb2cx7gxijqh4ymnc47nyrvhvir7rvjlw6x09ayb10lzp";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        
+      };
       "fake-simd" = rec {
         crateName = "fake-simd";
         version = "0.1.2";
@@ -502,6 +1014,23 @@ rec {
         ];
         
       };
+      "fastrand" = rec {
+        crateName = "fastrand";
+        version = "1.4.0";
+        edition = "2018";
+        sha256 = "1qvz1i7g5mb2hcsaawrvxx88b8vwrsr85qr98ffmrkj5fh2sypya";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "instant";
+            packageId = "instant";
+            target = { target, features }: (target."arch" == "wasm32");
+          }
+        ];
+        
+      };
       "fixedbitset" = rec {
         crateName = "fixedbitset";
         version = "0.2.0";
@@ -514,6 +1043,109 @@ rec {
           "default" = [ "std" ];
         };
       };
+      "futures-channel" = rec {
+        crateName = "futures-channel";
+        version = "0.3.12";
+        edition = "2018";
+        sha256 = "0ihq3a3yc6ial3sw536q75hrhixq22xk6wn5qzpnxazgqxz1plzj";
+        authors = [
+          "Alex Crichton <alex@alexcrichton.com>"
+        ];
+        dependencies = [
+          {
+            name = "futures-core";
+            packageId = "futures-core";
+            usesDefaultFeatures = false;
+          }
+        ];
+        features = {
+          "alloc" = [ "futures-core/alloc" ];
+          "cfg-target-has-atomic" = [ "futures-core/cfg-target-has-atomic" ];
+          "default" = [ "std" ];
+          "sink" = [ "futures-sink" ];
+          "std" = [ "alloc" "futures-core/std" ];
+          "unstable" = [ "futures-core/unstable" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "default" "std" ];
+      };
+      "futures-core" = rec {
+        crateName = "futures-core";
+        version = "0.3.12";
+        edition = "2018";
+        sha256 = "0r8ag0mkxx9cd74yrccjk31lph4gr6lhgb9di6rx39wdvrfi9rbr";
+        authors = [
+          "Alex Crichton <alex@alexcrichton.com>"
+        ];
+        features = {
+          "default" = [ "std" ];
+          "std" = [ "alloc" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "default" "std" ];
+      };
+      "futures-io" = rec {
+        crateName = "futures-io";
+        version = "0.3.12";
+        edition = "2018";
+        sha256 = "0005hz30pdxlbdamhd0imixmxcjpwrfxxr27kljxh6i84lshbgi8";
+        authors = [
+          "Alex Crichton <alex@alexcrichton.com>"
+        ];
+        features = {
+          "default" = [ "std" ];
+        };
+        resolvedDefaultFeatures = [ "default" "std" ];
+      };
+      "futures-lite" = rec {
+        crateName = "futures-lite";
+        version = "1.11.3";
+        edition = "2018";
+        sha256 = "1ywmyvpy4f348jri8rxhpj59a7bvy12pspm59x5207fys061sj5l";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+          "Contributors to futures-rs"
+        ];
+        dependencies = [
+          {
+            name = "fastrand";
+            packageId = "fastrand";
+            optional = true;
+          }
+          {
+            name = "futures-core";
+            packageId = "futures-core";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "futures-io";
+            packageId = "futures-io";
+            optional = true;
+          }
+          {
+            name = "memchr";
+            packageId = "memchr";
+            usesDefaultFeatures = false;
+          }
+          {
+            name = "parking";
+            packageId = "parking";
+            optional = true;
+          }
+          {
+            name = "pin-project-lite";
+            packageId = "pin-project-lite";
+          }
+          {
+            name = "waker-fn";
+            packageId = "waker-fn";
+            optional = true;
+          }
+        ];
+        features = {
+          "default" = [ "std" ];
+          "std" = [ "alloc" "fastrand" "futures-io" "parking" "memchr/std" "waker-fn" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "default" "fastrand" "futures-io" "parking" "std" "waker-fn" ];
+      };
       "generic-array" = rec {
         crateName = "generic-array";
         version = "0.12.3";
@@ -543,7 +1175,7 @@ rec {
         dependencies = [
           {
             name = "cfg-if";
-            packageId = "cfg-if";
+            packageId = "cfg-if 0.1.10";
           }
           {
             name = "libc";
@@ -562,6 +1194,44 @@ rec {
           "test-in-browser" = [ "wasm-bindgen" ];
         };
       };
+      "gloo-timers" = rec {
+        crateName = "gloo-timers";
+        version = "0.2.1";
+        edition = "2018";
+        sha256 = "07w999jm1r1i8r574qbmsa3l4w3gxhyx04cbllg0m4pzm934l827";
+        authors = [
+          "Rust and WebAssembly Working Group"
+        ];
+        dependencies = [
+          {
+            name = "futures-channel";
+            packageId = "futures-channel";
+            optional = true;
+          }
+          {
+            name = "futures-core";
+            packageId = "futures-core";
+            optional = true;
+          }
+          {
+            name = "js-sys";
+            packageId = "js-sys";
+          }
+          {
+            name = "wasm-bindgen";
+            packageId = "wasm-bindgen";
+          }
+          {
+            name = "web-sys";
+            packageId = "web-sys";
+            features = [ "Window" "WorkerGlobalScope" ];
+          }
+        ];
+        features = {
+          "futures" = [ "futures-core" "futures-channel" ];
+        };
+        resolvedDefaultFeatures = [ "default" "futures" "futures-channel" "futures-core" ];
+      };
       "hashbrown" = rec {
         crateName = "hashbrown";
         version = "0.9.0";
@@ -624,6 +1294,25 @@ rec {
           "serde-1" = [ "serde" ];
         };
       };
+      "instant" = rec {
+        crateName = "instant";
+        version = "0.1.9";
+        edition = "2018";
+        sha256 = "1v659qqm55misvjijfbl1p7azjp4yynjbwldan8836ynpgp4w4k1";
+        authors = [
+          "sebcrozet <developer@crozet.re>"
+        ];
+        dependencies = [
+          {
+            name = "cfg-if";
+            packageId = "cfg-if 1.0.0";
+          }
+        ];
+        features = {
+          "now" = [ "time" ];
+          "wasm-bindgen" = [ "js-sys" "wasm-bindgen_rs" "web-sys" ];
+        };
+      };
       "itertools" = rec {
         crateName = "itertools";
         version = "0.9.0";
@@ -644,6 +1333,39 @@ rec {
         };
         resolvedDefaultFeatures = [ "default" "use_std" ];
       };
+      "js-sys" = rec {
+        crateName = "js-sys";
+        version = "0.3.47";
+        edition = "2018";
+        sha256 = "0r8gxxgpgpg7y11jk34ccrvx1w0a20jbv35gglv3lhim3h9p7ysw";
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        dependencies = [
+          {
+            name = "wasm-bindgen";
+            packageId = "wasm-bindgen";
+          }
+        ];
+        
+      };
+      "kv-log-macro" = rec {
+        crateName = "kv-log-macro";
+        version = "1.0.7";
+        edition = "2018";
+        sha256 = "0zwp4bxkkp87rl7xy2dain77z977rvcry1gmr5bssdbn541v7s0d";
+        authors = [
+          "Yoshua Wuyts <yoshuawuyts@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "log";
+            packageId = "log";
+            features = [ "kv_unstable" ];
+          }
+        ];
+        
+      };
       "lalrpop" = rec {
         crateName = "lalrpop";
         version = "0.19.1";
@@ -762,9 +1484,9 @@ rec {
       };
       "libc" = rec {
         crateName = "libc";
-        version = "0.2.76";
+        version = "0.2.82";
         edition = "2015";
-        sha256 = "1hvv01y8cjlkg6xqgvflgq4p77p15a83w6xxpcggmrj4w3x5cm3m";
+        sha256 = "0a8r4wiyn7hbg8fmlkcr7zwhl368wfy8xbfad989adqap8zky849";
         authors = [
           "The Rust Project Developers"
         ];
@@ -773,7 +1495,7 @@ rec {
           "rustc-dep-of-std" = [ "align" "rustc-std-workspace-core" ];
           "use_std" = [ "std" ];
         };
-        resolvedDefaultFeatures = [ "default" "std" ];
+        resolvedDefaultFeatures = [ "default" "extra_traits" "std" ];
       };
       "log" = rec {
         crateName = "log";
@@ -786,12 +1508,13 @@ rec {
         dependencies = [
           {
             name = "cfg-if";
-            packageId = "cfg-if";
+            packageId = "cfg-if 0.1.10";
           }
         ];
         features = {
           "kv_unstable_sval" = [ "kv_unstable" "sval/fmt" ];
         };
+        resolvedDefaultFeatures = [ "kv_unstable" ];
       };
       "memchr" = rec {
         crateName = "memchr";
@@ -808,6 +1531,30 @@ rec {
         };
         resolvedDefaultFeatures = [ "default" "std" "use_std" ];
       };
+      "nb-connect" = rec {
+        crateName = "nb-connect";
+        version = "1.0.2";
+        edition = "2018";
+        sha256 = "1649m71wc0cg1rqgl8vbh0489znkhpwgl0isjd5x8mz470ash8w1";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+          "Jayce Fayne <jayce.fayne@mailbox.org>"
+        ];
+        dependencies = [
+          {
+            name = "libc";
+            packageId = "libc";
+            target = { target, features }: target."unix";
+          }
+          {
+            name = "winapi";
+            packageId = "winapi";
+            target = { target, features }: target."windows";
+            features = [ "handleapi" "ws2tcpip" ];
+          }
+        ];
+        
+      };
       "new_debug_unreachable" = rec {
         crateName = "new_debug_unreachable";
         version = "1.0.4";
@@ -820,6 +1567,73 @@ rec {
         ];
         
       };
+      "nix" = rec {
+        crateName = "nix";
+        version = "0.19.1";
+        edition = "2018";
+        sha256 = "1wk1pmaf9pv84sc4jf19gm1as2yq3ydwcx0n5nc1bpsgzq6bmk5j";
+        authors = [
+          "The nix-rust Project Developers"
+        ];
+        dependencies = [
+          {
+            name = "bitflags";
+            packageId = "bitflags";
+          }
+          {
+            name = "cfg-if";
+            packageId = "cfg-if 1.0.0";
+          }
+          {
+            name = "libc";
+            packageId = "libc";
+            features = [ "extra_traits" ];
+          }
+        ];
+        buildDependencies = [
+          {
+            name = "cc";
+            packageId = "cc";
+            target = {target, features}: (target."os" == "dragonfly");
+          }
+        ];
+        
+      };
+      "num_cpus" = rec {
+        crateName = "num_cpus";
+        version = "1.13.0";
+        edition = "2015";
+        sha256 = "1cv6yxhz2zbnwn8pn1yn8grg7zsnd523947fby41a737aqvryj85";
+        authors = [
+          "Sean McArthur <sean@seanmonstar.com>"
+        ];
+        dependencies = [
+          {
+            name = "hermit-abi";
+            packageId = "hermit-abi";
+            target = { target, features }: (((target."arch" == "x86_64") || (target."arch" == "aarch64")) && (target."os" == "hermit"));
+          }
+          {
+            name = "libc";
+            packageId = "libc";
+          }
+        ];
+        
+      };
+      "once_cell" = rec {
+        crateName = "once_cell";
+        version = "1.5.2";
+        edition = "2018";
+        sha256 = "183zs1dbmsv24mkafjypf9qwjrx46an58vb004a162l113sl3g8k";
+        authors = [
+          "Aleksey Kladov <aleksey.kladov@gmail.com>"
+        ];
+        features = {
+          "default" = [ "std" ];
+          "std" = [ "alloc" ];
+        };
+        resolvedDefaultFeatures = [ "alloc" "default" "std" ];
+      };
       "opaque-debug" = rec {
         crateName = "opaque-debug";
         version = "0.2.3";
@@ -830,6 +1644,17 @@ rec {
         ];
         
       };
+      "parking" = rec {
+        crateName = "parking";
+        version = "2.0.0";
+        edition = "2018";
+        sha256 = "0wnxxnizfxlax3n709s5r83f4n8awy3m4a18q4fdk0z7z693hz22";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+          "The Rust Project Developers"
+        ];
+        
+      };
       "petgraph" = rec {
         crateName = "petgraph";
         version = "0.5.1";
@@ -877,6 +1702,108 @@ rec {
         };
         resolvedDefaultFeatures = [ "default" "std" ];
       };
+      "pin-project" = rec {
+        crateName = "pin-project";
+        version = "1.0.4";
+        edition = "2018";
+        sha256 = "1wm2gjmgcsglw8yqka67fhvcj7zj1fh6yfw6awlal5wza1l0pdwm";
+        authors = [
+          "Taiki Endo <te316e89@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "pin-project-internal";
+            packageId = "pin-project-internal";
+            usesDefaultFeatures = false;
+          }
+        ];
+        
+      };
+      "pin-project-internal" = rec {
+        crateName = "pin-project-internal";
+        version = "1.0.4";
+        edition = "2018";
+        sha256 = "0wcy3n9w856aw27f6ns2ipd2yac7jbl0n3pmn0cyhb7jjdimm8na";
+        procMacro = true;
+        authors = [
+          "Taiki Endo <te316e89@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "proc-macro2";
+            packageId = "proc-macro2";
+          }
+          {
+            name = "quote";
+            packageId = "quote";
+          }
+          {
+            name = "syn";
+            packageId = "syn";
+            features = [ "full" "visit-mut" ];
+          }
+        ];
+        
+      };
+      "pin-project-lite" = rec {
+        crateName = "pin-project-lite";
+        version = "0.2.4";
+        edition = "2018";
+        sha256 = "09x8chns8apal89pndqdrr0c2nv8jw6nmi8hl38acjbc6sprg5j3";
+        authors = [
+          "Taiki Endo <te316e89@gmail.com>"
+        ];
+        
+      };
+      "pin-utils" = rec {
+        crateName = "pin-utils";
+        version = "0.1.0";
+        edition = "2018";
+        sha256 = "117ir7vslsl2z1a7qzhws4pd01cg2d3338c47swjyvqv2n60v1wb";
+        authors = [
+          "Josef Brandl <mail@josefbrandl.de>"
+        ];
+        
+      };
+      "polling" = rec {
+        crateName = "polling";
+        version = "2.0.2";
+        edition = "2018";
+        sha256 = "1r5xm3f6qs84ibg09nw1cz78r883521l3jaiakj35ri959mvr9x2";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "cfg-if";
+            packageId = "cfg-if 0.1.10";
+          }
+          {
+            name = "libc";
+            packageId = "libc";
+            target = { target, features }: target."unix";
+          }
+          {
+            name = "log";
+            packageId = "log";
+          }
+          {
+            name = "wepoll-sys";
+            packageId = "wepoll-sys";
+            target = { target, features }: target."windows";
+          }
+          {
+            name = "winapi";
+            packageId = "winapi";
+            target = { target, features }: target."windows";
+            features = [ "ioapiset" "winsock2" ];
+          }
+        ];
+        features = {
+          "default" = [ "std" ];
+        };
+        resolvedDefaultFeatures = [ "default" "std" ];
+      };
       "precomputed-hash" = rec {
         crateName = "precomputed-hash";
         version = "0.1.1";
@@ -889,9 +1816,9 @@ rec {
       };
       "proc-macro2" = rec {
         crateName = "proc-macro2";
-        version = "1.0.20";
+        version = "1.0.24";
         edition = "2018";
-        sha256 = "0a8sgk1i60nz7qlf611dxj1npawbv9nb0ch2lafvk7bialym2p0p";
+        sha256 = "0wcabxzrddcjmryndw8fpyxcq6rw63m701vx86xxf03y3bp081qy";
         authors = [
           "Alex Crichton <alex@alexcrichton.com>"
           "David Tolnay <dtolnay@gmail.com>"
@@ -1055,7 +1982,7 @@ rec {
           }
           {
             name = "crossbeam-utils";
-            packageId = "crossbeam-utils";
+            packageId = "crossbeam-utils 0.7.2";
             optional = true;
           }
         ];
@@ -1175,9 +2102,29 @@ rec {
         ];
         dependencies = [
           {
+            name = "async-std";
+            packageId = "async-std";
+          }
+          {
             name = "lalrpop-util";
             packageId = "lalrpop-util";
           }
+          {
+            name = "nix";
+            packageId = "nix";
+          }
+          {
+            name = "pin-project";
+            packageId = "pin-project";
+          }
+          {
+            name = "pin-utils";
+            packageId = "pin-utils";
+          }
+          {
+            name = "signal-hook";
+            packageId = "signal-hook";
+          }
         ];
         buildDependencies = [
           {
@@ -1188,6 +2135,50 @@ rec {
         ];
         
       };
+      "signal-hook" = rec {
+        crateName = "signal-hook";
+        version = "0.3.4";
+        edition = "2018";
+        sha256 = "0h628smm9y22qi3szpkg3xpj31hyvs4ps29nf8cnfvy6w0zmw3vq";
+        authors = [
+          "Michal 'vorner' Vaner <vorner@vorner.cz>"
+          "Thomas Himmelstoss <thimm@posteo.de>"
+        ];
+        dependencies = [
+          {
+            name = "libc";
+            packageId = "libc";
+          }
+          {
+            name = "signal-hook-registry";
+            packageId = "signal-hook-registry";
+          }
+        ];
+        features = {
+          "default" = [ "channel" "iterator" ];
+          "extended-siginfo" = [ "channel" "iterator" "extended-siginfo-raw" ];
+          "extended-siginfo-raw" = [ "cc" ];
+          "iterator" = [ "channel" ];
+        };
+        resolvedDefaultFeatures = [ "channel" "default" "iterator" ];
+      };
+      "signal-hook-registry" = rec {
+        crateName = "signal-hook-registry";
+        version = "1.3.0";
+        edition = "2015";
+        sha256 = "19hirq0h33jjyh505s8hf9q5dq0ky80ygivkl3vshjv0y7zd1w8n";
+        authors = [
+          "Michal 'vorner' Vaner <vorner@vorner.cz>"
+          "Masaki Hara <ackie.h.gmai@gmail.com>"
+        ];
+        dependencies = [
+          {
+            name = "libc";
+            packageId = "libc";
+          }
+        ];
+        
+      };
       "siphasher" = rec {
         crateName = "siphasher";
         version = "0.3.3";
@@ -1203,6 +2194,16 @@ rec {
         };
         resolvedDefaultFeatures = [ "default" "std" ];
       };
+      "slab" = rec {
+        crateName = "slab";
+        version = "0.4.2";
+        edition = "2015";
+        sha256 = "1y59xsa27jk84sxzswjk60xcjf8b4fm5960jwpznrrcmasyva4f1";
+        authors = [
+          "Carl Lerche <me@carllerche.com>"
+        ];
+        
+      };
       "string_cache" = rec {
         crateName = "string_cache";
         version = "0.8.0";
@@ -1247,9 +2248,9 @@ rec {
       };
       "syn" = rec {
         crateName = "syn";
-        version = "1.0.39";
+        version = "1.0.58";
         edition = "2018";
-        sha256 = "1y8ikwihdrfn64ybrhaqlbxlcf4g43s8mad36n47yz7ycxjqs7c9";
+        sha256 = "1m85bvywsm6cf17d534c5ma73zch0cgwqc6q2bblqnd67vbs6q6c";
         authors = [
           "David Tolnay <dtolnay@gmail.com>"
         ];
@@ -1276,7 +2277,7 @@ rec {
           "proc-macro" = [ "proc-macro2/proc-macro" "quote/proc-macro" ];
           "test" = [ "syn-test-suite/all-features" ];
         };
-        resolvedDefaultFeatures = [ "clone-impls" "default" "derive" "parsing" "printing" "proc-macro" "quote" "visit" ];
+        resolvedDefaultFeatures = [ "clone-impls" "default" "derive" "full" "parsing" "printing" "proc-macro" "quote" "visit" "visit-mut" ];
       };
       "term" = rec {
         crateName = "term";
@@ -1349,6 +2350,26 @@ rec {
         };
         resolvedDefaultFeatures = [ "default" ];
       };
+      "vec-arena" = rec {
+        crateName = "vec-arena";
+        version = "1.0.0";
+        edition = "2018";
+        sha256 = "07866gmvn4cf2656bjf75nrmbnw4cj0cyqkv2wlmavzw5ndipz7a";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        
+      };
+      "waker-fn" = rec {
+        crateName = "waker-fn";
+        version = "1.1.0";
+        edition = "2018";
+        sha256 = "1jpfiis0frk2b36krqvk8264kgxk2dyhfzjsr8g3wah1nii2qnwx";
+        authors = [
+          "Stjepan Glavina <stjepang@gmail.com>"
+        ];
+        
+      };
       "wasi" = rec {
         crateName = "wasi";
         version = "0.9.0+wasi-snapshot-preview1";
@@ -1363,6 +2384,640 @@ rec {
         };
         resolvedDefaultFeatures = [ "default" "std" ];
       };
+      "wasm-bindgen" = rec {
+        crateName = "wasm-bindgen";
+        version = "0.2.70";
+        edition = "2018";
+        sha256 = "1gikjjsm85wvpqmjbxg2s6f386bv9rhzs03xkfmhskz77l9ggh2m";
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        dependencies = [
+          {
+            name = "cfg-if";
+            packageId = "cfg-if 1.0.0";
+          }
+          {
+            name = "wasm-bindgen-macro";
+            packageId = "wasm-bindgen-macro";
+          }
+        ];
+        features = {
+          "default" = [ "spans" "std" ];
+          "enable-interning" = [ "std" ];
+          "serde-serialize" = [ "serde" "serde_json" "std" ];
+          "spans" = [ "wasm-bindgen-macro/spans" ];
+          "strict-macro" = [ "wasm-bindgen-macro/strict-macro" ];
+          "xxx_debug_only_print_generated_code" = [ "wasm-bindgen-macro/xxx_debug_only_print_generated_code" ];
+        };
+        resolvedDefaultFeatures = [ "default" "spans" "std" ];
+      };
+      "wasm-bindgen-backend" = rec {
+        crateName = "wasm-bindgen-backend";
+        version = "0.2.70";
+        edition = "2018";
+        sha256 = "1iv4fzabql4625q4cw7d43lnrpf3pimn63vjclykymyly13m9i3v";
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        dependencies = [
+          {
+            name = "bumpalo";
+            packageId = "bumpalo";
+          }
+          {
+            name = "lazy_static";
+            packageId = "lazy_static";
+          }
+          {
+            name = "log";
+            packageId = "log";
+          }
+          {
+            name = "proc-macro2";
+            packageId = "proc-macro2";
+          }
+          {
+            name = "quote";
+            packageId = "quote";
+          }
+          {
+            name = "syn";
+            packageId = "syn";
+            features = [ "full" ];
+          }
+          {
+            name = "wasm-bindgen-shared";
+            packageId = "wasm-bindgen-shared";
+          }
+        ];
+        features = {
+          "extra-traits" = [ "syn/extra-traits" ];
+        };
+        resolvedDefaultFeatures = [ "spans" ];
+      };
+      "wasm-bindgen-futures" = rec {
+        crateName = "wasm-bindgen-futures";
+        version = "0.4.20";
+        edition = "2018";
+        sha256 = "156zm9r8h530j1kbc9zc19zbsjjfdzv36fi86jf6g1hcj6i33r1x";
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        dependencies = [
+          {
+            name = "cfg-if";
+            packageId = "cfg-if 1.0.0";
+          }
+          {
+            name = "js-sys";
+            packageId = "js-sys";
+          }
+          {
+            name = "wasm-bindgen";
+            packageId = "wasm-bindgen";
+          }
+          {
+            name = "web-sys";
+            packageId = "web-sys";
+            target = { target, features }: (target."feature" == "atomics");
+            features = [ "MessageEvent" "Worker" ];
+          }
+        ];
+        features = {
+          "futures-core-03-stream" = [ "futures-core" ];
+        };
+      };
+      "wasm-bindgen-macro" = rec {
+        crateName = "wasm-bindgen-macro";
+        version = "0.2.70";
+        edition = "2018";
+        sha256 = "0b5srgzjmi5j7gv27li683l68nl6r5px4k8pshx5jfgg5s45721v";
+        procMacro = true;
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        dependencies = [
+          {
+            name = "quote";
+            packageId = "quote";
+          }
+          {
+            name = "wasm-bindgen-macro-support";
+            packageId = "wasm-bindgen-macro-support";
+          }
+        ];
+        features = {
+          "spans" = [ "wasm-bindgen-macro-support/spans" ];
+          "strict-macro" = [ "wasm-bindgen-macro-support/strict-macro" ];
+        };
+        resolvedDefaultFeatures = [ "spans" ];
+      };
+      "wasm-bindgen-macro-support" = rec {
+        crateName = "wasm-bindgen-macro-support";
+        version = "0.2.70";
+        edition = "2018";
+        sha256 = "118kl12vcp19zbd8fzpn3jkhb2h34plra5is7d0zlcd5ybkvacs1";
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        dependencies = [
+          {
+            name = "proc-macro2";
+            packageId = "proc-macro2";
+          }
+          {
+            name = "quote";
+            packageId = "quote";
+          }
+          {
+            name = "syn";
+            packageId = "syn";
+            features = [ "visit" "full" ];
+          }
+          {
+            name = "wasm-bindgen-backend";
+            packageId = "wasm-bindgen-backend";
+          }
+          {
+            name = "wasm-bindgen-shared";
+            packageId = "wasm-bindgen-shared";
+          }
+        ];
+        features = {
+          "extra-traits" = [ "syn/extra-traits" ];
+          "spans" = [ "wasm-bindgen-backend/spans" ];
+        };
+        resolvedDefaultFeatures = [ "spans" ];
+      };
+      "wasm-bindgen-shared" = rec {
+        crateName = "wasm-bindgen-shared";
+        version = "0.2.70";
+        edition = "2018";
+        sha256 = "0r7xlkba8r5gfpp4w8bi9gfym08ybf5b6qirq4ajvq1sjkj4ajfx";
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        
+      };
+      "web-sys" = rec {
+        crateName = "web-sys";
+        version = "0.3.47";
+        edition = "2018";
+        sha256 = "1cw0aqbyzhya0f02jwd95la9hmn12dqxlf3wh6x3w028zj8wc3f4";
+        authors = [
+          "The wasm-bindgen Developers"
+        ];
+        dependencies = [
+          {
+            name = "js-sys";
+            packageId = "js-sys";
+          }
+          {
+            name = "wasm-bindgen";
+            packageId = "wasm-bindgen";
+          }
+        ];
+        features = {
+          "AbortSignal" = [ "EventTarget" ];
+          "AnalyserNode" = [ "AudioNode" "EventTarget" ];
+          "Animation" = [ "EventTarget" ];
+          "AnimationEvent" = [ "Event" ];
+          "AnimationPlaybackEvent" = [ "Event" ];
+          "Attr" = [ "EventTarget" "Node" ];
+          "AudioBufferSourceNode" = [ "AudioNode" "AudioScheduledSourceNode" "EventTarget" ];
+          "AudioContext" = [ "BaseAudioContext" "EventTarget" ];
+          "AudioDestinationNode" = [ "AudioNode" "EventTarget" ];
+          "AudioNode" = [ "EventTarget" ];
+          "AudioProcessingEvent" = [ "Event" ];
+          "AudioScheduledSourceNode" = [ "AudioNode" "EventTarget" ];
+          "AudioStreamTrack" = [ "EventTarget" "MediaStreamTrack" ];
+          "AudioTrackList" = [ "EventTarget" ];
+          "AudioWorklet" = [ "Worklet" ];
+          "AudioWorkletGlobalScope" = [ "WorkletGlobalScope" ];
+          "AudioWorkletNode" = [ "AudioNode" "EventTarget" ];
+          "AuthenticatorAssertionResponse" = [ "AuthenticatorResponse" ];
+          "AuthenticatorAttestationResponse" = [ "AuthenticatorResponse" ];
+          "BaseAudioContext" = [ "EventTarget" ];
+          "BatteryManager" = [ "EventTarget" ];
+          "BeforeUnloadEvent" = [ "Event" ];
+          "BiquadFilterNode" = [ "AudioNode" "EventTarget" ];
+          "BlobEvent" = [ "Event" ];
+          "Bluetooth" = [ "EventTarget" ];
+          "BluetoothAdvertisingEvent" = [ "Event" ];
+          "BluetoothDevice" = [ "EventTarget" ];
+          "BluetoothPermissionResult" = [ "EventTarget" "PermissionStatus" ];
+          "BluetoothRemoteGattCharacteristic" = [ "EventTarget" ];
+          "BluetoothRemoteGattService" = [ "EventTarget" ];
+          "BroadcastChannel" = [ "EventTarget" ];
+          "CanvasCaptureMediaStream" = [ "EventTarget" "MediaStream" ];
+          "CdataSection" = [ "CharacterData" "EventTarget" "Node" "Text" ];
+          "ChannelMergerNode" = [ "AudioNode" "EventTarget" ];
+          "ChannelSplitterNode" = [ "AudioNode" "EventTarget" ];
+          "CharacterData" = [ "EventTarget" "Node" ];
+          "ChromeWorker" = [ "EventTarget" "Worker" ];
+          "Clipboard" = [ "EventTarget" ];
+          "ClipboardEvent" = [ "Event" ];
+          "CloseEvent" = [ "Event" ];
+          "Comment" = [ "CharacterData" "EventTarget" "Node" ];
+          "CompositionEvent" = [ "Event" "UiEvent" ];
+          "ConstantSourceNode" = [ "AudioNode" "AudioScheduledSourceNode" "EventTarget" ];
+          "ConvolverNode" = [ "AudioNode" "EventTarget" ];
+          "CssAnimation" = [ "Animation" "EventTarget" ];
+          "CssConditionRule" = [ "CssGroupingRule" "CssRule" ];
+          "CssCounterStyleRule" = [ "CssRule" ];
+          "CssFontFaceRule" = [ "CssRule" ];
+          "CssFontFeatureValuesRule" = [ "CssRule" ];
+          "CssGroupingRule" = [ "CssRule" ];
+          "CssImportRule" = [ "CssRule" ];
+          "CssKeyframeRule" = [ "CssRule" ];
+          "CssKeyframesRule" = [ "CssRule" ];
+          "CssMediaRule" = [ "CssConditionRule" "CssGroupingRule" "CssRule" ];
+          "CssNamespaceRule" = [ "CssRule" ];
+          "CssPageRule" = [ "CssRule" ];
+          "CssStyleRule" = [ "CssRule" ];
+          "CssStyleSheet" = [ "StyleSheet" ];
+          "CssSupportsRule" = [ "CssConditionRule" "CssGroupingRule" "CssRule" ];
+          "CssTransition" = [ "Animation" "EventTarget" ];
+          "CustomEvent" = [ "Event" ];
+          "DedicatedWorkerGlobalScope" = [ "EventTarget" "WorkerGlobalScope" ];
+          "DelayNode" = [ "AudioNode" "EventTarget" ];
+          "DeviceLightEvent" = [ "Event" ];
+          "DeviceMotionEvent" = [ "Event" ];
+          "DeviceOrientationEvent" = [ "Event" ];
+          "DeviceProximityEvent" = [ "Event" ];
+          "Document" = [ "EventTarget" "Node" ];
+          "DocumentFragment" = [ "EventTarget" "Node" ];
+          "DocumentTimeline" = [ "AnimationTimeline" ];
+          "DocumentType" = [ "EventTarget" "Node" ];
+          "DomMatrix" = [ "DomMatrixReadOnly" ];
+          "DomPoint" = [ "DomPointReadOnly" ];
+          "DomRect" = [ "DomRectReadOnly" ];
+          "DomRequest" = [ "EventTarget" ];
+          "DragEvent" = [ "Event" "MouseEvent" "UiEvent" ];
+          "DynamicsCompressorNode" = [ "AudioNode" "EventTarget" ];
+          "Element" = [ "EventTarget" "Node" ];
+          "ErrorEvent" = [ "Event" ];
+          "EventSource" = [ "EventTarget" ];
+          "ExtendableEvent" = [ "Event" ];
+          "ExtendableMessageEvent" = [ "Event" "ExtendableEvent" ];
+          "FetchEvent" = [ "Event" "ExtendableEvent" ];
+          "FetchObserver" = [ "EventTarget" ];
+          "File" = [ "Blob" ];
+          "FileReader" = [ "EventTarget" ];
+          "FileSystemDirectoryEntry" = [ "FileSystemEntry" ];
+          "FileSystemFileEntry" = [ "FileSystemEntry" ];
+          "FocusEvent" = [ "Event" "UiEvent" ];
+          "FontFaceSet" = [ "EventTarget" ];
+          "FontFaceSetLoadEvent" = [ "Event" ];
+          "GainNode" = [ "AudioNode" "EventTarget" ];
+          "GamepadAxisMoveEvent" = [ "Event" "GamepadEvent" ];
+          "GamepadButtonEvent" = [ "Event" "GamepadEvent" ];
+          "GamepadEvent" = [ "Event" ];
+          "GpuDevice" = [ "EventTarget" ];
+          "GpuUncapturedErrorEvent" = [ "Event" ];
+          "HashChangeEvent" = [ "Event" ];
+          "HtmlAnchorElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlAreaElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlAudioElement" = [ "Element" "EventTarget" "HtmlElement" "HtmlMediaElement" "Node" ];
+          "HtmlBaseElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlBodyElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlBrElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlButtonElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlCanvasElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDListElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDataElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDataListElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDetailsElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDialogElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDirectoryElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDivElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlDocument" = [ "Document" "EventTarget" "Node" ];
+          "HtmlElement" = [ "Element" "EventTarget" "Node" ];
+          "HtmlEmbedElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlFieldSetElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlFontElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlFormControlsCollection" = [ "HtmlCollection" ];
+          "HtmlFormElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlFrameElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlFrameSetElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlHeadElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlHeadingElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlHrElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlHtmlElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlIFrameElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlImageElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlInputElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlLabelElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlLegendElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlLiElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlLinkElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlMapElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlMediaElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlMenuElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlMenuItemElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlMetaElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlMeterElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlModElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlOListElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlObjectElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlOptGroupElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlOptionElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlOptionsCollection" = [ "HtmlCollection" ];
+          "HtmlOutputElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlParagraphElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlParamElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlPictureElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlPreElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlProgressElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlQuoteElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlScriptElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlSelectElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlSlotElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlSourceElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlSpanElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlStyleElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTableCaptionElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTableCellElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTableColElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTableElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTableRowElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTableSectionElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTemplateElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTextAreaElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTimeElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTitleElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlTrackElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlUListElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlUnknownElement" = [ "Element" "EventTarget" "HtmlElement" "Node" ];
+          "HtmlVideoElement" = [ "Element" "EventTarget" "HtmlElement" "HtmlMediaElement" "Node" ];
+          "IdbCursorWithValue" = [ "IdbCursor" ];
+          "IdbDatabase" = [ "EventTarget" ];
+          "IdbFileHandle" = [ "EventTarget" ];
+          "IdbFileRequest" = [ "DomRequest" "EventTarget" ];
+          "IdbLocaleAwareKeyRange" = [ "IdbKeyRange" ];
+          "IdbMutableFile" = [ "EventTarget" ];
+          "IdbOpenDbRequest" = [ "EventTarget" "IdbRequest" ];
+          "IdbRequest" = [ "EventTarget" ];
+          "IdbTransaction" = [ "EventTarget" ];
+          "IdbVersionChangeEvent" = [ "Event" ];
+          "IirFilterNode" = [ "AudioNode" "EventTarget" ];
+          "ImageCaptureErrorEvent" = [ "Event" ];
+          "InputEvent" = [ "Event" "UiEvent" ];
+          "KeyboardEvent" = [ "Event" "UiEvent" ];
+          "KeyframeEffect" = [ "AnimationEffect" ];
+          "LocalMediaStream" = [ "EventTarget" "MediaStream" ];
+          "MediaDevices" = [ "EventTarget" ];
+          "MediaElementAudioSourceNode" = [ "AudioNode" "EventTarget" ];
+          "MediaEncryptedEvent" = [ "Event" ];
+          "MediaKeyError" = [ "Event" ];
+          "MediaKeyMessageEvent" = [ "Event" ];
+          "MediaKeySession" = [ "EventTarget" ];
+          "MediaQueryList" = [ "EventTarget" ];
+          "MediaQueryListEvent" = [ "Event" ];
+          "MediaRecorder" = [ "EventTarget" ];
+          "MediaRecorderErrorEvent" = [ "Event" ];
+          "MediaSource" = [ "EventTarget" ];
+          "MediaStream" = [ "EventTarget" ];
+          "MediaStreamAudioDestinationNode" = [ "AudioNode" "EventTarget" ];
+          "MediaStreamAudioSourceNode" = [ "AudioNode" "EventTarget" ];
+          "MediaStreamEvent" = [ "Event" ];
+          "MediaStreamTrack" = [ "EventTarget" ];
+          "MediaStreamTrackEvent" = [ "Event" ];
+          "MessageEvent" = [ "Event" ];
+          "MessagePort" = [ "EventTarget" ];
+          "MidiAccess" = [ "EventTarget" ];
+          "MidiConnectionEvent" = [ "Event" ];
+          "MidiInput" = [ "EventTarget" "MidiPort" ];
+          "MidiMessageEvent" = [ "Event" ];
+          "MidiOutput" = [ "EventTarget" "MidiPort" ];
+          "MidiPort" = [ "EventTarget" ];
+          "MouseEvent" = [ "Event" "UiEvent" ];
+          "MouseScrollEvent" = [ "Event" "MouseEvent" "UiEvent" ];
+          "MutationEvent" = [ "Event" ];
+          "NetworkInformation" = [ "EventTarget" ];
+          "Node" = [ "EventTarget" ];
+          "Notification" = [ "EventTarget" ];
+          "NotificationEvent" = [ "Event" "ExtendableEvent" ];
+          "OfflineAudioCompletionEvent" = [ "Event" ];
+          "OfflineAudioContext" = [ "BaseAudioContext" "EventTarget" ];
+          "OfflineResourceList" = [ "EventTarget" ];
+          "OffscreenCanvas" = [ "EventTarget" ];
+          "OscillatorNode" = [ "AudioNode" "AudioScheduledSourceNode" "EventTarget" ];
+          "PageTransitionEvent" = [ "Event" ];
+          "PaintWorkletGlobalScope" = [ "WorkletGlobalScope" ];
+          "PannerNode" = [ "AudioNode" "EventTarget" ];
+          "PaymentMethodChangeEvent" = [ "Event" "PaymentRequestUpdateEvent" ];
+          "PaymentRequestUpdateEvent" = [ "Event" ];
+          "Performance" = [ "EventTarget" ];
+          "PerformanceMark" = [ "PerformanceEntry" ];
+          "PerformanceMeasure" = [ "PerformanceEntry" ];
+          "PerformanceNavigationTiming" = [ "PerformanceEntry" "PerformanceResourceTiming" ];
+          "PerformanceResourceTiming" = [ "PerformanceEntry" ];
+          "PermissionStatus" = [ "EventTarget" ];
+          "PointerEvent" = [ "Event" "MouseEvent" "UiEvent" ];
+          "PopStateEvent" = [ "Event" ];
+          "PopupBlockedEvent" = [ "Event" ];
+          "PresentationAvailability" = [ "EventTarget" ];
+          "PresentationConnection" = [ "EventTarget" ];
+          "PresentationConnectionAvailableEvent" = [ "Event" ];
+          "PresentationConnectionCloseEvent" = [ "Event" ];
+          "PresentationConnectionList" = [ "EventTarget" ];
+          "PresentationRequest" = [ "EventTarget" ];
+          "ProcessingInstruction" = [ "CharacterData" "EventTarget" "Node" ];
+          "ProgressEvent" = [ "Event" ];
+          "PromiseRejectionEvent" = [ "Event" ];
+          "PublicKeyCredential" = [ "Credential" ];
+          "PushEvent" = [ "Event" "ExtendableEvent" ];
+          "RadioNodeList" = [ "NodeList" ];
+          "RtcDataChannel" = [ "EventTarget" ];
+          "RtcDataChannelEvent" = [ "Event" ];
+          "RtcPeerConnection" = [ "EventTarget" ];
+          "RtcPeerConnectionIceEvent" = [ "Event" ];
+          "RtcTrackEvent" = [ "Event" ];
+          "RtcdtmfSender" = [ "EventTarget" ];
+          "RtcdtmfToneChangeEvent" = [ "Event" ];
+          "Screen" = [ "EventTarget" ];
+          "ScreenOrientation" = [ "EventTarget" ];
+          "ScriptProcessorNode" = [ "AudioNode" "EventTarget" ];
+          "ScrollAreaEvent" = [ "Event" "UiEvent" ];
+          "SecurityPolicyViolationEvent" = [ "Event" ];
+          "ServiceWorker" = [ "EventTarget" ];
+          "ServiceWorkerContainer" = [ "EventTarget" ];
+          "ServiceWorkerGlobalScope" = [ "EventTarget" "WorkerGlobalScope" ];
+          "ServiceWorkerRegistration" = [ "EventTarget" ];
+          "ShadowRoot" = [ "DocumentFragment" "EventTarget" "Node" ];
+          "SharedWorker" = [ "EventTarget" ];
+          "SharedWorkerGlobalScope" = [ "EventTarget" "WorkerGlobalScope" ];
+          "SourceBuffer" = [ "EventTarget" ];
+          "SourceBufferList" = [ "EventTarget" ];
+          "SpeechRecognition" = [ "EventTarget" ];
+          "SpeechRecognitionError" = [ "Event" ];
+          "SpeechRecognitionEvent" = [ "Event" ];
+          "SpeechSynthesis" = [ "EventTarget" ];
+          "SpeechSynthesisErrorEvent" = [ "Event" "SpeechSynthesisEvent" ];
+          "SpeechSynthesisEvent" = [ "Event" ];
+          "SpeechSynthesisUtterance" = [ "EventTarget" ];
+          "StereoPannerNode" = [ "AudioNode" "EventTarget" ];
+          "StorageEvent" = [ "Event" ];
+          "SvgAnimateElement" = [ "Element" "EventTarget" "Node" "SvgAnimationElement" "SvgElement" ];
+          "SvgAnimateMotionElement" = [ "Element" "EventTarget" "Node" "SvgAnimationElement" "SvgElement" ];
+          "SvgAnimateTransformElement" = [ "Element" "EventTarget" "Node" "SvgAnimationElement" "SvgElement" ];
+          "SvgAnimationElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgCircleElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgClipPathElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgComponentTransferFunctionElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgDefsElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgDescElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgElement" = [ "Element" "EventTarget" "Node" ];
+          "SvgEllipseElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgFilterElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgForeignObjectElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgGeometryElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgGradientElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgGraphicsElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgImageElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgLineElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgLinearGradientElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGradientElement" ];
+          "SvgMarkerElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgMaskElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgMetadataElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgPathElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgPathSegArcAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegArcRel" = [ "SvgPathSeg" ];
+          "SvgPathSegClosePath" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoCubicAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoCubicRel" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoCubicSmoothAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoCubicSmoothRel" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoQuadraticAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoQuadraticRel" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoQuadraticSmoothAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegCurvetoQuadraticSmoothRel" = [ "SvgPathSeg" ];
+          "SvgPathSegLinetoAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegLinetoHorizontalAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegLinetoHorizontalRel" = [ "SvgPathSeg" ];
+          "SvgPathSegLinetoRel" = [ "SvgPathSeg" ];
+          "SvgPathSegLinetoVerticalAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegLinetoVerticalRel" = [ "SvgPathSeg" ];
+          "SvgPathSegMovetoAbs" = [ "SvgPathSeg" ];
+          "SvgPathSegMovetoRel" = [ "SvgPathSeg" ];
+          "SvgPatternElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgPolygonElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgPolylineElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgRadialGradientElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGradientElement" ];
+          "SvgRectElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGeometryElement" "SvgGraphicsElement" ];
+          "SvgScriptElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgSetElement" = [ "Element" "EventTarget" "Node" "SvgAnimationElement" "SvgElement" ];
+          "SvgStopElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgStyleElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgSwitchElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgSymbolElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgTextContentElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgTextElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" "SvgTextContentElement" "SvgTextPositioningElement" ];
+          "SvgTextPathElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" "SvgTextContentElement" ];
+          "SvgTextPositioningElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" "SvgTextContentElement" ];
+          "SvgTitleElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgUseElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgViewElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgaElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgfeBlendElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeColorMatrixElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeComponentTransferElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeCompositeElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeConvolveMatrixElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeDiffuseLightingElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeDisplacementMapElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeDistantLightElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeDropShadowElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeFloodElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeFuncAElement" = [ "Element" "EventTarget" "Node" "SvgComponentTransferFunctionElement" "SvgElement" ];
+          "SvgfeFuncBElement" = [ "Element" "EventTarget" "Node" "SvgComponentTransferFunctionElement" "SvgElement" ];
+          "SvgfeFuncGElement" = [ "Element" "EventTarget" "Node" "SvgComponentTransferFunctionElement" "SvgElement" ];
+          "SvgfeFuncRElement" = [ "Element" "EventTarget" "Node" "SvgComponentTransferFunctionElement" "SvgElement" ];
+          "SvgfeGaussianBlurElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeImageElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeMergeElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeMergeNodeElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeMorphologyElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeOffsetElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfePointLightElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeSpecularLightingElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeSpotLightElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeTileElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgfeTurbulenceElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvggElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgmPathElement" = [ "Element" "EventTarget" "Node" "SvgElement" ];
+          "SvgsvgElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" ];
+          "SvgtSpanElement" = [ "Element" "EventTarget" "Node" "SvgElement" "SvgGraphicsElement" "SvgTextContentElement" "SvgTextPositioningElement" ];
+          "TcpServerSocket" = [ "EventTarget" ];
+          "TcpServerSocketEvent" = [ "Event" ];
+          "TcpSocket" = [ "EventTarget" ];
+          "TcpSocketErrorEvent" = [ "Event" ];
+          "TcpSocketEvent" = [ "Event" ];
+          "Text" = [ "CharacterData" "EventTarget" "Node" ];
+          "TextTrack" = [ "EventTarget" ];
+          "TextTrackCue" = [ "EventTarget" ];
+          "TextTrackList" = [ "EventTarget" ];
+          "TimeEvent" = [ "Event" ];
+          "TouchEvent" = [ "Event" "UiEvent" ];
+          "TrackEvent" = [ "Event" ];
+          "TransitionEvent" = [ "Event" ];
+          "UiEvent" = [ "Event" ];
+          "Usb" = [ "EventTarget" ];
+          "UsbConnectionEvent" = [ "Event" ];
+          "UsbPermissionResult" = [ "EventTarget" "PermissionStatus" ];
+          "UserProximityEvent" = [ "Event" ];
+          "ValueEvent" = [ "Event" ];
+          "VideoStreamTrack" = [ "EventTarget" "MediaStreamTrack" ];
+          "VideoTrackList" = [ "EventTarget" ];
+          "VrDisplay" = [ "EventTarget" ];
+          "VttCue" = [ "EventTarget" "TextTrackCue" ];
+          "WaveShaperNode" = [ "AudioNode" "EventTarget" ];
+          "WebGlContextEvent" = [ "Event" ];
+          "WebKitCssMatrix" = [ "DomMatrix" "DomMatrixReadOnly" ];
+          "WebSocket" = [ "EventTarget" ];
+          "WheelEvent" = [ "Event" "MouseEvent" "UiEvent" ];
+          "Window" = [ "EventTarget" ];
+          "WindowClient" = [ "Client" ];
+          "Worker" = [ "EventTarget" ];
+          "WorkerDebuggerGlobalScope" = [ "EventTarget" ];
+          "WorkerGlobalScope" = [ "EventTarget" ];
+          "XmlDocument" = [ "Document" "EventTarget" "Node" ];
+          "XmlHttpRequest" = [ "EventTarget" "XmlHttpRequestEventTarget" ];
+          "XmlHttpRequestEventTarget" = [ "EventTarget" ];
+          "XmlHttpRequestUpload" = [ "EventTarget" "XmlHttpRequestEventTarget" ];
+          "Xr" = [ "EventTarget" ];
+          "XrBoundedReferenceSpace" = [ "EventTarget" "XrReferenceSpace" "XrSpace" ];
+          "XrInputSourceEvent" = [ "Event" ];
+          "XrInputSourcesChangeEvent" = [ "Event" ];
+          "XrReferenceSpace" = [ "EventTarget" "XrSpace" ];
+          "XrReferenceSpaceEvent" = [ "Event" ];
+          "XrSession" = [ "EventTarget" ];
+          "XrSessionEvent" = [ "Event" ];
+          "XrSpace" = [ "EventTarget" ];
+          "XrViewerPose" = [ "XrPose" ];
+        };
+        resolvedDefaultFeatures = [ "Event" "EventTarget" "MessageEvent" "Window" "Worker" "WorkerGlobalScope" ];
+      };
+      "wepoll-sys" = rec {
+        crateName = "wepoll-sys";
+        version = "3.0.1";
+        edition = "2018";
+        sha256 = "1zvpkr4dz3ny0k20mg1wdlp8vawz5p4gnya7h8j24119m7g19jqg";
+        authors = [
+          "Yorick Peterse <yorickpeterse@gmail.com>"
+        ];
+        buildDependencies = [
+          {
+            name = "cc";
+            packageId = "cc";
+          }
+        ];
+        features = {
+        };
+        resolvedDefaultFeatures = [ "default" ];
+      };
       "winapi" = rec {
         crateName = "winapi";
         version = "0.3.9";
@@ -1386,7 +3041,7 @@ rec {
         features = {
           "debug" = [ "impl-debug" ];
         };
-        resolvedDefaultFeatures = [ "consoleapi" "fileapi" "handleapi" "knownfolders" "minwinbase" "minwindef" "objbase" "processenv" "shlobj" "winbase" "wincon" "winerror" ];
+        resolvedDefaultFeatures = [ "consoleapi" "fileapi" "handleapi" "ioapiset" "knownfolders" "minwinbase" "minwindef" "objbase" "processenv" "shlobj" "winbase" "wincon" "winerror" "winsock2" "ws2tcpip" ];
       };
       "winapi-i686-pc-windows-gnu" = rec {
         crateName = "winapi-i686-pc-windows-gnu";
diff --git a/Cargo.toml b/Cargo.toml
index f858223..fe931da 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -8,6 +8,12 @@ edition = "2018"
 #futures = "0.3"
 lalrpop-util = "0.19"
 nix = "0.19"
+pin-project = "1.0.4"
+pin-utils = "0.1.0"
+signal-hook = "0.3.4"
+
+[dependencies.async-std]
+version = "1.7.0"
 
 [build-dependencies]
 lalrpop = { version = "0.19", features = [ "lexer" ] }
diff --git a/src/error.rs b/src/error.rs
index b8289f6..1d291ed 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -1,5 +1,7 @@
+#![forbid(unsafe_code)]
+
 use crate::path::GenericPath;
-use crate::path::error::{FileNameError, DirectoryNameError};
+use crate::path::error::{FileNameError, DirectoryNameError, PathError};
 use crate::terminal::error::TerminalError;
 
 
@@ -12,10 +14,7 @@ pub enum Error {
   Parse(String),
   FileName(FileNameError),
   DirectoryName(DirectoryNameError),
-  PathListHasEmptyComponents(String),
-  PathLexicallyDirectory(GenericPath),
-  PathLexicallyRelative(GenericPath),
-  PathLexicallyInvalid(GenericPath),
+  Path(PathError),
   PathEmpiricallyFile(GenericPath),
   Terminal(TerminalError),
 }
@@ -29,23 +28,7 @@ impl std::fmt::Display for Error {
       Error::Parse(e) => e.fmt(f),
       Error::FileName(e) => e.fmt(f),
       Error::DirectoryName(e) => e.fmt(f),
-      Error::PathListHasEmptyComponents(path_list) =>
-        f.write_fmt(format_args!(
-            "Path list has empty components: {}",
-            path_list)),
-      Error::PathLexicallyDirectory(path) =>
-        f.write_fmt(format_args!(
-            "The path {} ends in a slash, but is supposed to refer to a file, \
-             not a directory.",
-            path)),
-      Error::PathLexicallyRelative(path) =>
-        f.write_fmt(format_args!(
-            "The path {} is relative, not absolute.",
-            path)),
-      Error::PathLexicallyInvalid(path) =>
-        f.write_fmt(format_args!(
-            "This isn't a valid path. {}",
-            path)),
+      Error::Path(e) => e.fmt(f),
       Error::PathEmpiricallyFile(path) =>
         f.write_fmt(format_args!(
             "There's a file at {}, not a directory.",
@@ -85,6 +68,12 @@ impl From<DirectoryNameError> for Error {
   }
 }
 
+impl From<PathError> for Error {
+  fn from(e: PathError) -> Error {
+    Error::Path(e)
+  }
+}
+
 impl From<TerminalError> for Error {
   fn from(e: TerminalError) -> Error {
     Error::Terminal(e)
diff --git a/src/main.rs b/src/main.rs
index d7a2aff..935155c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,10 +1,15 @@
+#![forbid(unsafe_code)]
 use crate::prelude::*;
+
+use crate::result::Result;
+use crate::terminal::{Input, Terminal};
+
+use async_std::io;
 use std::collections::HashMap;
 use std::collections::HashSet;
-use std::io;
-use std::io::prelude::*;
+use std::env;
 use std::os::unix::fs::PermissionsExt;
-use std::process::Command;
+use std::process::{self, Command};
 
 #[macro_use] extern crate lalrpop_util;
 
@@ -16,14 +21,9 @@ pub mod result;
 pub mod terminal;
 
 
-pub enum Input {
-  String(String),
-  End,
-}
-
-
 fn main() -> Result<()> {
-  std::process::exit(match repl() {
+  let result = async_std::task::block_on(async { repl().await });
+  process::exit(match result {
     Ok(()) => 0,
     Err(ref e) => {
       eprintln!("{}", e);
@@ -33,45 +33,42 @@ fn main() -> Result<()> {
 }
 
 
-fn repl() -> Result<()> {
+async fn repl() -> Result<()> {
   println!("Hello, terminal!");
 
+  let mut terminal = Terminal::init(io::stdin())?;
+
   loop {
-    prompt()?;
+    prompt().await?;
+
+    let input = terminal.handle_input().await?;
 
-    terminal::handle_input_terminal(io::stdin())?;
-    let input = read()?;
     match input {
-      Input::String(string) => execute(&string)?,
+      Input::String(string) => {
+        println!("{:?} {}", string, string.len());
+        execute(&string).await?
+      },
       Input::End => break,
     }
+
+    break;
   }
 
+  terminal.cleanup()?;
+
   Ok(())
 }
 
 
-fn prompt() -> Result<()> {
+async fn prompt() -> Result<()> {
   print!("\n$ ");
-  io::stdout().flush()?;
+  io::stdout().flush().await?;
 
   Ok(())
 }
 
 
-fn read() -> Result<Input> {
-  let mut input = String::new();
-  let n_bytes = io::stdin().read_line(&mut input)?;
-
-  if n_bytes == 0 {
-    Ok(Input::End)
-  } else {
-    Ok(Input::String(input))
-  }
-}
-
-
-fn execute(input: &str) -> Result<()> {
+async fn execute(input: &str) -> Result<()> {
   let invocation = commandline::InvocationParser::new().parse(input)?;
 
   match invocation.as_slice() {
@@ -114,12 +111,12 @@ fn execute(input: &str) -> Result<()> {
 
 
 fn read_environment() -> Result<HashMap<String,String>> {
-  Ok(std::env::vars().collect())
+  Ok(env::vars().collect())
 }
 
 
 fn get_environment(variable_name: &str) -> Result<Option<String>> {
-  Ok(std::env::vars()
+  Ok(env::vars()
      .find(|(key, _)| key == variable_name)
      .map(|(_, value)| value))
 }
diff --git a/src/path.rs b/src/path.rs
index 570b8ef..7df10b2 100644
--- a/src/path.rs
+++ b/src/path.rs
@@ -6,14 +6,15 @@
  * to get the benefit of its functionality for handling non-Unicode filenames.
  */
 
-use crate::prelude::*;
-use crate::path::error::*;
+#![forbid(unsafe_code)]
+use crate::path::prelude::*;
 
 use std::str::FromStr;
 
 
 lalrpop_mod!(pub parser, "/path/parser.rs");
 pub mod error;
+pub mod prelude;
 
 
 #[derive(Clone,Debug,Eq,Hash,Ord,PartialEq,PartialOrd)]
@@ -230,10 +231,10 @@ pub fn parse_path_list(path_list: &str)
         .parse(path_list)
       {
         Ok(_) => {
-          Err(Error::PathListHasEmptyComponents(path_list.to_string()))
+          Err(PathError::PathListHasEmptyComponents(path_list.to_string()))
         },
         Err(_) => {
-          Err(Error::Parse(original_error.to_string()))
+          Err(PathError::Parse(original_error.to_string()))
         },
       }
     },
@@ -245,7 +246,7 @@ pub fn absolute_directory_path(generic_path: GenericPath)
   -> Result<AbsoluteDirectoryPath>
 {
   if !generic_path.starts_with_slash {
-    return Err(Error::PathLexicallyRelative(generic_path));
+    return Err(PathError::PathLexicallyRelative(generic_path));
   }
 
   let mut flattened_components = Vec::new();
@@ -256,7 +257,7 @@ pub fn absolute_directory_path(generic_path: GenericPath)
         if flattened_components.len() > 0 {
           flattened_components.pop();
         } else {
-          return Err(Error::PathLexicallyInvalid(generic_path));
+          return Err(PathError::PathLexicallyInvalid(generic_path));
         }
       },
       GenericPathComponent::FileOrDirectoryName(name) => {
@@ -275,11 +276,11 @@ pub fn absolute_file_path(generic_path: GenericPath)
   -> Result<AbsoluteFilePath>
 {
   if !generic_path.starts_with_slash {
-    return Err(Error::PathLexicallyRelative(generic_path));
+    return Err(PathError::PathLexicallyRelative(generic_path));
   }
 
   if generic_path.ends_with_slash {
-    return Err(Error::PathLexicallyDirectory(generic_path));
+    return Err(PathError::PathLexicallyDirectory(generic_path));
   }
 
   let mut iterator = generic_path.components.iter();
@@ -289,7 +290,7 @@ pub fn absolute_file_path(generic_path: GenericPath)
       FileName(name.to_string())
     }
     _ => {
-      return Err(Error::PathLexicallyInvalid(generic_path));
+      return Err(PathError::PathLexicallyInvalid(generic_path));
     }
   };
 
@@ -301,7 +302,7 @@ pub fn absolute_file_path(generic_path: GenericPath)
         if flattened_components.len() > 0 {
           flattened_components.pop();
         } else {
-          return Err(Error::PathLexicallyInvalid(generic_path));
+          return Err(PathError::PathLexicallyInvalid(generic_path));
         }
       },
       GenericPathComponent::FileOrDirectoryName(name) => {
diff --git a/src/path/error.rs b/src/path/error.rs
index 0ee5423..aee6e9f 100644
--- a/src/path/error.rs
+++ b/src/path/error.rs
@@ -1,3 +1,10 @@
+#![forbid(unsafe_code)]
+
+use crate::path::GenericPath;
+
+pub type Result<T> = std::result::Result<T, PathError>;
+
+
 #[derive(Clone,Debug,Eq,Hash,Ord,PartialEq,PartialOrd)]
 pub enum FileNameError {
   ContainsSlash(String),
@@ -11,6 +18,10 @@ pub enum DirectoryNameError {
 #[derive(Clone,Debug,Eq,Hash,Ord,PartialEq,PartialOrd)]
 pub enum PathError {
   Parse(String),
+  PathLexicallyDirectory(GenericPath),
+  PathLexicallyRelative(GenericPath),
+  PathLexicallyInvalid(GenericPath),
+  PathListHasEmptyComponents(String),
 }
 
 
@@ -45,6 +56,23 @@ impl std::fmt::Display for PathError {
     match self {
       PathError::Parse(s) =>
         f.write_fmt(format_args!("Syntax error in path: {}", s)),
+      PathError::PathLexicallyDirectory(path) =>
+        f.write_fmt(format_args!(
+            "The path {} ends in a slash, but is supposed to refer to a file, \
+             not a directory.",
+            path)),
+      PathError::PathLexicallyRelative(path) =>
+        f.write_fmt(format_args!(
+            "The path {} is relative, not absolute.",
+            path)),
+      PathError::PathLexicallyInvalid(path) =>
+        f.write_fmt(format_args!(
+            "This isn't a valid path. {}",
+            path)),
+      PathError::PathListHasEmptyComponents(path_list) =>
+        f.write_fmt(format_args!(
+            "Path list has empty components: {}",
+            path_list)),
     }
   }
 }
diff --git a/src/path/prelude.rs b/src/path/prelude.rs
new file mode 100644
index 0000000..f7b23dd
--- /dev/null
+++ b/src/path/prelude.rs
@@ -0,0 +1,5 @@
+#![forbid(unsafe_code)]
+
+pub use crate::path::error::{
+    Result, DirectoryNameError, FileNameError, PathError};
+
diff --git a/src/prelude.rs b/src/prelude.rs
index b44fe02..f678ba1 100644
--- a/src/prelude.rs
+++ b/src/prelude.rs
@@ -1,2 +1,3 @@
-pub use crate::error::Error;
-pub use crate::result::Result;
+#![forbid(unsafe_code)]
+pub use async_std::prelude::*;
+
diff --git a/src/result.rs b/src/result.rs
index 8207680..b757636 100644
--- a/src/result.rs
+++ b/src/result.rs
@@ -1,3 +1,5 @@
+#![forbid(unsafe_code)]
+
 use crate::error::Error;
 
 pub type Result<T> = std::result::Result<T, Error>;
diff --git a/src/terminal.rs b/src/terminal.rs
index 298cc8c..73ba035 100644
--- a/src/terminal.rs
+++ b/src/terminal.rs
@@ -1,12 +1,19 @@
+#![forbid(unsafe_code)]
+use crate::prelude::*;
+use crate::terminal::prelude::*;
+
 use crate::terminal::decoding::CharBufReader;
-use crate::terminal::error::TerminalError;
 
-use nix::sys::termios;
-use std::io::Read;
-use std::os::unix::io::AsRawFd;
+use async_std::io::{self, Read};
+use async_std::os::unix::io::{AsRawFd, RawFd};
+use async_std::sync::{Arc, Mutex};
+use nix::sys::termios::{self, Termios};
+use signal_hook::consts::TERM_SIGNALS;
+use std::sync::atomic::{AtomicBool, Ordering};
 
 pub mod decoding;
 pub mod error;
+pub mod prelude;
 
 
 #[derive(Clone,Debug,Eq,Hash,Ord,PartialEq,PartialOrd)]
@@ -60,6 +67,16 @@ impl LineBuffer {
       first_line.push_str(&second_line);
     }
   }
+
+  pub fn as_string(&self) -> String {
+    self.lines.join("\n")
+  }
+}
+
+
+pub enum Input {
+  String(String),
+  End,
 }
 
 
@@ -70,83 +87,164 @@ enum InputAction {
 }
 
 
-pub fn handle_input_terminal(input_stream: impl Read + AsRawFd)
-  -> std::result::Result<(), TerminalError>
-{
-  let fd = input_stream.as_raw_fd();
-  let mut termios = termios::tcgetattr(fd)
-      .map_err(error::mode_setting)?;
-  termios.local_flags.insert(termios::LocalFlags::ECHO);
-  termios.local_flags.remove(termios::LocalFlags::ECHOCTL);
-  termios.local_flags.remove(termios::LocalFlags::ICANON);
-  termios.control_chars[termios::SpecialCharacterIndices::VMIN as usize] = 1;
-  termios.control_chars[termios::SpecialCharacterIndices::VTIME as usize] = 0;
-  termios::tcsetattr(fd, termios::SetArg::TCSANOW, &termios)
-      .map_err(error::mode_setting)?;
-
-  handle_input(input_stream)
+pub struct Terminal<InputStream: Read + Unpin> {
+  reader: Arc<Mutex<CharBufReader<InputStream>>>,
+  //reader: Arc<CharBufReader<InputStream>>,
+  line_buffer: LineBuffer,
+  file_descriptor: RawFd,
+  initial_termios: Termios,
+  is_interrupted: Arc<AtomicBool>,
 }
 
 
-pub fn handle_input(input_stream: impl Read)
-  -> std::result::Result<(), TerminalError>
-{
-  let mut reader = CharBufReader::new(input_stream);
-  let mut line_buffer = LineBuffer::new();
+impl<InputStream: Read + AsRawFd + Unpin> Terminal<InputStream> {
+  pub fn init(input_stream: InputStream) -> Result<Terminal<InputStream>> {
+    let is_interrupted = Arc::new(AtomicBool::new(false));
 
-  loop {
-    let mut action: Option<InputAction> = None;
+    for signal in TERM_SIGNALS {
+      signal_hook::flag::register(*signal, Arc::clone(&is_interrupted))
+          .map_err(error::internal)?;
+    }
 
-    let string = reader.fill_buf().map_err(error::input)?;
+    let fd = input_stream.as_raw_fd();
+    let termios = termios::tcgetattr(fd).map_err(error::mode_setting)?;
+    let reader = Arc::new(Mutex::new(CharBufReader::new(
+          input_stream, Arc::clone(&is_interrupted))));
+    //let reader = Arc::new(CharBufReader::new(
+          //input_stream, Arc::clone(&is_interrupted)));
+    let line_buffer = LineBuffer::new();
+
+    let terminal = Terminal {
+      reader: reader,
+      line_buffer: line_buffer,
+      file_descriptor: fd,
+      initial_termios: termios,
+      is_interrupted: is_interrupted,
+    };
 
-    let mut chars = string.char_indices();
+    terminal.init_modes()?;
 
-    for (_, c) in &mut chars {
-      match c {
-        '\n' => {
-          action = Some(InputAction::Execute);
-        }
-        '\u{7f}' => {
-          action = Some(InputAction::Backspace);
-        }
-        _ => {
-          line_buffer.insert(&c.to_string());
-        }
-      }
+    Ok(terminal)
+  }
 
-      if action.is_some() {
-        break;
-      }
-    }
 
-    let n_to_consume = match chars.next() {
-      Some((offset, _)) => offset,
-      None => string.len(),
-    };
+  pub fn cleanup(self) -> Result<()> {
+    self.cleanup_modes()?;
+
+    Ok(())
+  }
+
+
+  fn init_modes(&self) -> Result<()> {
+    let mut termios = self.initial_termios.clone();
+
+    termios.local_flags.remove(termios::LocalFlags::ECHO);
+    termios.local_flags.remove(termios::LocalFlags::ECHONL);
+    termios.local_flags.remove(termios::LocalFlags::ECHOCTL);
+    termios.local_flags.remove(termios::LocalFlags::ICANON);
+
+    termios.local_flags.insert(termios::LocalFlags::ISIG);
+
+    termios.control_chars[termios::SpecialCharacterIndices::VMIN as usize] = 1;
+    termios.control_chars[termios::SpecialCharacterIndices::VTIME as usize] = 0;
+
+    termios::tcsetattr(self.file_descriptor,
+                       termios::SetArg::TCSANOW,
+                       &termios)
+        .map_err(error::mode_setting)?;
+
+    Ok(())
+  }
 
-    reader.consume(n_to_consume);
 
-    match action {
-      Some(InputAction::Execute) => {
+  pub fn cleanup_modes(&self) -> Result<()> {
+    println!("de-initializing"); // DO NOT SUBMIT
+
+    let termios = self.initial_termios.clone();
+
+    termios::tcsetattr(self.file_descriptor,
+                       termios::SetArg::TCSANOW,
+                       &termios)
+        .map_err(error::mode_setting)?;
+
+    Ok(())
+  }
+
+
+  pub fn is_exiting(&self) -> bool {
+    self.is_interrupted.load(Ordering::Relaxed)
+  }
+
+
+  pub async fn handle_input(&mut self) -> Result<Input>
+  {
+    let is_interrupted = Arc::clone(&self.is_interrupted);
+
+    loop {
+      let mut action: Option<InputAction> = None;
+
+      let string = CharBufReader::fill_buf(Arc::clone(&self.reader)).await.map_err(error::input)?;
+
+      if is_interrupted.load(Ordering::Relaxed) {
         break;
       }
-      Some(InputAction::Backspace) => {
-        line_buffer.backspace();
+
+      let mut chars = string.char_indices();
+
+      for (_, c) in &mut chars {
+        match c {
+          '\n' => {
+            action = Some(InputAction::Execute);
+          }
+          '\u{7f}' => {
+            action = Some(InputAction::Backspace);
+          }
+          _ => {
+            self.line_buffer.insert(&c.to_string());
+            print!("{}", c);
+            io::stdout().flush();
+          }
+        }
+
+        if action.is_some() {
+          break;
+        }
+      }
+
+      let n_to_consume = match chars.next() {
+        Some((offset, _)) => offset,
+        None => string.len(),
+      };
+
+      Arc::get_mut(&mut self.reader).unwrap().lock().await.consume(n_to_consume);
+
+      match action {
+        Some(InputAction::Execute) => {
+          break;
+        }
+        Some(InputAction::Backspace) => {
+          self.line_buffer.backspace();
+        }
+        None => { }
       }
-      None => { }
     }
-  }
 
-  println!("line buffer {:?}", line_buffer);
-
-  Ok(())
+    println!("line buffer {:?}", self.line_buffer);
+    if self.is_interrupted.load(Ordering::Relaxed) {
+      println!("exiting 3");
+      Ok(Input::End)
+    } else {
+      let input = Input::String(self.line_buffer.as_string());
+      Ok(input)
+    }
+  }
 }
 
 
 #[cfg(test)]
 mod tests {
   use super::*;
-  use std::io::Cursor;
+  use io::Cursor;
 
   #[test]
   fn test_empty_input() {
diff --git a/src/terminal/decoding.rs b/src/terminal/decoding.rs
index e2654fb..11f6046 100644
--- a/src/terminal/decoding.rs
+++ b/src/terminal/decoding.rs
@@ -1,63 +1,128 @@
-use crate::terminal::error::{self, TerminalError};
+#![forbid(unsafe_code)]
+use crate::terminal::prelude::*;
 
-use std::io::{BufRead, BufReader, Read};
+use crate::terminal::error;
+
+use async_std::future::Future;
+use async_std::io::{BufRead, BufReader, Read};
+use async_std::sync::{Arc, Mutex};
+use async_std::task::{Context, Poll};
+use pin_project::pin_project;
+use pin_utils::pin_mut;
+use std::pin::Pin;
 use std::str;
+use std::sync::atomic::{AtomicBool, Ordering};
 
 
-pub struct CharBufReader<R: Read> {
-  byte_reader: BufReader<R>,
-  char_buffer: String,
+#[pin_project]
+pub struct CharBufReader<R: Read + Unpin> {
+  #[pin] byte_reader: BufReader<R>,
+  #[pin] char_buffer: String,
+  is_interrupted: Arc<AtomicBool>,
 }
 
 
-impl<R: Read> CharBufReader<R> {
-  pub fn new(input_stream: R) -> CharBufReader<R> {
-    let byte_reader = BufReader::new(input_stream);
+#[pin_project]
+struct FillBufFuture<R: Read + Unpin> {
+  char_reader: Arc<Mutex<CharBufReader<R>>>,
+  //char_reader: Arc<CharBufReader<R>>,
+}
 
-    CharBufReader {
-      byte_reader: byte_reader,
-      char_buffer: String::new(),
-    }
-  }
 
-  pub fn fill_buf(&mut self)
-    -> std::result::Result<&str, TerminalError>
+impl<R: Read + Unpin> Future for FillBufFuture<R> {
+  type Output = Result<String>;
+
+  fn poll(self: Pin<&mut Self>, context: &mut Context<'_>)
+    -> Poll<Self::Output>
   {
-    loop {
-      let byte_buffer = self.byte_reader.fill_buf().map_err(error::input)?;
-
-      match str::from_utf8(byte_buffer) {
-        Err(error) => {
-          let n_valid = error.valid_up_to();
-          if n_valid == 0 {
-            self.byte_reader.consume(1);
-          } else {
-            match str::from_utf8(&byte_buffer[..n_valid]) {
-              Err(_) => {
-                self.byte_reader.consume(1);
-              },
-              Ok(chars) => {
-                self.char_buffer.push_str(chars);
-
-                self.byte_reader.consume(n_valid);
-
-                break;
-              },
-            }
+    let future = self.project();
+    let char_reader: &mut Arc<Mutex<CharBufReader<R>>> = future.char_reader;
+    let char_reader_future = char_reader.lock();
+    pin_mut!(char_reader_future);
+    match char_reader_future.poll(context) {
+      Poll::Ready(mut char_reader) => {
+        let char_reader = &mut *char_reader;
+        let mut byte_reader: Pin<&mut BufReader<R>> = Pin::new(&mut char_reader.byte_reader);
+
+        loop {
+          if char_reader.is_interrupted.load(Ordering::Relaxed) {
+            println!("char reader got interrupt");
+            return Poll::Pending;
           }
-        },
-        Ok(chars) => {
-          self.char_buffer.push_str(chars);
 
-          let n_to_consume = byte_buffer.len();
-          self.byte_reader.consume(n_to_consume);
+          println!("about to fill_buf");
+          match byte_reader.as_mut().poll_fill_buf(context).map_err(error::input)?
+          {
+            Poll::Ready(byte_buffer) => {
+              println!("done with fill_buf");
+              match str::from_utf8(&byte_buffer) {
+                Err(error) => {
+                  let n_valid = error.valid_up_to();
+                  if n_valid == 0 {
+                    byte_reader.as_mut().consume(1);
+                  } else {
+                    match str::from_utf8(&byte_buffer[..n_valid]) {
+                      Err(_) => {
+                        byte_reader.as_mut().consume(1);
+                      },
+                      Ok(chars) => {
+                        char_reader.char_buffer.push_str(chars);
+
+                        byte_reader.as_mut().consume(n_valid);
+
+                        break;
+                      },
+                    }
+                  }
+                }
+                Ok(chars) => {
+                  char_reader.char_buffer.push_str(chars);
 
-          break;
+                  let n_to_consume = byte_buffer.len();
+                  byte_reader.as_mut().consume(n_to_consume);
+
+                  break;
+                }
+              }
+            }
+            Poll::Pending => {
+              println!("fill_buf pending");
+              return Poll::Pending;
+            }
+          }
         }
+
+        return Poll::Ready(Ok(char_reader.char_buffer.to_string()));
+      }
+      Poll::Pending => {
+        println!("char_reader mutex pending");
+        return Poll::Pending;
       }
     }
+  }
+}
+
+
+impl<R: Read + Unpin> CharBufReader<R> {
+  pub fn new(input_stream: R, is_interrupted: Arc<AtomicBool>)
+    -> CharBufReader<R>
+  {
+    let byte_reader = BufReader::new(input_stream);
+
+    CharBufReader {
+      byte_reader: byte_reader,
+      char_buffer: String::new(),
+      is_interrupted: is_interrupted,
+    }
+  }
 
-    return Ok(&self.char_buffer);
+  pub fn fill_buf(reader: Arc<Mutex<Self>>)
+  //pub fn fill_buf(reader: Arc<Self>)
+    -> impl Future<Output = Result<String>>
+  {
+    FillBufFuture {
+      char_reader: reader,
+    }
   }
 
   pub fn consume(&mut self, amount: usize) {
diff --git a/src/terminal/error.rs b/src/terminal/error.rs
index 6666e49..795f973 100644
--- a/src/terminal/error.rs
+++ b/src/terminal/error.rs
@@ -1,7 +1,13 @@
+#![forbid(unsafe_code)]
+
+pub type Result<T> = std::result::Result<T, TerminalError>;
+
+
 #[derive(Clone,Debug,Eq,Hash,Ord,PartialEq,PartialOrd)]
 pub enum TerminalError {
   Input(String),
   ModeSetting(String),
+  Internal(String),
 }
 
 impl std::error::Error for TerminalError { }
@@ -15,6 +21,9 @@ impl std::fmt::Display for TerminalError {
       TerminalError::ModeSetting(s) =>
         f.write_fmt(format_args!(
             "Can't set terminal mode: {}", s)),
+      TerminalError::Internal(s) =>
+        f.write_fmt(format_args!(
+            "Internal error regarding the terminal: {}", s)),
     }
   }
 }
@@ -29,3 +38,8 @@ pub fn mode_setting(e: impl std::error::Error) -> TerminalError {
   TerminalError::ModeSetting(format!("{}", e))
 }
 
+
+pub fn internal(e: impl std::error::Error) -> TerminalError {
+  TerminalError::Internal(format!("{}", e))
+}
+
diff --git a/src/terminal/prelude.rs b/src/terminal/prelude.rs
new file mode 100644
index 0000000..bada817
--- /dev/null
+++ b/src/terminal/prelude.rs
@@ -0,0 +1,4 @@
+#![forbid(unsafe_code)]
+
+pub use crate::terminal::error::{Result, TerminalError};
+