From 1915878f9c198b05e25873562078abeaa905c411 Mon Sep 17 00:00:00 2001
From: StarArawn <toasterthegamer@gmail.com>
Date: Wed, 24 Nov 2021 14:57:43 -0500
Subject: [PATCH] First commit..

---
 .gitignore                                    |   17 +-
 Cargo.lock                                    | 3641 +++++++++++++++++
 bevy_kayak_ui/Cargo.toml                      |   13 +
 bevy_kayak_ui/src/bevy_context.rs             |   32 +
 bevy_kayak_ui/src/camera/camera.rs            |   58 +
 bevy_kayak_ui/src/camera/mod.rs               |   23 +
 bevy_kayak_ui/src/camera/ortho.rs             |   73 +
 bevy_kayak_ui/src/lib.rs                      |   29 +
 bevy_kayak_ui/src/render/mod.rs               |   95 +
 bevy_kayak_ui/src/render/quad/mod.rs          |   43 +
 bevy_kayak_ui/src/render/quad/pipeline.rs     |  344 ++
 bevy_kayak_ui/src/render/quad/shader.wgsl     |   30 +
 bevy_kayak_ui/src/render/text/font.rs         |    8 +
 bevy_kayak_ui/src/render/text/font_mapping.rs |   40 +
 .../src/render/text/font_texture_cache.rs     |  201 +
 bevy_kayak_ui/src/render/text/mod.rs          |  141 +
 bevy_kayak_ui/src/render/text/pipeline.rs     |  360 ++
 bevy_kayak_ui/src/render/text/shader.wgsl     |   45 +
 bevy_kayak_ui/src/render/ui_pass.rs           |  102 +
 bevy_kayak_ui/src/render/ui_pass_driver.rs    |   29 +
 .../src/render/unified/font/extract.rs        |   87 +
 bevy_kayak_ui/src/render/unified/font/font.rs |    8 +
 .../src/render/unified/font/font_mapping.rs   |   40 +
 .../render/unified/font/font_texture_cache.rs |  248 ++
 bevy_kayak_ui/src/render/unified/font/mod.rs  |  112 +
 bevy_kayak_ui/src/render/unified/mod.rs       |   46 +
 bevy_kayak_ui/src/render/unified/pipeline.rs  |  438 ++
 .../src/render/unified/quad/extract.rs        |   52 +
 bevy_kayak_ui/src/render/unified/quad/mod.rs  |   15 +
 bevy_kayak_ui/src/render/unified/shader.wgsl  |   56 +
 cargo.toml                                    |   21 +
 examples/bevy.rs                              |   65 +
 kayak_components/.gitignore                   |    7 +
 kayak_components/Cargo.toml                   |    8 +
 kayak_components/src/app.rs                   |   12 +
 kayak_components/src/background.rs            |   19 +
 kayak_components/src/clip.rs                  |   19 +
 kayak_components/src/element.rs               |   10 +
 kayak_components/src/lib.rs                   |   11 +
 kayak_components/src/text.rs                  |   24 +
 kayak_components/src/window.rs                |   72 +
 kayak_core/cargo.toml                         |   17 +
 kayak_core/examples/test3.rs                  |   63 +
 kayak_core/src/color.rs                       |   48 +
 kayak_core/src/context.rs                     |  102 +
 kayak_core/src/fragment.rs                    |   33 +
 kayak_core/src/generational_arena.rs          | 1326 ++++++
 kayak_core/src/layout_cache.rs                |  358 ++
 kayak_core/src/lib.rs                         |   29 +
 kayak_core/src/node.rs                        |  285 ++
 kayak_core/src/render_command.rs              |   17 +
 kayak_core/src/render_primitive.rs            |   59 +
 kayak_core/src/styles.rs                      |  136 +
 kayak_core/src/tree.rs                        |  257 ++
 kayak_core/src/widget.rs                      |   15 +
 kayak_core/src/widget_manager.rs              |  216 +
 kayak_font/.gitignore                         |    1 +
 kayak_font/Cargo.toml                         |   17 +
 kayak_font/examples/main.rs                   |   54 +
 kayak_font/examples/simple.rs                 |   30 +
 kayak_font/resources/Roboto-Regular.ttf       |  Bin 0 -> 171272 bytes
 kayak_font/src/color_flags.rs                 |   62 +
 kayak_font/src/contour.rs                     |  108 +
 kayak_font/src/font.rs                        |  253 ++
 kayak_font/src/lib.rs                         |   27 +
 kayak_font/src/msdf.rs                        |  171 +
 kayak_font/src/path_collector.rs              |  134 +
 kayak_font/src/path_element.rs                |  191 +
 kayak_font/src/recolor.rs                     |  124 +
 kayak_font/src/sdf.rs                         |   87 +
 kayak_font/src/ttf_parser.rs                  |   69 +
 kayak_font/src/utils.rs                       |   61 +
 kayak_render_macros/Cargo.toml                |   17 +
 kayak_render_macros/examples/main.rs          |   70 +
 kayak_render_macros/src/arc_function.rs       |   28 +
 kayak_render_macros/src/attribute.rs          |   95 +
 kayak_render_macros/src/child.rs              |   58 +
 kayak_render_macros/src/children.rs           |  219 +
 kayak_render_macros/src/function_component.rs |  192 +
 kayak_render_macros/src/lib.rs                |  100 +
 kayak_render_macros/src/partial_eq.rs         |   16 +
 kayak_render_macros/src/tags.rs               |   78 +
 kayak_render_macros/src/widget.rs             |   97 +
 kayak_render_macros/src/widget_attributes.rs  |  108 +
 resources/Roboto-Regular.ttf                  |  Bin 0 -> 171272 bytes
 src/lib.rs                                    |    7 +
 86 files changed, 12122 insertions(+), 7 deletions(-)
 create mode 100644 Cargo.lock
 create mode 100644 bevy_kayak_ui/Cargo.toml
 create mode 100644 bevy_kayak_ui/src/bevy_context.rs
 create mode 100644 bevy_kayak_ui/src/camera/camera.rs
 create mode 100644 bevy_kayak_ui/src/camera/mod.rs
 create mode 100644 bevy_kayak_ui/src/camera/ortho.rs
 create mode 100644 bevy_kayak_ui/src/lib.rs
 create mode 100644 bevy_kayak_ui/src/render/mod.rs
 create mode 100644 bevy_kayak_ui/src/render/quad/mod.rs
 create mode 100644 bevy_kayak_ui/src/render/quad/pipeline.rs
 create mode 100644 bevy_kayak_ui/src/render/quad/shader.wgsl
 create mode 100644 bevy_kayak_ui/src/render/text/font.rs
 create mode 100644 bevy_kayak_ui/src/render/text/font_mapping.rs
 create mode 100644 bevy_kayak_ui/src/render/text/font_texture_cache.rs
 create mode 100644 bevy_kayak_ui/src/render/text/mod.rs
 create mode 100644 bevy_kayak_ui/src/render/text/pipeline.rs
 create mode 100644 bevy_kayak_ui/src/render/text/shader.wgsl
 create mode 100644 bevy_kayak_ui/src/render/ui_pass.rs
 create mode 100644 bevy_kayak_ui/src/render/ui_pass_driver.rs
 create mode 100644 bevy_kayak_ui/src/render/unified/font/extract.rs
 create mode 100644 bevy_kayak_ui/src/render/unified/font/font.rs
 create mode 100644 bevy_kayak_ui/src/render/unified/font/font_mapping.rs
 create mode 100644 bevy_kayak_ui/src/render/unified/font/font_texture_cache.rs
 create mode 100644 bevy_kayak_ui/src/render/unified/font/mod.rs
 create mode 100644 bevy_kayak_ui/src/render/unified/mod.rs
 create mode 100644 bevy_kayak_ui/src/render/unified/pipeline.rs
 create mode 100644 bevy_kayak_ui/src/render/unified/quad/extract.rs
 create mode 100644 bevy_kayak_ui/src/render/unified/quad/mod.rs
 create mode 100644 bevy_kayak_ui/src/render/unified/shader.wgsl
 create mode 100644 cargo.toml
 create mode 100644 examples/bevy.rs
 create mode 100644 kayak_components/.gitignore
 create mode 100644 kayak_components/Cargo.toml
 create mode 100644 kayak_components/src/app.rs
 create mode 100644 kayak_components/src/background.rs
 create mode 100644 kayak_components/src/clip.rs
 create mode 100644 kayak_components/src/element.rs
 create mode 100644 kayak_components/src/lib.rs
 create mode 100644 kayak_components/src/text.rs
 create mode 100644 kayak_components/src/window.rs
 create mode 100644 kayak_core/cargo.toml
 create mode 100644 kayak_core/examples/test3.rs
 create mode 100644 kayak_core/src/color.rs
 create mode 100644 kayak_core/src/context.rs
 create mode 100644 kayak_core/src/fragment.rs
 create mode 100644 kayak_core/src/generational_arena.rs
 create mode 100644 kayak_core/src/layout_cache.rs
 create mode 100644 kayak_core/src/lib.rs
 create mode 100644 kayak_core/src/node.rs
 create mode 100644 kayak_core/src/render_command.rs
 create mode 100644 kayak_core/src/render_primitive.rs
 create mode 100644 kayak_core/src/styles.rs
 create mode 100644 kayak_core/src/tree.rs
 create mode 100644 kayak_core/src/widget.rs
 create mode 100644 kayak_core/src/widget_manager.rs
 create mode 100644 kayak_font/.gitignore
 create mode 100644 kayak_font/Cargo.toml
 create mode 100644 kayak_font/examples/main.rs
 create mode 100644 kayak_font/examples/simple.rs
 create mode 100644 kayak_font/resources/Roboto-Regular.ttf
 create mode 100644 kayak_font/src/color_flags.rs
 create mode 100644 kayak_font/src/contour.rs
 create mode 100644 kayak_font/src/font.rs
 create mode 100644 kayak_font/src/lib.rs
 create mode 100644 kayak_font/src/msdf.rs
 create mode 100644 kayak_font/src/path_collector.rs
 create mode 100644 kayak_font/src/path_element.rs
 create mode 100644 kayak_font/src/recolor.rs
 create mode 100644 kayak_font/src/sdf.rs
 create mode 100644 kayak_font/src/ttf_parser.rs
 create mode 100644 kayak_font/src/utils.rs
 create mode 100644 kayak_render_macros/Cargo.toml
 create mode 100644 kayak_render_macros/examples/main.rs
 create mode 100644 kayak_render_macros/src/arc_function.rs
 create mode 100644 kayak_render_macros/src/attribute.rs
 create mode 100644 kayak_render_macros/src/child.rs
 create mode 100644 kayak_render_macros/src/children.rs
 create mode 100644 kayak_render_macros/src/function_component.rs
 create mode 100644 kayak_render_macros/src/lib.rs
 create mode 100644 kayak_render_macros/src/partial_eq.rs
 create mode 100644 kayak_render_macros/src/tags.rs
 create mode 100644 kayak_render_macros/src/widget.rs
 create mode 100644 kayak_render_macros/src/widget_attributes.rs
 create mode 100644 resources/Roboto-Regular.ttf
 create mode 100644 src/lib.rs

diff --git a/.gitignore b/.gitignore
index 088ba6b..afb05e5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,13 @@
-# Generated by Cargo
-# will have compiled files and executables
-/target/
-
-# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
-# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
-Cargo.lock
+target
 
 # These are backup files generated by rustfmt
 **/*.rs.bk
+
+# MSVC Windows builds of rustc generate these, which store debugging information
+*.pdb
+
+.vscode
+
+*.log
+
+msdfgen
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..4b9e0ca
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,3641 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "Inflector"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
+
+[[package]]
+name = "ab_glyph"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20b228f2c198f98d4337ceb560333fb12cbb2f4948a953bf8c57d09deb219603"
+dependencies = [
+ "ab_glyph_rasterizer",
+ "owned_ttf_parser",
+]
+
+[[package]]
+name = "ab_glyph_rasterizer"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a13739d7177fbd22bb0ed28badfff9f372f8bef46c863db4e1c6248f6b223b6e"
+
+[[package]]
+name = "adler32"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
+
+[[package]]
+name = "ahash"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
+dependencies = [
+ "getrandom",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
+name = "aho-corasick"
+version = "0.7.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "alsa"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75c4da790adcb2ce5e758c064b4f3ec17a30349f9961d3e5e6c9688b052a9e18"
+dependencies = [
+ "alsa-sys",
+ "bitflags",
+ "libc",
+ "nix",
+]
+
+[[package]]
+name = "alsa-sys"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527"
+dependencies = [
+ "libc",
+ "pkg-config",
+]
+
+[[package]]
+name = "android_log-sys"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b8052e2d8aabbb8d556d6abbcce2a22b9590996c5f849b9c7ce4544a2e3b984e"
+
+[[package]]
+name = "android_log-sys"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85965b6739a430150bdd138e2374a98af0c3ee0d030b3bb7fc3bddff58d0102e"
+
+[[package]]
+name = "android_logger"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cbd542dd180566fad88fd2729a53a62a734843c626638006a9d63ec0688484e"
+dependencies = [
+ "android_log-sys 0.1.2",
+ "env_logger",
+ "lazy_static",
+ "log",
+]
+
+[[package]]
+name = "ansi_term"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
+
+[[package]]
+name = "ansi_term"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38d9ff5d688f1c13395289f67db01d4826b46dd694e7580accdc3e8430f2d98e"
+
+[[package]]
+name = "approx"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "072df7202e63b127ab55acfe16ce97013d5b97bf160489336d3f1840fd78e99e"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "arrayvec"
+version = "0.4.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
+dependencies = [
+ "nodrop",
+]
+
+[[package]]
+name = "arrayvec"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
+
+[[package]]
+name = "as-any"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b564204d863976c470dbd0e41d1fcc351a8cd1b58222aaaae466f82c493fae4"
+
+[[package]]
+name = "ash"
+version = "0.33.3+1.2.191"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc4f1d82f164f838ae413296d1131aa6fa79b917d25bebaa7033d25620c09219"
+dependencies = [
+ "libloading",
+]
+
+[[package]]
+name = "async-channel"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319"
+dependencies = [
+ "concurrent-queue",
+ "event-listener",
+ "futures-core",
+]
+
+[[package]]
+name = "async-executor"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965"
+dependencies = [
+ "async-task",
+ "concurrent-queue",
+ "fastrand",
+ "futures-lite",
+ "once_cell",
+ "slab",
+]
+
+[[package]]
+name = "async-task"
+version = "4.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0"
+
+[[package]]
+name = "autocfg"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
+
+[[package]]
+name = "base-x"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b"
+
+[[package]]
+name = "base64"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+
+[[package]]
+name = "bevy"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_internal",
+]
+
+[[package]]
+name = "bevy-glsl-to-spirv"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d5f2f58f0aec3c50a20799792c3705e80dd7df327e79791cacec197e84e5e61"
+
+[[package]]
+name = "bevy_app"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_derive",
+ "bevy_ecs",
+ "bevy_reflect",
+ "bevy_utils",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "bevy_asset"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "anyhow",
+ "bevy_app",
+ "bevy_diagnostic",
+ "bevy_ecs",
+ "bevy_log",
+ "bevy_reflect",
+ "bevy_tasks",
+ "bevy_utils",
+ "crossbeam-channel",
+ "downcast-rs",
+ "js-sys",
+ "ndk-glue 0.2.1",
+ "notify",
+ "parking_lot",
+ "rand",
+ "serde",
+ "thiserror",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+]
+
+[[package]]
+name = "bevy_audio"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "anyhow",
+ "bevy_app",
+ "bevy_asset",
+ "bevy_ecs",
+ "bevy_reflect",
+ "bevy_utils",
+ "parking_lot",
+ "rodio",
+]
+
+[[package]]
+name = "bevy_core"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_derive",
+ "bevy_ecs",
+ "bevy_math",
+ "bevy_reflect",
+ "bevy_tasks",
+ "bevy_utils",
+ "bytemuck",
+]
+
+[[package]]
+name = "bevy_core_pipeline"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_asset",
+ "bevy_core",
+ "bevy_ecs",
+ "bevy_render2",
+]
+
+[[package]]
+name = "bevy_derive"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "Inflector",
+ "bevy_macro_utils",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "bevy_diagnostic"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_core",
+ "bevy_ecs",
+ "bevy_log",
+ "bevy_utils",
+]
+
+[[package]]
+name = "bevy_dynamic_plugin"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "libloading",
+]
+
+[[package]]
+name = "bevy_ecs"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "async-channel",
+ "bevy_ecs_macros",
+ "bevy_reflect",
+ "bevy_tasks",
+ "bevy_utils",
+ "downcast-rs",
+ "fixedbitset",
+ "fxhash",
+ "rand",
+ "serde",
+ "thiserror",
+]
+
+[[package]]
+name = "bevy_ecs_macros"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_macro_utils",
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "bevy_gilrs"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_ecs",
+ "bevy_input",
+ "bevy_utils",
+ "gilrs",
+]
+
+[[package]]
+name = "bevy_gltf2"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "anyhow",
+ "base64",
+ "bevy_app",
+ "bevy_asset",
+ "bevy_core",
+ "bevy_ecs",
+ "bevy_log",
+ "bevy_math",
+ "bevy_pbr2",
+ "bevy_reflect",
+ "bevy_render2",
+ "bevy_scene",
+ "bevy_transform",
+ "gltf",
+ "percent-encoding",
+ "thiserror",
+ "wgpu",
+]
+
+[[package]]
+name = "bevy_input"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_ecs",
+ "bevy_math",
+ "bevy_utils",
+]
+
+[[package]]
+name = "bevy_internal"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_asset",
+ "bevy_audio",
+ "bevy_core",
+ "bevy_core_pipeline",
+ "bevy_derive",
+ "bevy_diagnostic",
+ "bevy_dynamic_plugin",
+ "bevy_ecs",
+ "bevy_gilrs",
+ "bevy_gltf2",
+ "bevy_input",
+ "bevy_log",
+ "bevy_math",
+ "bevy_pbr",
+ "bevy_pbr2",
+ "bevy_reflect",
+ "bevy_render",
+ "bevy_render2",
+ "bevy_scene",
+ "bevy_sprite",
+ "bevy_sprite2",
+ "bevy_tasks",
+ "bevy_text",
+ "bevy_transform",
+ "bevy_ui",
+ "bevy_utils",
+ "bevy_wgpu",
+ "bevy_window",
+ "bevy_winit",
+ "ndk-glue 0.2.1",
+]
+
+[[package]]
+name = "bevy_kayak_ui"
+version = "0.0.1"
+dependencies = [
+ "bevy",
+ "bytemuck",
+ "crevice",
+ "kayak_components",
+ "kayak_core",
+ "kayak_font",
+ "kayak_render_macros",
+]
+
+[[package]]
+name = "bevy_log"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "android_log-sys 0.2.0",
+ "bevy_app",
+ "bevy_utils",
+ "console_error_panic_hook",
+ "tracing-log",
+ "tracing-subscriber",
+ "tracing-wasm",
+]
+
+[[package]]
+name = "bevy_macro_utils"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "cargo-manifest",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "bevy_math"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_reflect",
+ "glam",
+]
+
+[[package]]
+name = "bevy_pbr"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_asset",
+ "bevy_core",
+ "bevy_ecs",
+ "bevy_math",
+ "bevy_reflect",
+ "bevy_render",
+ "bevy_transform",
+ "bytemuck",
+]
+
+[[package]]
+name = "bevy_pbr2"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_asset",
+ "bevy_core",
+ "bevy_core_pipeline",
+ "bevy_ecs",
+ "bevy_math",
+ "bevy_reflect",
+ "bevy_render2",
+ "bevy_transform",
+ "bevy_utils",
+ "bitflags",
+ "bytemuck",
+ "crevice",
+ "wgpu",
+]
+
+[[package]]
+name = "bevy_reflect"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_reflect_derive",
+ "bevy_utils",
+ "downcast-rs",
+ "erased-serde",
+ "glam",
+ "parking_lot",
+ "serde",
+ "smallvec",
+ "thiserror",
+]
+
+[[package]]
+name = "bevy_reflect_derive"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_macro_utils",
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+ "uuid",
+]
+
+[[package]]
+name = "bevy_render"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "anyhow",
+ "bevy-glsl-to-spirv",
+ "bevy_app",
+ "bevy_asset",
+ "bevy_core",
+ "bevy_derive",
+ "bevy_ecs",
+ "bevy_math",
+ "bevy_reflect",
+ "bevy_transform",
+ "bevy_utils",
+ "bevy_window",
+ "bitflags",
+ "downcast-rs",
+ "hex",
+ "hexasphere",
+ "image",
+ "once_cell",
+ "parking_lot",
+ "serde",
+ "shaderc",
+ "spirv-reflect",
+ "thiserror",
+]
+
+[[package]]
+name = "bevy_render2"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "anyhow",
+ "bevy_app",
+ "bevy_asset",
+ "bevy_core",
+ "bevy_derive",
+ "bevy_ecs",
+ "bevy_math",
+ "bevy_reflect",
+ "bevy_transform",
+ "bevy_utils",
+ "bevy_window",
+ "bitflags",
+ "crevice",
+ "downcast-rs",
+ "futures-lite",
+ "hex",
+ "hexasphere",
+ "image",
+ "naga",
+ "once_cell",
+ "parking_lot",
+ "regex",
+ "serde",
+ "smallvec",
+ "thiserror",
+ "wgpu",
+]
+
+[[package]]
+name = "bevy_scene"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "anyhow",
+ "bevy_app",
+ "bevy_asset",
+ "bevy_ecs",
+ "bevy_reflect",
+ "bevy_transform",
+ "bevy_utils",
+ "ron",
+ "serde",
+ "thiserror",
+ "uuid",
+]
+
+[[package]]
+name = "bevy_sprite"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_asset",
+ "bevy_core",
+ "bevy_ecs",
+ "bevy_log",
+ "bevy_math",
+ "bevy_reflect",
+ "bevy_render",
+ "bevy_transform",
+ "bevy_utils",
+ "bevy_window",
+ "bytemuck",
+ "guillotiere",
+ "rectangle-pack",
+ "serde",
+ "thiserror",
+]
+
+[[package]]
+name = "bevy_sprite2"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_asset",
+ "bevy_core",
+ "bevy_core_pipeline",
+ "bevy_ecs",
+ "bevy_log",
+ "bevy_math",
+ "bevy_reflect",
+ "bevy_render2",
+ "bevy_transform",
+ "bevy_utils",
+ "bytemuck",
+ "guillotiere",
+ "rectangle-pack",
+ "serde",
+ "thiserror",
+]
+
+[[package]]
+name = "bevy_tasks"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "async-channel",
+ "async-executor",
+ "event-listener",
+ "futures-lite",
+ "num_cpus",
+ "wasm-bindgen-futures",
+]
+
+[[package]]
+name = "bevy_text"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "ab_glyph",
+ "anyhow",
+ "bevy_app",
+ "bevy_asset",
+ "bevy_core",
+ "bevy_ecs",
+ "bevy_math",
+ "bevy_reflect",
+ "bevy_render",
+ "bevy_sprite",
+ "bevy_transform",
+ "bevy_utils",
+ "bevy_window",
+ "glyph_brush_layout",
+ "thiserror",
+]
+
+[[package]]
+name = "bevy_transform"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_ecs",
+ "bevy_math",
+ "bevy_reflect",
+ "bevy_utils",
+ "smallvec",
+]
+
+[[package]]
+name = "bevy_ui"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_asset",
+ "bevy_core",
+ "bevy_derive",
+ "bevy_ecs",
+ "bevy_input",
+ "bevy_log",
+ "bevy_math",
+ "bevy_reflect",
+ "bevy_render",
+ "bevy_sprite",
+ "bevy_text",
+ "bevy_transform",
+ "bevy_utils",
+ "bevy_window",
+ "serde",
+ "smallvec",
+ "stretch",
+]
+
+[[package]]
+name = "bevy_utils"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "ahash",
+ "bevy_derive",
+ "getrandom",
+ "instant",
+ "tracing",
+ "uuid",
+]
+
+[[package]]
+name = "bevy_wgpu"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_asset",
+ "bevy_core",
+ "bevy_diagnostic",
+ "bevy_ecs",
+ "bevy_render",
+ "bevy_utils",
+ "bevy_window",
+ "bevy_winit",
+ "crossbeam-channel",
+ "crossbeam-utils",
+ "futures-lite",
+ "parking_lot",
+ "wgpu",
+]
+
+[[package]]
+name = "bevy_window"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_ecs",
+ "bevy_math",
+ "bevy_utils",
+ "raw-window-handle",
+ "web-sys",
+]
+
+[[package]]
+name = "bevy_winit"
+version = "0.5.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bevy_app",
+ "bevy_ecs",
+ "bevy_input",
+ "bevy_math",
+ "bevy_utils",
+ "bevy_window",
+ "raw-window-handle",
+ "wasm-bindgen",
+ "web-sys",
+ "winit",
+]
+
+[[package]]
+name = "bindgen"
+version = "0.56.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2da379dbebc0b76ef63ca68d8fc6e71c0f13e59432e0987e508c1820e6ab5239"
+dependencies = [
+ "bitflags",
+ "cexpr",
+ "clang-sys",
+ "lazy_static",
+ "lazycell",
+ "peeking_take_while",
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "regex",
+ "rustc-hash",
+ "shlex",
+]
+
+[[package]]
+name = "bit-set"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
+dependencies = [
+ "bit-vec",
+]
+
+[[package]]
+name = "bit-vec"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "block"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
+
+[[package]]
+name = "bumpalo"
+version = "3.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
+
+[[package]]
+name = "bytemuck"
+version = "1.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72957246c41db82b8ef88a5486143830adeb8227ef9837740bdec67724cf2c5b"
+dependencies = [
+ "bytemuck_derive",
+]
+
+[[package]]
+name = "bytemuck_derive"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e215f8c2f9f79cb53c8335e687ffd07d5bfcb6fe5fc80723762d0be46e7cc54"
+dependencies = [
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "bytes"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
+
+[[package]]
+name = "cache-padded"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
+
+[[package]]
+name = "cargo-manifest"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af6d65c7592744998c67947ec771c62687c76f00179a83ffd563c0482046bb98"
+dependencies = [
+ "serde",
+ "serde_derive",
+ "toml",
+]
+
+[[package]]
+name = "cc"
+version = "1.0.72"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
+dependencies = [
+ "jobserver",
+]
+
+[[package]]
+name = "cesu8"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
+
+[[package]]
+name = "cexpr"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "cfg-if"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "cfg_aliases"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
+
+[[package]]
+name = "chrono"
+version = "0.4.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
+dependencies = [
+ "libc",
+ "num-integer",
+ "num-traits",
+ "winapi",
+]
+
+[[package]]
+name = "clang-sys"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa66045b9cb23c2e9c1520732030608b02ee07e5cfaa5a521ec15ded7fa24c90"
+dependencies = [
+ "glob",
+ "libc",
+ "libloading",
+]
+
+[[package]]
+name = "cmake"
+version = "0.1.46"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7b858541263efe664aead4a5209a4ae5c5d2811167d4ed4ee0944503f8d2089"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "cocoa"
+version = "0.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832"
+dependencies = [
+ "bitflags",
+ "block",
+ "cocoa-foundation",
+ "core-foundation 0.9.2",
+ "core-graphics 0.22.3",
+ "foreign-types",
+ "libc",
+ "objc",
+]
+
+[[package]]
+name = "cocoa-foundation"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318"
+dependencies = [
+ "bitflags",
+ "block",
+ "core-foundation 0.9.2",
+ "core-graphics-types",
+ "foreign-types",
+ "libc",
+ "objc",
+]
+
+[[package]]
+name = "codespan-reporting"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
+dependencies = [
+ "termcolor",
+ "unicode-width",
+]
+
+[[package]]
+name = "color_quant"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
+
+[[package]]
+name = "combine"
+version = "4.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2b2f5d0ee456f3928812dfc8c6d9a1d592b98678f6d56db9b0cd2b7bc6c8db5"
+dependencies = [
+ "bytes",
+ "memchr",
+]
+
+[[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 = "console_error_panic_hook"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
+dependencies = [
+ "cfg-if 1.0.0",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "copyless"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536"
+
+[[package]]
+name = "core-foundation"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d"
+dependencies = [
+ "core-foundation-sys 0.6.2",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
+dependencies = [
+ "core-foundation-sys 0.7.0",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3"
+dependencies = [
+ "core-foundation-sys 0.8.3",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
+
+[[package]]
+name = "core-graphics"
+version = "0.19.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923"
+dependencies = [
+ "bitflags",
+ "core-foundation 0.7.0",
+ "foreign-types",
+ "libc",
+]
+
+[[package]]
+name = "core-graphics"
+version = "0.22.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb"
+dependencies = [
+ "bitflags",
+ "core-foundation 0.9.2",
+ "core-graphics-types",
+ "foreign-types",
+ "libc",
+]
+
+[[package]]
+name = "core-graphics-types"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b"
+dependencies = [
+ "bitflags",
+ "core-foundation 0.9.2",
+ "foreign-types",
+ "libc",
+]
+
+[[package]]
+name = "core-video-sys"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828"
+dependencies = [
+ "cfg-if 0.1.10",
+ "core-foundation-sys 0.7.0",
+ "core-graphics 0.19.2",
+ "libc",
+ "objc",
+]
+
+[[package]]
+name = "coreaudio-rs"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11894b20ebfe1ff903cbdc52259693389eea03b94918a2def2c30c3bf227ad88"
+dependencies = [
+ "bitflags",
+ "coreaudio-sys",
+]
+
+[[package]]
+name = "coreaudio-sys"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b7e3347be6a09b46aba228d6608386739fb70beff4f61e07422da87b0bb31fa"
+dependencies = [
+ "bindgen",
+]
+
+[[package]]
+name = "cpal"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "98f45f0a21f617cd2c788889ef710b63f075c949259593ea09c826f1e47a2418"
+dependencies = [
+ "alsa",
+ "core-foundation-sys 0.8.3",
+ "coreaudio-rs",
+ "jni",
+ "js-sys",
+ "lazy_static",
+ "libc",
+ "mach 0.3.2",
+ "ndk 0.3.0",
+ "ndk-glue 0.3.0",
+ "nix",
+ "oboe",
+ "parking_lot",
+ "stdweb 0.1.3",
+ "thiserror",
+ "web-sys",
+ "winapi",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "crevice"
+version = "0.8.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "bytemuck",
+ "crevice-derive",
+ "glam",
+ "mint",
+]
+
+[[package]]
+name = "crevice-derive"
+version = "0.8.0"
+source = "git+https://github.com/StarArawn/bevy?rev=b26f563b13c267ffe1ee801bd71fd40b98a256e7#b26f563b13c267ffe1ee801bd71fd40b98a256e7"
+dependencies = [
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "crossbeam"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845"
+dependencies = [
+ "cfg-if 1.0.0",
+ "crossbeam-channel",
+ "crossbeam-deque",
+ "crossbeam-epoch",
+ "crossbeam-queue",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
+dependencies = [
+ "cfg-if 1.0.0",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
+dependencies = [
+ "cfg-if 1.0.0",
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
+dependencies = [
+ "cfg-if 1.0.0",
+ "crossbeam-utils",
+ "lazy_static",
+ "memoffset",
+ "scopeguard",
+]
+
+[[package]]
+name = "crossbeam-queue"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9"
+dependencies = [
+ "cfg-if 1.0.0",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
+dependencies = [
+ "cfg-if 1.0.0",
+ "lazy_static",
+]
+
+[[package]]
+name = "d3d12"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2daefd788d1e96e0a9d66dee4b828b883509bc3ea9ce30665f04c3246372690c"
+dependencies = [
+ "bitflags",
+ "libloading",
+ "winapi",
+]
+
+[[package]]
+name = "darling"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "strsim",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
+dependencies = [
+ "darling_core",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "deflate"
+version = "0.8.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174"
+dependencies = [
+ "adler32",
+ "byteorder",
+]
+
+[[package]]
+name = "derivative"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
+dependencies = [
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "diff-struct"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f30a0f0aafc8da0d598388b1897310646f45f47f17e31d581b4390f9dd88e826"
+dependencies = [
+ "diff_derive",
+ "serde",
+]
+
+[[package]]
+name = "diff_derive"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56f9c37d395456d9c1785499421c6288931b6e3dbc2500acb95b8adaa0e69db3"
+dependencies = [
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "difference"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3304d19798a8e067e48d8e69b2c37f0b5e9b4e462504ad9e27e9f3fce02bba8"
+
+[[package]]
+name = "discard"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
+
+[[package]]
+name = "dispatch"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
+
+[[package]]
+name = "downcast-rs"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
+
+[[package]]
+name = "env_logger"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
+dependencies = [
+ "log",
+ "regex",
+]
+
+[[package]]
+name = "erased-serde"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3de9ad4541d99dc22b59134e7ff8dc3d6c988c89ecd7324bf10a8362b07a2afa"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "euclid"
+version = "0.19.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "596b99621b9477e7a5f94d2d8dd13a9c5c302ac358b822c67a42b6f1054450e1"
+dependencies = [
+ "euclid_macros",
+ "num-traits",
+]
+
+[[package]]
+name = "euclid"
+version = "0.22.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da96828553a086d7b18dcebfc579bd9628b016f86590d7453c115e490fa74b80"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "euclid_macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15"
+dependencies = [
+ "proc-macro2 0.4.30",
+ "quote 0.6.13",
+ "syn 0.15.44",
+]
+
+[[package]]
+name = "event-listener"
+version = "2.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59"
+
+[[package]]
+name = "fastrand"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b394ed3d285a429378d3b384b9eb1285267e7df4b166df24b7a6939a04dc392e"
+dependencies = [
+ "instant",
+]
+
+[[package]]
+name = "filetime"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98"
+dependencies = [
+ "cfg-if 1.0.0",
+ "libc",
+ "redox_syscall",
+ "winapi",
+]
+
+[[package]]
+name = "fixedbitset"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "398ea4fabe40b9b0d885340a2a991a44c8a645624075ad966d21f88688e2b69e"
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "fontdue"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8669141fd879e023ac6fcfe1d90dfe3f83ca7e322781ddf3f5be59147e4b8113"
+dependencies = [
+ "hashbrown",
+ "ttf-parser 0.12.3",
+]
+
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
+[[package]]
+name = "fsevent-sys"
+version = "4.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c0e564d24da983c053beff1bb7178e237501206840a3e6bf4e267b9e8ae734a"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d"
+
+[[package]]
+name = "futures-io"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377"
+
+[[package]]
+name = "futures-lite"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48"
+dependencies = [
+ "fastrand",
+ "futures-core",
+ "futures-io",
+ "memchr",
+ "parking",
+ "pin-project-lite",
+ "waker-fn",
+]
+
+[[package]]
+name = "fxhash"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
+dependencies = [
+ "cfg-if 1.0.0",
+ "js-sys",
+ "libc",
+ "wasi",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "gilrs"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e986f911d937f4395dfc2a39618dcef452773d32dcdbe0828c623f76588f749"
+dependencies = [
+ "fnv",
+ "gilrs-core",
+ "log",
+ "uuid",
+ "vec_map",
+]
+
+[[package]]
+name = "gilrs-core"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a5e5bb97bf9a0d9519a28cf38839cf1d6d9bb572b48e3c67202271fec2ed5e7"
+dependencies = [
+ "core-foundation 0.6.4",
+ "io-kit-sys",
+ "libc",
+ "libudev-sys",
+ "log",
+ "nix",
+ "rusty-xinput",
+ "stdweb 0.4.20",
+ "uuid",
+ "vec_map",
+ "winapi",
+]
+
+[[package]]
+name = "glam"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2c626156a479bfb5a4362c43f5abadd700af33ebc8db068089d9cb92493d6ab"
+dependencies = [
+ "bytemuck",
+ "mint",
+ "serde",
+]
+
+[[package]]
+name = "glob"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+
+[[package]]
+name = "glow"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f04649123493bc2483cbef4daddb45d40bbdae5adb221a63a23efdb0cc99520"
+dependencies = [
+ "js-sys",
+ "slotmap",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "gltf"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ff38b75359a0096dd0a8599b6e4f37a6ee41d5df300cc7669e62aafa697f7a2"
+dependencies = [
+ "byteorder",
+ "gltf-json",
+ "lazy_static",
+]
+
+[[package]]
+name = "gltf-derive"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f2a9333e0f9c7bca94dfc20bcf44fa12a61eeec662d6e007563ff748aa59c70"
+dependencies = [
+ "inflections",
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "gltf-json"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1414d3a98cbaabdb2f134328b1f6036d14b282febc1df51952a435d2ca17fb6"
+dependencies = [
+ "gltf-derive",
+ "serde",
+ "serde_derive",
+ "serde_json",
+]
+
+[[package]]
+name = "glyph_brush_layout"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc32c2334f00ca5ac3695c5009ae35da21da8c62d255b5b96d56e2597a637a38"
+dependencies = [
+ "ab_glyph",
+ "approx",
+ "xi-unicode",
+]
+
+[[package]]
+name = "gpu-alloc"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e64cbb8d36508d3e19da95e56e196a84f674fc190881f2cc010000798838aa6"
+dependencies = [
+ "bitflags",
+ "gpu-alloc-types",
+]
+
+[[package]]
+name = "gpu-alloc-types"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54804d0d6bc9d7f26db4eaec1ad10def69b599315f487d32c334a80d1efe67a5"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "gpu-descriptor"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a538f217be4d405ff4719a283ca68323cc2384003eca5baaa87501e821c81dda"
+dependencies = [
+ "bitflags",
+ "gpu-descriptor-types",
+ "hashbrown",
+]
+
+[[package]]
+name = "gpu-descriptor-types"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "363e3677e55ad168fef68cf9de3a4a310b53124c5e784c53a1d70e92d23f2126"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "guillotiere"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b62d5865c036cb1393e23c50693df631d3f5d7bcca4c04fe4cc0fd592e74a782"
+dependencies = [
+ "euclid 0.22.6",
+ "svg_fmt",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
+dependencies = [
+ "ahash",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "hexasphere"
+version = "6.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9dc62dcfd68ec810c4707804556f2e88655012b1a373b0e0bbbe88a9db366627"
+dependencies = [
+ "glam",
+ "lazy_static",
+]
+
+[[package]]
+name = "hexf-parse"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
+
+[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
+name = "image"
+version = "0.23.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1"
+dependencies = [
+ "bytemuck",
+ "byteorder",
+ "color_quant",
+ "num-iter",
+ "num-rational",
+ "num-traits",
+ "png",
+ "scoped_threadpool",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "inflections"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a257582fdcde896fd96463bf2d40eefea0580021c0712a0e2b028b60b47a837a"
+
+[[package]]
+name = "inotify"
+version = "0.9.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff"
+dependencies = [
+ "bitflags",
+ "inotify-sys",
+ "libc",
+]
+
+[[package]]
+name = "inotify-sys"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "inplace_it"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90953f308a79fe6d62a4643e51f848fbfddcd05975a38e69fdf4ab86a7baf7ca"
+
+[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if 1.0.0",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "io-kit-sys"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f21dcc74995dd4cd090b147e79789f8d65959cbfb5f0b118002db869ea3bd0a0"
+dependencies = [
+ "core-foundation-sys 0.6.2",
+ "mach 0.2.3",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
+
+[[package]]
+name = "jni"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec"
+dependencies = [
+ "cesu8",
+ "combine",
+ "jni-sys",
+ "log",
+ "thiserror",
+ "walkdir",
+]
+
+[[package]]
+name = "jni-sys"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
+
+[[package]]
+name = "jobserver"
+version = "0.1.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "js-sys"
+version = "0.3.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "kayak_components"
+version = "0.1.0"
+dependencies = [
+ "kayak_core",
+]
+
+[[package]]
+name = "kayak_core"
+version = "0.1.0"
+dependencies = [
+ "as-any",
+ "derivative",
+ "diff-struct",
+ "fontdue",
+ "kayak_render_macros",
+ "morphorm",
+ "resources",
+]
+
+[[package]]
+name = "kayak_font"
+version = "0.1.0"
+dependencies = [
+ "arrayvec 0.7.2",
+ "bitflags",
+ "fontdue",
+ "lyon_geom",
+ "lyon_path",
+ "png",
+ "ttf-parser 0.13.3",
+]
+
+[[package]]
+name = "kayak_render_macros"
+version = "0.1.0"
+dependencies = [
+ "kayak_core",
+ "pretty_assertions",
+ "proc-macro-error",
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "kayak_ui"
+version = "0.1.0"
+dependencies = [
+ "bevy",
+ "bevy_kayak_ui",
+ "kayak_components",
+ "kayak_core",
+]
+
+[[package]]
+name = "khronos-egl"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c2352bd1d0bceb871cb9d40f24360c8133c11d7486b68b5381c1dd1a32015e3"
+dependencies = [
+ "libc",
+ "libloading",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "lazycell"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
+
+[[package]]
+name = "libc"
+version = "0.2.108"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119"
+
+[[package]]
+name = "libloading"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "afe203d669ec979b7128619bae5a63b7b42e9203c1b29146079ee05e2f604b52"
+dependencies = [
+ "cfg-if 1.0.0",
+ "winapi",
+]
+
+[[package]]
+name = "libm"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
+
+[[package]]
+name = "libudev-sys"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324"
+dependencies = [
+ "libc",
+ "pkg-config",
+]
+
+[[package]]
+name = "lock_api"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
+dependencies = [
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "lyon_geom"
+version = "0.12.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bdb9bf1f1d43be9a9cc2343a7a096dc113cc25337a13e8f99721b01d1d548b60"
+dependencies = [
+ "arrayvec 0.4.12",
+ "euclid 0.19.9",
+ "num-traits",
+]
+
+[[package]]
+name = "lyon_path"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9dc8e0746b7cca11960b602f7fe037bb067746a01eab4aa502fed1494544843"
+dependencies = [
+ "lyon_geom",
+]
+
+[[package]]
+name = "mach"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "mach"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "malloc_buf"
+version = "0.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "matchers"
+version = "0.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1"
+dependencies = [
+ "regex-automata",
+]
+
+[[package]]
+name = "memchr"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
+
+[[package]]
+name = "memoffset"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "metal"
+version = "0.23.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0514f491f4cc03632ab399ee01e2c1c1b12d3e1cf2d667c1ff5f87d6dcd2084"
+dependencies = [
+ "bitflags",
+ "block",
+ "core-graphics-types",
+ "foreign-types",
+ "log",
+ "objc",
+]
+
+[[package]]
+name = "minimp3"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "985438f75febf74c392071a975a29641b420dd84431135a6e6db721de4b74372"
+dependencies = [
+ "minimp3-sys",
+ "slice-deque",
+ "thiserror",
+]
+
+[[package]]
+name = "minimp3-sys"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e21c73734c69dc95696c9ed8926a2b393171d98b3f5f5935686a26a487ab9b90"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "miniz_oxide"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
+dependencies = [
+ "adler32",
+]
+
+[[package]]
+name = "mint"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "162e591484b4b8fe9e1ca16ebf07ab584fdc3334508d76a788cd54d89cfc20dc"
+
+[[package]]
+name = "mio"
+version = "0.7.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
+dependencies = [
+ "libc",
+ "log",
+ "miow",
+ "ntapi",
+ "winapi",
+]
+
+[[package]]
+name = "mio-misc"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ddf05411bb159cdb5801bb10002afb66cb4572be656044315e363460ce69dc2"
+dependencies = [
+ "crossbeam",
+ "crossbeam-queue",
+ "log",
+ "mio",
+]
+
+[[package]]
+name = "miow"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "morphorm"
+version = "0.2.0"
+source = "git+https://github.com/geom3trik/morphorm#df4129d0e4fa390e92ede1a303aeeae71be5d3f4"
+dependencies = [
+ "bitflags",
+ "smallvec",
+]
+
+[[package]]
+name = "naga"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eda66d09f712e1f0a6ab436137da4fac312f78301f6d4ac7cb8bfe96e988734f"
+dependencies = [
+ "bit-set",
+ "bitflags",
+ "codespan-reporting",
+ "fxhash",
+ "hexf-parse",
+ "indexmap",
+ "log",
+ "num-traits",
+ "petgraph",
+ "pp-rs",
+ "spirv",
+ "thiserror",
+]
+
+[[package]]
+name = "ndk"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5eb167c1febed0a496639034d0c76b3b74263636045db5489eee52143c246e73"
+dependencies = [
+ "jni-sys",
+ "ndk-sys",
+ "num_enum 0.4.3",
+ "thiserror",
+]
+
+[[package]]
+name = "ndk"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8794322172319b972f528bf90c6b467be0079f1fa82780ffb431088e741a73ab"
+dependencies = [
+ "jni-sys",
+ "ndk-sys",
+ "num_enum 0.5.4",
+ "thiserror",
+]
+
+[[package]]
+name = "ndk"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d64d6af06fde0e527b1ba5c7b79a6cc89cfc46325b0b2887dffe8f70197e0c3c"
+dependencies = [
+ "bitflags",
+ "jni-sys",
+ "ndk-sys",
+ "num_enum 0.5.4",
+ "thiserror",
+]
+
+[[package]]
+name = "ndk-glue"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bdf399b8b7a39c6fb153c4ec32c72fd5fe789df24a647f229c239aa7adb15241"
+dependencies = [
+ "android_logger",
+ "lazy_static",
+ "libc",
+ "log",
+ "ndk 0.2.1",
+ "ndk-macro",
+ "ndk-sys",
+]
+
+[[package]]
+name = "ndk-glue"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5caf0c24d51ac1c905c27d4eda4fa0635bbe0de596b8f79235e0b17a4d29385"
+dependencies = [
+ "lazy_static",
+ "libc",
+ "log",
+ "ndk 0.3.0",
+ "ndk-macro",
+ "ndk-sys",
+]
+
+[[package]]
+name = "ndk-glue"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3e9e94628f24e7a3cb5b96a2dc5683acd9230bf11991c2a1677b87695138420"
+dependencies = [
+ "lazy_static",
+ "libc",
+ "log",
+ "ndk 0.4.0",
+ "ndk-macro",
+ "ndk-sys",
+]
+
+[[package]]
+name = "ndk-macro"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d"
+dependencies = [
+ "darling",
+ "proc-macro-crate 0.1.5",
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "ndk-sys"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121"
+
+[[package]]
+name = "nix"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa9b4819da1bc61c0ea48b63b7bc8604064dd43013e7cc325df098d49cd7c18a"
+dependencies = [
+ "bitflags",
+ "cc",
+ "cfg-if 1.0.0",
+ "libc",
+]
+
+[[package]]
+name = "nodrop"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
+
+[[package]]
+name = "nom"
+version = "5.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
+dependencies = [
+ "memchr",
+ "version_check",
+]
+
+[[package]]
+name = "notify"
+version = "5.0.0-pre.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51f18203a26893ca1d3526cf58084025d5639f91c44f8b70ab3b724f60e819a0"
+dependencies = [
+ "bitflags",
+ "crossbeam-channel",
+ "filetime",
+ "fsevent-sys",
+ "inotify",
+ "libc",
+ "mio",
+ "walkdir",
+ "winapi",
+]
+
+[[package]]
+name = "ntapi"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "num-derive"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d"
+dependencies = [
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-iter"
+version = "0.1.42"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-rational"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
+dependencies = [
+ "autocfg",
+]
+
+[[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 = "num_enum"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca565a7df06f3d4b485494f25ba05da1435950f4dc263440eda7a6fa9b8e36e4"
+dependencies = [
+ "derivative",
+ "num_enum_derive 0.4.3",
+]
+
+[[package]]
+name = "num_enum"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9bd055fb730c4f8f4f57d45d35cd6b3f0980535b056dc7ff119cee6a66ed6f"
+dependencies = [
+ "derivative",
+ "num_enum_derive 0.5.4",
+]
+
+[[package]]
+name = "num_enum_derive"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffa5a33ddddfee04c0283a7653987d634e880347e96b5b2ed64de07efb59db9d"
+dependencies = [
+ "proc-macro-crate 0.1.5",
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "num_enum_derive"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "486ea01961c4a818096de679a8b740b26d9033146ac5291b1c98557658f8cdd9"
+dependencies = [
+ "proc-macro-crate 1.1.0",
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "objc"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
+dependencies = [
+ "malloc_buf",
+ "objc_exception",
+]
+
+[[package]]
+name = "objc_exception"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "oboe"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e15e22bc67e047fe342a32ecba55f555e3be6166b04dd157cd0f803dfa9f48e1"
+dependencies = [
+ "jni",
+ "ndk 0.4.0",
+ "ndk-glue 0.4.0",
+ "num-derive",
+ "num-traits",
+ "oboe-sys",
+]
+
+[[package]]
+name = "oboe-sys"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "338142ae5ab0aaedc8275aa8f67f460e43ae0fca76a695a742d56da0a269eadc"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
+
+[[package]]
+name = "owned_ttf_parser"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65ee3f72636e6f164cc41c9f9057f4e58c4e13507699ea7f5e5242b64b8198ee"
+dependencies = [
+ "ttf-parser 0.13.3",
+]
+
+[[package]]
+name = "parking"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
+
+[[package]]
+name = "parking_lot"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
+dependencies = [
+ "instant",
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
+dependencies = [
+ "cfg-if 1.0.0",
+ "instant",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "winapi",
+]
+
+[[package]]
+name = "peeking_take_while"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
+
+[[package]]
+name = "percent-encoding"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
+
+[[package]]
+name = "petgraph"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a13a2fa9d0b63e5f22328828741e523766fff0ee9e779316902290dff3f824f"
+dependencies = [
+ "fixedbitset",
+ "indexmap",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f"
+
+[[package]]
+name = "png"
+version = "0.16.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6"
+dependencies = [
+ "bitflags",
+ "crc32fast",
+ "deflate",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "pp-rs"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb458bb7f6e250e6eb79d5026badc10a3ebb8f9a15d1fff0f13d17c71f4d6dee"
+dependencies = [
+ "unicode-xid 0.2.2",
+]
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
+
+[[package]]
+name = "pretty_assertions"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5dc44a7f8ba9e19aeb6f900eb518343170f2aae27d3c9c78e4d5c3db623638d"
+dependencies = [
+ "ansi_term 0.9.0",
+ "difference",
+]
+
+[[package]]
+name = "proc-macro-crate"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
+dependencies = [
+ "toml",
+]
+
+[[package]]
+name = "proc-macro-crate"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83"
+dependencies = [
+ "thiserror",
+ "toml",
+]
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "0.4.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
+dependencies = [
+ "unicode-xid 0.1.0",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
+dependencies = [
+ "unicode-xid 0.2.2",
+]
+
+[[package]]
+name = "profiling"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9926767b8b8244d7b6b64546585121d193c3d0b4856ccd656b7bfa9deb91ab6a"
+
+[[package]]
+name = "quote"
+version = "0.6.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
+dependencies = [
+ "proc-macro2 0.4.30",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
+dependencies = [
+ "proc-macro2 1.0.32",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+ "rand_hc",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
+dependencies = [
+ "rand_core",
+]
+
+[[package]]
+name = "range-alloc"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "63e935c45e09cc6dcf00d2f0b2d630a58f4095320223d47fc68918722f0538b6"
+
+[[package]]
+name = "raw-window-handle"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "rectangle-pack"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0d463f2884048e7153449a55166f91028d5b0ea53c79377099ce4e8cf0cf9bb"
+
+[[package]]
+name = "redox_syscall"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "regex"
+version = "1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+dependencies = [
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
+
+[[package]]
+name = "renderdoc-sys"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157"
+
+[[package]]
+name = "resources"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42070ea13709eb92d2977b48c7d3bd44866fa328e14248f8d1f00d6ea14d5066"
+dependencies = [
+ "downcast-rs",
+ "fxhash",
+ "parking_lot",
+]
+
+[[package]]
+name = "rodio"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4d98f5e557b61525057e2bc142c8cd7f0e70d75dc32852309bec440e6e046bf9"
+dependencies = [
+ "cpal",
+ "minimp3",
+]
+
+[[package]]
+name = "ron"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86018df177b1beef6c7c8ef949969c4f7cb9a9344181b92486b23c79995bdaa4"
+dependencies = [
+ "base64",
+ "bitflags",
+ "serde",
+]
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
+name = "rustc_version"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "rusty-xinput"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2aa654bc32eb9ca14cce1a084abc9dfe43949a4547c35269a094c39272db3bb"
+dependencies = [
+ "lazy_static",
+ "log",
+ "winapi",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "scoped_threadpool"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
+dependencies = [
+ "semver-parser",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
+
+[[package]]
+name = "serde"
+version = "1.0.130"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.130"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b"
+dependencies = [
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.71"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "063bf466a64011ac24040a49009724ee60a57da1b437617ceb32e53ad61bfb19"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "sha1"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d"
+
+[[package]]
+name = "shaderc"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58da8aaf4ad3508598cdf098567114c98d5f455de7d69b1213232ac557bc67ea"
+dependencies = [
+ "libc",
+ "shaderc-sys",
+]
+
+[[package]]
+name = "shaderc-sys"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8bd76ec0bd25f2017a65250373485e43cdc81b5cb8fd83c6115375c8d018cdf9"
+dependencies = [
+ "cmake",
+ "libc",
+]
+
+[[package]]
+name = "sharded-slab"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "shlex"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
+
+[[package]]
+name = "slab"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
+
+[[package]]
+name = "slice-deque"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31ef6ee280cdefba6d2d0b4b78a84a1c1a3f3a4cec98c2d4231c8bc225de0f25"
+dependencies = [
+ "libc",
+ "mach 0.3.2",
+ "winapi",
+]
+
+[[package]]
+name = "slotmap"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342"
+dependencies = [
+ "version_check",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "spirv"
+version = "0.2.0+1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830"
+dependencies = [
+ "bitflags",
+ "num-traits",
+]
+
+[[package]]
+name = "spirv-reflect"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cecc7af6a7d3ca6d15f4d6b5077df89c77ad1f4b314d0cabee221656d041dad7"
+dependencies = [
+ "bitflags",
+ "cc",
+ "num-traits",
+ "serde",
+ "serde_derive",
+ "spirv_headers",
+]
+
+[[package]]
+name = "spirv_headers"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f5b132530b1ac069df335577e3581765995cba5a13995cdbbdbc8fb057c532c"
+dependencies = [
+ "bitflags",
+ "num-traits",
+]
+
+[[package]]
+name = "stdweb"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef5430c8e36b713e13b48a9f709cc21e046723fe44ce34587b73a830203b533e"
+
+[[package]]
+name = "stdweb"
+version = "0.4.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
+dependencies = [
+ "discard",
+ "rustc_version",
+ "serde",
+ "serde_json",
+ "stdweb-derive",
+ "stdweb-internal-macros",
+ "stdweb-internal-runtime",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "stdweb-derive"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
+dependencies = [
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "serde",
+ "serde_derive",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "stdweb-internal-macros"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
+dependencies = [
+ "base-x",
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "sha1",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "stdweb-internal-runtime"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0"
+
+[[package]]
+name = "stretch"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b0dc6d20ce137f302edf90f9cd3d278866fd7fb139efca6f246161222ad6d87"
+dependencies = [
+ "lazy_static",
+ "libm",
+]
+
+[[package]]
+name = "strsim"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
+
+[[package]]
+name = "svg_fmt"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fb1df15f412ee2e9dfc1c504260fa695c1c3f10fe9f4a6ee2d2184d7d6450e2"
+
+[[package]]
+name = "syn"
+version = "0.15.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
+dependencies = [
+ "proc-macro2 0.4.30",
+ "quote 0.6.13",
+ "unicode-xid 0.1.0",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.81"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
+dependencies = [
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "unicode-xid 0.2.2",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
+dependencies = [
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "thread_local"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "toml"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
+dependencies = [
+ "indexmap",
+ "serde",
+]
+
+[[package]]
+name = "tracing"
+version = "0.1.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
+dependencies = [
+ "cfg-if 1.0.0",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e"
+dependencies = [
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "tracing-log"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3"
+dependencies = [
+ "lazy_static",
+ "log",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-serde"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b"
+dependencies = [
+ "serde",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-subscriber"
+version = "0.2.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdd0568dbfe3baf7048b7908d2b32bca0d81cd56bec6d2a8f894b01d74f86be3"
+dependencies = [
+ "ansi_term 0.12.1",
+ "chrono",
+ "lazy_static",
+ "matchers",
+ "regex",
+ "serde",
+ "serde_json",
+ "sharded-slab",
+ "smallvec",
+ "thread_local",
+ "tracing",
+ "tracing-core",
+ "tracing-log",
+ "tracing-serde",
+]
+
+[[package]]
+name = "tracing-wasm"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ae741706df70547fca8715f74a8569677666e7be3454313af70f6e158034485"
+dependencies = [
+ "tracing",
+ "tracing-subscriber",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "ttf-parser"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ae2f58a822f08abdaf668897e96a5656fe72f5a9ce66422423e8849384872e6"
+
+[[package]]
+name = "ttf-parser"
+version = "0.13.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47094e61a758dfddc5bc6de0862c2640ee2643997835e58332a4863bcd5852e9"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
+
+[[package]]
+name = "unicode-xid"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
+
+[[package]]
+name = "uuid"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
+dependencies = [
+ "getrandom",
+ "serde",
+]
+
+[[package]]
+name = "vec_map"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
+
+[[package]]
+name = "version_check"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
+
+[[package]]
+name = "waker-fn"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
+
+[[package]]
+name = "walkdir"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+dependencies = [
+ "same-file",
+ "winapi",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasi"
+version = "0.10.2+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
+dependencies = [
+ "cfg-if 1.0.0",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
+dependencies = [
+ "bumpalo",
+ "lazy_static",
+ "log",
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39"
+dependencies = [
+ "cfg-if 1.0.0",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
+dependencies = [
+ "quote 1.0.10",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
+dependencies = [
+ "proc-macro2 1.0.32",
+ "quote 1.0.10",
+ "syn 1.0.81",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
+
+[[package]]
+name = "web-sys"
+version = "0.3.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "wgpu"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1577ecc4f6992b9e965878ac594efb24eed2bdf089c11f45b3d1c5f216e2e30"
+dependencies = [
+ "arrayvec 0.7.2",
+ "js-sys",
+ "log",
+ "naga",
+ "parking_lot",
+ "raw-window-handle",
+ "smallvec",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "wgpu-core",
+ "wgpu-hal",
+ "wgpu-types",
+]
+
+[[package]]
+name = "wgpu-core"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3bdcbfa4885b32c2b1feb2faeb8b6a76065b752b8f08751b82f994e937687f46"
+dependencies = [
+ "arrayvec 0.7.2",
+ "bitflags",
+ "cfg_aliases",
+ "copyless",
+ "fxhash",
+ "log",
+ "naga",
+ "parking_lot",
+ "profiling",
+ "raw-window-handle",
+ "smallvec",
+ "thiserror",
+ "wgpu-hal",
+ "wgpu-types",
+]
+
+[[package]]
+name = "wgpu-hal"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0e493835d9edb153d5c8a9d8d016e1811dbe32ddb707a110be1453c7b051d3ec"
+dependencies = [
+ "arrayvec 0.7.2",
+ "ash",
+ "bit-set",
+ "bitflags",
+ "block",
+ "core-graphics-types",
+ "d3d12",
+ "foreign-types",
+ "fxhash",
+ "glow",
+ "gpu-alloc",
+ "gpu-descriptor",
+ "inplace_it",
+ "js-sys",
+ "khronos-egl",
+ "libloading",
+ "log",
+ "metal",
+ "naga",
+ "objc",
+ "parking_lot",
+ "profiling",
+ "range-alloc",
+ "raw-window-handle",
+ "renderdoc-sys",
+ "thiserror",
+ "wasm-bindgen",
+ "web-sys",
+ "wgpu-types",
+ "winapi",
+]
+
+[[package]]
+name = "wgpu-types"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e15e44ba88ec415466e18e91881319e7c9e96cb905dc623305168aea65b85ccc"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "winit"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "79610794594d5e86be473ef7763f604f2159cbac8c94debd00df8fb41e86c2f8"
+dependencies = [
+ "bitflags",
+ "cocoa",
+ "core-foundation 0.9.2",
+ "core-graphics 0.22.3",
+ "core-video-sys",
+ "dispatch",
+ "instant",
+ "lazy_static",
+ "libc",
+ "log",
+ "mio",
+ "mio-misc",
+ "ndk 0.3.0",
+ "ndk-glue 0.3.0",
+ "ndk-sys",
+ "objc",
+ "parking_lot",
+ "percent-encoding",
+ "raw-window-handle",
+ "scopeguard",
+ "wasm-bindgen",
+ "web-sys",
+ "winapi",
+ "x11-dl",
+]
+
+[[package]]
+name = "x11-dl"
+version = "2.19.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59"
+dependencies = [
+ "lazy_static",
+ "libc",
+ "pkg-config",
+]
+
+[[package]]
+name = "xi-unicode"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a"
diff --git a/bevy_kayak_ui/Cargo.toml b/bevy_kayak_ui/Cargo.toml
new file mode 100644
index 0000000..1ffcf7e
--- /dev/null
+++ b/bevy_kayak_ui/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+name = "bevy_kayak_ui"
+version = "0.0.1"
+edition = "2021"
+
+[dependencies]
+bytemuck = "1.7.2"
+bevy = { git = "https://github.com/StarArawn/bevy", rev = "b26f563b13c267ffe1ee801bd71fd40b98a256e7" }
+kayak_core = { path = "../kayak_core" }
+kayak_components = { path = "../kayak_components" }
+kayak_render_macros = { path = "../kayak_render_macros" }
+kayak_font = { path = "../kayak_font" }
+crevice = { git = "https://github.com/StarArawn/bevy", rev = "b26f563b13c267ffe1ee801bd71fd40b98a256e7" }
diff --git a/bevy_kayak_ui/src/bevy_context.rs b/bevy_kayak_ui/src/bevy_context.rs
new file mode 100644
index 0000000..9322b73
--- /dev/null
+++ b/bevy_kayak_ui/src/bevy_context.rs
@@ -0,0 +1,32 @@
+use std::sync::{Arc, RwLock};
+
+use kayak_core::{
+    context::KayakContext,
+    styles::{Style, StyleProp, Units},
+};
+
+pub struct BevyContext {
+    pub kayak_context: Arc<RwLock<KayakContext>>,
+}
+
+impl BevyContext {
+    pub fn new<F: Fn(&mut Style, &mut KayakContext)>(width: f32, height: f32, f: F) -> Self {
+        let mut app_styles = Style {
+            width: StyleProp::Value(Units::Pixels(width)),
+            height: StyleProp::Value(Units::Pixels(height)),
+            ..Style::default()
+        };
+
+        let kayak_context = Arc::new(RwLock::new(KayakContext::new()));
+
+        if let Ok(mut kayak_context) = kayak_context.write() {
+            f(&mut app_styles, &mut kayak_context);
+
+            kayak_context.render();
+
+            kayak_context.widget_manager.dirty(true);
+        }
+
+        Self { kayak_context }
+    }
+}
diff --git a/bevy_kayak_ui/src/camera/camera.rs b/bevy_kayak_ui/src/camera/camera.rs
new file mode 100644
index 0000000..f0ed588
--- /dev/null
+++ b/bevy_kayak_ui/src/camera/camera.rs
@@ -0,0 +1,58 @@
+use bevy::{
+    prelude::{Bundle, GlobalTransform, Transform},
+    render2::{
+        camera::{Camera, CameraPlugin, CameraProjection, DepthCalculation, WindowOrigin},
+        primitives::Frustum,
+        view::VisibleEntities,
+    },
+};
+
+use super::ortho::UIOrthographicProjection;
+
+#[derive(Bundle)]
+pub struct UICameraBundle {
+    pub camera: Camera,
+    pub orthographic_projection: UIOrthographicProjection,
+    pub visible_entities: VisibleEntities,
+    pub frustum: Frustum,
+    pub transform: Transform,
+    pub global_transform: GlobalTransform,
+}
+
+impl UICameraBundle {
+    pub const UI_CAMERA: &'static str = "KAYAK_UI_CAMERA";
+    pub fn new() -> Self {
+        // we want 0 to be "closest" and +far to be "farthest" in 2d, so we offset
+        // the camera's translation by far and use a right handed coordinate system
+        let far = 1000.0;
+
+        let orthographic_projection = UIOrthographicProjection {
+            far,
+            depth_calculation: DepthCalculation::ZDifference,
+            window_origin: WindowOrigin::BottomLeft,
+            ..Default::default()
+        };
+
+        let transform = Transform::from_xyz(0.0, 0.0, far - 0.1);
+
+        let view_projection =
+            orthographic_projection.get_projection_matrix() * transform.compute_matrix().inverse();
+        let frustum = Frustum::from_view_projection(
+            &view_projection,
+            &transform.translation,
+            &transform.back(),
+            orthographic_projection.far(),
+        );
+        UICameraBundle {
+            camera: Camera {
+                name: Some(Self::UI_CAMERA.to_string()),
+                ..Default::default()
+            },
+            orthographic_projection,
+            frustum,
+            visible_entities: VisibleEntities::default(),
+            transform,
+            global_transform: Default::default(),
+        }
+    }
+}
diff --git a/bevy_kayak_ui/src/camera/mod.rs b/bevy_kayak_ui/src/camera/mod.rs
new file mode 100644
index 0000000..2d0c1db
--- /dev/null
+++ b/bevy_kayak_ui/src/camera/mod.rs
@@ -0,0 +1,23 @@
+use bevy::{
+    prelude::{CoreStage, Plugin},
+    render2::camera::ActiveCameras,
+};
+
+mod camera;
+mod ortho;
+
+pub use camera::UICameraBundle;
+pub(crate) use ortho::UIOrthographicProjection;
+
+pub struct KayakUICameraPlugin;
+
+impl Plugin for KayakUICameraPlugin {
+    fn build(&self, app: &mut bevy::prelude::App) {
+        let mut active_cameras = app.world.get_resource_mut::<ActiveCameras>().unwrap();
+        active_cameras.add(UICameraBundle::UI_CAMERA);
+        app.add_system_to_stage(
+            CoreStage::PostUpdate,
+            bevy::render2::camera::camera_system::<UIOrthographicProjection>,
+        );
+    }
+}
diff --git a/bevy_kayak_ui/src/camera/ortho.rs b/bevy_kayak_ui/src/camera/ortho.rs
new file mode 100644
index 0000000..e4e6621
--- /dev/null
+++ b/bevy_kayak_ui/src/camera/ortho.rs
@@ -0,0 +1,73 @@
+use bevy::ecs::reflect::ReflectComponent;
+use bevy::{
+    math::Mat4,
+    reflect::Reflect,
+    render2::camera::{CameraProjection, DepthCalculation, ScalingMode, WindowOrigin},
+};
+
+#[derive(Debug, Clone, Reflect)]
+#[reflect(Component)]
+pub struct UIOrthographicProjection {
+    pub left: f32,
+    pub right: f32,
+    pub bottom: f32,
+    pub top: f32,
+    pub near: f32,
+    pub far: f32,
+    pub window_origin: WindowOrigin,
+    pub scaling_mode: ScalingMode,
+    pub scale: f32,
+    pub depth_calculation: DepthCalculation,
+}
+
+impl CameraProjection for UIOrthographicProjection {
+    fn get_projection_matrix(&self) -> Mat4 {
+        Mat4::orthographic_rh(
+            self.left * self.scale,
+            self.right * self.scale,
+            self.bottom * self.scale,
+            self.top * self.scale,
+            // NOTE: near and far are swapped to invert the depth range from [0,1] to [1,0]
+            // This is for interoperability with pipelines using infinite reverse perspective projections.
+            self.far,
+            self.near,
+        )
+    }
+
+    fn update(&mut self, width: f32, height: f32) {
+        match (&self.scaling_mode, &self.window_origin) {
+            (ScalingMode::WindowSize, WindowOrigin::BottomLeft) => {
+                self.left = 0.0;
+                self.right = width;
+                self.top = 0.0;
+                self.bottom = height;
+            }
+            _ => {}
+        }
+    }
+
+    fn depth_calculation(&self) -> DepthCalculation {
+        self.depth_calculation
+    }
+
+    fn far(&self) -> f32 {
+        self.far
+    }
+}
+
+impl Default for UIOrthographicProjection {
+    fn default() -> Self {
+        UIOrthographicProjection {
+            left: -1.0,
+            right: 1.0,
+            bottom: -1.0,
+            top: 1.0,
+            near: 0.0,
+            far: 1000.0,
+            window_origin: WindowOrigin::Center,
+            scaling_mode: ScalingMode::WindowSize,
+            scale: 1.0,
+            depth_calculation: DepthCalculation::Distance,
+        }
+    }
+}
diff --git a/bevy_kayak_ui/src/lib.rs b/bevy_kayak_ui/src/lib.rs
new file mode 100644
index 0000000..c5f8e11
--- /dev/null
+++ b/bevy_kayak_ui/src/lib.rs
@@ -0,0 +1,29 @@
+use bevy::{prelude::{Plugin, ResMut}, render2::color::Color};
+
+mod bevy_context;
+mod camera;
+mod render;
+
+pub use bevy_context::BevyContext;
+pub use camera::*;
+
+#[derive(Default)]
+pub struct BevyKayakUIPlugin;
+
+impl Plugin for BevyKayakUIPlugin {
+    fn build(&self, app: &mut bevy::prelude::App) {
+        app.add_plugin(render::BevyKayakUIRenderPlugin)
+            .add_plugin(camera::KayakUICameraPlugin)
+            .add_system(update);
+    }
+}
+
+pub(crate) fn to_bevy_color(color: &kayak_core::color::Color) -> Color {
+    Color::rgba(color.r, color.g, color.b, color.a)
+}
+
+pub fn update(bevy_context: ResMut<BevyContext>) {
+    if let Ok(mut context) = bevy_context.kayak_context.write() {
+        context.render();
+    }
+}
diff --git a/bevy_kayak_ui/src/render/mod.rs b/bevy_kayak_ui/src/render/mod.rs
new file mode 100644
index 0000000..051005c
--- /dev/null
+++ b/bevy_kayak_ui/src/render/mod.rs
@@ -0,0 +1,95 @@
+use bevy::{
+    prelude::{Commands, Entity, Plugin, Query, Res, ResMut, With},
+    render2::{
+        camera::ActiveCameras,
+        render_graph::{EmptyNode, RenderGraph, SlotInfo, SlotType},
+        render_phase::{sort_phase_system, DrawFunctions, RenderPhase},
+        render_resource::{
+            Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
+        },
+        renderer::RenderDevice,
+        texture::TextureCache,
+        view::{ExtractedView, ViewDepthTexture},
+        RenderApp, RenderStage,
+    },
+};
+
+use crate::{
+    render::{
+        ui_pass::MainPassUINode, ui_pass_driver::UIPassDriverNode, unified::UnifiedRenderPlugin,
+    },
+    UICameraBundle,
+};
+
+use self::ui_pass::TransparentUI;
+
+mod ui_pass;
+mod ui_pass_driver;
+mod unified;
+
+pub mod node {
+    pub const UI_PASS_DEPENDENCIES: &str = "ui_pass_dependencies";
+    pub const UI_PASS_DRIVER: &str = "ui_pass_driver";
+}
+
+pub mod draw_ui_graph {
+    pub const NAME: &str = "draw_ui";
+    pub mod input {
+        pub const VIEW_ENTITY: &str = "view_entity";
+    }
+    pub mod node {
+        pub const MAIN_PASS: &str = "ui_pass";
+    }
+}
+
+pub struct BevyKayakUIRenderPlugin;
+
+impl Plugin for BevyKayakUIRenderPlugin {
+    fn build(&self, app: &mut bevy::prelude::App) {
+        let render_app = app.sub_app(RenderApp);
+        render_app
+            .init_resource::<DrawFunctions<TransparentUI>>()
+            .add_system_to_stage(RenderStage::Extract, extract_core_pipeline_camera_phases)
+            .add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<TransparentUI>);
+
+        let pass_node_ui = MainPassUINode::new(&mut render_app.world);
+        let mut graph = render_app.world.get_resource_mut::<RenderGraph>().unwrap();
+
+        let mut draw_ui_graph = RenderGraph::default();
+        draw_ui_graph.add_node(draw_ui_graph::node::MAIN_PASS, pass_node_ui);
+        let input_node_id = draw_ui_graph.set_input(vec![SlotInfo::new(
+            draw_ui_graph::input::VIEW_ENTITY,
+            SlotType::Entity,
+        )]);
+        draw_ui_graph
+            .add_slot_edge(
+                input_node_id,
+                draw_ui_graph::input::VIEW_ENTITY,
+                draw_ui_graph::node::MAIN_PASS,
+                MainPassUINode::IN_VIEW,
+            )
+            .unwrap();
+        graph.add_sub_graph(draw_ui_graph::NAME, draw_ui_graph);
+
+        graph.add_node(node::UI_PASS_DEPENDENCIES, EmptyNode);
+        graph.add_node(node::UI_PASS_DRIVER, UIPassDriverNode);
+        graph
+            .add_node_edge(node::UI_PASS_DEPENDENCIES, node::UI_PASS_DRIVER)
+            .unwrap();
+
+        app.add_plugin(UnifiedRenderPlugin);
+    }
+}
+
+pub fn extract_core_pipeline_camera_phases(
+    mut commands: Commands,
+    active_cameras: Res<ActiveCameras>,
+) {
+    if let Some(camera_2d) = active_cameras.get(UICameraBundle::UI_CAMERA) {
+        if let Some(entity) = camera_2d.entity {
+            commands
+                .get_or_spawn(entity)
+                .insert(RenderPhase::<TransparentUI>::default());
+        }
+    }
+}
diff --git a/bevy_kayak_ui/src/render/quad/mod.rs b/bevy_kayak_ui/src/render/quad/mod.rs
new file mode 100644
index 0000000..222f983
--- /dev/null
+++ b/bevy_kayak_ui/src/render/quad/mod.rs
@@ -0,0 +1,43 @@
+use bevy::{
+    prelude::{Assets, HandleUntyped, Plugin},
+    reflect::TypeUuid,
+    render2::{render_phase::DrawFunctions, render_resource::Shader, RenderApp, RenderStage},
+};
+
+use crate::render::{
+    quad::pipeline::{DrawQuad, QuadMeta, QuadPipeline},
+    ui_pass::TransparentUI,
+};
+
+mod pipeline;
+
+pub const QUAD_SHADER_HANDLE: HandleUntyped =
+    HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 7604018236855288450);
+
+#[derive(Default)]
+pub struct QuadRendererPlugin;
+
+impl Plugin for QuadRendererPlugin {
+    fn build(&self, app: &mut bevy::prelude::App) {
+        let mut shaders = app.world.get_resource_mut::<Assets<Shader>>().unwrap();
+        let quad_shader = Shader::from_wgsl(include_str!("shader.wgsl"));
+        shaders.set_untracked(QUAD_SHADER_HANDLE, quad_shader);
+
+        let render_app = app.sub_app(RenderApp);
+        render_app
+            .init_resource::<QuadPipeline>()
+            .init_resource::<QuadMeta>()
+            .add_system_to_stage(RenderStage::Extract, pipeline::extract_quads)
+            .add_system_to_stage(RenderStage::Prepare, pipeline::prepare_quads)
+            .add_system_to_stage(RenderStage::Queue, pipeline::queue_quads);
+
+        let draw_quad = DrawQuad::new(&mut render_app.world);
+
+        render_app
+            .world
+            .get_resource::<DrawFunctions<TransparentUI>>()
+            .unwrap()
+            .write()
+            .add(draw_quad);
+    }
+}
diff --git a/bevy_kayak_ui/src/render/quad/pipeline.rs b/bevy_kayak_ui/src/render/quad/pipeline.rs
new file mode 100644
index 0000000..8c5d857
--- /dev/null
+++ b/bevy_kayak_ui/src/render/quad/pipeline.rs
@@ -0,0 +1,344 @@
+use bevy::{
+    core::FloatOrd,
+    ecs::system::{
+        lifetimeless::{Read, SQuery, SRes},
+        SystemState,
+    },
+    math::{const_vec3, Mat4, Quat, Vec2, Vec3},
+    prelude::{Bundle, Color, Commands, Entity, FromWorld, Query, Res, ResMut, World},
+    render2::{
+        render_phase::{Draw, DrawFunctions, RenderPhase, TrackedRenderPass},
+        render_resource::{
+            BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout,
+            BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType, BlendComponent,
+            BlendFactor, BlendOperation, BlendState, BufferBindingType, BufferSize, BufferUsages,
+            BufferVec, CachedPipelineId, ColorTargetState, ColorWrites, CompareFunction,
+            DepthBiasState, DepthStencilState, FragmentState, FrontFace, MultisampleState,
+            PolygonMode, PrimitiveState, PrimitiveTopology, RenderPipelineCache,
+            RenderPipelineDescriptor, Shader, ShaderStages, StencilFaceState, StencilState,
+            TextureFormat, VertexAttribute, VertexBufferLayout, VertexFormat, VertexState,
+            VertexStepMode,
+        },
+        renderer::{RenderDevice, RenderQueue},
+        texture::BevyDefault,
+        view::{ViewUniformOffset, ViewUniforms},
+    },
+    sprite2::Rect,
+};
+use bytemuck::{Pod, Zeroable};
+use kayak_core::render_primitive::RenderPrimitive;
+
+use crate::{
+    render::{quad::QUAD_SHADER_HANDLE, ui_pass::TransparentUI},
+    to_bevy_color, BevyContext,
+};
+
+pub struct QuadPipeline {
+    view_layout: BindGroupLayout,
+    pipeline: CachedPipelineId,
+}
+
+const QUAD_VERTEX_POSITIONS: &[Vec3] = &[
+    const_vec3!([0.0, 0.0, 0.0]),
+    const_vec3!([1.0, 1.0, 0.0]),
+    const_vec3!([0.0, 1.0, 0.0]),
+    const_vec3!([0.0, 0.0, 0.0]),
+    const_vec3!([1.0, 0.0, 0.0]),
+    const_vec3!([1.0, 1.0, 0.0]),
+];
+
+impl FromWorld for QuadPipeline {
+    fn from_world(world: &mut World) -> Self {
+        let world = world.cell();
+        let render_device = world.get_resource::<RenderDevice>().unwrap();
+        let mut pipeline_cache = world.get_resource_mut::<RenderPipelineCache>().unwrap();
+
+        let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
+            entries: &[BindGroupLayoutEntry {
+                binding: 0,
+                visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
+                ty: BindingType::Buffer {
+                    ty: BufferBindingType::Uniform,
+                    has_dynamic_offset: true,
+                    // TODO: change this to ViewUniform::std140_size_static once crevice fixes this!
+                    // Context: https://github.com/LPGhatguy/crevice/issues/29
+                    min_binding_size: BufferSize::new(144),
+                },
+                count: None,
+            }],
+            label: Some("quad_view_layout"),
+        });
+
+        let vertex_buffer_layout = VertexBufferLayout {
+            array_stride: 28,
+            step_mode: VertexStepMode::Vertex,
+            attributes: vec![
+                VertexAttribute {
+                    format: VertexFormat::Float32x3,
+                    offset: 0,
+                    shader_location: 0,
+                },
+                VertexAttribute {
+                    format: VertexFormat::Float32x4,
+                    offset: 12,
+                    shader_location: 1,
+                },
+            ],
+        };
+
+        let pipeline_desc = RenderPipelineDescriptor {
+            vertex: VertexState {
+                shader: QUAD_SHADER_HANDLE.typed::<Shader>(),
+                entry_point: "vertex".into(),
+                shader_defs: vec![],
+                buffers: vec![vertex_buffer_layout],
+            },
+            fragment: Some(FragmentState {
+                shader: QUAD_SHADER_HANDLE.typed::<Shader>(),
+                shader_defs: vec![],
+                entry_point: "fragment".into(),
+                targets: vec![ColorTargetState {
+                    format: TextureFormat::bevy_default(),
+                    blend: Some(BlendState {
+                        color: BlendComponent {
+                            src_factor: BlendFactor::SrcAlpha,
+                            dst_factor: BlendFactor::OneMinusSrcAlpha,
+                            operation: BlendOperation::Add,
+                        },
+                        alpha: BlendComponent {
+                            src_factor: BlendFactor::One,
+                            dst_factor: BlendFactor::One,
+                            operation: BlendOperation::Add,
+                        },
+                    }),
+                    write_mask: ColorWrites::ALL,
+                }],
+            }),
+            layout: Some(vec![view_layout.clone()]),
+            primitive: PrimitiveState {
+                front_face: FrontFace::Ccw,
+                cull_mode: None,
+                polygon_mode: PolygonMode::Fill,
+                clamp_depth: false,
+                conservative: false,
+                topology: PrimitiveTopology::TriangleList,
+                strip_index_format: None,
+            },
+            depth_stencil: Some(DepthStencilState {
+                format: TextureFormat::Depth32Float,
+                depth_write_enabled: true,
+                depth_compare: CompareFunction::Greater,
+                stencil: StencilState {
+                    front: StencilFaceState::IGNORE,
+                    back: StencilFaceState::IGNORE,
+                    read_mask: 0,
+                    write_mask: 0,
+                },
+                bias: DepthBiasState {
+                    constant: 0,
+                    slope_scale: 0.0,
+                    clamp: 0.0,
+                },
+            }),
+            multisample: MultisampleState {
+                count: 1,
+                mask: !0,
+                alpha_to_coverage_enabled: false,
+            },
+            label: Some("quad_pipeline".into()),
+        };
+
+        QuadPipeline {
+            pipeline: pipeline_cache.queue(pipeline_desc),
+            view_layout,
+        }
+    }
+}
+
+#[derive(Bundle)]
+pub struct ExtractQuadBundle {
+    extracted_quad: ExtractedQuad,
+}
+
+pub struct ExtractedQuad {
+    rect: Rect,
+    background_color: Color,
+    vertex_index: usize,
+}
+
+pub fn extract_quads(mut commands: Commands, context: Res<BevyContext>) {
+    let render_commands = if let Ok(context) = context.kayak_context.read() {
+        context.widget_manager.build_render_primitives()
+    } else {
+        vec![]
+    };
+
+    let quad_commands: Vec<&RenderPrimitive> = render_commands
+        .iter()
+        .filter(|command| matches!(command, RenderPrimitive::Quad { .. }))
+        .collect::<Vec<_>>();
+
+    let mut extracted_quads = Vec::new();
+    for render_primitive in quad_commands {
+        let (background_color, layout) = match render_primitive {
+            RenderPrimitive::Quad {
+                background_color,
+                layout,
+            } => (background_color, layout),
+            _ => panic!(""),
+        };
+
+        extracted_quads.push(ExtractQuadBundle {
+            extracted_quad: ExtractedQuad {
+                rect: Rect {
+                    min: Vec2::new(layout.posx, layout.posy),
+                    max: Vec2::new(layout.width, layout.height),
+                },
+                background_color: to_bevy_color(background_color),
+                vertex_index: 0,
+            },
+        });
+    }
+    commands.spawn_batch(extracted_quads);
+}
+
+#[repr(C)]
+#[derive(Copy, Clone, Pod, Zeroable)]
+struct QuadVertex {
+    pub position: [f32; 3],
+    pub color: [f32; 4],
+}
+
+pub struct QuadMeta {
+    vertices: BufferVec<QuadVertex>,
+    view_bind_group: Option<BindGroup>,
+}
+
+impl Default for QuadMeta {
+    fn default() -> Self {
+        Self {
+            vertices: BufferVec::new(BufferUsages::VERTEX),
+            view_bind_group: None,
+        }
+    }
+}
+
+pub fn prepare_quads(
+    render_device: Res<RenderDevice>,
+    render_queue: Res<RenderQueue>,
+    mut sprite_meta: ResMut<QuadMeta>,
+    mut extracted_sprites: Query<&mut ExtractedQuad>,
+) {
+    let extracted_sprite_len = extracted_sprites.iter_mut().len();
+    // dont create buffers when there are no quads
+    if extracted_sprite_len == 0 {
+        return;
+    }
+
+    sprite_meta.vertices.clear();
+    sprite_meta.vertices.reserve(
+        extracted_sprite_len * QUAD_VERTEX_POSITIONS.len(),
+        &render_device,
+    );
+
+    for (i, mut extracted_sprite) in extracted_sprites.iter_mut().enumerate() {
+        let sprite_rect = extracted_sprite.rect;
+        let color = extracted_sprite.background_color.as_linear_rgba_f32();
+
+        extracted_sprite.vertex_index = i;
+        for vertex_position in QUAD_VERTEX_POSITIONS.iter() {
+            let world = Mat4::from_scale_rotation_translation(
+                sprite_rect.size().extend(1.0),
+                Quat::default(),
+                sprite_rect.min.extend(0.0),
+            );
+            let final_position = (world * Vec3::from(*vertex_position).extend(1.0)).truncate();
+            sprite_meta.vertices.push(QuadVertex {
+                position: final_position.into(),
+                color,
+            });
+        }
+    }
+    sprite_meta
+        .vertices
+        .write_buffer(&render_device, &render_queue);
+}
+
+pub fn queue_quads(
+    draw_functions: Res<DrawFunctions<TransparentUI>>,
+    render_device: Res<RenderDevice>,
+    mut sprite_meta: ResMut<QuadMeta>,
+    view_uniforms: Res<ViewUniforms>,
+    quad_pipeline: Res<QuadPipeline>,
+    mut extracted_sprites: Query<(Entity, &ExtractedQuad)>,
+    mut views: Query<&mut RenderPhase<TransparentUI>>,
+) {
+    if let Some(view_binding) = view_uniforms.uniforms.binding() {
+        sprite_meta.view_bind_group = Some(render_device.create_bind_group(&BindGroupDescriptor {
+            entries: &[BindGroupEntry {
+                binding: 0,
+                resource: view_binding,
+            }],
+            label: Some("quad_view_bind_group"),
+            layout: &quad_pipeline.view_layout,
+        }));
+        let draw_quad = draw_functions.read().get_id::<DrawQuad>().unwrap();
+        for mut transparent_phase in views.iter_mut() {
+            for (entity, quad) in extracted_sprites.iter_mut() {
+                transparent_phase.add(TransparentUI {
+                    draw_function: draw_quad,
+                    pipeline: quad_pipeline.pipeline,
+                    entity,
+                    sort_key: FloatOrd(0.0),
+                });
+            }
+        }
+    }
+}
+
+pub struct DrawQuad {
+    params: SystemState<(
+        SRes<QuadMeta>,
+        SRes<RenderPipelineCache>,
+        SQuery<Read<ViewUniformOffset>>,
+        SQuery<Read<ExtractedQuad>>,
+    )>,
+}
+
+impl DrawQuad {
+    pub fn new(world: &mut World) -> Self {
+        Self {
+            params: SystemState::new(world),
+        }
+    }
+}
+
+impl Draw<TransparentUI> for DrawQuad {
+    fn draw<'w>(
+        &mut self,
+        world: &'w World,
+        pass: &mut TrackedRenderPass<'w>,
+        view: Entity,
+        item: &TransparentUI,
+    ) {
+        let (quad_meta, pipelines, views, quads) = self.params.get(world);
+        let view_uniform = views.get(view).unwrap();
+        let quad_meta = quad_meta.into_inner();
+        let extracted_quad = quads.get(item.entity).unwrap();
+        if let Some(pipeline) = pipelines.into_inner().get(item.pipeline) {
+            pass.set_render_pipeline(pipeline);
+            pass.set_vertex_buffer(0, quad_meta.vertices.buffer().unwrap().slice(..));
+            pass.set_bind_group(
+                0,
+                quad_meta.view_bind_group.as_ref().unwrap(),
+                &[view_uniform.offset],
+            );
+
+            pass.draw(
+                (extracted_quad.vertex_index * QUAD_VERTEX_POSITIONS.len()) as u32
+                    ..((extracted_quad.vertex_index + 1) * QUAD_VERTEX_POSITIONS.len()) as u32,
+                0..1,
+            );
+        }
+    }
+}
diff --git a/bevy_kayak_ui/src/render/quad/shader.wgsl b/bevy_kayak_ui/src/render/quad/shader.wgsl
new file mode 100644
index 0000000..df4e649
--- /dev/null
+++ b/bevy_kayak_ui/src/render/quad/shader.wgsl
@@ -0,0 +1,30 @@
+[[block]]
+struct View {
+    view_proj: mat4x4<f32>;
+    world_position: vec3<f32>;
+};
+[[group(0), binding(0)]]
+var<uniform> view: View;
+
+struct VertexOutput {
+    [[builtin(position)]] position: vec4<f32>;
+    [[location(0)]] color: vec4<f32>;
+    [[location(1)]] uv: vec3<f32>;
+};
+
+[[stage(vertex)]]
+fn vertex(
+    [[location(0)]] vertex_position: vec3<f32>,
+    [[location(1)]] vertex_color: vec4<f32>,
+    [[location(2)]] vertex_uv: vec3<f32>;
+) -> VertexOutput {
+    var out: VertexOutput;
+    out.color = vertex_color;
+    out.position = view.view_proj * vec4<f32>(vertex_position, 1.0);
+    return out;
+}
+
+[[stage(fragment)]]
+fn fragment(in: VertexOutput) -> [[location(0)]] vec4<f32> {
+    return in.color;
+}
\ No newline at end of file
diff --git a/bevy_kayak_ui/src/render/text/font.rs b/bevy_kayak_ui/src/render/text/font.rs
new file mode 100644
index 0000000..7a4424c
--- /dev/null
+++ b/bevy_kayak_ui/src/render/text/font.rs
@@ -0,0 +1,8 @@
+use bevy::reflect::TypeUuid;
+use kayak_font::Font;
+
+#[derive(Debug, Clone, TypeUuid)]
+#[uuid = "4fe4732c-6731-49bb-bafc-4690d636b848"]
+pub struct KayakFont {
+    pub font: Font,
+}
diff --git a/bevy_kayak_ui/src/render/text/font_mapping.rs b/bevy_kayak_ui/src/render/text/font_mapping.rs
new file mode 100644
index 0000000..eeb405a
--- /dev/null
+++ b/bevy_kayak_ui/src/render/text/font_mapping.rs
@@ -0,0 +1,40 @@
+use bevy::{prelude::Handle, utils::HashMap};
+
+use super::font::KayakFont;
+
+pub struct FontMapping {
+    count: u16,
+    font_ids: HashMap<Handle<KayakFont>, u16>,
+    font_handles: HashMap<u16, Handle<KayakFont>>,
+}
+
+impl Default for FontMapping {
+    fn default() -> Self {
+        Self {
+            count: 0,
+            font_ids: HashMap::default(),
+            font_handles: HashMap::default(),
+        }
+    }
+}
+
+impl FontMapping {
+    pub(crate) fn add(&mut self, handle: Handle<KayakFont>) -> u16 {
+        if !self.font_ids.contains_key(&handle) {
+            let id = self.count;
+            self.font_ids.insert(handle.clone(), id);
+            self.font_handles.insert(id, handle);
+            self.count += 1;
+
+            id
+        } else {
+            *self.font_ids.get(&handle).unwrap()
+        }
+    }
+
+    pub(crate) fn get_handle(&self, id: u16) -> Option<Handle<KayakFont>> {
+        self.font_handles
+            .get(&id)
+            .and_then(|item| Some(item.clone()))
+    }
+}
diff --git a/bevy_kayak_ui/src/render/text/font_texture_cache.rs b/bevy_kayak_ui/src/render/text/font_texture_cache.rs
new file mode 100644
index 0000000..a15bb07
--- /dev/null
+++ b/bevy_kayak_ui/src/render/text/font_texture_cache.rs
@@ -0,0 +1,201 @@
+use bevy::{
+    prelude::Handle,
+    render2::{
+        render_resource::{
+            AddressMode, BindGroup, BindGroupDescriptor, BindGroupEntry, BindingResource, Extent3d,
+            FilterMode, ImageCopyTexture, ImageDataLayout, Origin3d, SamplerDescriptor,
+            TextureAspect, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
+            TextureViewDescriptor, TextureViewDimension,
+        },
+        renderer::{RenderDevice, RenderQueue},
+        texture::{GpuImage, TextureFormatPixelInfo},
+    },
+    utils::HashMap,
+};
+
+use super::{font::KayakFont, pipeline::TextPipeline};
+
+pub const MAX_CHARACTERS: u32 = 100;
+
+pub struct FontTextureCache {
+    images: HashMap<Handle<KayakFont>, GpuImage>,
+    pub(crate) bind_groups: HashMap<Handle<KayakFont>, BindGroup>,
+    fonts: HashMap<Handle<KayakFont>, KayakFont>,
+    new_fonts: Vec<Handle<KayakFont>>,
+    updated_fonts: Vec<Handle<KayakFont>>,
+}
+
+impl Default for FontTextureCache {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl FontTextureCache {
+    pub fn new() -> Self {
+        Self {
+            images: HashMap::default(),
+            bind_groups: HashMap::default(),
+            fonts: HashMap::default(),
+            new_fonts: Vec::new(),
+            updated_fonts: Vec::new(),
+        }
+    }
+
+    pub fn add(&mut self, kayak_font_handle: Handle<KayakFont>, font: KayakFont) {
+        if !self.fonts.contains_key(&kayak_font_handle) {
+            self.fonts.insert(kayak_font_handle.clone(), font);
+            self.new_fonts.push(kayak_font_handle);
+        } else {
+            if let Some(old_font) = self.fonts.get_mut(&kayak_font_handle) {
+                *old_font = font;
+                self.updated_fonts.push(kayak_font_handle);
+            }
+        }
+    }
+
+    pub fn process_new(&mut self, device: &RenderDevice, pipeline: &TextPipeline) {
+        let new_fonts = self.new_fonts.drain(..);
+        for kayak_font_handle in new_fonts {
+            if let Some(font) = self.fonts.get(&kayak_font_handle) {
+                Self::create_texture(
+                    &mut self.images,
+                    kayak_font_handle.clone_weak(),
+                    font,
+                    device,
+                );
+
+                let gpu_image = self.images.get(&kayak_font_handle).unwrap();
+
+                // create bind group
+                let binding = device.create_bind_group(&BindGroupDescriptor {
+                    label: Some("text_image_bind_group"),
+                    entries: &[
+                        BindGroupEntry {
+                            binding: 0,
+                            resource: BindingResource::TextureView(&gpu_image.texture_view),
+                        },
+                        BindGroupEntry {
+                            binding: 1,
+                            resource: BindingResource::Sampler(&gpu_image.sampler),
+                        },
+                    ],
+                    layout: &pipeline.image_layout,
+                });
+
+                self.bind_groups.insert(kayak_font_handle, binding);
+            }
+        }
+    }
+
+    pub fn process_updated(&mut self, queue: &RenderQueue) {
+        let updated_fonts = self.updated_fonts.drain(..);
+        for kayak_font_handle in updated_fonts {
+            if let Some(font) = self.fonts.get_mut(&kayak_font_handle) {
+                Self::process_new_chars_into_texture(
+                    &mut self.images,
+                    kayak_font_handle,
+                    font,
+                    queue,
+                );
+            }
+        }
+    }
+
+    fn create_texture(
+        images: &mut HashMap<Handle<KayakFont>, GpuImage>,
+        font_handle: Handle<KayakFont>,
+        font: &KayakFont,
+        device: &RenderDevice,
+    ) {
+        let texture_descriptor = TextureDescriptor {
+            label: Some("font_texture_array"),
+            size: Extent3d {
+                width: font.font.cache.dimensions,
+                height: font.font.cache.dimensions,
+                depth_or_array_layers: MAX_CHARACTERS,
+            },
+            mip_level_count: 1,
+            sample_count: 1,
+            dimension: TextureDimension::D2,
+            format: TextureFormat::Rgba32Float,
+            usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST,
+        };
+
+        let sampler_descriptor = SamplerDescriptor {
+            label: Some("font_texture_array_sampler"),
+            address_mode_u: AddressMode::ClampToEdge,
+            address_mode_v: AddressMode::ClampToEdge,
+            address_mode_w: AddressMode::ClampToEdge,
+            mag_filter: FilterMode::Linear,
+            min_filter: FilterMode::Linear,
+            mipmap_filter: FilterMode::Nearest,
+            lod_min_clamp: 0.0,
+            lod_max_clamp: std::f32::MAX,
+            compare: None,
+            anisotropy_clamp: None,
+            border_color: None,
+        };
+
+        let texture = device.create_texture(&texture_descriptor);
+        let sampler = device.create_sampler(&sampler_descriptor);
+
+        let texture_view = texture.create_view(&TextureViewDescriptor {
+            label: Some("font_texture_array_view"),
+            format: None,
+            dimension: Some(TextureViewDimension::D2Array),
+            aspect: bevy::render2::render_resource::TextureAspect::All,
+            base_mip_level: 0,
+            base_array_layer: 0,
+            mip_level_count: None,
+            array_layer_count: std::num::NonZeroU32::new(MAX_CHARACTERS),
+        });
+
+        let image = GpuImage {
+            texture,
+            sampler,
+            texture_view,
+        };
+
+        images.insert(font_handle, image);
+    }
+
+    pub fn process_new_chars_into_texture(
+        images: &mut HashMap<Handle<KayakFont>, GpuImage>,
+        kayak_font_handle: Handle<KayakFont>,
+        font: &mut KayakFont,
+        queue: &RenderQueue,
+    ) {
+        let size = font.font.cache.dimensions;
+        if let Some(gpu_image) = images.get_mut(&kayak_font_handle) {
+            for (_, id, pixels) in font.font.get_data_to_process() {
+                let format_size = TextureFormat::Rgba32Float.pixel_size();
+                queue.write_texture(
+                    ImageCopyTexture {
+                        texture: &gpu_image.texture,
+                        mip_level: 0,
+                        origin: Origin3d {
+                            x: 0,
+                            y: 0,
+                            z: id as u32,
+                        },
+                        aspect: TextureAspect::All,
+                    },
+                    &pixels,
+                    ImageDataLayout {
+                        offset: 0,
+                        bytes_per_row: Some(
+                            std::num::NonZeroU32::new(size * format_size as u32).unwrap(),
+                        ),
+                        rows_per_image: None,
+                    },
+                    Extent3d {
+                        width: size,
+                        height: size,
+                        depth_or_array_layers: 1,
+                    },
+                );
+            }
+        }
+    }
+}
diff --git a/bevy_kayak_ui/src/render/text/mod.rs b/bevy_kayak_ui/src/render/text/mod.rs
new file mode 100644
index 0000000..bfe4381
--- /dev/null
+++ b/bevy_kayak_ui/src/render/text/mod.rs
@@ -0,0 +1,141 @@
+use bevy::{
+    prelude::{
+        AddAsset, AssetEvent, Assets, Commands, EventReader, Handle, HandleUntyped, Plugin, Res,
+        ResMut,
+    },
+    reflect::TypeUuid,
+    render2::{
+        render_phase::DrawFunctions,
+        render_resource::Shader,
+        renderer::{RenderDevice, RenderQueue},
+        RenderApp, RenderStage,
+    },
+    utils::HashSet,
+};
+
+use crate::render::{
+    text::{
+        font_mapping::FontMapping,
+        pipeline::{DrawText, TextMeta, TextPipeline},
+    },
+    ui_pass::TransparentUI,
+};
+
+use self::{font::KayakFont, font_texture_cache::FontTextureCache};
+
+mod font;
+mod font_mapping;
+mod font_texture_cache;
+mod pipeline;
+
+pub const TEXT_SHADER_HANDLE: HandleUntyped =
+    HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 1561765330850392701);
+
+#[derive(Default)]
+pub struct TextRendererPlugin;
+
+impl Plugin for TextRendererPlugin {
+    fn build(&self, app: &mut bevy::prelude::App) {
+        let mut shaders = app.world.get_resource_mut::<Assets<Shader>>().unwrap();
+        let text_shader = Shader::from_wgsl(include_str!("shader.wgsl"));
+        shaders.set_untracked(TEXT_SHADER_HANDLE, text_shader);
+
+        let render_app = app.sub_app(RenderApp);
+        render_app
+            .init_resource::<TextPipeline>()
+            .init_resource::<TextMeta>()
+            .add_system_to_stage(RenderStage::Extract, pipeline::extract_texts)
+            .add_system_to_stage(RenderStage::Prepare, pipeline::prepare_texts)
+            .add_system_to_stage(RenderStage::Queue, pipeline::queue_texts);
+
+        let draw_text = DrawText::new(&mut render_app.world);
+
+        render_app
+            .world
+            .get_resource::<DrawFunctions<TransparentUI>>()
+            .unwrap()
+            .write()
+            .add(draw_text);
+
+        render_app
+            .init_resource::<FontTextureCache>()
+            .init_resource::<ExtractedFonts>()
+            .add_system_to_stage(RenderStage::Extract, extract_fonts)
+            .add_system_to_stage(RenderStage::Prepare, prepare_fonts)
+            .add_system_to_stage(RenderStage::Queue, create_and_update_font_cache_texture);
+
+        app.add_asset::<KayakFont>()
+            .init_resource::<FontMapping>()
+            .add_startup_system(load_fonts);
+    }
+}
+
+#[derive(Default)]
+pub struct ExtractedFonts {
+    pub fonts: Vec<(Handle<KayakFont>, KayakFont)>,
+}
+
+fn load_fonts(mut font_assets: ResMut<Assets<KayakFont>>, mut font_mapping: ResMut<FontMapping>) {
+    let font_bytes = include_bytes!("../../../../resources/Roboto-Regular.ttf");
+    let font = kayak_font::Font::new(font_bytes, 128);
+
+    let handle = font_assets.add(KayakFont { font });
+    font_mapping.add(handle);
+
+    dbg!("Loaded base font!");
+}
+
+fn extract_fonts(
+    mut commands: Commands,
+    font_assets: Res<Assets<KayakFont>>,
+    mut events: EventReader<AssetEvent<KayakFont>>,
+) {
+    let mut extracted_fonts = ExtractedFonts { fonts: Vec::new() };
+    let mut changed_assets = HashSet::default();
+    let mut removed = Vec::new();
+    for event in events.iter() {
+        match event {
+            AssetEvent::Created { handle } => {
+                changed_assets.insert(handle);
+                dbg!("New font added!");
+            }
+            AssetEvent::Modified { handle } => {
+                changed_assets.insert(handle);
+                dbg!("Font changed!");
+            }
+            AssetEvent::Removed { handle } => {
+                if !changed_assets.remove(handle) {
+                    removed.push(handle.clone_weak());
+                }
+            }
+        }
+    }
+
+    for handle in changed_assets {
+        let font_asset = font_assets.get(handle).unwrap();
+        let font = font_asset.clone();
+
+        extracted_fonts.fonts.push((handle.clone_weak(), font));
+    }
+
+    commands.insert_resource(extracted_fonts);
+}
+
+fn prepare_fonts(
+    mut extracted_fonts: ResMut<ExtractedFonts>,
+    mut font_texture_cache: ResMut<FontTextureCache>,
+) {
+    for (handle, font) in extracted_fonts.fonts.drain(..) {
+        font_texture_cache.add(handle, font);
+    }
+}
+
+fn create_and_update_font_cache_texture(
+    device: Res<RenderDevice>,
+    queue: Res<RenderQueue>,
+    pipeline: Res<TextPipeline>,
+    mut font_texture_cache: ResMut<FontTextureCache>,
+) {
+    font_texture_cache.process_new(&device, &pipeline);
+    font_texture_cache.process_updated(&queue);
+}
diff --git a/bevy_kayak_ui/src/render/text/pipeline.rs b/bevy_kayak_ui/src/render/text/pipeline.rs
new file mode 100644
index 0000000..6b2691e
--- /dev/null
+++ b/bevy_kayak_ui/src/render/text/pipeline.rs
@@ -0,0 +1,360 @@
+use bevy::{
+    core::FloatOrd,
+    ecs::system::{
+        lifetimeless::{Read, SQuery, SRes},
+        SystemState,
+    },
+    math::{const_vec3, Mat4, Quat, Vec2, Vec3},
+    prelude::{
+        Assets, Bundle, Color, Commands, Entity, FromWorld, Handle, Query, Res, ResMut, World,
+    },
+    render2::{
+        render_phase::{Draw, DrawFunctions, RenderPhase, TrackedRenderPass},
+        render_resource::{
+            BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout,
+            BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType, BlendComponent,
+            BlendFactor, BlendOperation, BlendState, BufferBindingType, BufferSize, BufferUsages,
+            BufferVec, CachedPipelineId, ColorTargetState, ColorWrites, CompareFunction,
+            DepthBiasState, DepthStencilState, FragmentState, FrontFace, MultisampleState,
+            PolygonMode, PrimitiveState, PrimitiveTopology, RenderPipelineCache,
+            RenderPipelineDescriptor, Shader, ShaderStages, StencilFaceState, StencilState,
+            TextureFormat, TextureSampleType, TextureViewDimension, VertexAttribute,
+            VertexBufferLayout, VertexFormat, VertexState, VertexStepMode,
+        },
+        renderer::{RenderDevice, RenderQueue},
+        texture::BevyDefault,
+        view::{ViewUniformOffset, ViewUniforms},
+    },
+    sprite2::Rect,
+};
+use bytemuck::{Pod, Zeroable};
+use kayak_core::render_primitive::RenderPrimitive;
+
+use crate::{
+    render::{text::TEXT_SHADER_HANDLE, ui_pass::TransparentUI},
+    to_bevy_color, BevyContext,
+};
+
+use super::{font::KayakFont, font_mapping::FontMapping, font_texture_cache::FontTextureCache};
+
+pub struct TextPipeline {
+    view_layout: BindGroupLayout,
+    pub(crate) image_layout: BindGroupLayout,
+    pipeline: CachedPipelineId,
+}
+
+const QUAD_VERTEX_POSITIONS: &[Vec3] = &[
+    const_vec3!([0.0, 0.0, 0.0]),
+    const_vec3!([1.0, 1.0, 0.0]),
+    const_vec3!([0.0, 1.0, 0.0]),
+    const_vec3!([0.0, 0.0, 0.0]),
+    const_vec3!([1.0, 0.0, 0.0]),
+    const_vec3!([1.0, 1.0, 0.0]),
+];
+
+impl FromWorld for TextPipeline {
+    fn from_world(world: &mut World) -> Self {
+        let world = world.cell();
+        let render_device = world.get_resource::<RenderDevice>().unwrap();
+        let mut pipeline_cache = world.get_resource_mut::<RenderPipelineCache>().unwrap();
+
+        let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
+            entries: &[BindGroupLayoutEntry {
+                binding: 0,
+                visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
+                ty: BindingType::Buffer {
+                    ty: BufferBindingType::Uniform,
+                    has_dynamic_offset: true,
+                    // TODO: change this to ViewUniform::std140_size_static once crevice fixes this!
+                    // Context: https://github.com/LPGhatguy/crevice/issues/29
+                    min_binding_size: BufferSize::new(144),
+                },
+                count: None,
+            }],
+            label: Some("text_view_layout"),
+        });
+
+        let image_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
+            entries: &[
+                BindGroupLayoutEntry {
+                    binding: 0,
+                    visibility: ShaderStages::FRAGMENT,
+                    ty: BindingType::Texture {
+                        multisampled: false,
+                        sample_type: TextureSampleType::Float { filterable: false },
+                        view_dimension: TextureViewDimension::D2Array,
+                    },
+                    count: None,
+                },
+                BindGroupLayoutEntry {
+                    binding: 1,
+                    visibility: ShaderStages::FRAGMENT,
+                    ty: BindingType::Sampler {
+                        comparison: false,
+                        filtering: true,
+                    },
+                    count: None,
+                },
+            ],
+            label: Some("text_image_layout"),
+        });
+
+        let vertex_buffer_layout = VertexBufferLayout {
+            array_stride: 40,
+            step_mode: VertexStepMode::Vertex,
+            attributes: vec![
+                VertexAttribute {
+                    format: VertexFormat::Float32x3,
+                    offset: 0,
+                    shader_location: 0,
+                },
+                VertexAttribute {
+                    format: VertexFormat::Float32x4,
+                    offset: 12,
+                    shader_location: 1,
+                },
+                VertexAttribute {
+                    format: VertexFormat::Float32x3,
+                    offset: 28,
+                    shader_location: 2,
+                },
+            ],
+        };
+
+        let pipeline_desc = RenderPipelineDescriptor {
+            vertex: VertexState {
+                shader: TEXT_SHADER_HANDLE.typed::<Shader>(),
+                entry_point: "vertex".into(),
+                shader_defs: vec![],
+                buffers: vec![vertex_buffer_layout],
+            },
+            fragment: Some(FragmentState {
+                shader: TEXT_SHADER_HANDLE.typed::<Shader>(),
+                shader_defs: vec![],
+                entry_point: "fragment".into(),
+                targets: vec![ColorTargetState {
+                    format: TextureFormat::bevy_default(),
+                    blend: Some(BlendState {
+                        color: BlendComponent {
+                            src_factor: BlendFactor::SrcAlpha,
+                            dst_factor: BlendFactor::OneMinusSrcAlpha,
+                            operation: BlendOperation::Add,
+                        },
+                        alpha: BlendComponent {
+                            src_factor: BlendFactor::One,
+                            dst_factor: BlendFactor::One,
+                            operation: BlendOperation::Add,
+                        },
+                    }),
+                    write_mask: ColorWrites::ALL,
+                }],
+            }),
+            layout: Some(vec![view_layout.clone(), image_layout.clone()]),
+            primitive: PrimitiveState {
+                front_face: FrontFace::Ccw,
+                cull_mode: None,
+                polygon_mode: PolygonMode::Fill,
+                clamp_depth: false,
+                conservative: false,
+                topology: PrimitiveTopology::TriangleList,
+                strip_index_format: None,
+            },
+            depth_stencil: Some(DepthStencilState {
+                format: TextureFormat::Depth32Float,
+                depth_write_enabled: false,
+                depth_compare: CompareFunction::Greater,
+                stencil: StencilState {
+                    front: StencilFaceState::IGNORE,
+                    back: StencilFaceState::IGNORE,
+                    read_mask: 0,
+                    write_mask: 0,
+                },
+                bias: DepthBiasState {
+                    constant: 0,
+                    slope_scale: 0.0,
+                    clamp: 0.0,
+                },
+            }),
+            multisample: MultisampleState {
+                count: 1,
+                mask: !0,
+                alpha_to_coverage_enabled: false,
+            },
+            label: Some("text_pipeline".into()),
+        };
+
+        TextPipeline {
+            pipeline: pipeline_cache.queue(pipeline_desc),
+            view_layout,
+            image_layout,
+        }
+    }
+}
+
+
+
+#[repr(C)]
+#[derive(Copy, Clone, Pod, Zeroable)]
+struct TextVertex {
+    pub position: [f32; 3],
+    pub color: [f32; 4],
+    pub uv: [f32; 3],
+}
+
+pub struct TextMeta {
+    vertices: BufferVec<TextVertex>,
+    view_bind_group: Option<BindGroup>,
+}
+
+impl Default for TextMeta {
+    fn default() -> Self {
+        Self {
+            vertices: BufferVec::new(BufferUsages::VERTEX),
+            view_bind_group: None,
+        }
+    }
+}
+
+pub fn prepare_texts(
+    render_device: Res<RenderDevice>,
+    render_queue: Res<RenderQueue>,
+    mut sprite_meta: ResMut<TextMeta>,
+    mut extracted_sprites: Query<&mut ExtractedText>,
+) {
+    let extracted_sprite_len = extracted_sprites.iter_mut().len();
+    // dont create buffers when there are no texts
+    if extracted_sprite_len == 0 {
+        return;
+    }
+
+    sprite_meta.vertices.clear();
+    sprite_meta.vertices.reserve(
+        extracted_sprite_len * QUAD_VERTEX_POSITIONS.len(),
+        &render_device,
+    );
+
+    for (i, mut extracted_sprite) in extracted_sprites.iter_mut().enumerate() {
+        let sprite_rect = extracted_sprite.rect;
+        let color = extracted_sprite.background_color.as_linear_rgba_f32();
+
+        let bottom_left = Vec3::new(0.0, 1.0, extracted_sprite.char_id as f32);
+        let top_left = Vec3::new(0.0, 0.0, extracted_sprite.char_id as f32);
+        let top_right = Vec3::new(1.0, 0.0, extracted_sprite.char_id as f32);
+        let bottom_right = Vec3::new(1.0, 1.0, extracted_sprite.char_id as f32);
+
+        let uvs: [[f32; 3]; 6] = [
+            bottom_left.into(),
+            top_right.into(),
+            top_left.into(),
+            bottom_left.into(),
+            bottom_right.into(),
+            top_right.into(),
+        ];
+
+        extracted_sprite.vertex_index = i;
+        for (index, vertex_position) in QUAD_VERTEX_POSITIONS.iter().enumerate() {
+            let world = Mat4::from_scale_rotation_translation(
+                sprite_rect.size().extend(1.0),
+                Quat::default(),
+                sprite_rect.min.extend(extracted_sprite.z_index),
+            );
+            let final_position = (world * Vec3::from(*vertex_position).extend(1.0)).truncate();
+            sprite_meta.vertices.push(TextVertex {
+                position: final_position.into(),
+                color,
+                uv: uvs[index],
+            });
+        }
+    }
+    sprite_meta
+        .vertices
+        .write_buffer(&render_device, &render_queue);
+}
+
+pub fn queue_texts(
+    draw_functions: Res<DrawFunctions<TransparentUI>>,
+    render_device: Res<RenderDevice>,
+    mut sprite_meta: ResMut<TextMeta>,
+    view_uniforms: Res<ViewUniforms>,
+    text_pipeline: Res<TextPipeline>,
+    mut extracted_sprites: Query<(Entity, &ExtractedText)>,
+    mut views: Query<&mut RenderPhase<TransparentUI>>,
+) {
+    if let Some(view_binding) = view_uniforms.uniforms.binding() {
+        sprite_meta.view_bind_group = Some(render_device.create_bind_group(&BindGroupDescriptor {
+            entries: &[BindGroupEntry {
+                binding: 0,
+                resource: view_binding,
+            }],
+            label: Some("text_view_bind_group"),
+            layout: &text_pipeline.view_layout,
+        }));
+        let draw_text = draw_functions.read().get_id::<DrawText>().unwrap();
+        for mut transparent_phase in views.iter_mut() {
+            for (entity, _) in extracted_sprites.iter_mut() {
+                transparent_phase.add(TransparentUI {
+                    draw_function: draw_text,
+                    pipeline: text_pipeline.pipeline,
+                    entity,
+                    sort_key: FloatOrd(0.0),
+                });
+            }
+        }
+    }
+}
+
+pub struct DrawText {
+    params: SystemState<(
+        SRes<TextMeta>,
+        SRes<RenderPipelineCache>,
+        SRes<FontTextureCache>,
+        SQuery<Read<ViewUniformOffset>>,
+        SQuery<Read<ExtractedText>>,
+    )>,
+}
+
+impl DrawText {
+    pub fn new(world: &mut World) -> Self {
+        Self {
+            params: SystemState::new(world),
+        }
+    }
+}
+
+impl Draw<TransparentUI> for DrawText {
+    fn draw<'w>(
+        &mut self,
+        world: &'w World,
+        pass: &mut TrackedRenderPass<'w>,
+        view: Entity,
+        item: &TransparentUI,
+    ) {
+        let (text_meta, pipelines, font_texture_cache, views, texts) = self.params.get(world);
+        let view_uniform = views.get(view).unwrap();
+        let text_meta = text_meta.into_inner();
+        let extracted_text = texts.get(item.entity).unwrap();
+        if let Some(pipeline) = pipelines.into_inner().get(item.pipeline) {
+            pass.set_render_pipeline(pipeline);
+            pass.set_vertex_buffer(0, text_meta.vertices.buffer().unwrap().slice(..));
+            pass.set_bind_group(
+                0,
+                text_meta.view_bind_group.as_ref().unwrap(),
+                &[view_uniform.offset],
+            );
+
+            if let Some(image_bindings) = font_texture_cache
+                .into_inner()
+                .bind_groups
+                .get(&extracted_text.font_handle)
+            {
+                pass.set_bind_group(1, image_bindings, &[]);
+
+                pass.draw(
+                    (extracted_text.vertex_index * QUAD_VERTEX_POSITIONS.len()) as u32
+                        ..((extracted_text.vertex_index + 1) * QUAD_VERTEX_POSITIONS.len()) as u32,
+                    0..1,
+                );
+            }
+        }
+    }
+}
diff --git a/bevy_kayak_ui/src/render/text/shader.wgsl b/bevy_kayak_ui/src/render/text/shader.wgsl
new file mode 100644
index 0000000..5a2b1ec
--- /dev/null
+++ b/bevy_kayak_ui/src/render/text/shader.wgsl
@@ -0,0 +1,45 @@
+[[block]]
+struct View {
+    view_proj: mat4x4<f32>;
+    world_position: vec3<f32>;
+};
+[[group(0), binding(0)]]
+var<uniform> view: View;
+
+struct VertexOutput {
+    [[builtin(position)]] position: vec4<f32>;
+    [[location(0)]] color: vec4<f32>;
+    [[location(1)]] uv: vec3<f32>;
+};
+
+[[stage(vertex)]]
+fn vertex(
+    [[location(0)]] vertex_position: vec3<f32>,
+    [[location(1)]] vertex_color: vec4<f32>,
+    [[location(2)]] vertex_uv: vec3<f32>,
+) -> VertexOutput {
+    var out: VertexOutput;
+    out.color = vertex_color;
+    out.uv = vertex_uv;
+    out.position = view.view_proj * vec4<f32>(vertex_position, 1.0);
+    return out;
+}
+
+[[group(1), binding(0)]]
+var sprite_texture: texture_2d_array<f32>;
+[[group(1), binding(1)]]
+var sprite_sampler: sampler;
+
+let RADIUS: f32 = 0.5;
+
+[[stage(fragment)]]
+fn fragment(in: VertexOutput) -> [[location(0)]] vec4<f32> {
+    var x = textureSample(sprite_texture, sprite_sampler, in.uv.xy, i32(in.uv.z)); 
+    var v = max(min(x.r, x.g), min(max(x.r, x.g), x.b));
+    var c = v; //remap(v);
+
+    var v2 = c / fwidth( c );
+    var a = v2 + RADIUS; //clamp( v2 + RADIUS, 0.0, 1.0 );
+
+    return vec4<f32>(in.color.rgb, a);
+}
\ No newline at end of file
diff --git a/bevy_kayak_ui/src/render/ui_pass.rs b/bevy_kayak_ui/src/render/ui_pass.rs
new file mode 100644
index 0000000..d04383c
--- /dev/null
+++ b/bevy_kayak_ui/src/render/ui_pass.rs
@@ -0,0 +1,102 @@
+use bevy::core::FloatOrd;
+use bevy::core_pipeline::ClearColor;
+use bevy::ecs::prelude::*;
+use bevy::render2::render_phase::{DrawFunctionId, PhaseItem};
+use bevy::render2::render_resource::{CachedPipelineId, RenderPassColorAttachment};
+use bevy::render2::{
+    render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType},
+    render_phase::{DrawFunctions, RenderPhase, TrackedRenderPass},
+    render_resource::{LoadOp, Operations, RenderPassDepthStencilAttachment, RenderPassDescriptor},
+    renderer::RenderContext,
+    view::{ExtractedView, ViewDepthTexture, ViewTarget},
+};
+
+pub struct TransparentUI {
+    pub sort_key: FloatOrd,
+    pub entity: Entity,
+    pub pipeline: CachedPipelineId,
+    pub draw_function: DrawFunctionId,
+}
+
+impl PhaseItem for TransparentUI {
+    type SortKey = FloatOrd;
+
+    #[inline]
+    fn sort_key(&self) -> Self::SortKey {
+        self.sort_key
+    }
+
+    #[inline]
+    fn draw_function(&self) -> DrawFunctionId {
+        self.draw_function
+    }
+}
+
+pub struct MainPassUINode {
+    query:
+        QueryState<(&'static RenderPhase<TransparentUI>, &'static ViewTarget), With<ExtractedView>>,
+}
+
+impl MainPassUINode {
+    pub const IN_VIEW: &'static str = "view";
+
+    pub fn new(world: &mut World) -> Self {
+        Self {
+            query: QueryState::new(world),
+        }
+    }
+}
+
+impl Node for MainPassUINode {
+    fn input(&self) -> Vec<SlotInfo> {
+        vec![SlotInfo::new(MainPassUINode::IN_VIEW, SlotType::Entity)]
+    }
+
+    fn update(&mut self, world: &mut World) {
+        self.query.update_archetypes(world);
+    }
+
+    fn run(
+        &self,
+        graph: &mut RenderGraphContext,
+        render_context: &mut RenderContext,
+        world: &World,
+    ) -> Result<(), NodeRunError> {
+        let view_entity = graph.get_input_entity(Self::IN_VIEW)?;
+        let (transparent_phase, target) = self
+            .query
+            .get_manual(world, view_entity)
+            .expect("view entity should exist");
+        let clear_color = world.get_resource::<ClearColor>().unwrap();
+        {
+            let pass_descriptor = RenderPassDescriptor {
+                label: Some("main_transparent_pass_UI"),
+                color_attachments: &[RenderPassColorAttachment {
+                    view: &target.view,
+                    resolve_target: None,
+                    ops: Operations {
+                        load: LoadOp::Clear(clear_color.0.into()),
+                        store: true,
+                    },
+                }],
+                depth_stencil_attachment: None,
+            };
+
+            let draw_functions = world
+                .get_resource::<DrawFunctions<TransparentUI>>()
+                .unwrap();
+
+            let render_pass = render_context
+                .command_encoder
+                .begin_render_pass(&pass_descriptor);
+            let mut draw_functions = draw_functions.write();
+            let mut tracked_pass = TrackedRenderPass::new(render_pass);
+            for item in transparent_phase.items.iter() {
+                let draw_function = draw_functions.get_mut(item.draw_function).unwrap();
+                draw_function.draw(world, &mut tracked_pass, view_entity, item);
+            }
+        }
+
+        Ok(())
+    }
+}
diff --git a/bevy_kayak_ui/src/render/ui_pass_driver.rs b/bevy_kayak_ui/src/render/ui_pass_driver.rs
new file mode 100644
index 0000000..edce5b8
--- /dev/null
+++ b/bevy_kayak_ui/src/render/ui_pass_driver.rs
@@ -0,0 +1,29 @@
+use bevy::ecs::world::World;
+use bevy::render2::{
+    camera::{CameraPlugin, ExtractedCameraNames},
+    render_graph::{Node, NodeRunError, RenderGraphContext, SlotValue},
+    renderer::RenderContext,
+};
+
+use crate::UICameraBundle;
+
+pub struct UIPassDriverNode;
+
+impl Node for UIPassDriverNode {
+    fn run(
+        &self,
+        graph: &mut RenderGraphContext,
+        _render_context: &mut RenderContext,
+        world: &World,
+    ) -> Result<(), NodeRunError> {
+        let extracted_cameras = world.get_resource::<ExtractedCameraNames>().unwrap();
+        if let Some(camera_ui) = extracted_cameras.entities.get(UICameraBundle::UI_CAMERA) {
+            graph.run_sub_graph(
+                super::draw_ui_graph::NAME,
+                vec![SlotValue::Entity(*camera_ui)],
+            )?;
+        }
+
+        Ok(())
+    }
+}
diff --git a/bevy_kayak_ui/src/render/unified/font/extract.rs b/bevy_kayak_ui/src/render/unified/font/extract.rs
new file mode 100644
index 0000000..2b55316
--- /dev/null
+++ b/bevy_kayak_ui/src/render/unified/font/extract.rs
@@ -0,0 +1,87 @@
+use bevy::{
+    math::Vec2,
+    prelude::{Assets, Bundle, Commands, Handle, Res, ResMut},
+    render2::color::Color,
+    sprite2::Rect,
+};
+use kayak_core::render_primitive::RenderPrimitive;
+
+use crate::{
+    render::unified::pipeline::{ExtractQuadBundle, ExtractedQuad, UIQuadType},
+    to_bevy_color, BevyContext,
+};
+
+use super::{font::KayakFont, font_mapping::FontMapping};
+
+pub fn extract_texts(
+    mut commands: Commands,
+    context: Res<BevyContext>,
+    mut fonts: ResMut<Assets<KayakFont>>,
+    font_mapping: Res<FontMapping>,
+) {
+    let render_commands = if let Ok(context) = context.kayak_context.read() {
+        context.widget_manager.build_render_primitives()
+    } else {
+        vec![]
+    };
+
+    let text_commands: Vec<&RenderPrimitive> = render_commands
+        .iter()
+        .filter(|command| matches!(command, RenderPrimitive::Text { .. }))
+        .collect::<Vec<_>>();
+
+    let mut extracted_texts = Vec::new();
+    for render_primitive in text_commands {
+        let (background_color, layout, font_size, content, font) = match render_primitive {
+            RenderPrimitive::Text {
+                color,
+                layout,
+                size,
+                content,
+                font,
+            } => (color, layout, *size, content, *font),
+            _ => panic!(""),
+        };
+
+        let font_handle = font_mapping.get_handle(font).unwrap();
+        let new_chars = {
+            let font = fonts.get(font_handle.clone()).unwrap();
+            font.font.check_chars(content.chars())
+        };
+        // Filter out non-renderable spaces.
+        let new_chars: Vec<_> = new_chars.into_iter().filter(|c| *c != ' ').collect();
+        // Add chars to font.
+        if new_chars.len() > 0 {
+            let font = fonts.get_mut(font_handle.clone()).unwrap();
+            for c in new_chars {
+                dbg!("Adding char: ");
+                dbg!(c);
+                font.font.add_character(c);
+            }
+        }
+        let font = fonts.get(font_handle.clone()).unwrap();
+        let char_layouts = font.font.get_layout(content, font_size);
+
+        for (c, (x, y), (width, height)) in char_layouts {
+            // let size = font.font.get_size(c, font_size);
+            let position_x = layout.posx + x;
+            let position_y = layout.posy + y;
+            extracted_texts.push(ExtractQuadBundle {
+                extracted_quad: ExtractedQuad {
+                    font_handle: Some(font_handle.clone()),
+                    rect: Rect {
+                        min: Vec2::new(position_x, position_y),
+                        max: Vec2::new(position_x + width, position_y + height),
+                    },
+                    color: to_bevy_color(background_color),
+                    vertex_index: 0,
+                    char_id: font.font.get_char_id(c),
+                    z_index: layout.z_index,
+                    quad_type: UIQuadType::Text,
+                    type_index: 0,
+                },
+            });
+        }
+    }
+    commands.spawn_batch(extracted_texts);
+}
diff --git a/bevy_kayak_ui/src/render/unified/font/font.rs b/bevy_kayak_ui/src/render/unified/font/font.rs
new file mode 100644
index 0000000..7a4424c
--- /dev/null
+++ b/bevy_kayak_ui/src/render/unified/font/font.rs
@@ -0,0 +1,8 @@
+use bevy::reflect::TypeUuid;
+use kayak_font::Font;
+
+#[derive(Debug, Clone, TypeUuid)]
+#[uuid = "4fe4732c-6731-49bb-bafc-4690d636b848"]
+pub struct KayakFont {
+    pub font: Font,
+}
diff --git a/bevy_kayak_ui/src/render/unified/font/font_mapping.rs b/bevy_kayak_ui/src/render/unified/font/font_mapping.rs
new file mode 100644
index 0000000..eeb405a
--- /dev/null
+++ b/bevy_kayak_ui/src/render/unified/font/font_mapping.rs
@@ -0,0 +1,40 @@
+use bevy::{prelude::Handle, utils::HashMap};
+
+use super::font::KayakFont;
+
+pub struct FontMapping {
+    count: u16,
+    font_ids: HashMap<Handle<KayakFont>, u16>,
+    font_handles: HashMap<u16, Handle<KayakFont>>,
+}
+
+impl Default for FontMapping {
+    fn default() -> Self {
+        Self {
+            count: 0,
+            font_ids: HashMap::default(),
+            font_handles: HashMap::default(),
+        }
+    }
+}
+
+impl FontMapping {
+    pub(crate) fn add(&mut self, handle: Handle<KayakFont>) -> u16 {
+        if !self.font_ids.contains_key(&handle) {
+            let id = self.count;
+            self.font_ids.insert(handle.clone(), id);
+            self.font_handles.insert(id, handle);
+            self.count += 1;
+
+            id
+        } else {
+            *self.font_ids.get(&handle).unwrap()
+        }
+    }
+
+    pub(crate) fn get_handle(&self, id: u16) -> Option<Handle<KayakFont>> {
+        self.font_handles
+            .get(&id)
+            .and_then(|item| Some(item.clone()))
+    }
+}
diff --git a/bevy_kayak_ui/src/render/unified/font/font_texture_cache.rs b/bevy_kayak_ui/src/render/unified/font/font_texture_cache.rs
new file mode 100644
index 0000000..d96b6d0
--- /dev/null
+++ b/bevy_kayak_ui/src/render/unified/font/font_texture_cache.rs
@@ -0,0 +1,248 @@
+use bevy::{prelude::Handle, render2::{render_resource::{AddressMode, BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindingResource, Extent3d, FilterMode, ImageCopyTexture, ImageDataLayout, Origin3d, SamplerDescriptor, TextureAspect, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages, TextureViewDescriptor, TextureViewDimension}, renderer::{RenderDevice, RenderQueue}, texture::{GpuImage, TextureFormatPixelInfo}}, utils::HashMap};
+
+use crate::render::unified::pipeline::UnifiedPipeline;
+
+use super::font::KayakFont;
+
+pub const MAX_CHARACTERS: u32 = 100;
+
+pub struct FontTextureCache {
+    images: HashMap<Handle<KayakFont>, GpuImage>,
+    pub(crate) bind_groups: HashMap<Handle<KayakFont>, BindGroup>,
+    fonts: HashMap<Handle<KayakFont>, KayakFont>,
+    new_fonts: Vec<Handle<KayakFont>>,
+    updated_fonts: Vec<Handle<KayakFont>>,
+}
+
+impl Default for FontTextureCache {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl FontTextureCache {
+    pub fn new() -> Self {
+        Self {
+            images: HashMap::default(),
+            bind_groups: HashMap::default(),
+            fonts: HashMap::default(),
+            new_fonts: Vec::new(),
+            updated_fonts: Vec::new(),
+        }
+    }
+
+    pub fn add(&mut self, kayak_font_handle: Handle<KayakFont>, font: KayakFont) {
+        if !self.fonts.contains_key(&kayak_font_handle) {
+            self.fonts.insert(kayak_font_handle.clone(), font);
+            self.new_fonts.push(kayak_font_handle);
+        } else {
+            if let Some(old_font) = self.fonts.get_mut(&kayak_font_handle) {
+                *old_font = font;
+                self.updated_fonts.push(kayak_font_handle);
+            }
+        }
+    }
+
+    pub fn process_new(&mut self, device: &RenderDevice, pipeline: &UnifiedPipeline) {
+        let new_fonts = self.new_fonts.drain(..);
+        for kayak_font_handle in new_fonts {
+            if let Some(font) = self.fonts.get(&kayak_font_handle) {
+                Self::create_texture(
+                    &mut self.images,
+                    kayak_font_handle.clone_weak(),
+                    font,
+                    device,
+                );
+
+                let gpu_image = self.images.get(&kayak_font_handle).unwrap();
+
+                // create bind group
+                let binding = device.create_bind_group(&BindGroupDescriptor {
+                    label: Some("text_image_bind_group"),
+                    entries: &[
+                        BindGroupEntry {
+                            binding: 0,
+                            resource: BindingResource::TextureView(&gpu_image.texture_view),
+                        },
+                        BindGroupEntry {
+                            binding: 1,
+                            resource: BindingResource::Sampler(&gpu_image.sampler),
+                        },
+                    ],
+                    layout: &pipeline.image_layout,
+                });
+
+                self.bind_groups.insert(kayak_font_handle, binding);
+            }
+        }
+    }
+
+    pub fn process_updated(&mut self, queue: &RenderQueue) {
+        let updated_fonts = self.updated_fonts.drain(..);
+        for kayak_font_handle in updated_fonts {
+            if let Some(font) = self.fonts.get_mut(&kayak_font_handle) {
+                Self::process_new_chars_into_texture(
+                    &mut self.images,
+                    kayak_font_handle,
+                    font,
+                    queue,
+                );
+            }
+        }
+    }
+
+    fn create_texture(
+        images: &mut HashMap<Handle<KayakFont>, GpuImage>,
+        font_handle: Handle<KayakFont>,
+        font: &KayakFont,
+        device: &RenderDevice,
+    ) {
+        let texture_descriptor = TextureDescriptor {
+            label: Some("font_texture_array"),
+            size: Extent3d {
+                width: font.font.cache.dimensions,
+                height: font.font.cache.dimensions,
+                depth_or_array_layers: MAX_CHARACTERS,
+            },
+            mip_level_count: 1,
+            sample_count: 1,
+            dimension: TextureDimension::D2,
+            format: TextureFormat::Rgba32Float,
+            usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST,
+        };
+
+        let sampler_descriptor = SamplerDescriptor {
+            label: Some("font_texture_array_sampler"),
+            address_mode_u: AddressMode::ClampToEdge,
+            address_mode_v: AddressMode::ClampToEdge,
+            address_mode_w: AddressMode::ClampToEdge,
+            mag_filter: FilterMode::Linear,
+            min_filter: FilterMode::Linear,
+            mipmap_filter: FilterMode::Nearest,
+            lod_min_clamp: 0.0,
+            lod_max_clamp: std::f32::MAX,
+            compare: None,
+            anisotropy_clamp: None,
+            border_color: None,
+        };
+
+        let texture = device.create_texture(&texture_descriptor);
+        let sampler = device.create_sampler(&sampler_descriptor);
+
+        let texture_view = texture.create_view(&TextureViewDescriptor {
+            label: Some("font_texture_array_view"),
+            format: None,
+            dimension: Some(TextureViewDimension::D2Array),
+            aspect: bevy::render2::render_resource::TextureAspect::All,
+            base_mip_level: 0,
+            base_array_layer: 0,
+            mip_level_count: None,
+            array_layer_count: std::num::NonZeroU32::new(MAX_CHARACTERS),
+        });
+
+        let image = GpuImage {
+            texture,
+            sampler,
+            texture_view,
+        };
+
+        images.insert(font_handle, image);
+    }
+
+    pub fn process_new_chars_into_texture(
+        images: &mut HashMap<Handle<KayakFont>, GpuImage>,
+        kayak_font_handle: Handle<KayakFont>,
+        font: &mut KayakFont,
+        queue: &RenderQueue,
+    ) {
+        let size = font.font.cache.dimensions;
+        if let Some(gpu_image) = images.get_mut(&kayak_font_handle) {
+            for (_, id, pixels) in font.font.get_data_to_process() {
+                let format_size = TextureFormat::Rgba32Float.pixel_size();
+                queue.write_texture(
+                    ImageCopyTexture {
+                        texture: &gpu_image.texture,
+                        mip_level: 0,
+                        origin: Origin3d {
+                            x: 0,
+                            y: 0,
+                            z: id as u32,
+                        },
+                        aspect: TextureAspect::All,
+                    },
+                    &pixels,
+                    ImageDataLayout {
+                        offset: 0,
+                        bytes_per_row: Some(
+                            std::num::NonZeroU32::new(size * format_size as u32).unwrap(),
+                        ),
+                        rows_per_image: None,
+                    },
+                    Extent3d {
+                        width: size,
+                        height: size,
+                        depth_or_array_layers: 1,
+                    },
+                );
+            }
+        }
+    }
+
+    pub fn get_empty(
+        device: &RenderDevice,
+        image_layout: &BindGroupLayout,
+    ) -> (GpuImage, BindGroup) {
+        let texture_descriptor = TextureDescriptor {
+            label: Some("font_texture_array"),
+            size: Extent3d {
+                width: 1,
+                height: 1,
+                depth_or_array_layers: MAX_CHARACTERS,
+            },
+            mip_level_count: 1,
+            sample_count: 1,
+            dimension: TextureDimension::D2,
+            format: TextureFormat::Rgba32Float,
+            usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST,
+        };
+
+        let sampler_descriptor = SamplerDescriptor::default();
+
+        let texture = device.create_texture(&texture_descriptor);
+        let sampler = device.create_sampler(&sampler_descriptor);
+
+        let texture_view = texture.create_view(&TextureViewDescriptor {
+            label: Some("font_texture_array_view"),
+            format: None,
+            dimension: Some(TextureViewDimension::D2Array),
+            aspect: bevy::render2::render_resource::TextureAspect::All,
+            base_mip_level: 0,
+            base_array_layer: 0,
+            mip_level_count: None,
+            array_layer_count: std::num::NonZeroU32::new(MAX_CHARACTERS),
+        });
+
+        let image = GpuImage {
+            texture,
+            sampler,
+            texture_view,
+        };
+
+        let binding = device.create_bind_group(&BindGroupDescriptor {
+            label: Some("text_image_bind_group"),
+            entries: &[
+                BindGroupEntry {
+                    binding: 0,
+                    resource: BindingResource::TextureView(&image.texture_view),
+                },
+                BindGroupEntry {
+                    binding: 1,
+                    resource: BindingResource::Sampler(&image.sampler),
+                },
+            ],
+            layout: image_layout,
+        });
+
+        (image, binding)
+    }
+}
diff --git a/bevy_kayak_ui/src/render/unified/font/mod.rs b/bevy_kayak_ui/src/render/unified/font/mod.rs
new file mode 100644
index 0000000..e356d38
--- /dev/null
+++ b/bevy_kayak_ui/src/render/unified/font/mod.rs
@@ -0,0 +1,112 @@
+use bevy::{
+    prelude::{AddAsset, AssetEvent, Assets, Commands, EventReader, Handle, Plugin, Res, ResMut},
+    render2::{
+        renderer::{RenderDevice, RenderQueue},
+        RenderApp, RenderStage,
+    },
+    utils::HashSet,
+};
+
+use self::extract::extract_texts;
+
+use super::pipeline::UnifiedPipeline;
+
+mod extract;
+mod font;
+mod font_mapping;
+mod font_texture_cache;
+
+pub use font::*;
+pub use font_mapping::*;
+pub(crate) use font_texture_cache::FontTextureCache;
+
+#[derive(Default)]
+pub struct TextRendererPlugin;
+
+impl Plugin for TextRendererPlugin {
+    fn build(&self, app: &mut bevy::prelude::App) {
+        app.add_asset::<KayakFont>()
+            .init_resource::<FontMapping>()
+            .add_startup_system(load_fonts);
+
+        let render_app = app.sub_app(RenderApp);
+        render_app.add_system_to_stage(RenderStage::Extract, extract_texts);
+
+        render_app
+            .init_resource::<FontTextureCache>()
+            .init_resource::<ExtractedFonts>()
+            .add_system_to_stage(RenderStage::Extract, extract_fonts)
+            .add_system_to_stage(RenderStage::Prepare, prepare_fonts)
+            .add_system_to_stage(RenderStage::Queue, create_and_update_font_cache_texture);
+    }
+}
+
+#[derive(Default)]
+pub struct ExtractedFonts {
+    pub fonts: Vec<(Handle<KayakFont>, KayakFont)>,
+}
+
+fn load_fonts(mut font_assets: ResMut<Assets<KayakFont>>, mut font_mapping: ResMut<FontMapping>) {
+    let font_bytes = include_bytes!("../../../../../resources/Roboto-Regular.ttf");
+    let font = kayak_font::Font::new(font_bytes, 128);
+
+    let handle = font_assets.add(KayakFont { font });
+    font_mapping.add(handle);
+
+    dbg!("Loaded base font!");
+}
+
+fn extract_fonts(
+    mut commands: Commands,
+    font_assets: Res<Assets<KayakFont>>,
+    mut events: EventReader<AssetEvent<KayakFont>>,
+) {
+    let mut extracted_fonts = ExtractedFonts { fonts: Vec::new() };
+    let mut changed_assets = HashSet::default();
+    let mut removed = Vec::new();
+    for event in events.iter() {
+        match event {
+            AssetEvent::Created { handle } => {
+                changed_assets.insert(handle);
+                dbg!("New font added!");
+            }
+            AssetEvent::Modified { handle } => {
+                changed_assets.insert(handle);
+                dbg!("Font changed!");
+            }
+            AssetEvent::Removed { handle } => {
+                if !changed_assets.remove(handle) {
+                    removed.push(handle.clone_weak());
+                }
+            }
+        }
+    }
+
+    for handle in changed_assets {
+        let font_asset = font_assets.get(handle).unwrap();
+        let font = font_asset.clone();
+
+        extracted_fonts.fonts.push((handle.clone_weak(), font));
+    }
+
+    commands.insert_resource(extracted_fonts);
+}
+
+fn prepare_fonts(
+    mut extracted_fonts: ResMut<ExtractedFonts>,
+    mut font_texture_cache: ResMut<FontTextureCache>,
+) {
+    for (handle, font) in extracted_fonts.fonts.drain(..) {
+        font_texture_cache.add(handle, font);
+    }
+}
+
+fn create_and_update_font_cache_texture(
+    device: Res<RenderDevice>,
+    queue: Res<RenderQueue>,
+    pipeline: Res<UnifiedPipeline>,
+    mut font_texture_cache: ResMut<FontTextureCache>,
+) {
+    font_texture_cache.process_new(&device, &pipeline);
+    font_texture_cache.process_updated(&queue);
+}
diff --git a/bevy_kayak_ui/src/render/unified/mod.rs b/bevy_kayak_ui/src/render/unified/mod.rs
new file mode 100644
index 0000000..37aeb58
--- /dev/null
+++ b/bevy_kayak_ui/src/render/unified/mod.rs
@@ -0,0 +1,46 @@
+use bevy::{
+    prelude::{Assets, HandleUntyped, Plugin},
+    reflect::TypeUuid,
+    render2::{render_phase::DrawFunctions, render_resource::Shader, RenderApp, RenderStage},
+};
+
+use crate::render::{
+    ui_pass::TransparentUI,
+    unified::pipeline::{DrawUI, QuadMeta, UnifiedPipeline},
+};
+
+pub mod font;
+mod pipeline;
+mod quad;
+
+pub const UNIFIED_SHADER_HANDLE: HandleUntyped =
+    HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 7604018236855288450);
+
+pub struct UnifiedRenderPlugin;
+
+impl Plugin for UnifiedRenderPlugin {
+    fn build(&self, app: &mut bevy::prelude::App) {
+        let mut shaders = app.world.get_resource_mut::<Assets<Shader>>().unwrap();
+        let unified_shader = Shader::from_wgsl(include_str!("shader.wgsl"));
+        shaders.set_untracked(UNIFIED_SHADER_HANDLE, unified_shader);
+
+        let render_app = app.sub_app(RenderApp);
+        render_app
+            .init_resource::<UnifiedPipeline>()
+            .init_resource::<QuadMeta>()
+            .add_system_to_stage(RenderStage::Prepare, pipeline::prepare_quads)
+            .add_system_to_stage(RenderStage::Queue, pipeline::queue_quads);
+
+        let draw_quad = DrawUI::new(&mut render_app.world);
+
+        render_app
+            .world
+            .get_resource::<DrawFunctions<TransparentUI>>()
+            .unwrap()
+            .write()
+            .add(draw_quad);
+
+        app.add_plugin(font::TextRendererPlugin)
+            .add_plugin(quad::QuadRendererPlugin);
+    }
+}
diff --git a/bevy_kayak_ui/src/render/unified/pipeline.rs b/bevy_kayak_ui/src/render/unified/pipeline.rs
new file mode 100644
index 0000000..043f0c5
--- /dev/null
+++ b/bevy_kayak_ui/src/render/unified/pipeline.rs
@@ -0,0 +1,438 @@
+use bevy::{
+    core::FloatOrd,
+    ecs::system::{
+        lifetimeless::{Read, SQuery, SRes},
+        SystemState,
+    },
+    math::{const_vec3, Mat4, Quat, Vec2, Vec3},
+    prelude::{Bundle, Commands, Entity, FromWorld, Handle, Query, Res, ResMut, World},
+    render2::{
+        color::Color,
+        render_phase::{Draw, DrawFunctions, RenderPhase, TrackedRenderPass},
+        render_resource::{
+            BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout,
+            BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType, BlendComponent,
+            BlendFactor, BlendOperation, BlendState, BufferBindingType, BufferSize, BufferUsages,
+            BufferVec, CachedPipelineId, ColorTargetState, ColorWrites, CompareFunction,
+            DepthBiasState, DepthStencilState, DynamicUniformVec, FragmentState, FrontFace,
+            MultisampleState, PolygonMode, PrimitiveState, PrimitiveTopology, RenderPipelineCache,
+            RenderPipelineDescriptor, Shader, ShaderStages, StencilFaceState, StencilState,
+            TextureFormat, TextureSampleType, TextureViewDimension, VertexAttribute,
+            VertexBufferLayout, VertexFormat, VertexState, VertexStepMode,
+        },
+        renderer::{RenderDevice, RenderQueue},
+        texture::{BevyDefault, GpuImage},
+        view::{ViewUniformOffset, ViewUniforms},
+    },
+    sprite2::Rect,
+};
+use bytemuck::{Pod, Zeroable};
+use crevice::std140::AsStd140;
+
+use super::font::{FontTextureCache, KayakFont};
+use super::UNIFIED_SHADER_HANDLE;
+use crate::{render::ui_pass::TransparentUI, BevyContext};
+
+pub struct UnifiedPipeline {
+    view_layout: BindGroupLayout,
+    types_layout: BindGroupLayout,
+    pub(crate) image_layout: BindGroupLayout,
+    pipeline: CachedPipelineId,
+    empty_font_texture: (GpuImage, BindGroup),
+}
+
+const QUAD_VERTEX_POSITIONS: &[Vec3] = &[
+    const_vec3!([0.0, 0.0, 0.0]),
+    const_vec3!([1.0, 1.0, 0.0]),
+    const_vec3!([0.0, 1.0, 0.0]),
+    const_vec3!([0.0, 0.0, 0.0]),
+    const_vec3!([1.0, 0.0, 0.0]),
+    const_vec3!([1.0, 1.0, 0.0]),
+];
+
+impl FromWorld for UnifiedPipeline {
+    fn from_world(world: &mut World) -> Self {
+        let world = world.cell();
+        let render_device = world.get_resource::<RenderDevice>().unwrap();
+        let mut pipeline_cache = world.get_resource_mut::<RenderPipelineCache>().unwrap();
+
+        let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
+            entries: &[BindGroupLayoutEntry {
+                binding: 0,
+                visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
+                ty: BindingType::Buffer {
+                    ty: BufferBindingType::Uniform,
+                    has_dynamic_offset: true,
+                    // TODO: change this to ViewUniform::std140_size_static once crevice fixes this!
+                    // Context: https://github.com/LPGhatguy/crevice/issues/29
+                    min_binding_size: BufferSize::new(144),
+                },
+                count: None,
+            }],
+            label: Some("ui_view_layout"),
+        });
+
+        let types_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
+            entries: &[BindGroupLayoutEntry {
+                binding: 0,
+                visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
+                ty: BindingType::Buffer {
+                    ty: BufferBindingType::Uniform,
+                    has_dynamic_offset: true,
+                    // TODO: change this to ViewUniform::std140_size_static once crevice fixes this!
+                    // Context: https://github.com/LPGhatguy/crevice/issues/29
+                    min_binding_size: BufferSize::new(4),
+                },
+                count: None,
+            }],
+            label: Some("ui_types_layout"),
+        });
+
+        let image_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor {
+            entries: &[
+                BindGroupLayoutEntry {
+                    binding: 0,
+                    visibility: ShaderStages::FRAGMENT,
+                    ty: BindingType::Texture {
+                        multisampled: false,
+                        sample_type: TextureSampleType::Float { filterable: false },
+                        view_dimension: TextureViewDimension::D2Array,
+                    },
+                    count: None,
+                },
+                BindGroupLayoutEntry {
+                    binding: 1,
+                    visibility: ShaderStages::FRAGMENT,
+                    ty: BindingType::Sampler {
+                        comparison: false,
+                        filtering: true,
+                    },
+                    count: None,
+                },
+            ],
+            label: Some("text_image_layout"),
+        });
+
+        let vertex_buffer_layout = VertexBufferLayout {
+            array_stride: 40,
+            step_mode: VertexStepMode::Vertex,
+            attributes: vec![
+                VertexAttribute {
+                    format: VertexFormat::Float32x3,
+                    offset: 0,
+                    shader_location: 0,
+                },
+                VertexAttribute {
+                    format: VertexFormat::Float32x4,
+                    offset: 12,
+                    shader_location: 1,
+                },
+                VertexAttribute {
+                    format: VertexFormat::Float32x3,
+                    offset: 28,
+                    shader_location: 2,
+                },
+            ],
+        };
+
+        let empty_font_texture = FontTextureCache::get_empty(&render_device, &image_layout);
+
+        let pipeline_desc = RenderPipelineDescriptor {
+            vertex: VertexState {
+                shader: UNIFIED_SHADER_HANDLE.typed::<Shader>(),
+                entry_point: "vertex".into(),
+                shader_defs: vec![],
+                buffers: vec![vertex_buffer_layout],
+            },
+            fragment: Some(FragmentState {
+                shader: UNIFIED_SHADER_HANDLE.typed::<Shader>(),
+                shader_defs: vec![],
+                entry_point: "fragment".into(),
+                targets: vec![ColorTargetState {
+                    format: TextureFormat::bevy_default(),
+                    blend: Some(BlendState {
+                        color: BlendComponent {
+                            src_factor: BlendFactor::SrcAlpha,
+                            dst_factor: BlendFactor::OneMinusSrcAlpha,
+                            operation: BlendOperation::Add,
+                        },
+                        alpha: BlendComponent {
+                            src_factor: BlendFactor::One,
+                            dst_factor: BlendFactor::One,
+                            operation: BlendOperation::Add,
+                        },
+                    }),
+                    write_mask: ColorWrites::ALL,
+                }],
+            }),
+            layout: Some(vec![
+                view_layout.clone(),
+                image_layout.clone(),
+                types_layout.clone(),
+            ]),
+            primitive: PrimitiveState {
+                front_face: FrontFace::Ccw,
+                cull_mode: None,
+                polygon_mode: PolygonMode::Fill,
+                clamp_depth: false,
+                conservative: false,
+                topology: PrimitiveTopology::TriangleList,
+                strip_index_format: None,
+            },
+            depth_stencil: None,
+            multisample: MultisampleState {
+                count: 1,
+                mask: !0,
+                alpha_to_coverage_enabled: false,
+            },
+            label: Some("quad_pipeline".into()),
+        };
+
+        UnifiedPipeline {
+            pipeline: pipeline_cache.queue(pipeline_desc),
+            view_layout,
+            image_layout,
+            empty_font_texture,
+            types_layout,
+        }
+    }
+}
+
+#[derive(Bundle)]
+pub struct ExtractQuadBundle {
+    pub(crate) extracted_quad: ExtractedQuad,
+}
+
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub enum UIQuadType {
+    Quad,
+    Text,
+}
+
+pub struct ExtractedQuad {
+    pub rect: Rect,
+    pub color: Color,
+    pub vertex_index: usize,
+    pub char_id: usize,
+    pub z_index: f32,
+    pub font_handle: Option<Handle<KayakFont>>,
+    pub quad_type: UIQuadType,
+    pub type_index: u32,
+}
+
+#[repr(C)]
+#[derive(Copy, Clone, Pod, Zeroable)]
+struct QuadVertex {
+    pub position: [f32; 3],
+    pub color: [f32; 4],
+    pub uv: [f32; 3],
+}
+
+#[repr(C)]
+#[derive(Copy, Clone, AsStd140)]
+struct QuadType {
+    pub t: i32,
+}
+
+pub struct QuadMeta {
+    vertices: BufferVec<QuadVertex>,
+    view_bind_group: Option<BindGroup>,
+    types_buffer: DynamicUniformVec<QuadType>,
+    types_bind_group: Option<BindGroup>,
+}
+
+impl Default for QuadMeta {
+    fn default() -> Self {
+        Self {
+            vertices: BufferVec::new(BufferUsages::VERTEX),
+            view_bind_group: None,
+            types_buffer: DynamicUniformVec::default(),
+            types_bind_group: None,
+        }
+    }
+}
+
+pub fn prepare_quads(
+    render_device: Res<RenderDevice>,
+    render_queue: Res<RenderQueue>,
+    mut sprite_meta: ResMut<QuadMeta>,
+    mut extracted_quads: Query<&mut ExtractedQuad>,
+) {
+    let extracted_sprite_len = extracted_quads.iter_mut().len();
+    // dont create buffers when there are no quads
+    if extracted_sprite_len == 0 {
+        return;
+    }
+
+    sprite_meta.types_buffer.clear();
+    sprite_meta.types_buffer.reserve(2, &render_device);
+    let quad_type_offset = sprite_meta.types_buffer.push(QuadType { t: 0 });
+    let text_type_offset = sprite_meta.types_buffer.push(QuadType { t: 1 });
+    sprite_meta
+        .types_buffer
+        .write_buffer(&render_device, &render_queue);
+
+    sprite_meta.vertices.clear();
+    sprite_meta.vertices.reserve(
+        extracted_sprite_len * QUAD_VERTEX_POSITIONS.len(),
+        &render_device,
+    );
+
+    for (i, mut extracted_sprite) in extracted_quads.iter_mut().enumerate() {
+        let sprite_rect = extracted_sprite.rect;
+        let color = extracted_sprite.color.as_linear_rgba_f32();
+
+        match extracted_sprite.quad_type {
+            UIQuadType::Quad => extracted_sprite.type_index = quad_type_offset,
+            UIQuadType::Text => extracted_sprite.type_index = text_type_offset,
+        };
+
+        let bottom_left = Vec3::new(0.0, 1.0, extracted_sprite.char_id as f32);
+        let top_left = Vec3::new(0.0, 0.0, extracted_sprite.char_id as f32);
+        let top_right = Vec3::new(1.0, 0.0, extracted_sprite.char_id as f32);
+        let bottom_right = Vec3::new(1.0, 1.0, extracted_sprite.char_id as f32);
+
+        let uvs: [[f32; 3]; 6] = [
+            bottom_left.into(),
+            top_right.into(),
+            top_left.into(),
+            bottom_left.into(),
+            bottom_right.into(),
+            top_right.into(),
+        ];
+
+        extracted_sprite.vertex_index = i;
+        for (index, vertex_position) in QUAD_VERTEX_POSITIONS.iter().enumerate() {
+            let world = Mat4::from_scale_rotation_translation(
+                sprite_rect.size().extend(1.0),
+                Quat::default(),
+                sprite_rect.min.extend(0.0),
+            );
+            let final_position = (world * Vec3::from(*vertex_position).extend(1.0)).truncate();
+            sprite_meta.vertices.push(QuadVertex {
+                position: final_position.into(),
+                color,
+                uv: uvs[index],
+            });
+        }
+    }
+    sprite_meta
+        .vertices
+        .write_buffer(&render_device, &render_queue);
+}
+
+pub fn queue_quads(
+    draw_functions: Res<DrawFunctions<TransparentUI>>,
+    render_device: Res<RenderDevice>,
+    mut sprite_meta: ResMut<QuadMeta>,
+    view_uniforms: Res<ViewUniforms>,
+    quad_pipeline: Res<UnifiedPipeline>,
+    mut extracted_sprites: Query<(Entity, &ExtractedQuad)>,
+    mut views: Query<&mut RenderPhase<TransparentUI>>,
+) {
+    if let Some(type_binding) = sprite_meta.types_buffer.binding() {
+        sprite_meta.types_bind_group =
+            Some(render_device.create_bind_group(&BindGroupDescriptor {
+                entries: &[BindGroupEntry {
+                    binding: 0,
+                    resource: type_binding,
+                }],
+                label: Some("quad_type_bind_group"),
+                layout: &quad_pipeline.types_layout,
+            }));
+    }
+
+    if let Some(view_binding) = view_uniforms.uniforms.binding() {
+        sprite_meta.view_bind_group = Some(render_device.create_bind_group(&BindGroupDescriptor {
+            entries: &[BindGroupEntry {
+                binding: 0,
+                resource: view_binding,
+            }],
+            label: Some("quad_view_bind_group"),
+            layout: &quad_pipeline.view_layout,
+        }));
+        let draw_quad = draw_functions.read().get_id::<DrawUI>().unwrap();
+        for mut transparent_phase in views.iter_mut() {
+            for (entity, quad) in extracted_sprites.iter_mut() {
+                transparent_phase.add(TransparentUI {
+                    draw_function: draw_quad,
+                    pipeline: quad_pipeline.pipeline,
+                    entity,
+                    sort_key: FloatOrd(quad.z_index),
+                });
+            }
+        }
+    }
+}
+
+pub struct DrawUI {
+    params: SystemState<(
+        SRes<QuadMeta>,
+        SRes<UnifiedPipeline>,
+        SRes<RenderPipelineCache>,
+        SRes<FontTextureCache>,
+        SQuery<Read<ViewUniformOffset>>,
+        SQuery<Read<ExtractedQuad>>,
+    )>,
+}
+
+impl DrawUI {
+    pub fn new(world: &mut World) -> Self {
+        Self {
+            params: SystemState::new(world),
+        }
+    }
+}
+
+impl Draw<TransparentUI> for DrawUI {
+    fn draw<'w>(
+        &mut self,
+        world: &'w World,
+        pass: &mut TrackedRenderPass<'w>,
+        view: Entity,
+        item: &TransparentUI,
+    ) {
+        let (quad_meta, unified_pipeline, pipelines, font_texture_cache, views, quads) =
+            self.params.get(world);
+        let view_uniform = views.get(view).unwrap();
+        let quad_meta = quad_meta.into_inner();
+        let extracted_quad = quads.get(item.entity).unwrap();
+        if let Some(pipeline) = pipelines.into_inner().get(item.pipeline) {
+            pass.set_render_pipeline(pipeline);
+            pass.set_vertex_buffer(0, quad_meta.vertices.buffer().unwrap().slice(..));
+            pass.set_bind_group(
+                0,
+                quad_meta.view_bind_group.as_ref().unwrap(),
+                &[view_uniform.offset],
+            );
+
+            pass.set_bind_group(
+                2,
+                quad_meta.types_bind_group.as_ref().unwrap(),
+                &[extracted_quad.type_index],
+            );
+
+            if let Some(font_handle) = extracted_quad.font_handle.as_ref() {
+                if let Some(image_bindings) =
+                    font_texture_cache.into_inner().bind_groups.get(font_handle)
+                {
+                    pass.set_bind_group(1, image_bindings, &[]);
+                } else {
+                    pass.set_bind_group(
+                        1,
+                        &unified_pipeline.into_inner().empty_font_texture.1,
+                        &[],
+                    );
+                }
+            } else {
+                pass.set_bind_group(1, &unified_pipeline.into_inner().empty_font_texture.1, &[]);
+            }
+
+            pass.draw(
+                (extracted_quad.vertex_index * QUAD_VERTEX_POSITIONS.len()) as u32
+                    ..((extracted_quad.vertex_index + 1) * QUAD_VERTEX_POSITIONS.len()) as u32,
+                0..1,
+            );
+        }
+    }
+}
diff --git a/bevy_kayak_ui/src/render/unified/quad/extract.rs b/bevy_kayak_ui/src/render/unified/quad/extract.rs
new file mode 100644
index 0000000..523ed83
--- /dev/null
+++ b/bevy_kayak_ui/src/render/unified/quad/extract.rs
@@ -0,0 +1,52 @@
+use bevy::{
+    math::Vec2,
+    prelude::{Commands, Res},
+    sprite2::Rect,
+};
+use kayak_core::render_primitive::RenderPrimitive;
+
+use crate::{
+    render::unified::pipeline::{ExtractQuadBundle, ExtractedQuad, UIQuadType},
+    to_bevy_color, BevyContext,
+};
+
+pub fn extract_quads(mut commands: Commands, context: Res<BevyContext>) {
+    let render_commands = if let Ok(context) = context.kayak_context.read() {
+        context.widget_manager.build_render_primitives()
+    } else {
+        vec![]
+    };
+
+    let quad_commands: Vec<&RenderPrimitive> = render_commands
+        .iter()
+        .filter(|command| matches!(command, RenderPrimitive::Quad { .. }))
+        .collect::<Vec<_>>();
+
+    let mut extracted_quads = Vec::new();
+    for render_primitive in quad_commands {
+        let (background_color, layout) = match render_primitive {
+            RenderPrimitive::Quad {
+                background_color,
+                layout,
+            } => (background_color, layout),
+            _ => panic!(""),
+        };
+
+        extracted_quads.push(ExtractQuadBundle {
+            extracted_quad: ExtractedQuad {
+                rect: Rect {
+                    min: Vec2::new(layout.posx, layout.posy),
+                    max: Vec2::new(layout.width, layout.height),
+                },
+                color: to_bevy_color(background_color),
+                vertex_index: 0,
+                char_id: 0,
+                z_index: layout.z_index,
+                font_handle: None,
+                quad_type: UIQuadType::Quad,
+                type_index: 0,
+            },
+        });
+    }
+    commands.spawn_batch(extracted_quads);
+}
diff --git a/bevy_kayak_ui/src/render/unified/quad/mod.rs b/bevy_kayak_ui/src/render/unified/quad/mod.rs
new file mode 100644
index 0000000..6d9ba65
--- /dev/null
+++ b/bevy_kayak_ui/src/render/unified/quad/mod.rs
@@ -0,0 +1,15 @@
+use bevy::{
+    prelude::Plugin,
+    render2::{RenderApp, RenderStage},
+};
+
+mod extract;
+
+pub struct QuadRendererPlugin;
+
+impl Plugin for QuadRendererPlugin {
+    fn build(&self, app: &mut bevy::prelude::App) {
+        let render_app = app.sub_app(RenderApp);
+        render_app.add_system_to_stage(RenderStage::Extract, extract::extract_quads);
+    }
+}
diff --git a/bevy_kayak_ui/src/render/unified/shader.wgsl b/bevy_kayak_ui/src/render/unified/shader.wgsl
new file mode 100644
index 0000000..0032221
--- /dev/null
+++ b/bevy_kayak_ui/src/render/unified/shader.wgsl
@@ -0,0 +1,56 @@
+[[block]]
+struct View {
+    view_proj: mat4x4<f32>;
+    world_position: vec3<f32>;
+};
+[[group(0), binding(0)]]
+var<uniform> view: View;
+
+[[block]]
+struct QuadType {
+    t: i32;
+};
+[[group(2), binding(0)]]
+var<uniform> quad_type: QuadType;
+
+
+struct VertexOutput {
+    [[builtin(position)]] position: vec4<f32>;
+    [[location(0)]] color: vec4<f32>;
+    [[location(1)]] uv: vec3<f32>;
+};
+
+[[stage(vertex)]]
+fn vertex(
+    [[location(0)]] vertex_position: vec3<f32>,
+    [[location(1)]] vertex_color: vec4<f32>,
+    [[location(2)]] vertex_uv: vec3<f32>,
+) -> VertexOutput {
+    var out: VertexOutput;
+    out.color = vertex_color;
+    out.position = view.view_proj * vec4<f32>(vertex_position, 1.0);
+    out.uv = vertex_uv;
+    return out;
+}
+
+[[group(1), binding(0)]]
+var sprite_texture: texture_2d_array<f32>;
+[[group(1), binding(1)]]
+var sprite_sampler: sampler;
+
+let RADIUS: f32 = 0.5;
+
+[[stage(fragment)]]
+fn fragment(in: VertexOutput) -> [[location(0)]] vec4<f32> {
+    if (quad_type.t == 1) {
+         var x = textureSample(sprite_texture, sprite_sampler, in.uv.xy, i32(in.uv.z)); 
+        var v = max(min(x.r, x.g), min(max(x.r, x.g), x.b));
+        var c = v; //remap(v);
+
+        var v2 = c / fwidth( c );
+        var a = v2 + RADIUS; //clamp( v2 + RADIUS, 0.0, 1.0 );
+
+        return vec4<f32>(in.color.rgb, a);
+    }
+    return in.color;
+}
\ No newline at end of file
diff --git a/cargo.toml b/cargo.toml
new file mode 100644
index 0000000..86833ba
--- /dev/null
+++ b/cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "kayak_ui"
+version = "0.1.0"
+edition = "2021"
+resolver = "2"
+
+[workspace]
+members = [
+    "kayak_components",
+    "kayak_core",
+    "kayak_render_macros",
+    "kayak_font",
+]
+
+[dependencies]
+kayak_components = { path = "kayak_components" }
+kayak_core = { path = "kayak_core" }
+
+[dev-dependencies]
+bevy = { git = "https://github.com/StarArawn/bevy", rev = "b26f563b13c267ffe1ee801bd71fd40b98a256e7" }
+bevy_kayak_ui = { path = "bevy_kayak_ui" }
diff --git a/examples/bevy.rs b/examples/bevy.rs
new file mode 100644
index 0000000..dedfde9
--- /dev/null
+++ b/examples/bevy.rs
@@ -0,0 +1,65 @@
+use bevy::{
+    math::Vec2,
+    prelude::{App as BevyApp, Commands, Res},
+    window::{WindowDescriptor, Windows},
+    PipelinedDefaultPlugins,
+};
+use bevy_kayak_ui::{BevyContext, BevyKayakUIPlugin, UICameraBundle};
+use kayak_components::Window;
+use kayak_core::Index;
+use kayak_ui::components::App;
+use kayak_ui::core::{rsx, widget};
+
+#[widget]
+fn TestState() {
+    let _new_x = {
+        let x = context.create_state(0.0f32).unwrap();
+        *x + 0.1
+    };
+    rsx! {
+        <>
+            <Window position={(50.0, 50.0)} size={(300.0, 300.0)} title={"Window 1".to_string()}>
+                {}
+            </Window>
+            <Window position={(550.0, 50.0)} size={(200.0, 200.0)} title={"Window 2".to_string()}>
+                {}
+            </Window>
+        </>
+    }
+}
+
+fn startup(mut commands: Commands, windows: Res<Windows>) {
+    commands.spawn_bundle(UICameraBundle::new());
+
+    let window_size = if let Some(window) = windows.get_primary() {
+        Vec2::new(window.width(), window.height())
+    } else {
+        panic!("Couldn't find primary window!");
+    };
+
+    let context = BevyContext::new(window_size.x, window_size.y, |styles, context| {
+        // Hack to trick the proc macro for right now..
+        let parent_id: Option<Index> = None;
+        rsx! {
+            <App styles={Some(styles.clone())}>
+                <TestState>{}</TestState>
+            </App>
+        }
+    });
+
+    commands.insert_resource(context);
+}
+
+fn main() {
+    BevyApp::new()
+        .insert_resource(WindowDescriptor {
+            width: 1270.0,
+            height: 720.0,
+            title: String::from("UI Example"),
+            ..Default::default()
+        })
+        .add_plugins(PipelinedDefaultPlugins)
+        .add_plugin(BevyKayakUIPlugin)
+        .add_startup_system(startup)
+        .run();
+}
diff --git a/kayak_components/.gitignore b/kayak_components/.gitignore
new file mode 100644
index 0000000..cdd43ad
--- /dev/null
+++ b/kayak_components/.gitignore
@@ -0,0 +1,7 @@
+target
+
+# These are backup files generated by rustfmt
+**/*.rs.bk
+
+# MSVC Windows builds of rustc generate these, which store debugging information
+*.pdb
\ No newline at end of file
diff --git a/kayak_components/Cargo.toml b/kayak_components/Cargo.toml
new file mode 100644
index 0000000..4f8fea6
--- /dev/null
+++ b/kayak_components/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "kayak_components"
+version = "0.1.0"
+edition = "2021"
+resolver = "2"
+
+[dependencies]
+kayak_core = { path = "../kayak_core", version = "0.1.0" }
diff --git a/kayak_components/src/app.rs b/kayak_components/src/app.rs
new file mode 100644
index 0000000..31167ba
--- /dev/null
+++ b/kayak_components/src/app.rs
@@ -0,0 +1,12 @@
+use kayak_core::{rsx, widget, Children};
+
+use kayak_core::derivative::*;
+
+#[widget]
+pub fn App(children: Children) {
+    rsx! {
+        <>
+            {children}
+        </>
+    }
+}
diff --git a/kayak_components/src/background.rs b/kayak_components/src/background.rs
new file mode 100644
index 0000000..bd1ad1f
--- /dev/null
+++ b/kayak_components/src/background.rs
@@ -0,0 +1,19 @@
+use kayak_core::{
+    render_command::RenderCommand,
+    rsx,
+    styles::{Style, StyleProp},
+    widget, Children, Fragment,
+};
+
+#[widget]
+pub fn Background(children: Children, styles: Option<Style>) {
+    if styles.is_none() {
+        *styles = Some(Style::default())
+    }
+    styles.as_mut().unwrap().render_command = StyleProp::Value(RenderCommand::Quad);
+    rsx! {
+        <Fragment>
+            {children}
+        </Fragment>
+    }
+}
diff --git a/kayak_components/src/clip.rs b/kayak_components/src/clip.rs
new file mode 100644
index 0000000..d5883f6
--- /dev/null
+++ b/kayak_components/src/clip.rs
@@ -0,0 +1,19 @@
+use kayak_core::{
+    render_command::RenderCommand,
+    rsx,
+    styles::{Style, StyleProp},
+    widget, Children,
+};
+
+#[widget]
+pub fn Clip(children: Children, styles: Option<Style>) {
+    if styles.is_none() {
+        *styles = Some(Style::default())
+    }
+    styles.as_mut().unwrap().render_command = StyleProp::Value(RenderCommand::Clip);
+    rsx! {
+        <>
+            {children}
+        </>
+    }
+}
diff --git a/kayak_components/src/element.rs b/kayak_components/src/element.rs
new file mode 100644
index 0000000..2972b94
--- /dev/null
+++ b/kayak_components/src/element.rs
@@ -0,0 +1,10 @@
+use kayak_core::{component, rsx, Render, Update};
+
+#[component]
+pub fn Element<Children: Render + Update + Clone>(children: Children) {
+    rsx! {
+        <>
+            {children}
+        </>
+    }
+}
diff --git a/kayak_components/src/lib.rs b/kayak_components/src/lib.rs
new file mode 100644
index 0000000..9e72b31
--- /dev/null
+++ b/kayak_components/src/lib.rs
@@ -0,0 +1,11 @@
+mod app;
+mod background;
+mod clip;
+mod text;
+mod window;
+
+pub use app::*;
+pub use background::*;
+pub use clip::*;
+pub use text::*;
+pub use window::*;
diff --git a/kayak_components/src/text.rs b/kayak_components/src/text.rs
new file mode 100644
index 0000000..8fd1a98
--- /dev/null
+++ b/kayak_components/src/text.rs
@@ -0,0 +1,24 @@
+use kayak_core::{
+    render_command::RenderCommand,
+    rsx,
+    styles::{Style, StyleProp},
+    widget,
+};
+
+#[widget]
+pub fn Text(size: f32, content: String, styles: Option<Style>) {
+    let render_command = RenderCommand::Text {
+        content: content.clone(),
+        size: *size,
+        font: 0, // TODO: Support font passing here. Perhaps move to style?
+    };
+    *styles = Some(Style {
+        render_command: StyleProp::Value(render_command),
+        ..styles.clone().unwrap_or_default()
+    });
+    rsx! {
+        <>
+            {}
+        </>
+    }
+}
diff --git a/kayak_components/src/window.rs b/kayak_components/src/window.rs
new file mode 100644
index 0000000..3abf6e4
--- /dev/null
+++ b/kayak_components/src/window.rs
@@ -0,0 +1,72 @@
+use kayak_core::{
+    color::Color,
+    render_command::RenderCommand,
+    rsx,
+    styles::{PositionType, Style, StyleProp, Units},
+    widget, Children, Fragment,
+};
+
+use crate::{Background, Clip, Text};
+
+#[widget]
+pub fn Window(
+    children: Children,
+    styles: Option<Style>,
+    position: (f32, f32),
+    size: (f32, f32),
+    title: String,
+) {
+    // let mut changed_styles = styles.clone().unwrap_or_default();
+    // changed_styles.render_command = RenderCommand::Quad;
+    // changed_styles.position_type = Some(PositionType::Absolute);
+    // changed_styles.background = Some(Color::new(0.0588, 0.0588, 0.588, 1.0));
+    // changed_styles.position = Some(Rect {
+    //     start: Dimension::Points(position.x),
+    //     end: Dimension::Points(position.x + size.width),
+    //     top: Dimension::Points(position.y),
+    //     bottom: Dimension::Points(position.y + size.height),
+    // });
+    // changed_styles.size = Some(Size {
+    //     width: Dimension::Points(size.width),
+    //     height: Dimension::Points(size.height),
+    // });
+    // styles = Some(changed_styles);
+
+    *styles = Some(Style {
+        background_color: StyleProp::Value(Color::new(0.125, 0.125, 0.125, 1.0)),
+        render_command: StyleProp::Value(RenderCommand::Quad),
+        position_type: StyleProp::Value(PositionType::SelfDirected),
+        left: StyleProp::Value(Units::Pixels(position.0)),
+        top: StyleProp::Value(Units::Pixels(position.1)),
+        width: StyleProp::Value(Units::Pixels(size.0)),
+        height: StyleProp::Value(Units::Pixels(size.1)),
+        ..styles.clone().unwrap_or_default()
+    });
+
+    let title_background_styles = Style {
+        background_color: StyleProp::Value(Color::new(0.0781, 0.0898, 0.101, 1.0)),
+        height: StyleProp::Value(Units::Pixels(24.0)),
+        ..Style::default()
+    };
+
+    let title_text_styles = Style {
+        position_type: StyleProp::Value(PositionType::SelfDirected),
+        top: StyleProp::Value(Units::Pixels(-22.0)),
+        left: StyleProp::Value(Units::Pixels(5.0)),
+        ..Style::default()
+    };
+
+    let title = title.clone();
+    rsx! {
+        <Fragment>
+            <Clip>
+                <Background styles={Some(title_background_styles)}>
+                    <Text styles={Some(title_text_styles)} size={14.0} content={title}>{}</Text>
+                </Background>
+            </Clip>
+            <Clip>
+                {children}
+            </Clip>
+        </Fragment>
+    }
+}
diff --git a/kayak_core/cargo.toml b/kayak_core/cargo.toml
new file mode 100644
index 0000000..1f1eb40
--- /dev/null
+++ b/kayak_core/cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "kayak_core"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+as-any = "0.2"
+diff-struct = "0.3"
+derivative = "2.2"
+fontdue = "0.6"
+
+kayak_render_macros = { path = "../kayak_render_macros" }
+morphorm = { git = "https://github.com/geom3trik/morphorm" }
+# dyn_partial_eq = "0.1"
+resources = "1.1"
diff --git a/kayak_core/examples/test3.rs b/kayak_core/examples/test3.rs
new file mode 100644
index 0000000..34079bc
--- /dev/null
+++ b/kayak_core/examples/test3.rs
@@ -0,0 +1,63 @@
+use kayak_core::color::Color;
+use kayak_core::context::KayakContext;
+use kayak_core::render_command::RenderCommand;
+use kayak_core::styles::{Style, StyleProp};
+use kayak_core::{rsx, widget, Children, Index};
+use morphorm::{PositionType, Units};
+
+#[widget]
+fn MyWidget(context: &mut KayakContext, children: Children) {
+    let number = *context.create_state::<u32>(0).unwrap();
+    let my_styles = Style {
+        render_command: StyleProp::Value(RenderCommand::Quad),
+        width: StyleProp::Value(Units::Pixels(300.0)),
+        height: StyleProp::Value(Units::Pixels(300.0)),
+        background_color: StyleProp::Value(Color::BLACK),
+        ..Style::default()
+    };
+    rsx! {
+        <MyWidget2 styles={Some(my_styles)} test={number}>
+            {children}
+        </MyWidget2>
+    }
+}
+
+#[widget]
+fn MyWidget2(test: u32, children: Children) {
+    dbg!(test);
+    rsx! {
+        <>
+            {children}
+        </>
+    }
+}
+
+fn main() {
+    let mut context = KayakContext::new();
+
+    let my_widget = MyWidget {
+        id: Index::default(),
+        children: None,
+        styles: Some(Style {
+            position_type: StyleProp::Value(PositionType::SelfDirected),
+            width: StyleProp::Value(Units::Pixels(1280.0)),
+            height: StyleProp::Value(Units::Pixels(720.0)),
+            ..Style::default()
+        }),
+    };
+
+    let (_, widget_id) = context.widget_manager.create_widget(0, my_widget, None);
+
+    let mut my_widget = context.widget_manager.take(widget_id);
+    my_widget.render(&mut context);
+    context.set_current_id(widget_id);
+    context.set_state::<u32>(1);
+    my_widget.render(&mut context);
+    context.widget_manager.repossess(my_widget);
+
+    context.widget_manager.render();
+
+    context.widget_manager.calculate_layout();
+
+    dbg!(context.widget_manager.build_render_primitives());
+}
diff --git a/kayak_core/src/color.rs b/kayak_core/src/color.rs
new file mode 100644
index 0000000..b71a107
--- /dev/null
+++ b/kayak_core/src/color.rs
@@ -0,0 +1,48 @@
+/// A color in the sRGB color space.
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub struct Color {
+    /// Red component, 0.0 - 1.0
+    pub r: f32,
+    /// Green component, 0.0 - 1.0
+    pub g: f32,
+    /// Blue component, 0.0 - 1.0
+    pub b: f32,
+    /// Transparency, 0.0 - 1.0
+    pub a: f32,
+}
+
+impl Default for Color {
+    fn default() -> Self {
+        Self::WHITE
+    }
+}
+
+impl Color {
+    /// The black color.
+    pub const BLACK: Color = Color {
+        r: 0.0,
+        g: 0.0,
+        b: 0.0,
+        a: 1.0,
+    };
+
+    /// The white color.
+    pub const WHITE: Color = Color {
+        r: 1.0,
+        g: 1.0,
+        b: 1.0,
+        a: 1.0,
+    };
+
+    /// A color with no opacity.
+    pub const TRANSPARENT: Color = Color {
+        r: 0.0,
+        g: 0.0,
+        b: 0.0,
+        a: 0.0,
+    };
+
+    pub fn new(r: f32, g: f32, b: f32, a: f32) -> Self {
+        Self { r, g, b, a }
+    }
+}
diff --git a/kayak_core/src/context.rs b/kayak_core/src/context.rs
new file mode 100644
index 0000000..74cd09b
--- /dev/null
+++ b/kayak_core/src/context.rs
@@ -0,0 +1,102 @@
+use std::collections::HashMap;
+
+use resources::Ref;
+
+use crate::widget_manager::WidgetManager;
+
+pub struct KayakContext {
+    component_states: HashMap<crate::Index, resources::Resources>,
+    current_id: crate::Index,
+    pub widget_manager: WidgetManager,
+}
+
+impl std::fmt::Debug for KayakContext {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("KayakContext")
+            .field("current_id", &self.current_id)
+            .finish()
+    }
+}
+
+impl KayakContext {
+    pub fn new() -> Self {
+        Self {
+            component_states: HashMap::new(),
+            current_id: crate::Index::default(),
+            widget_manager: WidgetManager::new(),
+        }
+    }
+
+    pub fn set_current_id(&mut self, id: crate::Index) {
+        self.current_id = id;
+    }
+
+    pub fn create_state<T: resources::Resource + Clone>(
+        &mut self,
+        initial_state: T,
+    ) -> Option<Ref<T>> {
+        if self.component_states.contains_key(&self.current_id) {
+            let states = self.component_states.get_mut(&self.current_id).unwrap();
+            if !states.contains::<T>() {
+                states.insert(initial_state);
+            }
+        } else {
+            let mut states = resources::Resources::default();
+            states.insert(initial_state);
+            self.component_states.insert(self.current_id, states);
+        }
+        return self.get_state();
+    }
+
+    fn get_state<T: resources::Resource + Clone>(&self) -> Option<Ref<T>> {
+        if self.component_states.contains_key(&self.current_id) {
+            let states = self.component_states.get(&self.current_id).unwrap();
+            if let Ok(state) = states.get::<T>() {
+                return Some(state);
+            }
+        }
+        return None;
+    }
+
+    pub fn set_state<T: resources::Resource + Clone>(&mut self, state: T) {
+        if self.component_states.contains_key(&self.current_id) {
+            let states = self.component_states.get(&self.current_id).unwrap();
+            if states.contains::<T>() {
+                let mut mutate_t = states.get_mut::<T>().unwrap();
+                self.widget_manager.dirty_nodes.push(self.current_id);
+                *mutate_t = state;
+            } else {
+                panic!(
+                    "No specific state created for component with id: {:?}!",
+                    self.current_id
+                );
+            }
+        } else {
+            panic!(
+                "No state created for component with id: {:?}!",
+                self.current_id
+            );
+        }
+    }
+
+    pub fn render(&mut self) {
+        let dirty_nodes = self.widget_manager.dirty_nodes.clone();
+        for node_index in dirty_nodes {
+            if self
+                .widget_manager
+                .dirty_nodes
+                .iter()
+                .any(|dirty_index| node_index == *dirty_index)
+            {
+                let mut widget = self.widget_manager.take(node_index);
+                widget.render(self);
+                self.widget_manager.repossess(widget);
+            }
+        }
+
+        self.widget_manager.dirty_nodes.clear();
+
+        self.widget_manager.render();
+        self.widget_manager.calculate_layout();
+    }
+}
diff --git a/kayak_core/src/fragment.rs b/kayak_core/src/fragment.rs
new file mode 100644
index 0000000..837a5e6
--- /dev/null
+++ b/kayak_core/src/fragment.rs
@@ -0,0 +1,33 @@
+use derivative::*;
+
+use crate::{context::KayakContext, styles::Style, Index, Widget};
+
+#[derive(Derivative)]
+#[derivative(Debug, PartialEq)]
+pub struct Fragment {
+    pub id: Index,
+    #[derivative(Debug = "ignore", PartialEq = "ignore")]
+    pub children: crate::Children,
+    pub styles: Option<Style>,
+}
+
+impl Widget for Fragment {
+    fn get_id(&self) -> Index {
+        self.id
+    }
+
+    fn set_id(&mut self, id: Index) {
+        self.id = id;
+    }
+
+    fn get_styles(&self) -> Option<Style> {
+        self.styles.clone()
+    }
+
+    fn render(&mut self, context: &mut KayakContext) {
+        dbg!("Rendering fragment children!");
+        if let Some(children) = self.children.as_ref() {
+            children(Some(self.get_id()), context);
+        }
+    }
+}
diff --git a/kayak_core/src/generational_arena.rs b/kayak_core/src/generational_arena.rs
new file mode 100644
index 0000000..e363ea5
--- /dev/null
+++ b/kayak_core/src/generational_arena.rs
@@ -0,0 +1,1326 @@
+/*!
+[![](https://docs.rs/generational-arena/badge.svg)](https://docs.rs/generational-arena/)
+[![](https://img.shields.io/crates/v/generational-arena.svg)](https://crates.io/crates/generational-arena)
+[![](https://img.shields.io/crates/d/generational-arena.svg)](https://crates.io/crates/generational-arena)
+[![Travis CI Build Status](https://travis-ci.org/fitzgen/generational-arena.svg?branch=master)](https://travis-ci.org/fitzgen/generational-arena)
+A safe arena allocator that allows deletion without suffering from [the ABA
+problem](https://en.wikipedia.org/wiki/ABA_problem) by using generational
+indices.
+Inspired by [Catherine West's closing keynote at RustConf
+2018](https://www.youtube.com/watch?v=aKLntZcp27M), where these ideas (and many
+more!) were presented in the context of an Entity-Component-System for games
+programming.
+## What? Why?
+Imagine you are working with a graph and you want to add and delete individual
+nodes at a time, or you are writing a game and its world consists of many
+inter-referencing objects with dynamic lifetimes that depend on user
+input. These are situations where matching Rust's ownership and lifetime rules
+can get tricky.
+It doesn't make sense to use shared ownership with interior mutability (i.e.
+`Rc<RefCell<T>>` or `Arc<Mutex<T>>`) nor borrowed references (ie `&'a T` or `&'a
+mut T`) for structures. The cycles rule out reference counted types, and the
+required shared mutability rules out borrows. Furthermore, lifetimes are dynamic
+and don't follow the borrowed-data-outlives-the-borrower discipline.
+In these situations, it is tempting to store objects in a `Vec<T>` and have them
+reference each other via their indices. No more borrow checker or ownership
+problems! Often, this solution is good enough.
+However, now we can't delete individual items from that `Vec<T>` when we no
+longer need them, because we end up either
+* messing up the indices of every element that follows the deleted one, or
+* suffering from the [ABA
+  problem](https://en.wikipedia.org/wiki/ABA_problem). To elaborate further, if
+  we tried to replace the `Vec<T>` with a `Vec<Option<T>>`, and delete an
+  element by setting it to `None`, then we create the possibility for this buggy
+  sequence:
+    * `obj1` references `obj2` at index `i`
+    * someone else deletes `obj2` from index `i`, setting that element to `None`
+    * a third thing allocates `obj3`, which ends up at index `i`, because the
+      element at that index is `None` and therefore available for allocation
+    * `obj1` attempts to get `obj2` at index `i`, but incorrectly is given
+      `obj3`, when instead the get should fail.
+By introducing a monotonically increasing generation counter to the collection,
+associating each element in the collection with the generation when it was
+inserted, and getting elements from the collection with the *pair* of index and
+the generation at the time when the element was inserted, then we can solve the
+aforementioned ABA problem. When indexing into the collection, if the index
+pair's generation does not match the generation of the element at that index,
+then the operation fails.
+## Features
+* Zero `unsafe`
+* Well tested, including quickchecks
+* `no_std` compatibility
+* All the trait implementations you expect: `IntoIterator`, `FromIterator`,
+  `Extend`, etc...
+## Usage
+First, add `generational-arena` to your `Cargo.toml`:
+```toml
+[dependencies]
+generational-arena = "0.2"
+```
+Then, import the crate and use the
+[`generational_arena::Arena`](./struct.Arena.html) type!
+```rust
+extern crate generational_arena;
+use generational_arena::Arena;
+let mut arena = Arena::new();
+// Insert some elements into the arena.
+let rza = arena.insert("Robert Fitzgerald Diggs");
+let gza = arena.insert("Gary Grice");
+let bill = arena.insert("Bill Gates");
+// Inserted elements can be accessed infallibly via indexing (and missing
+// entries will panic).
+assert_eq!(arena[rza], "Robert Fitzgerald Diggs");
+// Alternatively, the `get` and `get_mut` methods provide fallible lookup.
+if let Some(genius) = arena.get(gza) {
+    println!("The gza gza genius: {}", genius);
+}
+if let Some(val) = arena.get_mut(bill) {
+    *val = "Bill Gates doesn't belong in this set...";
+}
+// We can remove elements.
+arena.remove(bill);
+// Insert a new one.
+let murray = arena.insert("Bill Murray");
+// The arena does not contain `bill` anymore, but it does contain `murray`, even
+// though they are almost certainly at the same index within the arena in
+// practice. Ambiguities are resolved with an associated generation tag.
+assert!(!arena.contains(bill));
+assert!(arena.contains(murray));
+// Iterate over everything inside the arena.
+for (idx, value) in &arena {
+    println!("{:?} is at {:?}", value, idx);
+}
+```
+## `no_std`
+To enable `no_std` compatibility, disable the on-by-default "std" feature.
+```toml
+[dependencies]
+generational-arena = { version = "0.2", default-features = false }
+```
+### Serialization and Deserialization with [`serde`](https://crates.io/crates/serde)
+To enable serialization/deserialization support, enable the "serde" feature.
+```toml
+[dependencies]
+generational-arena = { version = "0.2", features = ["serde"] }
+```
+ */
+
+#![forbid(unsafe_code, missing_docs, missing_debug_implementations)]
+
+use std::vec::{self, Vec};
+
+use core::cmp;
+use core::iter::{self, Extend, FromIterator, FusedIterator};
+use core::mem;
+use core::ops;
+use core::slice;
+
+#[cfg(feature = "serde")]
+mod serde_impl;
+
+/// The `Arena` allows inserting and removing elements that are referred to by
+/// `Index`.
+///
+/// [See the module-level documentation for example usage and motivation.](./index.html)
+#[derive(Clone, Debug)]
+pub struct Arena<T> {
+    items: Vec<Entry<T>>,
+    generation: u64,
+    free_list_head: Option<usize>,
+    len: usize,
+}
+
+#[derive(Clone, Debug)]
+enum Entry<T> {
+    Free { next_free: Option<usize> },
+    Occupied { generation: u64, value: T },
+}
+
+/// An index (and generation) into an `Arena`.
+///
+/// To get an `Index`, insert an element into an `Arena`, and the `Index` for
+/// that element will be returned.
+///
+/// # Examples
+///
+/// ```
+/// use generational_arena::Arena;
+///
+/// let mut arena = Arena::new();
+/// let idx = arena.insert(123);
+/// assert_eq!(arena[idx], 123);
+/// ```
+#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct Index {
+    index: usize,
+    generation: u64,
+}
+
+impl Index {
+    /// Create a new `Index` from its raw parts.
+    ///
+    /// The parts must have been returned from an earlier call to
+    /// `into_raw_parts`.
+    ///
+    /// Providing arbitrary values will lead to malformed indices and ultimately
+    /// panics.
+    pub fn from_raw_parts(a: usize, b: u64) -> Index {
+        Index {
+            index: a,
+            generation: b,
+        }
+    }
+
+    /// Convert this `Index` into its raw parts.
+    ///
+    /// This niche method is useful for converting an `Index` into another
+    /// identifier type. Usually, you should prefer a newtype wrapper around
+    /// `Index` like `pub struct MyIdentifier(Index);`.  However, for external
+    /// types whose definition you can't customize, but which you can construct
+    /// instances of, this method can be useful.
+    pub fn into_raw_parts(self) -> (usize, u64) {
+        (self.index, self.generation)
+    }
+}
+
+const DEFAULT_CAPACITY: usize = 4;
+
+impl<T> Default for Arena<T> {
+    fn default() -> Arena<T> {
+        Arena::new()
+    }
+}
+
+impl<T> Arena<T> {
+    /// Constructs a new, empty `Arena`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::<usize>::new();
+    /// # let _ = arena;
+    /// ```
+    pub fn new() -> Arena<T> {
+        Arena::with_capacity(DEFAULT_CAPACITY)
+    }
+
+    /// Constructs a new, empty `Arena<T>` with the specified capacity.
+    ///
+    /// The `Arena<T>` will be able to hold `n` elements without further allocation.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::with_capacity(10);
+    ///
+    /// // These insertions will not require further allocation.
+    /// for i in 0..10 {
+    ///     assert!(arena.try_insert(i).is_ok());
+    /// }
+    ///
+    /// // But now we are at capacity, and there is no more room.
+    /// assert!(arena.try_insert(99).is_err());
+    /// ```
+    pub fn with_capacity(n: usize) -> Arena<T> {
+        let n = cmp::max(n, 1);
+        let mut arena = Arena {
+            items: Vec::new(),
+            generation: 0,
+            free_list_head: None,
+            len: 0,
+        };
+        arena.reserve(n);
+        arena
+    }
+
+    /// Clear all the items inside the arena, but keep its allocation.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::with_capacity(1);
+    /// arena.insert(42);
+    /// arena.insert(43);
+    ///
+    /// arena.clear();
+    ///
+    /// assert_eq!(arena.capacity(), 2);
+    /// ```
+    pub fn clear(&mut self) {
+        self.items.clear();
+
+        let end = self.items.capacity();
+        self.items.extend((0..end).map(|i| {
+            if i == end - 1 {
+                Entry::Free { next_free: None }
+            } else {
+                Entry::Free {
+                    next_free: Some(i + 1),
+                }
+            }
+        }));
+        if !self.is_empty() {
+            // Increment generation, but if there are no elements, do nothing to
+            // avoid unnecessary incrementing generation.
+            self.generation += 1;
+        }
+        self.free_list_head = Some(0);
+        self.len = 0;
+    }
+
+    /// Attempts to insert `value` into the arena using existing capacity.
+    ///
+    /// This method will never allocate new capacity in the arena.
+    ///
+    /// If insertion succeeds, then the `value`'s index is returned. If
+    /// insertion fails, then `Err(value)` is returned to give ownership of
+    /// `value` back to the caller.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::new();
+    ///
+    /// match arena.try_insert(42) {
+    ///     Ok(idx) => {
+    ///         // Insertion succeeded.
+    ///         assert_eq!(arena[idx], 42);
+    ///     }
+    ///     Err(x) => {
+    ///         // Insertion failed.
+    ///         assert_eq!(x, 42);
+    ///     }
+    /// };
+    /// ```
+    #[inline]
+    pub fn try_insert(&mut self, value: T) -> Result<Index, T> {
+        match self.try_alloc_next_index() {
+            None => Err(value),
+            Some(index) => {
+                self.items[index.index] = Entry::Occupied {
+                    generation: self.generation,
+                    value,
+                };
+                Ok(index)
+            }
+        }
+    }
+
+    /// Attempts to insert the value returned by `create` into the arena using existing capacity.
+    /// `create` is called with the new value's associated index, allowing values that know their own index.
+    ///
+    /// This method will never allocate new capacity in the arena.
+    ///
+    /// If insertion succeeds, then the new index is returned. If
+    /// insertion fails, then `Err(create)` is returned to give ownership of
+    /// `create` back to the caller.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::{Arena, Index};
+    ///
+    /// let mut arena = Arena::new();
+    ///
+    /// match arena.try_insert_with(|idx| (42, idx)) {
+    ///     Ok(idx) => {
+    ///         // Insertion succeeded.
+    ///         assert_eq!(arena[idx].0, 42);
+    ///         assert_eq!(arena[idx].1, idx);
+    ///     }
+    ///     Err(x) => {
+    ///         // Insertion failed.
+    ///     }
+    /// };
+    /// ```
+    #[inline]
+    pub fn try_insert_with<F: FnOnce(Index) -> T>(&mut self, create: F) -> Result<Index, F> {
+        match self.try_alloc_next_index() {
+            None => Err(create),
+            Some(index) => {
+                self.items[index.index] = Entry::Occupied {
+                    generation: self.generation,
+                    value: create(index),
+                };
+                Ok(index)
+            }
+        }
+    }
+
+    #[inline]
+    fn try_alloc_next_index(&mut self) -> Option<Index> {
+        match self.free_list_head {
+            None => None,
+            Some(i) => match self.items[i] {
+                Entry::Occupied { .. } => panic!("corrupt free list"),
+                Entry::Free { next_free } => {
+                    self.free_list_head = next_free;
+                    self.len += 1;
+                    Some(Index {
+                        index: i,
+                        generation: self.generation,
+                    })
+                }
+            },
+        }
+    }
+
+    /// Insert `value` into the arena, allocating more capacity if necessary.
+    ///
+    /// The `value`'s associated index in the arena is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::new();
+    ///
+    /// let idx = arena.insert(42);
+    /// assert_eq!(arena[idx], 42);
+    /// ```
+    #[inline]
+    pub fn insert(&mut self, value: T) -> Index {
+        match self.try_insert(value) {
+            Ok(i) => i,
+            Err(value) => self.insert_slow_path(value),
+        }
+    }
+
+    /// Insert the value returned by `create` into the arena, allocating more capacity if necessary.
+    /// `create` is called with the new value's associated index, allowing values that know their own index.
+    ///
+    /// The new value's associated index in the arena is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::{Arena, Index};
+    ///
+    /// let mut arena = Arena::new();
+    ///
+    /// let idx = arena.insert_with(|idx| (42, idx));
+    /// assert_eq!(arena[idx].0, 42);
+    /// assert_eq!(arena[idx].1, idx);
+    /// ```
+    #[inline]
+    pub fn insert_with(&mut self, create: impl FnOnce(Index) -> T) -> Index {
+        match self.try_insert_with(create) {
+            Ok(i) => i,
+            Err(create) => self.insert_with_slow_path(create),
+        }
+    }
+
+    #[inline(never)]
+    fn insert_slow_path(&mut self, value: T) -> Index {
+        let len = if self.capacity() == 0 {
+            // `drain()` sets the capacity to 0 and if the capacity is 0, the
+            // next `try_insert() `will refer to an out-of-range index because
+            // the next `reserve()` does not add element, resulting in a panic.
+            // So ensure that `self` have at least 1 capacity here.
+            //
+            // Ideally, this problem should be handled within `drain()`,but
+            // this problem cannot be handled within `drain()` because `drain()`
+            // returns an iterator that borrows `self` mutably.
+            1
+        } else {
+            self.items.len()
+        };
+        self.reserve(len);
+        self.try_insert(value)
+            .map_err(|_| ())
+            .expect("inserting will always succeed after reserving additional space")
+    }
+
+    #[inline(never)]
+    fn insert_with_slow_path(&mut self, create: impl FnOnce(Index) -> T) -> Index {
+        let len = self.items.len();
+        self.reserve(len);
+        self.try_insert_with(create)
+            .map_err(|_| ())
+            .expect("inserting will always succeed after reserving additional space")
+    }
+
+    /// Remove the element at index `i` from the arena.
+    ///
+    /// If the element at index `i` is still in the arena, then it is
+    /// returned. If it is not in the arena, then `None` is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::new();
+    /// let idx = arena.insert(42);
+    ///
+    /// assert_eq!(arena.remove(idx), Some(42));
+    /// assert_eq!(arena.remove(idx), None);
+    /// ```
+    pub fn remove(&mut self, i: Index) -> Option<T> {
+        if i.index >= self.items.len() {
+            return None;
+        }
+
+        match self.items[i.index] {
+            Entry::Occupied { generation, .. } if i.generation == generation => {
+                let entry = mem::replace(
+                    &mut self.items[i.index],
+                    Entry::Free {
+                        next_free: self.free_list_head,
+                    },
+                );
+                self.generation += 1;
+                self.free_list_head = Some(i.index);
+                self.len -= 1;
+
+                match entry {
+                    Entry::Occupied {
+                        generation: _,
+                        value,
+                    } => Some(value),
+                    _ => unreachable!(),
+                }
+            }
+            _ => None,
+        }
+    }
+
+    /// Retains only the elements specified by the predicate.
+    ///
+    /// In other words, remove all indices such that `predicate(index, &value)` returns `false`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut crew = Arena::new();
+    /// crew.extend(&["Jim Hawkins", "John Silver", "Alexander Smollett", "Israel Hands"]);
+    /// let pirates = ["John Silver", "Israel Hands"]; // too dangerous to keep them around
+    /// crew.retain(|_index, member| !pirates.contains(member));
+    /// let mut crew_members = crew.iter().map(|(_, member)| **member);
+    /// assert_eq!(crew_members.next(), Some("Jim Hawkins"));
+    /// assert_eq!(crew_members.next(), Some("Alexander Smollett"));
+    /// assert!(crew_members.next().is_none());
+    /// ```
+    pub fn retain(&mut self, mut predicate: impl FnMut(Index, &mut T) -> bool) {
+        for i in 0..self.capacity() {
+            let remove = match &mut self.items[i] {
+                Entry::Occupied { generation, value } => {
+                    let index = Index {
+                        index: i,
+                        generation: *generation,
+                    };
+                    if predicate(index, value) {
+                        None
+                    } else {
+                        Some(index)
+                    }
+                }
+
+                _ => None,
+            };
+            if let Some(index) = remove {
+                self.remove(index);
+            }
+        }
+    }
+
+    /// Is the element at index `i` in the arena?
+    ///
+    /// Returns `true` if the element at `i` is in the arena, `false` otherwise.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::new();
+    /// let idx = arena.insert(42);
+    ///
+    /// assert!(arena.contains(idx));
+    /// arena.remove(idx);
+    /// assert!(!arena.contains(idx));
+    /// ```
+    pub fn contains(&self, i: Index) -> bool {
+        self.get(i).is_some()
+    }
+
+    /// Get a shared reference to the element at index `i` if it is in the
+    /// arena.
+    ///
+    /// If the element at index `i` is not in the arena, then `None` is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::new();
+    /// let idx = arena.insert(42);
+    ///
+    /// assert_eq!(arena.get(idx), Some(&42));
+    /// arena.remove(idx);
+    /// assert!(arena.get(idx).is_none());
+    /// ```
+    pub fn get(&self, i: Index) -> Option<&T> {
+        match self.items.get(i.index) {
+            Some(Entry::Occupied { generation, value }) if *generation == i.generation => {
+                Some(value)
+            }
+            _ => None,
+        }
+    }
+
+    /// Get an exclusive reference to the element at index `i` if it is in the
+    /// arena.
+    ///
+    /// If the element at index `i` is not in the arena, then `None` is returned.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::new();
+    /// let idx = arena.insert(42);
+    ///
+    /// *arena.get_mut(idx).unwrap() += 1;
+    /// assert_eq!(arena.remove(idx), Some(43));
+    /// assert!(arena.get_mut(idx).is_none());
+    /// ```
+    pub fn get_mut(&mut self, i: Index) -> Option<&mut T> {
+        match self.items.get_mut(i.index) {
+            Some(Entry::Occupied { generation, value }) if *generation == i.generation => {
+                Some(value)
+            }
+            _ => None,
+        }
+    }
+
+    /// Get a pair of exclusive references to the elements at index `i1` and `i2` if it is in the
+    /// arena.
+    ///
+    /// If the element at index `i1` or `i2` is not in the arena, then `None` is returned for this
+    /// element.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `i1` and `i2` are pointing to the same item of the arena.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::new();
+    /// let idx1 = arena.insert(0);
+    /// let idx2 = arena.insert(1);
+    ///
+    /// {
+    ///     let (item1, item2) = arena.get2_mut(idx1, idx2);
+    ///
+    ///     *item1.unwrap() = 3;
+    ///     *item2.unwrap() = 4;
+    /// }
+    ///
+    /// assert_eq!(arena[idx1], 3);
+    /// assert_eq!(arena[idx2], 4);
+    /// ```
+    pub fn get2_mut(&mut self, i1: Index, i2: Index) -> (Option<&mut T>, Option<&mut T>) {
+        let len = self.items.len();
+
+        if i1.index == i2.index {
+            assert!(i1.generation != i2.generation);
+
+            if i1.generation > i2.generation {
+                return (self.get_mut(i1), None);
+            }
+            return (None, self.get_mut(i2));
+        }
+
+        if i1.index >= len {
+            return (None, self.get_mut(i2));
+        } else if i2.index >= len {
+            return (self.get_mut(i1), None);
+        }
+
+        let (raw_item1, raw_item2) = {
+            let (xs, ys) = self.items.split_at_mut(cmp::max(i1.index, i2.index));
+            if i1.index < i2.index {
+                (&mut xs[i1.index], &mut ys[0])
+            } else {
+                (&mut ys[0], &mut xs[i2.index])
+            }
+        };
+
+        let item1 = match raw_item1 {
+            Entry::Occupied { generation, value } if *generation == i1.generation => Some(value),
+            _ => None,
+        };
+
+        let item2 = match raw_item2 {
+            Entry::Occupied { generation, value } if *generation == i2.generation => Some(value),
+            _ => None,
+        };
+
+        (item1, item2)
+    }
+
+    /// Get the length of this arena.
+    ///
+    /// The length is the number of elements the arena holds.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::new();
+    /// assert_eq!(arena.len(), 0);
+    ///
+    /// let idx = arena.insert(42);
+    /// assert_eq!(arena.len(), 1);
+    ///
+    /// let _ = arena.insert(0);
+    /// assert_eq!(arena.len(), 2);
+    ///
+    /// assert_eq!(arena.remove(idx), Some(42));
+    /// assert_eq!(arena.len(), 1);
+    /// ```
+    pub fn len(&self) -> usize {
+        self.len
+    }
+
+    /// Returns true if the arena contains no elements
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::new();
+    /// assert!(arena.is_empty());
+    ///
+    /// let idx = arena.insert(42);
+    /// assert!(!arena.is_empty());
+    ///
+    /// assert_eq!(arena.remove(idx), Some(42));
+    /// assert!(arena.is_empty());
+    /// ```
+    pub fn is_empty(&self) -> bool {
+        self.len == 0
+    }
+
+    /// Get the capacity of this arena.
+    ///
+    /// The capacity is the maximum number of elements the arena can hold
+    /// without further allocation, including however many it currently
+    /// contains.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::with_capacity(10);
+    /// assert_eq!(arena.capacity(), 10);
+    ///
+    /// // `try_insert` does not allocate new capacity.
+    /// for i in 0..10 {
+    ///     assert!(arena.try_insert(1).is_ok());
+    ///     assert_eq!(arena.capacity(), 10);
+    /// }
+    ///
+    /// // But `insert` will if the arena is already at capacity.
+    /// arena.insert(0);
+    /// assert!(arena.capacity() > 10);
+    /// ```
+    pub fn capacity(&self) -> usize {
+        self.items.len()
+    }
+
+    /// Allocate space for `additional_capacity` more elements in the arena.
+    ///
+    /// # Panics
+    ///
+    /// Panics if this causes the capacity to overflow.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::with_capacity(10);
+    /// arena.reserve(5);
+    /// assert_eq!(arena.capacity(), 15);
+    /// # let _: Arena<usize> = arena;
+    /// ```
+    pub fn reserve(&mut self, additional_capacity: usize) {
+        let start = self.items.len();
+        let end = self.items.len() + additional_capacity;
+        let old_head = self.free_list_head;
+        self.items.reserve_exact(additional_capacity);
+        self.items.extend((start..end).map(|i| {
+            if i == end - 1 {
+                Entry::Free {
+                    next_free: old_head,
+                }
+            } else {
+                Entry::Free {
+                    next_free: Some(i + 1),
+                }
+            }
+        }));
+        self.free_list_head = Some(start);
+    }
+
+    /// Iterate over shared references to the elements in this arena.
+    ///
+    /// Yields pairs of `(Index, &T)` items.
+    ///
+    /// Order of iteration is not defined.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::new();
+    /// for i in 0..10 {
+    ///     arena.insert(i * i);
+    /// }
+    ///
+    /// for (idx, value) in arena.iter() {
+    ///     println!("{} is at index {:?}", value, idx);
+    /// }
+    /// ```
+    pub fn iter(&self) -> Iter<T> {
+        Iter {
+            len: self.len,
+            inner: self.items.iter().enumerate(),
+        }
+    }
+
+    /// Iterate over exclusive references to the elements in this arena.
+    ///
+    /// Yields pairs of `(Index, &mut T)` items.
+    ///
+    /// Order of iteration is not defined.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::new();
+    /// for i in 0..10 {
+    ///     arena.insert(i * i);
+    /// }
+    ///
+    /// for (_idx, value) in arena.iter_mut() {
+    ///     *value += 5;
+    /// }
+    /// ```
+    pub fn iter_mut(&mut self) -> IterMut<T> {
+        IterMut {
+            len: self.len,
+            inner: self.items.iter_mut().enumerate(),
+        }
+    }
+
+    /// Iterate over elements of the arena and remove them.
+    ///
+    /// Yields pairs of `(Index, T)` items.
+    ///
+    /// Order of iteration is not defined.
+    ///
+    /// Note: All elements are removed even if the iterator is only partially consumed or not consumed at all.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use generational_arena::Arena;
+    ///
+    /// let mut arena = Arena::new();
+    /// let idx_1 = arena.insert("hello");
+    /// let idx_2 = arena.insert("world");
+    ///
+    /// assert!(arena.get(idx_1).is_some());
+    /// assert!(arena.get(idx_2).is_some());
+    /// for (idx, value) in arena.drain() {
+    ///     assert!((idx == idx_1 && value == "hello") || (idx == idx_2 && value == "world"));
+    /// }
+    /// assert!(arena.get(idx_1).is_none());
+    /// assert!(arena.get(idx_2).is_none());
+    /// ```
+    pub fn drain(&mut self) -> Drain<T> {
+        let old_len = self.len;
+        if !self.is_empty() {
+            // Increment generation, but if there are no elements, do nothing to
+            // avoid unnecessary incrementing generation.
+            self.generation += 1;
+        }
+        self.free_list_head = None;
+        self.len = 0;
+        Drain {
+            len: old_len,
+            inner: self.items.drain(..).enumerate(),
+        }
+    }
+
+    /// Given an i of `usize` without a generation, get a shared reference
+    /// to the element and the matching `Index` of the entry behind `i`.
+    ///
+    /// This method is useful when you know there might be an element at the
+    /// position i, but don't know its generation or precise Index.
+    ///
+    /// Use cases include using indexing such as Hierarchical BitMap Indexing or
+    /// other kinds of bit-efficient indexing.
+    ///
+    /// You should use the `get` method instead most of the time.
+    pub fn get_unknown_gen(&self, i: usize) -> Option<(&T, Index)> {
+        match self.items.get(i) {
+            Some(Entry::Occupied { generation, value }) => Some((
+                value,
+                Index {
+                    generation: *generation,
+                    index: i,
+                },
+            )),
+            _ => None,
+        }
+    }
+
+    /// Given an i of `usize` without a generation, get an exclusive reference
+    /// to the element and the matching `Index` of the entry behind `i`.
+    ///
+    /// This method is useful when you know there might be an element at the
+    /// position i, but don't know its generation or precise Index.
+    ///
+    /// Use cases include using indexing such as Hierarchical BitMap Indexing or
+    /// other kinds of bit-efficient indexing.
+    ///
+    /// You should use the `get_mut` method instead most of the time.
+    pub fn get_unknown_gen_mut(&mut self, i: usize) -> Option<(&mut T, Index)> {
+        match self.items.get_mut(i) {
+            Some(Entry::Occupied { generation, value }) => Some((
+                value,
+                Index {
+                    generation: *generation,
+                    index: i,
+                },
+            )),
+            _ => None,
+        }
+    }
+}
+
+impl<T> IntoIterator for Arena<T> {
+    type Item = T;
+    type IntoIter = IntoIter<T>;
+    fn into_iter(self) -> Self::IntoIter {
+        IntoIter {
+            len: self.len,
+            inner: self.items.into_iter(),
+        }
+    }
+}
+
+/// An iterator over the elements in an arena.
+///
+/// Yields `T` items.
+///
+/// Order of iteration is not defined.
+///
+/// # Examples
+///
+/// ```
+/// use generational_arena::Arena;
+///
+/// let mut arena = Arena::new();
+/// for i in 0..10 {
+///     arena.insert(i * i);
+/// }
+///
+/// for value in arena {
+///     assert!(value < 100);
+/// }
+/// ```
+#[derive(Clone, Debug)]
+pub struct IntoIter<T> {
+    len: usize,
+    inner: vec::IntoIter<Entry<T>>,
+}
+
+impl<T> Iterator for IntoIter<T> {
+    type Item = T;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        loop {
+            match self.inner.next() {
+                Some(Entry::Free { .. }) => continue,
+                Some(Entry::Occupied { value, .. }) => {
+                    self.len -= 1;
+                    return Some(value);
+                }
+                None => {
+                    debug_assert_eq!(self.len, 0);
+                    return None;
+                }
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.len, Some(self.len))
+    }
+}
+
+impl<T> DoubleEndedIterator for IntoIter<T> {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        loop {
+            match self.inner.next_back() {
+                Some(Entry::Free { .. }) => continue,
+                Some(Entry::Occupied { value, .. }) => {
+                    self.len -= 1;
+                    return Some(value);
+                }
+                None => {
+                    debug_assert_eq!(self.len, 0);
+                    return None;
+                }
+            }
+        }
+    }
+}
+
+impl<T> ExactSizeIterator for IntoIter<T> {
+    fn len(&self) -> usize {
+        self.len
+    }
+}
+
+impl<T> FusedIterator for IntoIter<T> {}
+
+impl<'a, T> IntoIterator for &'a Arena<T> {
+    type Item = (Index, &'a T);
+    type IntoIter = Iter<'a, T>;
+    fn into_iter(self) -> Self::IntoIter {
+        self.iter()
+    }
+}
+
+/// An iterator over shared references to the elements in an arena.
+///
+/// Yields pairs of `(Index, &T)` items.
+///
+/// Order of iteration is not defined.
+///
+/// # Examples
+///
+/// ```
+/// use generational_arena::Arena;
+///
+/// let mut arena = Arena::new();
+/// for i in 0..10 {
+///     arena.insert(i * i);
+/// }
+///
+/// for (idx, value) in &arena {
+///     println!("{} is at index {:?}", value, idx);
+/// }
+/// ```
+#[derive(Clone, Debug)]
+pub struct Iter<'a, T: 'a> {
+    len: usize,
+    inner: iter::Enumerate<slice::Iter<'a, Entry<T>>>,
+}
+
+impl<'a, T> Iterator for Iter<'a, T> {
+    type Item = (Index, &'a T);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        loop {
+            match self.inner.next() {
+                Some((_, &Entry::Free { .. })) => continue,
+                Some((
+                    index,
+                    &Entry::Occupied {
+                        generation,
+                        ref value,
+                    },
+                )) => {
+                    self.len -= 1;
+                    let idx = Index { index, generation };
+                    return Some((idx, value));
+                }
+                None => {
+                    debug_assert_eq!(self.len, 0);
+                    return None;
+                }
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.len, Some(self.len))
+    }
+}
+
+impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        loop {
+            match self.inner.next_back() {
+                Some((_, &Entry::Free { .. })) => continue,
+                Some((
+                    index,
+                    &Entry::Occupied {
+                        generation,
+                        ref value,
+                    },
+                )) => {
+                    self.len -= 1;
+                    let idx = Index { index, generation };
+                    return Some((idx, value));
+                }
+                None => {
+                    debug_assert_eq!(self.len, 0);
+                    return None;
+                }
+            }
+        }
+    }
+}
+
+impl<'a, T> ExactSizeIterator for Iter<'a, T> {
+    fn len(&self) -> usize {
+        self.len
+    }
+}
+
+impl<'a, T> FusedIterator for Iter<'a, T> {}
+
+impl<'a, T> IntoIterator for &'a mut Arena<T> {
+    type Item = (Index, &'a mut T);
+    type IntoIter = IterMut<'a, T>;
+    fn into_iter(self) -> Self::IntoIter {
+        self.iter_mut()
+    }
+}
+
+/// An iterator over exclusive references to elements in this arena.
+///
+/// Yields pairs of `(Index, &mut T)` items.
+///
+/// Order of iteration is not defined.
+///
+/// # Examples
+///
+/// ```
+/// use generational_arena::Arena;
+///
+/// let mut arena = Arena::new();
+/// for i in 0..10 {
+///     arena.insert(i * i);
+/// }
+///
+/// for (_idx, value) in &mut arena {
+///     *value += 5;
+/// }
+/// ```
+#[derive(Debug)]
+pub struct IterMut<'a, T: 'a> {
+    len: usize,
+    inner: iter::Enumerate<slice::IterMut<'a, Entry<T>>>,
+}
+
+impl<'a, T> Iterator for IterMut<'a, T> {
+    type Item = (Index, &'a mut T);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        loop {
+            match self.inner.next() {
+                Some((_, &mut Entry::Free { .. })) => continue,
+                Some((
+                    index,
+                    &mut Entry::Occupied {
+                        generation,
+                        ref mut value,
+                    },
+                )) => {
+                    self.len -= 1;
+                    let idx = Index { index, generation };
+                    return Some((idx, value));
+                }
+                None => {
+                    debug_assert_eq!(self.len, 0);
+                    return None;
+                }
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.len, Some(self.len))
+    }
+}
+
+impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        loop {
+            match self.inner.next_back() {
+                Some((_, &mut Entry::Free { .. })) => continue,
+                Some((
+                    index,
+                    &mut Entry::Occupied {
+                        generation,
+                        ref mut value,
+                    },
+                )) => {
+                    self.len -= 1;
+                    let idx = Index { index, generation };
+                    return Some((idx, value));
+                }
+                None => {
+                    debug_assert_eq!(self.len, 0);
+                    return None;
+                }
+            }
+        }
+    }
+}
+
+impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
+    fn len(&self) -> usize {
+        self.len
+    }
+}
+
+impl<'a, T> FusedIterator for IterMut<'a, T> {}
+
+/// An iterator that removes elements from the arena.
+///
+/// Yields pairs of `(Index, T)` items.
+///
+/// Order of iteration is not defined.
+///
+/// Note: All elements are removed even if the iterator is only partially consumed or not consumed at all.
+///
+/// # Examples
+///
+/// ```
+/// use generational_arena::Arena;
+///
+/// let mut arena = Arena::new();
+/// let idx_1 = arena.insert("hello");
+/// let idx_2 = arena.insert("world");
+///
+/// assert!(arena.get(idx_1).is_some());
+/// assert!(arena.get(idx_2).is_some());
+/// for (idx, value) in arena.drain() {
+///     assert!((idx == idx_1 && value == "hello") || (idx == idx_2 && value == "world"));
+/// }
+/// assert!(arena.get(idx_1).is_none());
+/// assert!(arena.get(idx_2).is_none());
+/// ```
+#[derive(Debug)]
+pub struct Drain<'a, T: 'a> {
+    len: usize,
+    inner: iter::Enumerate<vec::Drain<'a, Entry<T>>>,
+}
+
+impl<'a, T> Iterator for Drain<'a, T> {
+    type Item = (Index, T);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        loop {
+            match self.inner.next() {
+                Some((_, Entry::Free { .. })) => continue,
+                Some((index, Entry::Occupied { generation, value })) => {
+                    let idx = Index { index, generation };
+                    self.len -= 1;
+                    return Some((idx, value));
+                }
+                None => {
+                    debug_assert_eq!(self.len, 0);
+                    return None;
+                }
+            }
+        }
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.len, Some(self.len))
+    }
+}
+
+impl<'a, T> DoubleEndedIterator for Drain<'a, T> {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        loop {
+            match self.inner.next_back() {
+                Some((_, Entry::Free { .. })) => continue,
+                Some((index, Entry::Occupied { generation, value })) => {
+                    let idx = Index { index, generation };
+                    self.len -= 1;
+                    return Some((idx, value));
+                }
+                None => {
+                    debug_assert_eq!(self.len, 0);
+                    return None;
+                }
+            }
+        }
+    }
+}
+
+impl<'a, T> ExactSizeIterator for Drain<'a, T> {
+    fn len(&self) -> usize {
+        self.len
+    }
+}
+
+impl<'a, T> FusedIterator for Drain<'a, T> {}
+
+impl<T> Extend<T> for Arena<T> {
+    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
+        for t in iter {
+            self.insert(t);
+        }
+    }
+}
+
+impl<T> FromIterator<T> for Arena<T> {
+    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
+        let iter = iter.into_iter();
+        let (lower, upper) = iter.size_hint();
+        let cap = upper.unwrap_or(lower);
+        let cap = cmp::max(cap, 1);
+        let mut arena = Arena::with_capacity(cap);
+        arena.extend(iter);
+        arena
+    }
+}
+
+impl<T> ops::Index<Index> for Arena<T> {
+    type Output = T;
+
+    fn index(&self, index: Index) -> &Self::Output {
+        self.get(index).expect("No element at index")
+    }
+}
+
+impl<T> ops::IndexMut<Index> for Arena<T> {
+    fn index_mut(&mut self, index: Index) -> &mut Self::Output {
+        self.get_mut(index).expect("No element at index")
+    }
+}
diff --git a/kayak_core/src/layout_cache.rs b/kayak_core/src/layout_cache.rs
new file mode 100644
index 0000000..59f251e
--- /dev/null
+++ b/kayak_core/src/layout_cache.rs
@@ -0,0 +1,358 @@
+use std::collections::HashMap;
+
+use morphorm::{Cache, GeometryChanged};
+
+use crate::node::NodeIndex;
+
+#[derive(Debug, Default, Clone, Copy, PartialEq)]
+pub struct Rect {
+    pub posx: f32,
+    pub posy: f32,
+    pub width: f32,
+    pub height: f32,
+    pub z_index: f32,
+}
+
+#[derive(Debug, Default, Clone, Copy)]
+pub struct Space {
+    pub left: f32,
+    pub right: f32,
+    pub top: f32,
+    pub bottom: f32,
+}
+
+#[derive(Debug, Default, Clone, Copy)]
+pub struct Size {
+    pub width: f32,
+    pub height: f32,
+}
+
+#[derive(Default, Debug)]
+pub struct LayoutCache {
+    // Computed Outputs
+    pub rect: HashMap<NodeIndex, Rect>,
+
+    // Intermediate Values
+    space: HashMap<NodeIndex, Space>,
+    size: HashMap<NodeIndex, Size>,
+
+    child_width_max: HashMap<NodeIndex, f32>,
+    child_height_max: HashMap<NodeIndex, f32>,
+    child_width_sum: HashMap<NodeIndex, f32>,
+    child_height_sum: HashMap<NodeIndex, f32>,
+
+    grid_row_max: HashMap<NodeIndex, f32>,
+    grid_col_max: HashMap<NodeIndex, f32>,
+
+    horizontal_free_space: HashMap<NodeIndex, f32>,
+    horizontal_stretch_sum: HashMap<NodeIndex, f32>,
+
+    vertical_free_space: HashMap<NodeIndex, f32>,
+    vertical_stretch_sum: HashMap<NodeIndex, f32>,
+
+    stack_first_child: HashMap<NodeIndex, bool>,
+    stack_last_child: HashMap<NodeIndex, bool>,
+
+    geometry_changed: HashMap<NodeIndex, GeometryChanged>,
+
+    visible: HashMap<NodeIndex, bool>,
+}
+
+impl LayoutCache {
+    pub fn add(&mut self, node_index: NodeIndex) {
+        self.rect.insert(node_index, Default::default());
+
+        self.space.insert(node_index, Default::default());
+
+        self.child_width_max.insert(node_index, Default::default());
+        self.child_height_max.insert(node_index, Default::default());
+        self.child_width_sum.insert(node_index, Default::default());
+        self.child_height_sum.insert(node_index, Default::default());
+
+        self.grid_row_max.insert(node_index, Default::default());
+        self.grid_col_max.insert(node_index, Default::default());
+
+        self.horizontal_free_space
+            .insert(node_index, Default::default());
+        self.horizontal_stretch_sum
+            .insert(node_index, Default::default());
+
+        self.vertical_free_space
+            .insert(node_index, Default::default());
+        self.vertical_stretch_sum
+            .insert(node_index, Default::default());
+
+        self.stack_first_child
+            .insert(node_index, Default::default());
+        self.stack_last_child.insert(node_index, Default::default());
+
+        self.size.insert(node_index, Default::default());
+
+        self.geometry_changed.insert(node_index, Default::default());
+
+        self.visible.insert(node_index, true);
+    }
+}
+
+impl Cache for LayoutCache {
+    type Item = NodeIndex;
+
+    fn visible(&self, node: Self::Item) -> bool {
+        if let Some(value) = self.visible.get(&node) {
+            return *value;
+        }
+
+        true
+    }
+
+    fn geometry_changed(&self, node: Self::Item) -> GeometryChanged {
+        if let Some(geometry_changed) = self.geometry_changed.get(&node) {
+            return *geometry_changed;
+        }
+
+        GeometryChanged::default()
+    }
+
+    fn set_geo_changed(&mut self, node: Self::Item, flag: GeometryChanged, value: bool) {
+        if let Some(geometry_changed) = self.geometry_changed.get_mut(&node) {
+            geometry_changed.set(flag, value);
+        }
+    }
+
+    fn width(&self, node: Self::Item) -> f32 {
+        if let Some(rect) = self.rect.get(&node) {
+            return rect.width;
+        }
+
+        0.0
+    }
+
+    fn height(&self, node: Self::Item) -> f32 {
+        if let Some(rect) = self.rect.get(&node) {
+            return rect.height;
+        }
+
+        0.0
+    }
+
+    fn posx(&self, node: Self::Item) -> f32 {
+        if let Some(rect) = self.rect.get(&node) {
+            return rect.posx;
+        }
+
+        0.0
+    }
+
+    fn posy(&self, node: Self::Item) -> f32 {
+        if let Some(rect) = self.rect.get(&node) {
+            return rect.posy;
+        }
+
+        0.0
+    }
+
+    fn left(&self, node: Self::Item) -> f32 {
+        if let Some(space) = self.space.get(&node) {
+            return space.left;
+        }
+
+        0.0
+    }
+
+    fn right(&self, node: Self::Item) -> f32 {
+        if let Some(space) = self.space.get(&node) {
+            return space.right;
+        }
+
+        0.0
+    }
+
+    fn top(&self, node: Self::Item) -> f32 {
+        if let Some(space) = self.space.get(&node) {
+            return space.top;
+        }
+
+        0.0
+    }
+
+    fn bottom(&self, node: Self::Item) -> f32 {
+        if let Some(space) = self.space.get(&node) {
+            return space.bottom;
+        }
+
+        0.0
+    }
+
+    fn new_width(&self, node: Self::Item) -> f32 {
+        if let Some(size) = self.size.get(&node) {
+            return size.width;
+        }
+
+        0.0
+    }
+
+    fn new_height(&self, node: Self::Item) -> f32 {
+        if let Some(size) = self.size.get(&node) {
+            return size.height;
+        }
+
+        0.0
+    }
+
+    fn child_width_max(&self, node: Self::Item) -> f32 {
+        *self.child_width_max.get(&node).unwrap()
+    }
+
+    /// Get the computed sum of the widths of the child nodes
+    fn child_width_sum(&self, node: Self::Item) -> f32 {
+        *self.child_width_sum.get(&node).unwrap()
+    }
+
+    /// Get the computed maximum width of the child nodes
+    fn child_height_max(&self, node: Self::Item) -> f32 {
+        *self.child_height_max.get(&node).unwrap()
+    }
+
+    /// Get the computed sum of the widths of the child nodes
+    fn child_height_sum(&self, node: Self::Item) -> f32 {
+        *self.child_height_sum.get(&node).unwrap()
+    }
+
+    /// Get the computed maximum grid row
+    fn grid_row_max(&self, node: Self::Item) -> f32 {
+        *self.grid_row_max.get(&node).unwrap()
+    }
+
+    /// Get the computed maximum grid column
+    fn grid_col_max(&self, node: Self::Item) -> f32 {
+        *self.grid_col_max.get(&node).unwrap()
+    }
+
+    // Setters
+    fn set_visible(&mut self, node: Self::Item, value: bool) {
+        *self.visible.get_mut(&node).unwrap() = value;
+    }
+
+    fn set_child_width_sum(&mut self, node: Self::Item, value: f32) {
+        *self.child_width_sum.get_mut(&node).unwrap() = value;
+    }
+
+    fn set_child_height_sum(&mut self, node: Self::Item, value: f32) {
+        *self.child_height_sum.get_mut(&node).unwrap() = value;
+    }
+
+    fn set_child_width_max(&mut self, node: Self::Item, value: f32) {
+        *self.child_width_max.get_mut(&node).unwrap() = value;
+    }
+
+    fn set_child_height_max(&mut self, node: Self::Item, value: f32) {
+        *self.child_height_max.get_mut(&node).unwrap() = value;
+    }
+
+    fn horizontal_free_space(&self, node: Self::Item) -> f32 {
+        *self.horizontal_free_space.get(&node).unwrap()
+    }
+    fn set_horizontal_free_space(&mut self, node: Self::Item, value: f32) {
+        *self.horizontal_free_space.get_mut(&node).unwrap() = value;
+    }
+    fn vertical_free_space(&self, node: Self::Item) -> f32 {
+        *self.vertical_free_space.get(&node).unwrap()
+    }
+    fn set_vertical_free_space(&mut self, node: Self::Item, value: f32) {
+        *self.vertical_free_space.get_mut(&node).unwrap() = value;
+    }
+
+    fn horizontal_stretch_sum(&self, node: Self::Item) -> f32 {
+        *self.horizontal_stretch_sum.get(&node).unwrap()
+    }
+    fn set_horizontal_stretch_sum(&mut self, node: Self::Item, value: f32) {
+        *self.horizontal_stretch_sum.get_mut(&node).unwrap() = value;
+    }
+    fn vertical_stretch_sum(&self, node: Self::Item) -> f32 {
+        *self.vertical_stretch_sum.get(&node).unwrap()
+    }
+    fn set_vertical_stretch_sum(&mut self, node: Self::Item, value: f32) {
+        *self.vertical_stretch_sum.get_mut(&node).unwrap() = value;
+    }
+
+    fn set_grid_row_max(&mut self, node: Self::Item, value: f32) {
+        *self.grid_row_max.get_mut(&node).unwrap() = value;
+    }
+
+    fn set_grid_col_max(&mut self, node: Self::Item, value: f32) {
+        *self.grid_row_max.get_mut(&node).unwrap() = value;
+    }
+
+    fn set_width(&mut self, node: Self::Item, value: f32) {
+        if let Some(rect) = self.rect.get_mut(&node) {
+            rect.width = value;
+        }
+    }
+    fn set_height(&mut self, node: Self::Item, value: f32) {
+        if let Some(rect) = self.rect.get_mut(&node) {
+            rect.height = value;
+        }
+    }
+    fn set_posx(&mut self, node: Self::Item, value: f32) {
+        if let Some(rect) = self.rect.get_mut(&node) {
+            rect.posx = value;
+        }
+    }
+    fn set_posy(&mut self, node: Self::Item, value: f32) {
+        if let Some(rect) = self.rect.get_mut(&node) {
+            rect.posy = value;
+        }
+    }
+
+    fn set_left(&mut self, node: Self::Item, value: f32) {
+        if let Some(space) = self.space.get_mut(&node) {
+            space.left = value;
+        }
+    }
+
+    fn set_right(&mut self, node: Self::Item, value: f32) {
+        if let Some(space) = self.space.get_mut(&node) {
+            space.right = value;
+        }
+    }
+
+    fn set_top(&mut self, node: Self::Item, value: f32) {
+        if let Some(space) = self.space.get_mut(&node) {
+            space.top = value;
+        }
+    }
+
+    fn set_bottom(&mut self, node: Self::Item, value: f32) {
+        if let Some(space) = self.space.get_mut(&node) {
+            space.bottom = value;
+        }
+    }
+
+    fn set_new_width(&mut self, node: Self::Item, value: f32) {
+        if let Some(size) = self.size.get_mut(&node) {
+            size.width = value;
+        }
+    }
+
+    fn set_new_height(&mut self, node: Self::Item, value: f32) {
+        if let Some(size) = self.size.get_mut(&node) {
+            size.height = value;
+        }
+    }
+
+    fn stack_first_child(&self, node: Self::Item) -> bool {
+        *self.stack_first_child.get(&node).unwrap()
+    }
+
+    fn set_stack_first_child(&mut self, node: Self::Item, value: bool) {
+        *self.stack_first_child.get_mut(&node).unwrap() = value;
+    }
+
+    fn stack_last_child(&self, node: Self::Item) -> bool {
+        *self.stack_last_child.get(&node).unwrap()
+    }
+
+    fn set_stack_last_child(&mut self, node: Self::Item, value: bool) {
+        *self.stack_last_child.get_mut(&node).unwrap() = value;
+    }
+}
diff --git a/kayak_core/src/lib.rs b/kayak_core/src/lib.rs
new file mode 100644
index 0000000..73ad0d8
--- /dev/null
+++ b/kayak_core/src/lib.rs
@@ -0,0 +1,29 @@
+pub mod color;
+pub mod context;
+pub mod fragment;
+pub mod layout_cache;
+pub mod node;
+pub mod render_command;
+pub mod render_primitive;
+pub mod styles;
+pub mod tree;
+pub mod widget;
+pub mod widget_manager;
+
+pub(crate) mod generational_arena;
+
+pub use generational_arena::{Arena, Index};
+
+pub use widget::Widget;
+
+pub use kayak_render_macros::{render, rsx, widget};
+
+pub use fragment::Fragment;
+
+pub type Children = Option<
+    std::sync::Arc<dyn Fn(Option<crate::Index>, &mut crate::context::KayakContext) + Send + Sync>,
+>;
+
+pub mod derivative {
+    pub use derivative::*;
+}
diff --git a/kayak_core/src/node.rs b/kayak_core/src/node.rs
new file mode 100644
index 0000000..704cc01
--- /dev/null
+++ b/kayak_core/src/node.rs
@@ -0,0 +1,285 @@
+use crate::{
+    styles::{Style, StyleProp},
+    Arena, Index,
+};
+
+#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
+pub struct NodeIndex(pub Index);
+
+#[derive(Debug, Clone)]
+pub struct Node {
+    pub children: Vec<Index>,
+    pub id: Index,
+    pub styles: Style,
+    pub z: f32,
+}
+
+impl Node {}
+
+pub struct NodeBuilder {
+    children: Vec<Index>,
+    id: Index,
+    styles: Style,
+}
+
+impl NodeBuilder {
+    pub fn empty() -> Self {
+        Self {
+            children: Vec::new(),
+            id: Index::default(),
+            styles: Style::default(),
+        }
+    }
+
+    pub fn new(id: Index, styles: Style) -> Self {
+        Self {
+            children: Vec::new(),
+            id,
+            styles,
+        }
+    }
+
+    pub fn with_id(mut self, id: Index) -> Self {
+        self.id = id;
+        self
+    }
+
+    pub fn with_children(mut self, children: Vec<Index>) -> Self {
+        self.children.extend(children);
+        self
+    }
+
+    pub fn with_styles(mut self, styles: Style) -> Self {
+        self.styles = styles;
+        self
+    }
+
+    pub fn build(self) -> Node {
+        Node {
+            children: self.children,
+            id: self.id,
+            styles: self.styles,
+            z: 0.0,
+        }
+    }
+}
+
+impl<'a> morphorm::Node<'a> for NodeIndex {
+    type Data = Arena<Option<Node>>;
+
+    fn layout_type(&self, store: &'_ Self::Data) -> Option<morphorm::LayoutType> {
+        if let Some(node) = store.get(self.0) {
+            if let Some(node) = node {
+                return match node.styles.layout_type {
+                    StyleProp::Default => Some(morphorm::LayoutType::default()),
+                    StyleProp::Value(prop) => Some(prop),
+                    _ => None,
+                };
+            }
+        }
+        return None;
+    }
+
+    fn position_type(&self, store: &'_ Self::Data) -> Option<morphorm::PositionType> {
+        if let Some(node) = store.get(self.0) {
+            if let Some(node) = node {
+                return match node.styles.position_type {
+                    StyleProp::Default => Some(morphorm::PositionType::default()),
+                    StyleProp::Value(prop) => Some(prop),
+                    _ => None,
+                };
+            }
+        }
+        return None;
+    }
+
+    fn width(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
+        if let Some(node) = store.get(self.0) {
+            if let Some(node) = node {
+                return match node.styles.width {
+                    StyleProp::Default => Some(morphorm::Units::Stretch(1.0)),
+                    StyleProp::Value(prop) => Some(prop),
+                    _ => None,
+                };
+            }
+        }
+        return None;
+    }
+
+    fn height(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
+        if let Some(node) = store.get(self.0) {
+            if let Some(node) = node {
+                return match node.styles.height {
+                    StyleProp::Default => Some(morphorm::Units::Stretch(1.0)),
+                    StyleProp::Value(prop) => Some(prop),
+                    _ => None,
+                };
+            }
+        }
+        return None;
+    }
+
+    fn min_width(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn min_height(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn max_width(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn max_height(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn left(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
+        if let Some(node) = store.get(self.0) {
+            if let Some(node) = node {
+                return match node.styles.left {
+                    StyleProp::Default => Some(morphorm::Units::Auto),
+                    StyleProp::Value(prop) => Some(prop),
+                    _ => None,
+                };
+            }
+        }
+        return None;
+    }
+
+    fn right(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
+        if let Some(node) = store.get(self.0) {
+            if let Some(node) = node {
+                return match node.styles.right {
+                    StyleProp::Default => Some(morphorm::Units::Auto),
+                    StyleProp::Value(prop) => Some(prop),
+                    _ => None,
+                };
+            }
+        }
+        return None;
+    }
+
+    fn top(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
+        if let Some(node) = store.get(self.0) {
+            if let Some(node) = node {
+                return match node.styles.top {
+                    StyleProp::Default => Some(morphorm::Units::Auto),
+                    StyleProp::Value(prop) => Some(prop),
+                    _ => None,
+                };
+            }
+        }
+        return None;
+    }
+
+    fn bottom(&self, store: &'_ Self::Data) -> Option<morphorm::Units> {
+        if let Some(node) = store.get(self.0) {
+            if let Some(node) = node {
+                return match node.styles.bottom {
+                    StyleProp::Default => Some(morphorm::Units::Auto),
+                    StyleProp::Value(prop) => Some(prop),
+                    _ => None,
+                };
+            }
+        }
+        return None;
+    }
+
+    fn min_left(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn max_left(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn min_right(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn max_right(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn min_top(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn max_top(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn min_bottom(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn max_bottom(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn child_left(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn child_right(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn child_top(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn child_bottom(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn row_between(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn col_between(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn grid_rows(&self, _store: &'_ Self::Data) -> Option<Vec<morphorm::Units>> {
+        Some(vec![])
+    }
+
+    fn grid_cols(&self, _store: &'_ Self::Data) -> Option<Vec<morphorm::Units>> {
+        Some(vec![])
+    }
+
+    fn row_index(&self, _store: &'_ Self::Data) -> Option<usize> {
+        Some(0)
+    }
+
+    fn col_index(&self, _store: &'_ Self::Data) -> Option<usize> {
+        Some(0)
+    }
+
+    fn row_span(&self, _store: &'_ Self::Data) -> Option<usize> {
+        Some(1)
+    }
+
+    fn col_span(&self, _store: &'_ Self::Data) -> Option<usize> {
+        Some(1)
+    }
+
+    fn border_left(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn border_right(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn border_top(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+
+    fn border_bottom(&self, _store: &'_ Self::Data) -> Option<morphorm::Units> {
+        Some(morphorm::Units::Auto)
+    }
+}
diff --git a/kayak_core/src/render_command.rs b/kayak_core/src/render_command.rs
new file mode 100644
index 0000000..eb75d0b
--- /dev/null
+++ b/kayak_core/src/render_command.rs
@@ -0,0 +1,17 @@
+#[derive(Debug, Clone, PartialEq)]
+pub enum RenderCommand {
+    Empty,
+    Clip,
+    Quad,
+    Text {
+        content: String,
+        size: f32,
+        font: u16,
+    },
+}
+
+impl Default for RenderCommand {
+    fn default() -> Self {
+        Self::Empty
+    }
+}
diff --git a/kayak_core/src/render_primitive.rs b/kayak_core/src/render_primitive.rs
new file mode 100644
index 0000000..1c54054
--- /dev/null
+++ b/kayak_core/src/render_primitive.rs
@@ -0,0 +1,59 @@
+use crate::{color::Color, layout_cache::Rect, render_command::RenderCommand, styles::Style};
+
+#[derive(Debug, Clone, PartialEq)]
+pub enum RenderPrimitive {
+    Empty,
+    Clip {
+        layout: Rect,
+    },
+    Quad {
+        layout: Rect,
+        background_color: Color,
+    },
+    Text {
+        layout: Rect,
+        color: Color,
+        size: f32,
+        content: String,
+        font: u16,
+    },
+}
+
+impl RenderPrimitive {
+    pub fn set_layout(&mut self, new_layout: Rect) {
+        match self {
+            RenderPrimitive::Clip { layout, .. } => *layout = new_layout,
+            RenderPrimitive::Quad { layout, .. } => *layout = new_layout,
+            RenderPrimitive::Text { layout, .. } => *layout = new_layout,
+            _ => (),
+        }
+    }
+}
+
+impl From<&Style> for RenderPrimitive {
+    fn from(style: &Style) -> Self {
+        let render_command = style.render_command.resolve();
+
+        match render_command {
+            RenderCommand::Empty => Self::Empty,
+            RenderCommand::Clip => Self::Clip {
+                layout: Rect::default(),
+            },
+            RenderCommand::Quad => Self::Quad {
+                background_color: style.background_color.resolve(),
+                layout: Rect::default(),
+            },
+            RenderCommand::Text {
+                content,
+                size,
+                font,
+            } => Self::Text {
+                layout: Rect::default(),
+                color: style.color.resolve(),
+                size,
+                content,
+                font,
+            },
+        }
+    }
+}
diff --git a/kayak_core/src/styles.rs b/kayak_core/src/styles.rs
new file mode 100644
index 0000000..d75533a
--- /dev/null
+++ b/kayak_core/src/styles.rs
@@ -0,0 +1,136 @@
+pub use morphorm::{LayoutType, PositionType, Units};
+
+use crate::{color::Color, render_command::RenderCommand};
+
+#[derive(Debug, Clone, PartialEq)]
+pub enum StyleProp<T: Default + Clone> {
+    Default,
+    Inherit,
+    Value(T),
+}
+
+impl<T> Default for StyleProp<T>
+where
+    T: Default + Clone,
+{
+    fn default() -> Self {
+        Self::Default
+    }
+}
+
+impl<T> StyleProp<T>
+where
+    T: Default + Clone,
+{
+    pub fn resolve(&self) -> T {
+        match self {
+            StyleProp::Default => T::default(),
+            StyleProp::Value(value) => value.clone(),
+            StyleProp::Inherit => panic!("All styles should be merged before resolving!"),
+        }
+    }
+}
+
+#[derive(Debug, Clone, PartialEq)]
+pub struct Style {
+    pub background_color: StyleProp<Color>,
+    pub bottom: StyleProp<Units>,
+    pub color: StyleProp<Color>,
+    pub height: StyleProp<Units>,
+    pub layout_type: StyleProp<LayoutType>,
+    pub left: StyleProp<Units>,
+    pub position_type: StyleProp<PositionType>,
+    pub render_command: StyleProp<RenderCommand>,
+    pub right: StyleProp<Units>,
+    pub top: StyleProp<Units>,
+    pub width: StyleProp<Units>,
+}
+
+impl Default for Style {
+    fn default() -> Self {
+        Self {
+            background_color: StyleProp::Value(Color::TRANSPARENT),
+            render_command: StyleProp::Value(RenderCommand::Empty),
+            bottom: StyleProp::Default,
+            color: StyleProp::Inherit,
+            height: StyleProp::Default,
+            layout_type: StyleProp::Default,
+            left: StyleProp::Default,
+            position_type: StyleProp::Default,
+            right: StyleProp::Default,
+            top: StyleProp::Default,
+            width: StyleProp::Default,
+        }
+    }
+}
+
+impl Style {
+    pub fn merge(&mut self, other: &Self) {
+        match self.background_color {
+            StyleProp::Inherit => {
+                self.background_color = other.background_color.clone();
+            }
+            _ => (),
+        }
+        match self.bottom {
+            StyleProp::Inherit => {
+                self.bottom = other.bottom.clone();
+            }
+            _ => (),
+        }
+        match self.color {
+            StyleProp::Inherit => {
+                self.color = other.color.clone();
+            }
+            _ => (),
+        }
+        match self.height {
+            StyleProp::Inherit => {
+                self.height = other.height.clone();
+            }
+            _ => (),
+        }
+        match self.layout_type {
+            StyleProp::Inherit => {
+                self.layout_type = other.layout_type.clone();
+            }
+            _ => (),
+        }
+        match self.left {
+            StyleProp::Inherit => {
+                self.left = other.left.clone();
+            }
+            _ => (),
+        }
+        match self.position_type {
+            StyleProp::Inherit => {
+                self.position_type = other.position_type.clone();
+            }
+            _ => (),
+        }
+        match self.render_command {
+            StyleProp::Inherit => {
+                self.render_command = other.render_command.clone();
+            }
+            _ => (),
+        }
+        match self.right {
+            StyleProp::Inherit => {
+                self.right = other.right.clone();
+            }
+            _ => (),
+        }
+        match self.top {
+            StyleProp::Inherit => {
+                self.top = other.top.clone();
+            }
+            _ => (),
+        }
+        match self.width {
+            StyleProp::Inherit => {
+                self.width = other.width.clone();
+            }
+            _ => (),
+        }
+    }
+}
diff --git a/kayak_core/src/tree.rs b/kayak_core/src/tree.rs
new file mode 100644
index 0000000..b9e2fe4
--- /dev/null
+++ b/kayak_core/src/tree.rs
@@ -0,0 +1,257 @@
+use std::{collections::HashMap, iter::Rev};
+
+use morphorm::Hierarchy;
+
+use crate::{node::NodeIndex, Index};
+
+#[derive(Default, Debug)]
+pub struct Tree {
+    pub children: HashMap<Index, Vec<Index>>,
+    pub parents: HashMap<Index, Index>,
+    pub root_node: Index,
+}
+
+impl Tree {
+    pub fn add(&mut self, _child_index: usize, index: Index, parent: Option<Index>) {
+        if let Some(parent_index) = parent {
+            self.parents.insert(index, parent_index);
+            if let Some(parent_children) = self.children.get_mut(&parent_index) {
+                parent_children.push(index);
+            } else {
+                self.children.insert(parent_index, vec![index]);
+            }
+        } else {
+            self.root_node = index;
+        }
+    }
+
+    pub fn flatten(&self) -> Vec<NodeIndex> {
+        let iterator = DownwardIterator {
+            tree: &self,
+            current_node: Some(NodeIndex(self.root_node)),
+            starting: true,
+        };
+
+        iterator.collect::<Vec<_>>()
+    }
+
+    pub fn get_parent(&self, index: NodeIndex) -> Option<NodeIndex> {
+        self.parents
+            .get(&index.0)
+            .map_or(None, |parent| Some(NodeIndex(*parent)))
+    }
+
+    pub fn get_first_child(&self, index: NodeIndex) -> Option<NodeIndex> {
+        self.children.get(&index.0).map_or(None, |children| {
+            children
+                .first()
+                .map_or(None, |first_child| Some(NodeIndex(*first_child)))
+        })
+    }
+
+    pub fn get_last_child(&self, _index: NodeIndex) -> Option<NodeIndex> {
+        todo!()
+    }
+
+    pub fn get_next_sibling(&self, index: NodeIndex) -> Option<NodeIndex> {
+        if let Some(parent_index) = self.get_parent(index) {
+            self.children.get(&parent_index.0).map_or(None, |children| {
+                children
+                    .iter()
+                    .position(|child| *child == index.0)
+                    .map_or(None, |child_index| {
+                        children
+                            .get(child_index + 1)
+                            .map_or(None, |next_child| Some(NodeIndex(*next_child)))
+                    })
+            })
+        } else {
+            None
+        }
+    }
+
+    pub fn get_prev_sibling(&self, index: NodeIndex) -> Option<NodeIndex> {
+        self.children.get(&index.0).map_or(None, |children| {
+            children
+                .iter()
+                .position(|child| *child == index.0)
+                .map_or(None, |child_index| {
+                    children
+                        .get(child_index - 1)
+                        .map_or(None, |next_child| Some(NodeIndex(*next_child)))
+                })
+        })
+    }
+}
+
+pub struct DownwardIterator<'a> {
+    tree: &'a Tree,
+    current_node: Option<NodeIndex>,
+    starting: bool,
+}
+
+impl<'a> DownwardIterator<'a> {}
+
+impl<'a> Iterator for DownwardIterator<'a> {
+    type Item = NodeIndex;
+    fn next(&mut self) -> Option<NodeIndex> {
+        if self.starting {
+            self.starting = false;
+            return self.current_node;
+        }
+
+        if let Some(current_index) = self.current_node {
+            if let Some(first_child) = self.tree.get_first_child(current_index) {
+                self.current_node = Some(first_child);
+                return Some(first_child);
+            } else if let Some(next_sibling) = self.tree.get_next_sibling(current_index) {
+                self.current_node = Some(next_sibling);
+                return Some(next_sibling);
+            } else {
+                let mut current_parent = self.tree.get_parent(current_index);
+                while current_parent.is_some() {
+                    if let Some(current_parent) = current_parent {
+                        if let Some(next_parent_sibling) =
+                            self.tree.get_next_sibling(current_parent)
+                        {
+                            self.current_node = Some(next_parent_sibling);
+                            return Some(next_parent_sibling);
+                        }
+                    }
+                    current_parent = self.tree.get_parent(current_parent.unwrap());
+                }
+            }
+        }
+
+        return None;
+    }
+}
+
+// pub struct UpwardIterator<'a> {
+//     tree: &'a Tree,
+//     current_node: Option<NodeIndex>,
+// }
+
+// impl<'a> Iterator for UpwardIterator<'a> {
+//     type Item = NodeIndex;
+
+//     // TODO - Needs Testing
+//     fn next(&mut self) -> Option<NodeIndex> {
+//         None
+//     }
+// }
+
+pub struct ChildIterator<'a> {
+    pub tree: &'a Tree,
+    pub current_node: Option<NodeIndex>,
+}
+
+impl<'a> Iterator for ChildIterator<'a> {
+    type Item = NodeIndex;
+    fn next(&mut self) -> Option<Self::Item> {
+        if let Some(entity) = self.current_node {
+            self.current_node = self.tree.get_next_sibling(entity);
+            return Some(entity);
+        }
+
+        None
+    }
+}
+
+impl<'a> Hierarchy<'a> for Tree {
+    type Item = NodeIndex;
+    type DownIter = std::vec::IntoIter<NodeIndex>;
+    type UpIter = Rev<std::vec::IntoIter<NodeIndex>>;
+    type ChildIter = ChildIterator<'a>;
+
+    fn up_iter(&'a self) -> Self::UpIter {
+        self.flatten().into_iter().rev()
+    }
+
+    fn down_iter(&'a self) -> Self::DownIter {
+        self.flatten().into_iter()
+    }
+
+    fn child_iter(&'a self, node: Self::Item) -> Self::ChildIter {
+        let first_child = self.get_first_child(node);
+        ChildIterator {
+            tree: self,
+            current_node: first_child,
+        }
+    }
+
+    fn parent(&self, node: Self::Item) -> Option<Self::Item> {
+        if let Some(parent_index) = self.parents.get(&node.0) {
+            return Some(NodeIndex(*parent_index));
+        }
+
+        None
+    }
+
+    fn is_first_child(&self, node: Self::Item) -> bool {
+        if let Some(parent) = self.parent(node) {
+            if let Some(first_child) = self.get_first_child(parent) {
+                if first_child == node {
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+        }
+
+        false
+    }
+
+    fn is_last_child(&self, node: Self::Item) -> bool {
+        if let Some(parent) = self.parent(node) {
+            if let Some(parent_children) = self.children.get(&parent.0) {
+                if let Some(last_child) = parent_children.last() {
+                    return *last_child == node.0;
+                }
+            }
+        }
+
+        false
+    }
+}
+
+#[test]
+fn test_tree() {
+    use crate::node::NodeBuilder;
+    use crate::Arena;
+    let mut store = Arena::new();
+    let root = store.insert(NodeBuilder::empty().build());
+    // Child 1 of root
+    let index1 = store.insert(NodeBuilder::empty().build());
+    // Children of child 1.
+    let index2 = store.insert(NodeBuilder::empty().build());
+    let index3 = store.insert(NodeBuilder::empty().build());
+    // Child 2 of root
+    let index4 = store.insert(NodeBuilder::empty().build());
+
+    let mut tree = Tree::default();
+    tree.root_node = root;
+
+    // Setup Parents..
+    tree.parents.insert(index1, root);
+    tree.parents.insert(index4, root);
+
+    tree.parents.insert(index2, index1);
+    tree.parents.insert(index3, index1);
+
+    tree.children.insert(root, vec![index1, index4]);
+    tree.children.insert(index1, vec![index2, index3]);
+
+    let flattened = tree.flatten();
+
+    let mapped = flattened
+        .iter()
+        .map(|x| x.0.into_raw_parts().0)
+        .collect::<Vec<_>>();
+
+    assert!(mapped[0] == 0);
+    assert!(mapped[1] == 1);
+    assert!(mapped[2] == 2);
+    assert!(mapped[3] == 3);
+    assert!(mapped[4] == 4);
+}
diff --git a/kayak_core/src/widget.rs b/kayak_core/src/widget.rs
new file mode 100644
index 0000000..3e63d87
--- /dev/null
+++ b/kayak_core/src/widget.rs
@@ -0,0 +1,15 @@
+use as_any::AsAny;
+
+use crate::{context::KayakContext, styles::Style, Index};
+
+pub trait Widget: std::fmt::Debug + AsAny + Send + Sync {
+    fn get_id(&self) -> Index;
+    fn set_id(&mut self, id: Index);
+    fn get_styles(&self) -> Option<Style>;
+    fn render(&mut self, context: &mut KayakContext);
+}
+
+impl as_any::Downcast for dyn Widget {}
+impl as_any::Downcast for dyn Widget + Send {}
+impl as_any::Downcast for dyn Widget + Sync {}
+impl as_any::Downcast for dyn Widget + Send + Sync {}
diff --git a/kayak_core/src/widget_manager.rs b/kayak_core/src/widget_manager.rs
new file mode 100644
index 0000000..f4e3b70
--- /dev/null
+++ b/kayak_core/src/widget_manager.rs
@@ -0,0 +1,216 @@
+use crate::{
+    layout_cache::LayoutCache,
+    node::{Node, NodeBuilder, NodeIndex},
+    render_primitive::RenderPrimitive,
+    styles::Style,
+    tree::Tree,
+    Arena, Index, Widget,
+};
+use as_any::Downcast;
+
+#[derive(Debug)]
+pub struct WidgetManager {
+    current_widgets: Arena<Option<Box<dyn Widget>>>,
+    pub(crate) dirty_render_nodes: Vec<Index>,
+    pub(crate) dirty_nodes: Vec<Index>,
+    pub(crate) nodes: Arena<Option<Node>>,
+    pub tree: Tree,
+    pub layout_cache: LayoutCache,
+    current_z: f32,
+}
+
+impl WidgetManager {
+    pub fn new() -> Self {
+        Self {
+            current_widgets: Arena::new(),
+            dirty_render_nodes: Vec::new(),
+            dirty_nodes: Vec::new(),
+            nodes: Arena::new(),
+            tree: Tree::default(),
+            layout_cache: LayoutCache::default(),
+            current_z: 0.0,
+        }
+    }
+
+    /// Re-renders from the root.
+    /// If force is true sets ALL nodes to re-render.
+    /// Can be slow.
+    pub fn dirty(&mut self, force: bool) {
+        // Force tree to re-render from root.
+        self.dirty_nodes.push(self.tree.root_node);
+
+        if force {
+            for (node_index, _) in self.current_widgets.iter() {
+                self.dirty_nodes.push(node_index);
+                self.dirty_render_nodes.push(node_index);
+            }
+        }
+    }
+
+    pub fn create_widget<T: Widget + PartialEq + 'static>(
+        &mut self,
+        index: usize,
+        mut widget: T,
+        parent: Option<Index>,
+    ) -> (bool, Index) {
+        if let Some(parent) = parent.clone() {
+            if let Some(parent_children) = self.tree.children.get_mut(&parent) {
+                // Pull child and update.
+                if let Some(widget_id) = parent_children.get(index) {
+                    widget.set_id(*widget_id);
+                    // Remove from the dirty nodes lists.
+                    if let Some(index) = self.dirty_nodes.iter().position(|id| *widget_id == *id) {
+                        self.dirty_nodes.remove(index);
+                    }
+
+                    if &widget
+                        != self.current_widgets[*widget_id]
+                            .as_ref()
+                            .unwrap()
+                            .downcast_ref::<T>()
+                            .unwrap()
+                    {
+                        let boxed_widget: Box<dyn Widget> = Box::new(widget);
+                        *self.current_widgets[*widget_id].as_mut().unwrap() = boxed_widget;
+                        dbg!("Widget changed!");
+                        // Tell renderer that the nodes changed.
+                        self.dirty_render_nodes.push(*widget_id);
+                        return (true, *widget_id);
+                    } else {
+                        dbg!("No widget changes!");
+                        return (false, *widget_id);
+                    }
+                }
+            }
+        }
+
+        // Create Flow
+        // We should only have one widget that doesn't have a parent.
+        // The root widget.
+        let widget_id = self.current_widgets.insert(Some(Box::new(widget)));
+        self.nodes.insert(None);
+        self.current_widgets[widget_id]
+            .as_mut()
+            .unwrap()
+            .set_id(widget_id);
+
+        // Tell renderer that the nodes changed.
+        self.dirty_render_nodes.push(widget_id);
+
+        // Remove from the dirty nodes lists.
+        if let Some(index) = self.dirty_nodes.iter().position(|id| widget_id == *id) {
+            self.dirty_nodes.remove(index);
+        }
+
+        self.tree.add(0, widget_id, parent);
+        self.layout_cache.add(NodeIndex(widget_id));
+
+        (true, widget_id)
+    }
+
+    pub fn take(&mut self, id: Index) -> Box<dyn Widget> {
+        self.current_widgets[id].take().unwrap()
+    }
+
+    pub fn repossess(&mut self, widget: Box<dyn Widget>) {
+        let widget_id = widget.get_id();
+        self.current_widgets[widget_id] = Some(widget);
+    }
+
+    pub fn render(&mut self) {
+        let default_styles = Style {
+            background_color: crate::styles::StyleProp::Default,
+            bottom: crate::styles::StyleProp::Default,
+            color: crate::styles::StyleProp::Default,
+            height: crate::styles::StyleProp::Default,
+            layout_type: crate::styles::StyleProp::Default,
+            left: crate::styles::StyleProp::Default,
+            position_type: crate::styles::StyleProp::Default,
+            render_command: crate::styles::StyleProp::Default,
+            right: crate::styles::StyleProp::Default,
+            top: crate::styles::StyleProp::Default,
+            width: crate::styles::StyleProp::Default,
+        };
+        for dirty_node_index in self.dirty_render_nodes.drain(..) {
+            let dirty_widget = self.current_widgets[dirty_node_index].as_ref().unwrap();
+            let parent_styles =
+                if let Some(parent_widget_id) = self.tree.parents.get(&dirty_node_index) {
+                    if let Some(parent) = self.current_widgets[*parent_widget_id].as_ref() {
+                        if let Some(styles) = parent.get_styles() {
+                            styles
+                        } else {
+                            default_styles.clone()
+                        }
+                    } else {
+                        default_styles.clone()
+                    }
+                } else {
+                    default_styles.clone()
+                };
+
+            // Get parent Z
+            let parent_z = if let Some(parent_widget_id) = self.tree.parents.get(&dirty_node_index)
+            {
+                if let Some(parent) = &self.nodes[*parent_widget_id] {
+                    parent.z
+                } else {
+                    -1.0
+                }
+            } else {
+                -1.0
+            };
+
+            let current_z = {
+                if parent_z > -1.0 {
+                    parent_z + 1.0
+                } else {
+                    let z = self.current_z;
+                    self.current_z += 1.0;
+                    z
+                }
+            };
+            dbg!(current_z);
+
+            let mut styles = dirty_widget.get_styles();
+            if styles.is_some() {
+                styles.as_mut().unwrap().merge(&parent_styles);
+            }
+            let children = self
+                .tree
+                .children
+                .get(&dirty_node_index)
+                .cloned()
+                .unwrap_or(vec![]);
+            let mut node = NodeBuilder::empty()
+                .with_id(dirty_node_index)
+                .with_styles(styles.unwrap_or(default_styles.clone()))
+                .with_children(children)
+                .build();
+            node.z = current_z;
+
+            self.nodes[dirty_node_index] = Some(node);
+        }
+    }
+
+    pub fn calculate_layout(&mut self) {
+        morphorm::layout(&mut self.layout_cache, &self.tree, &self.nodes);
+    }
+
+    pub fn build_render_primitives(&self) -> Vec<RenderPrimitive> {
+        let mut render_primitives = Vec::new();
+
+        for (index, node) in self.nodes.iter() {
+            if let Some(layout) = self.layout_cache.rect.get(&NodeIndex(index)) {
+                if let Some(node) = node {
+                    let mut render_primitive: RenderPrimitive = (&node.styles).into();
+                    let mut layout = *layout;
+                    layout.z_index = node.z;
+                    render_primitive.set_layout(layout);
+                    render_primitives.push(render_primitive);
+                }
+            }
+        }
+
+        render_primitives
+    }
+}
diff --git a/kayak_font/.gitignore b/kayak_font/.gitignore
new file mode 100644
index 0000000..aab52d9
--- /dev/null
+++ b/kayak_font/.gitignore
@@ -0,0 +1 @@
+*.png
\ No newline at end of file
diff --git a/kayak_font/Cargo.toml b/kayak_font/Cargo.toml
new file mode 100644
index 0000000..79436b7
--- /dev/null
+++ b/kayak_font/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "kayak_font"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+arrayvec = "0.7"
+bitflags = "1.0"
+lyon_path = "0.12"
+lyon_geom = "0.12"
+fontdue = "0.6"
+ttf-parser = "0.13"
+
+[dev-dependencies]
+png = "0.16.3"
diff --git a/kayak_font/examples/main.rs b/kayak_font/examples/main.rs
new file mode 100644
index 0000000..2bed828
--- /dev/null
+++ b/kayak_font/examples/main.rs
@@ -0,0 +1,54 @@
+use std::{fs::File, io::BufWriter};
+
+use kayak_font::{
+    compute_msdf, recolor_contours, rescale_contours, Angle, FlatPathBuilder, PathCollector, Point,
+    Rect,
+};
+
+pub fn main() {
+    let font_data = include_bytes!("../resources/Roboto-Regular.ttf");
+    let face = ttf_parser::Face::from_slice(font_data, 0).unwrap();
+
+    let char_dim: u32 = 64;
+
+    let c = 'A';
+    if let Some(glyph) = face.glyph_index(c) {
+        let mut path_collector = PathCollector::new();
+        path_collector.scale = 1.0; //0.0001; //1024 as f32 / face.units_per_em() as f32;
+        let rect = face.outline_glyph(glyph, &mut path_collector).unwrap();
+        let contours = path_collector.build();
+        let uv_rect = Rect::new(Point::new(0.0, 0.0), lyon_geom::math::Size::new(1.0, 1.0));
+
+        let font_rect = Rect::new(
+            Point::new(rect.x_min as f32, rect.y_min as f32),
+            lyon_geom::math::Size::new(rect.width() as f32, rect.height() as f32),
+        );
+
+        let (contours, _) = rescale_contours(contours, font_rect, uv_rect, 0);
+
+        let contours = recolor_contours(contours, Angle::degrees(3.0), 1);
+        let msdf = compute_msdf(&contours, char_dim as usize);
+
+        let file = File::create(format!("./test-{}.png", c)).unwrap();
+        let ref mut w = BufWriter::new(file);
+
+        let pixels: Vec<u8> = msdf
+            .iter()
+            .flat_map(|y| {
+                y.iter().flat_map(|pixel| {
+                    vec![
+                        (pixel.0 * 255.0) as u8,
+                        (pixel.1 * 255.0) as u8,
+                        (pixel.2 * 255.0) as u8,
+                        255u8,
+                    ]
+                })
+            })
+            .collect();
+
+        let mut encoder = png::Encoder::new(w, char_dim, char_dim);
+        encoder.set_color(png::ColorType::RGBA);
+        let mut writer = encoder.write_header().unwrap();
+        writer.write_image_data(&pixels).unwrap();
+    }
+}
diff --git a/kayak_font/examples/simple.rs b/kayak_font/examples/simple.rs
new file mode 100644
index 0000000..09f8903
--- /dev/null
+++ b/kayak_font/examples/simple.rs
@@ -0,0 +1,30 @@
+use std::{fs::File, io::BufWriter};
+
+use kayak_font::Font;
+
+fn main() {
+    let font_bytes = include_bytes!("../resources/Roboto-Regular.ttf");
+    let mut font = Font::new(font_bytes, 64);
+
+    font.add_character('A');
+    font.add_character('B');
+    font.add_character('C');
+    font.add_character('!');
+    font.add_character('&');
+
+    // Characters that have already been calculated wont be calculated again!
+    for _ in 0..1000000 {
+        font.add_character('A');
+    }
+
+    let dimensions = font.cache.dimensions;
+    for (c, _, pixels) in font.get_data_to_process() {
+        let file = File::create(format!("./test-{}.png", c)).unwrap();
+        let ref mut w = BufWriter::new(file);
+
+        let mut encoder = png::Encoder::new(w, dimensions, dimensions);
+        encoder.set_color(png::ColorType::RGBA);
+        let mut writer = encoder.write_header().unwrap();
+        writer.write_image_data(&pixels).unwrap();
+    }
+}
diff --git a/kayak_font/resources/Roboto-Regular.ttf b/kayak_font/resources/Roboto-Regular.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..2b6392ffe8712b9c5450733320cd220d6c0f4bce
GIT binary patch
literal 171272
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

literal 0
HcmV?d00001

diff --git a/kayak_font/src/color_flags.rs b/kayak_font/src/color_flags.rs
new file mode 100644
index 0000000..7322912
--- /dev/null
+++ b/kayak_font/src/color_flags.rs
@@ -0,0 +1,62 @@
+bitflags::bitflags! {
+    pub struct ColorFlags: u32 {
+        const BLACK = 0b000;
+        const RED = 0b001;
+        const GREEN = 0b010;
+        const BLUE = 0b100;
+        const YELLOW = 0b011;
+        const MAGENTA = 0b101;
+        const CYAN = 0b110;
+        const WHITE = 0b111;
+    }
+}
+
+impl ColorFlags {
+    pub(crate) fn switch(self, seed: &mut u64) -> Self {
+        match self {
+            ColorFlags::WHITE | ColorFlags::BLACK => {
+                const START: [ColorFlags; 3] =
+                    [ColorFlags::CYAN, ColorFlags::MAGENTA, ColorFlags::YELLOW];
+                let tr = START[(*seed % 3) as usize];
+                *seed /= 3;
+                tr
+            }
+            ColorFlags::RED | ColorFlags::GREEN | ColorFlags::BLUE => self ^ ColorFlags::WHITE,
+            _ => {
+                let v = self.bits();
+                let v = (v << (1 + (*seed & 1))) & 0b111;
+                let v = match v.count_ones() {
+                    0 => 0b11,           /* Somehow we lost all the bits. Default to yellow */
+                    1 => v | 0b001, /* We just shifted a bit off the left side, add one on the right */
+                    2 => v,         /* We already have 2 bits, nothing to do */
+                    _ => unreachable!(), /* There should never be 3+ bits set */
+                };
+                *seed >>= 1;
+
+                Self::from_bits_truncate(v)
+            }
+        }
+    }
+
+    pub(crate) fn switch_banned(self, seed: &mut u64, banned: ColorFlags) -> Self {
+        let combined = self & banned;
+        match combined {
+            ColorFlags::RED | ColorFlags::GREEN | ColorFlags::BLUE => combined ^ ColorFlags::WHITE,
+            _ => self.switch(seed),
+        }
+    }
+
+    pub fn float_color(self) -> [f32; 3] {
+        match self {
+            ColorFlags::BLACK => [0.0f32, 0.0f32, 0.0f32],
+            ColorFlags::RED => [1.0f32, 0.0f32, 0.0f32],
+            ColorFlags::GREEN => [0.0f32, 1.0f32, 0.0f32],
+            ColorFlags::BLUE => [0.0f32, 0.0f32, 1.0f32],
+            ColorFlags::CYAN => [0.0f32, 1.0f32, 1.0f32],
+            ColorFlags::MAGENTA => [1.0f32, 0.0f32, 1.0f32],
+            ColorFlags::YELLOW => [1.0f32, 1.0f32, 0.0f32],
+            ColorFlags::WHITE => [1.0f32, 1.0f32, 1.0f32],
+            _ => [0.5, 0.7, 0.5],
+        }
+    }
+}
diff --git a/kayak_font/src/contour.rs b/kayak_font/src/contour.rs
new file mode 100644
index 0000000..c963de3
--- /dev/null
+++ b/kayak_font/src/contour.rs
@@ -0,0 +1,108 @@
+use lyon_geom::math::{Point, Rect};
+use lyon_path::Segment;
+
+use crate::path_element::PathElement;
+
+/// A list of path elements forming a closed loop
+#[derive(Clone, Debug)]
+pub struct Contour {
+    pub elements: Vec<PathElement>,
+}
+
+impl Contour {
+    pub fn winding(&self) -> f32 {
+        let shoelace = |a: Point, b: Point| (b.x - a.x) * (a.y + b.y);
+        let n = self.elements.len();
+        match n {
+            0 => 0.0,
+            1 => {
+                let a = self.elements[0].sample(0.0);
+                let b = self.elements[0].sample(1.0 / 3.0);
+                let c = self.elements[0].sample(2.0 / 3.0);
+
+                shoelace(a, b) + shoelace(b, c) + shoelace(c, a)
+            }
+            2 => {
+                let a = self.elements[0].sample(0.0);
+                let b = self.elements[0].sample(0.5);
+                let c = self.elements[1].sample(0.0);
+                let d = self.elements[1].sample(0.5);
+
+                shoelace(a, b) + shoelace(b, c) + shoelace(c, d) + shoelace(d, a)
+            }
+            _ => {
+                let mut total = 0.0;
+                let mut prev = self.elements[n - 1].sample(0.0);
+
+                for e in &self.elements {
+                    let curr = e.sample(0.0);
+                    total += shoelace(prev, curr);
+                    prev = curr;
+                }
+
+                total
+            }
+        }
+        .signum()
+    }
+}
+
+/// Rescale contours so they fit in the provided rectangle.
+/// Returns the scaled contours along with the transformation used to rescale the contours
+pub fn rescale_contours(
+    mut contours: Vec<Contour>,
+    initial_bounds: Rect,
+    bounds: Rect,
+    _units_per_em: u16,
+) -> (Vec<Contour>, lyon_geom::math::Transform2D) {
+    // let (new_width, new_height) = if initial_bounds.size.width > initial_bounds.size.height {
+    //     let new_width = 1.0;
+    //     let new_height = aspect_ratio_height(
+    //         initial_bounds.size.height,
+    //         initial_bounds.size.width,
+    //         new_width,
+    //     );
+
+    //     (new_width, new_height)
+    // } else {
+    //     let new_height = 1.0;
+    //     let new_width = aspect_ratio_width(
+    //         initial_bounds.size.height,
+    //         initial_bounds.size.width,
+    //         new_height,
+    //     );
+
+    //     (new_width, new_height)
+    // };
+
+    // dbg!(new_width, new_height);
+
+    // let x_scale = new_width / initial_bounds.size.width;
+    // let y_scale = new_height / initial_bounds.size.height;
+
+    let initial_scale = initial_bounds.size.height.max(initial_bounds.size.width);
+    let bounds_scale = bounds.size.width.max(bounds.size.height);
+
+    // let size = 128.0 / units_per_em as f32;
+    let transformation = lyon_geom::math::Transform2D::create_translation(
+        -initial_bounds.origin.x as f32,
+        -initial_bounds.origin.y as f32,
+    )
+    .post_scale(bounds_scale / initial_scale, bounds_scale / initial_scale)
+    .post_translate(bounds.origin.to_vector());
+    for contour in &mut contours {
+        for mut elem in &mut contour.elements {
+            elem.segment = match elem.segment {
+                Segment::Line(s) => Segment::Line(s.transform(&transformation)),
+                Segment::Quadratic(s) => Segment::Quadratic(s.transform(&transformation)),
+                Segment::Cubic(s) => Segment::Cubic(s.transform(&transformation)),
+                Segment::Arc(s) => Segment::Arc(lyon_geom::Arc {
+                    center: transformation.transform_point(&s.center),
+                    ..s
+                }),
+            }
+        }
+    }
+
+    (contours, transformation)
+}
diff --git a/kayak_font/src/font.rs b/kayak_font/src/font.rs
new file mode 100644
index 0000000..806d47e
--- /dev/null
+++ b/kayak_font/src/font.rs
@@ -0,0 +1,253 @@
+use std::collections::{HashMap, HashSet};
+
+use lyon_geom::math::{Angle, Point, Rect, Size};
+use lyon_path::builder::FlatPathBuilder;
+
+use crate::{compute_msdf, recolor_contours, rescale_contours, PathCollector};
+
+#[derive(Debug, Clone)]
+pub struct FontCache {
+    count: usize,
+    pub dimensions: u32,
+    chars: HashMap<char, (usize, Vec<u8>)>,
+    needs_processing: HashSet<usize>,
+    id_to_char_mappings: HashMap<usize, char>,
+}
+
+impl FontCache {
+    pub fn new(texture_size: u32) -> Self {
+        Self {
+            count: 0,
+            dimensions: texture_size,
+            chars: HashMap::default(),
+            needs_processing: HashSet::default(),
+            id_to_char_mappings: HashMap::default(),
+        }
+    }
+
+    fn set_texture(&mut self, c: char, texture_data: Vec<Vec<(f32, f32, f32)>>) {
+        // let pixels: Vec<u8> = texture_data
+        //     .iter()
+        //     .flat_map(|y| {
+        //         y.iter().flat_map(|pixel| {
+        //             vec![
+        //                 (pixel.0 * 255.0) as u8,
+        //                 (pixel.1 * 255.0) as u8,
+        //                 (pixel.2 * 255.0) as u8,
+        //                 255u8,
+        //             ]
+        //         })
+        //     })
+        //     .collect();
+        let pixels = texture_data
+            .iter()
+            .flat_map(|x| {
+                x.iter()
+                    .flat_map(|p| {
+                        vec![
+                            p.0.to_le_bytes(),
+                            p.1.to_le_bytes(),
+                            p.2.to_le_bytes(),
+                            1.0f32.to_le_bytes(),
+                        ]
+                        .into_iter()
+                        .flatten()
+                        .collect::<Vec<u8>>()
+                    })
+                    .collect::<Vec<u8>>()
+            })
+            .collect();
+        self.chars.insert(c, (self.count, pixels));
+        self.needs_processing.insert(self.count);
+        self.id_to_char_mappings.insert(self.count, c);
+        self.count += 1;
+    }
+
+    fn has_character(&self, c: char) -> bool {
+        self.chars.contains_key(&c)
+    }
+
+    fn get_dimensions(&self) -> u32 {
+        self.dimensions
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Font {
+    internal_face: ttf_parser::Face<'static>,
+    font: fontdue::Font,
+    pub cache: FontCache,
+}
+
+impl Font {
+    pub fn new(font_data: &'static [u8], texture_size: u32) -> Font {
+        Font {
+            internal_face: ttf_parser::Face::from_slice(&font_data, 0).unwrap(),
+            font: fontdue::Font::from_bytes(font_data.clone(), fontdue::FontSettings::default())
+                .unwrap(),
+            cache: FontCache::new(texture_size),
+        }
+    }
+
+    /// Adds all of the common known characters.
+    pub fn add_all_common(&mut self) {
+        let chars = vec![
+            '`', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '~', '!', '@', '#',
+            '$', '%', '^', '&', '*', '(', ')', '_', '+', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
+            'o', 'p', '[', ']', '\\', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}',
+            '|', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', 'A', 'S', 'D', 'F', 'G',
+            'H', 'J', 'K', 'L', ':', '"', 'z', 'x', 'c', 'v', 'b', 'n', 'n', 'm', ',', '.', '/',
+            'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?',
+        ];
+
+        for char in chars {
+            self.add_character(char);
+        }
+    }
+
+    pub fn get_layout(
+        &self,
+        content: &String,
+        font_size: f32,
+    ) -> Vec<(char, (f32, f32), (f32, f32))> {
+        let mut layout =
+            fontdue::layout::Layout::new(fontdue::layout::CoordinateSystem::PositiveYDown);
+        layout.append(
+            &[&self.font],
+            &fontdue::layout::TextStyle::new(content, font_size, 0),
+        );
+
+        let glyphs = layout.glyphs();
+        let glyphs: Vec<_> = glyphs
+            .iter()
+            .filter_map(|glyph_position| {
+                if glyph_position.parent == ' ' {
+                    return None;
+                }
+                // let metrics = self.font.metrics(glyph_position.parent, font_size);
+                let font_scale = font_size / self.font.units_per_em() as f32;
+                let scale =
+                    if let Some(glyph) = self.internal_face.glyph_index(glyph_position.parent) {
+                        // TODO: Cache this in add_character..
+                        let mut path_collector = PathCollector::new();
+                        let rect = self
+                            .internal_face
+                            .outline_glyph(glyph, &mut path_collector)
+                            .unwrap();
+                        let width = rect.width();
+                        let height = rect.height();
+                        width.max(height) as f32 * font_scale
+                    } else {
+                        0.0
+                    };
+
+                // let shift_x = if scale > glyph_position.width as f32 {
+                //     scale - glyph_position.width as f32
+                // } else {
+                //     // glyph_position.width as f32 - scale
+                //     0.0
+                // };
+                let shift_y = if scale > glyph_position.height as f32 {
+                    scale - glyph_position.height as f32
+                } else {
+                    0.0
+                };
+                Some((
+                    glyph_position.parent,
+                    (glyph_position.x, glyph_position.y - shift_y),
+                    (scale, scale),
+                ))
+            })
+            .collect();
+        glyphs
+    }
+
+    // pub fn get_size(&self, c: char, font_size: f32) -> (f32, f32) {
+    //     if let Some(glyph) = self.internal_face.glyph_index(c) {
+    //         // Collect our path's from the glyph's outline shape.
+    //         let mut path_collector = PathCollector::new();
+    //         let rect = self
+    //             .internal_face
+    //             .outline_glyph(glyph, &mut path_collector)
+    //             .unwrap();
+    //         let metrics = font_size / self.font.units_per_em();
+
+    //         (width as f32 * metrics, height as f32 * metrics)
+    //     } else {
+    //         panic!("")
+    //     }
+    // }
+
+    pub fn get_char_id(&self, c: char) -> usize {
+        if self.cache.has_character(c) {
+            if let Some((id, _)) = self.cache.chars.get(&c) {
+                return *id;
+            }
+        }
+        panic!("No char found!");
+    }
+
+    pub fn add_character(&mut self, c: char) {
+        if !self.cache.has_character(c) {
+            if let Some(glyph) = self.internal_face.glyph_index(c) {
+                // Collect our path's from the glyph's outline shape.
+                let mut path_collector = PathCollector::new();
+                let rect = self
+                    .internal_face
+                    .outline_glyph(glyph, &mut path_collector)
+                    .unwrap();
+                let contours = path_collector.build();
+
+                // Bounds of our texture in UV's
+                // TODO: Allow this to change because some people may want texture atlases instead.
+                let uv_rect = Rect::new(Point::new(0.0, 0.0), Size::new(1.0, 1.0));
+
+                // Bounds of our rect in font space coords.
+                let font_rect = Rect::new(
+                    Point::new(rect.x_min as f32, rect.y_min as f32),
+                    Size::new(rect.width() as f32, rect.height() as f32),
+                );
+
+                let (contours, _transform) = rescale_contours(
+                    contours,
+                    font_rect,
+                    uv_rect,
+                    self.internal_face.units_per_em(),
+                );
+                let contours = recolor_contours(contours, Angle::degrees(3.0), 1);
+                let msdf = compute_msdf(&contours, self.cache.get_dimensions() as usize);
+
+                self.cache.set_texture(c, msdf);
+            }
+        }
+    }
+
+    pub fn get_data_to_process<'b>(&'b mut self) -> Vec<(char, usize, &'b Vec<u8>)> {
+        let data = self
+            .cache
+            .needs_processing
+            .iter()
+            .filter_map(|unprocessed_id| {
+                if let Some(c) = self.cache.id_to_char_mappings.get(unprocessed_id) {
+                    if let Some((_, data)) = self.cache.chars.get(c) {
+                        return Some((*c, *unprocessed_id, data));
+                    }
+                }
+
+                None
+            })
+            .collect();
+
+        self.cache.needs_processing.clear();
+
+        data
+    }
+
+    // Checks the given chars and returns ones that haven't been seen before.
+    pub fn check_chars(&self, chars: std::str::Chars<'_>) -> Vec<char> {
+        chars
+            .into_iter()
+            .filter(|c| !self.cache.chars.contains_key(&c))
+            .collect()
+    }
+}
diff --git a/kayak_font/src/lib.rs b/kayak_font/src/lib.rs
new file mode 100644
index 0000000..07499ca
--- /dev/null
+++ b/kayak_font/src/lib.rs
@@ -0,0 +1,27 @@
+mod color_flags;
+mod contour;
+mod font;
+mod msdf;
+mod path_collector;
+mod path_element;
+mod recolor;
+mod sdf;
+mod ttf_parser;
+mod utils;
+
+pub use color_flags::ColorFlags;
+pub use contour::{rescale_contours, Contour};
+pub use font::{Font, FontCache};
+pub use lyon_geom::math::{Angle, Point, Rect, Vector};
+pub use lyon_path::builder::FlatPathBuilder;
+pub use msdf::compute_msdf;
+pub use path_collector::PathCollector;
+pub use path_element::PathElement;
+pub use recolor::recolor_contours;
+pub use sdf::compute_sdf;
+
+pub(crate) fn median(a: f32, b: f32, c: f32) -> f32 {
+    let min = |a: f32, b: f32| a.min(b);
+    let max = |a: f32, b: f32| a.max(b);
+    max(min(a, b), min(max(a, b), c))
+}
diff --git a/kayak_font/src/msdf.rs b/kayak_font/src/msdf.rs
new file mode 100644
index 0000000..8429e93
--- /dev/null
+++ b/kayak_font/src/msdf.rs
@@ -0,0 +1,171 @@
+use lyon_geom::math::Vector;
+
+use crate::{contour::Contour, median, utils::EdgeDistance, ColorFlags};
+
+/// Computes an MSDF from a list of contours. The returned vectors are a `dim` by `dim`
+/// matrix of signed distance values. The output represents the signed distances to the contours
+/// within [0, 1] x [0, 1]
+pub fn compute_msdf(contours: &[Contour], dim: usize) -> Vec<Vec<(f32, f32, f32)>> {
+    #[derive(Copy, Clone, PartialEq)]
+    struct MultiDistance {
+        r: f32,
+        g: f32,
+        b: f32,
+        med: f32,
+    }
+    impl MultiDistance {
+        fn new(v: f32) -> Self {
+            Self {
+                r: v,
+                g: v,
+                b: v,
+                med: v,
+            }
+        }
+    }
+    let scale: f32 = 1.0 / (dim as f32);
+    let windings: Vec<i32> = contours.iter().map(|c| c.winding() as i32).collect();
+
+    (0..dim)
+        .map(|y| {
+            let py = (y as f32 + 0.5) * scale;
+            (0..dim)
+                .map(|x| {
+                    // We assume there is at least 1 contour
+                    // If there isn't make everything magenta
+                    if contours.len() == 0 {
+                        return (1.0f32, 0.0, 1.0);
+                    }
+
+                    let px = (x as f32 + 0.5) * scale;
+                    let p = Vector::new(px, py);
+
+                    let mut neg_dist = 1e24f32;
+                    let mut pos_dist = -1e24f32;
+                    let mut d = 1e24f32;
+                    let mut winding = 0;
+                    let mut contour_distances = Vec::new();
+                    contour_distances.reserve(contours.len());
+
+                    let mut sr = EdgeDistance::new();
+                    let mut sg = EdgeDistance::new();
+                    let mut sb = EdgeDistance::new();
+
+                    for (i, contour) in contours.iter().enumerate() {
+                        let mut contour_min_r = EdgeDistance::new();
+                        let mut contour_min_g = EdgeDistance::new();
+                        let mut contour_min_b = EdgeDistance::new();
+
+                        for elem in &contour.elements {
+                            let (d, na) = elem.distance(p.to_point());
+
+                            if elem.color.contains(ColorFlags::RED) && d < contour_min_r.dist {
+                                contour_min_r.dist = d;
+                                contour_min_r.edge = Some(&elem);
+                                contour_min_r.nearest_approach = na;
+                            }
+                            if elem.color.contains(ColorFlags::GREEN) && d < contour_min_g.dist {
+                                contour_min_g.dist = d;
+                                contour_min_g.edge = Some(&elem);
+                                contour_min_g.nearest_approach = na;
+                            }
+                            if elem.color.contains(ColorFlags::BLUE) && d < contour_min_b.dist {
+                                contour_min_b.dist = d;
+                                contour_min_b.edge = Some(&elem);
+                                contour_min_b.nearest_approach = na;
+                            }
+                        }
+
+                        if contour_min_r.dist < sr.dist {
+                            sr = contour_min_r;
+                        }
+                        if contour_min_g.dist < sg.dist {
+                            sg = contour_min_g;
+                        }
+                        if contour_min_b.dist < sb.dist {
+                            sb = contour_min_b;
+                        }
+
+                        let med_min_dist = median(
+                            contour_min_r.dist.distance,
+                            contour_min_g.dist.distance,
+                            contour_min_b.dist.distance,
+                        )
+                        .abs();
+                        if med_min_dist < d {
+                            d = med_min_dist;
+                            winding = -windings[i];
+                        }
+
+                        contour_min_r.to_pseudodistance(p);
+                        contour_min_g.to_pseudodistance(p);
+                        contour_min_b.to_pseudodistance(p);
+
+                        let med_min_dist = median(
+                            contour_min_r.dist.distance,
+                            contour_min_g.dist.distance,
+                            contour_min_b.dist.distance,
+                        );
+
+                        let mut msd = MultiDistance::new(med_min_dist);
+                        msd.r = contour_min_r.dist.distance;
+                        msd.g = contour_min_g.dist.distance;
+                        msd.b = contour_min_b.dist.distance;
+                        msd.med = med_min_dist;
+                        contour_distances.push(msd);
+                        if windings[i] > 0
+                            && med_min_dist >= 0.0
+                            && med_min_dist.abs() < pos_dist.abs()
+                        {
+                            pos_dist = med_min_dist;
+                        }
+                        if windings[i] < 0
+                            && med_min_dist <= 0.0
+                            && med_min_dist.abs() < neg_dist.abs()
+                        {
+                            neg_dist = med_min_dist;
+                        }
+                    }
+
+                    assert!(contour_distances.len() == windings.len());
+
+                    sr.to_pseudodistance(p);
+                    sg.to_pseudodistance(p);
+                    sb.to_pseudodistance(p);
+
+                    let mut mmsd = MultiDistance::new(-1e24);
+                    if pos_dist >= 0.0 && pos_dist.abs() <= neg_dist.abs() {
+                        mmsd.med = -1e24;
+                        winding = 1;
+                        for (csd, cw) in contour_distances.iter().zip(windings.iter()) {
+                            if *cw > 0 && csd.med > mmsd.med && csd.med.abs() < neg_dist.abs() {
+                                mmsd = *csd;
+                            }
+                        }
+                    } else if neg_dist <= 0.0 && neg_dist.abs() <= pos_dist.abs() {
+                        mmsd.med = 1e24;
+                        winding = -1;
+                        for (csd, cw) in contour_distances.iter().zip(windings.iter()) {
+                            if *cw < 0 && csd.med < mmsd.med && csd.med.abs() < pos_dist.abs() {
+                                mmsd = *csd;
+                            }
+                        }
+                    }
+                    for (csd, w) in contour_distances.iter().zip(windings.iter()) {
+                        if *w != winding && csd.med.abs() < mmsd.med.abs() {
+                            mmsd = *csd;
+                        }
+                    }
+
+                    if median(sr.dist.distance, sg.dist.distance, sb.dist.distance) == mmsd.med {
+                        mmsd.r = sr.dist.distance;
+                        mmsd.g = sg.dist.distance;
+                        mmsd.b = sb.dist.distance;
+                    }
+
+                    (mmsd.r / 0.5, mmsd.g / 0.5, mmsd.b / 0.5)
+                })
+                .collect()
+        })
+        .collect()
+}
diff --git a/kayak_font/src/path_collector.rs b/kayak_font/src/path_collector.rs
new file mode 100644
index 0000000..077bc44
--- /dev/null
+++ b/kayak_font/src/path_collector.rs
@@ -0,0 +1,134 @@
+use lyon_geom::math::{Angle, Point, Vector};
+use lyon_path::{
+    builder::{FlatPathBuilder, PathBuilder},
+    Segment,
+};
+
+use crate::{color_flags::ColorFlags, contour::Contour, path_element::PathElement};
+
+/// This is a path collector which produces our custom contour type.
+pub struct PathCollector {
+    /// The start point of the last contour
+    pub(crate) contour_start: Point,
+    /// The current pen location
+    pub(crate) pen: Point,
+    /// in-flight path elements
+    pub(crate) elements: Vec<PathElement>,
+    /// Completed contours
+    pub(crate) contours: Vec<Contour>,
+    pub scale: f32,
+}
+
+impl PathCollector {
+    pub fn new() -> Self {
+        Self {
+            contour_start: Point::new(0.0, 0.0),
+            pen: Point::new(0.0, 0.0),
+            elements: Vec::new(),
+            contours: Vec::new(),
+            scale: 1.0,
+        }
+    }
+}
+
+impl PathBuilder for PathCollector {
+    fn quadratic_bezier_to(&mut self, ctrl: Point, to: Point) {
+        self.elements.push(PathElement::new(
+            Segment::Quadratic(lyon_geom::QuadraticBezierSegment {
+                from: self.pen * self.scale,
+                to: to * self.scale,
+                ctrl: ctrl * self.scale,
+            }),
+            ColorFlags::WHITE,
+        ));
+        self.pen = to;
+    }
+
+    fn cubic_bezier_to(&mut self, ctrl1: Point, ctrl2: Point, to: Point) {
+        self.elements.push(PathElement::new(
+            Segment::Cubic(lyon_geom::CubicBezierSegment {
+                from: self.pen * self.scale,
+                to: to * self.scale,
+                ctrl1: ctrl1 * self.scale,
+                ctrl2: ctrl2 * self.scale,
+            }),
+            ColorFlags::WHITE,
+        ));
+
+        self.pen = to;
+    }
+
+    fn arc(&mut self, _center: Point, _radii: Vector, _sweep_angle: Angle, _x_rotation: Angle) {
+        unimplemented!()
+    }
+}
+
+impl FlatPathBuilder for PathCollector {
+    type PathType = Vec<Contour>;
+
+    fn move_to(&mut self, to: Point) {
+        self.pen = to * self.scale;
+        self.contour_start = to * self.scale;
+    }
+
+    fn line_to(&mut self, to: Point) {
+        self.elements.push(PathElement::new(
+            Segment::Line(lyon_geom::LineSegment {
+                from: self.pen * self.scale,
+                to: to * self.scale,
+            }),
+            ColorFlags::WHITE,
+        ));
+        self.pen = to * self.scale;
+    }
+
+    fn close(&mut self) {
+        if (self.pen - self.contour_start).length() > 1E-14 {
+            self.elements.push(PathElement::new(
+                Segment::Line(lyon_geom::LineSegment {
+                    from: self.pen * self.scale,
+                    to: self.contour_start * self.scale,
+                }),
+                ColorFlags::WHITE,
+            ));
+        }
+
+        self.pen = self.contour_start;
+        let elements = std::mem::replace(&mut self.elements, Vec::new());
+
+        self.contours.push(Contour { elements });
+    }
+
+    fn build(self) -> Self::PathType {
+        let mut contours = self.contours;
+        if self.elements.len() > 0 {
+            let final_contour = Contour {
+                elements: self.elements,
+            };
+
+            contours.push(final_contour);
+        }
+
+        contours
+    }
+
+    fn build_and_reset(&mut self) -> Self::PathType {
+        let elements = std::mem::replace(&mut self.elements, Vec::new());
+        if elements.len() > 0 {
+            let final_contour = Contour { elements };
+
+            self.contours.push(final_contour);
+        }
+
+        let tr = std::mem::replace(&mut self.contours, Vec::new());
+
+        self.contour_start = Point::new(0.0, 0.0);
+        self.pen = Point::new(0.0, 0.0);
+
+        tr
+    }
+
+    fn current_position(&self) -> Point {
+        self.pen
+    }
+}
diff --git a/kayak_font/src/path_element.rs b/kayak_font/src/path_element.rs
new file mode 100644
index 0000000..7500fcc
--- /dev/null
+++ b/kayak_font/src/path_element.rs
@@ -0,0 +1,191 @@
+use crate::{color_flags::ColorFlags, utils::AugmentedDistance};
+use lyon_geom::math::{Point, Vector};
+use lyon_path::Segment;
+
+#[derive(Clone, Debug, Copy)]
+pub struct PathElement {
+    pub segment: Segment,
+    pub color: ColorFlags,
+}
+
+impl PathElement {
+    pub fn new(segment: Segment, color: ColorFlags) -> PathElement {
+        Self { segment, color }
+    }
+
+    pub fn sample(&self, t: f32) -> Point {
+        match self.segment {
+            Segment::Line(s) => s.sample(t),
+            Segment::Quadratic(s) => s.sample(t),
+            Segment::Cubic(s) => s.sample(t),
+            Segment::Arc(s) => s.sample(t),
+        }
+    }
+
+    pub fn direction(&self, f: f32) -> Vector {
+        use lyon_geom::Segment as SegmentTrait;
+        let f = f.min(1.0).max(0.0);
+        match self.segment {
+            Segment::Line(s) => s.derivative(f),
+            Segment::Quadratic(s) => s.derivative(f),
+            Segment::Cubic(s) => s.derivative(f),
+            Segment::Arc(s) => s.derivative(f),
+        }
+    }
+
+    /// Split a path element into 3rds
+    pub fn split_in_thirds(&self) -> [PathElement; 3] {
+        macro_rules! segment_case {
+            ($i:expr, $s:expr) => {{
+                let (a, b) = ($i).split(1.0 / 3.0);
+                let (b, c) = b.split(1.0 / 2.0);
+
+                [a, b, c]
+                    .into_iter()
+                    .map(|x| PathElement::new(($s)(x), self.color))
+                    .collect()
+            }};
+        }
+        let segments: arrayvec::ArrayVec<PathElement, 3> = match self.segment {
+            Segment::Line(s) => segment_case!(s, Segment::Line),
+            Segment::Quadratic(s) => segment_case!(s, Segment::Quadratic),
+            Segment::Cubic(s) => segment_case!(s, Segment::Cubic),
+            Segment::Arc(s) => segment_case!(s, Segment::Arc),
+        };
+
+        segments
+            .into_inner()
+            .expect("We should have precisely the right capacity")
+    }
+
+    /// Computes the distance from p to this path element
+    /// Returns the distance from the point to this path element,
+    /// and the distance along this element to the closest point.
+    pub fn distance(&self, p: Point) -> (AugmentedDistance, f32) {
+        use lyon_geom::{LineSegment, QuadraticBezierSegment};
+        match self.segment {
+            Segment::Line(LineSegment { from: s, to: e }) => {
+                let aq = p - s;
+                let ab = e - s;
+                let f = aq.dot(ab) / ab.dot(ab);
+                let eq = if f >= 0.5 { p - e } else { p - s };
+
+                let dist_to_endpoint = eq.length();
+                let endpoint_sd = AugmentedDistance::new(
+                    aq.cross(ab).signum() * dist_to_endpoint,
+                    // ab.normalize().cross(eq.normalize()),
+                    ab.normalize().dot(eq.normalize()).abs(),
+                );
+
+                if 0.0 < f && f < 1.0 {
+                    let ortho = Vector::new(ab.y, -ab.x).normalize();
+                    let ortho_dist = ortho.dot(aq);
+                    if ortho_dist.abs() < endpoint_sd.distance.abs() {
+                        (AugmentedDistance::new(ortho_dist, 0.0), f)
+                    } else {
+                        (endpoint_sd, f)
+                    }
+                } else {
+                    (endpoint_sd, f)
+                }
+            }
+
+            Segment::Quadratic(QuadraticBezierSegment {
+                from: p0,
+                ctrl: p1,
+                to: p2,
+            }) => {
+                use lyon_geom::utils::cubic_polynomial_roots;
+                let qa = p0 - p;
+                let ab = p1 - p0;
+                let br = (p0 - p1) + (p2 - p1);
+                let a = br.dot(br);
+                let b = 3.0 * ab.dot(br);
+                let c = 2.0 * ab.dot(ab) + qa.dot(br);
+                let d = qa.dot(ab);
+                let solutions = cubic_polynomial_roots(a, b, c, d);
+
+                let mut min_dist = ab.cross(qa).signum() * qa.length();
+
+                let mut f = -qa.dot(ab) / ab.dot(ab);
+                {
+                    let ec = p2 - p1;
+                    let ep = p2 - p;
+                    let dist = ec.cross(ep).signum() * ep.length();
+                    if dist.abs() < min_dist.abs() {
+                        min_dist = dist;
+                        f = (p - p1).dot(ec) / ec.dot(ec);
+                    }
+                }
+                for t in solutions {
+                    if t <= 0.0 || 1.0 <= t {
+                        continue;
+                    }
+                    let endpoint = p0 + (ab * 2.0 * t) + (br * t * t);
+                    let delta = endpoint - p;
+                    let dist = (p2 - p0).cross(delta).signum() * delta.length();
+
+                    if dist.abs() < min_dist.abs() {
+                        min_dist = dist;
+                        f = t;
+                    }
+                }
+
+                if 0.0 <= f && f <= 1.0 {
+                    (AugmentedDistance::new(min_dist, 0.0), f)
+                // (AugmentedDistance::new(200f32, 0.0), f)
+                } else if f < 0.5 {
+                    (
+                        AugmentedDistance::new(min_dist, ab.normalize().dot(qa.normalize()).abs()),
+                        f,
+                    )
+                } else {
+                    (
+                        AugmentedDistance::new(
+                            min_dist,
+                            (p2 - p1).normalize().dot((p2 - p).normalize()).abs(),
+                        ),
+                        f,
+                    )
+                }
+            }
+
+            _ => unimplemented!(),
+        }
+    }
+
+    pub(crate) fn to_psuedodistance(
+        &self,
+        dist: AugmentedDistance,
+        p: Vector,
+        near: f32,
+    ) -> AugmentedDistance {
+        if near <= 0.0 {
+            let dir = self.direction(0.0).normalize();
+            let aq = p - self.sample(0.0).to_vector();
+            let ts = aq.dot(dir);
+            if ts < 0.0 {
+                let ds = aq.cross(dir);
+                if ds.abs() <= dist.distance.abs() {
+                    return AugmentedDistance::new(ds, 0.0);
+                }
+            }
+
+            dist
+        } else if near >= 1.0 {
+            let dir = self.direction(1.0).normalize();
+            let aq = p - self.sample(1.0).to_vector();
+            let ts = aq.dot(dir);
+            if ts > 0.0 {
+                let ds = aq.cross(dir);
+                if ds.abs() <= dist.distance.abs() {
+                    return AugmentedDistance::new(ds, 0.0);
+                }
+            }
+
+            dist
+        } else {
+            dist
+        }
+    }
+}
diff --git a/kayak_font/src/recolor.rs b/kayak_font/src/recolor.rs
new file mode 100644
index 0000000..61cbbe8
--- /dev/null
+++ b/kayak_font/src/recolor.rs
@@ -0,0 +1,124 @@
+use lyon_geom::math::{Angle, Vector};
+
+use crate::contour::Contour;
+use crate::ColorFlags;
+
+/// Recolor the contours prior to MSDF computation.
+/// This function uses a simple technique,
+/// again based on Viktor's implementation.
+/// It is left as a separate step so you can implement more complex techniques as desired.
+pub fn recolor_contours(contours: Vec<Contour>, threshold: Angle, mut seed: u64) -> Vec<Contour> {
+    let (threshold, _) = threshold.sin_cos();
+
+    // Determine if a point is a corner, assuming i and o are incoming and
+    // outgoing normalized direction vectors
+    let is_corner = |i: Vector, o: Vector| {
+        let d = i.dot(o); /* |i| |o| cos(t) */
+        let c = i.cross(o).abs(); /* |i| |o| sin(t) */
+
+        // if this corner turns more than 90 degrees (detected by dot product/cos)
+        // or if it turns more than the threshold angle (detected by cross product/sin)
+        (d <= 0.0) || (c > threshold)
+    };
+    contours
+        .into_iter()
+        .map(|mut c| {
+            let mut corners = Vec::new();
+            let n = c.elements.len();
+            // Find all the corners
+            if n != 0 {
+                let mut prev_dir = c.elements[n - 1].direction(1.0).normalize();
+                for (i, e) in c.elements.iter().enumerate() {
+                    let c_dir = e.direction(0.0).normalize();
+                    if is_corner(prev_dir, c_dir) {
+                        corners.push(i)
+                    }
+                    prev_dir = e.direction(1.0).normalize();
+                }
+            }
+
+            match corners.len() {
+                0 => {
+                    // The whole contour is smooth, and we initialized all colors to white.
+                    // No work to do
+                    c
+                }
+                1 => {
+                    // "Teardrop" case: there is only one sharp corner so we
+                    // just pick 3 colors up front and cycle through them
+                    let mut colors = [
+                        (ColorFlags::WHITE).switch(&mut seed),
+                        ColorFlags::WHITE,
+                        ColorFlags::WHITE,
+                    ];
+                    colors[1] = colors[0].switch(&mut seed);
+                    colors[2] = colors[1].switch(&mut seed);
+                    let corner = corners[0];
+                    match n {
+                        0 => {
+                            unreachable!();
+                        }
+                        1 => {
+                            // Only a single edge segment, but it's a teardrop.
+                            // We split it in 3 to make the colors happen
+                            let mut split = c.elements[0].split_in_thirds();
+                            split[0].color = colors[0];
+                            split[1].color = colors[1];
+                            split[2].color = colors[2];
+
+                            c.elements.clear();
+                            c.elements.extend_from_slice(&split);
+                        }
+                        2 => {
+                            // 2 segments. We split it into 6, and assign colors by hand
+                            let mut split0 = c.elements[0].split_in_thirds();
+                            let mut split1 = c.elements[1].split_in_thirds();
+                            split0[0].color = colors[0];
+                            split0[1].color = colors[0];
+                            split0[2].color = colors[1];
+                            split1[0].color = colors[1];
+                            split1[1].color = colors[2];
+                            split1[2].color = colors[2];
+
+                            c.elements.clear();
+                            c.elements.extend_from_slice(&split0);
+                            c.elements.extend_from_slice(&split1);
+                        }
+                        _ => {
+                            // We have more than 3 edges to rotate colors through
+                            for (i, e) in c.elements.iter_mut().enumerate() {
+                                // ported from this cursed C++ code:
+                                // contour->edges[(corner+i)%m]->color = (colors+1)[int(3+2.875*i/(m-1)-1.4375+.5)-3];
+                                let i = (n + i - corner) % n; // Emulate the ( corner + i) % m
+                                let idx_fractional =
+                                    3.5f32 + 2.875f32 * (i as f32) / ((n - 1) as f32) - 1.4375f32;
+                                let idx = idx_fractional.floor() as usize - 2;
+                                e.color = colors[idx];
+                            }
+                        }
+                    }
+                    c
+                }
+                _ => {
+                    // We have 2 or more corners
+                    // Cycle through colors, switching whenever we hit another corner
+                    let n_corners = corners.len();
+                    let mut spline = 0;
+                    let start = corners[0];
+                    let mut color = ColorFlags::WHITE;
+                    color = color.switch(&mut seed);
+                    let initial_color = color;
+                    for i in 0..n {
+                        let i = (start + i) % n;
+                        if spline + 1 < n_corners && corners[spline + 1] == i {
+                            spline = spline + 1;
+                            color = color.switch_banned(&mut seed, initial_color);
+                        }
+                        c.elements[i].color = color;
+                    }
+                    c
+                }
+            }
+        })
+        .collect()
+}
diff --git a/kayak_font/src/sdf.rs b/kayak_font/src/sdf.rs
new file mode 100644
index 0000000..c1cd976
--- /dev/null
+++ b/kayak_font/src/sdf.rs
@@ -0,0 +1,87 @@
+use lyon_geom::math::Vector;
+
+use crate::{contour::Contour, utils::EdgeDistance};
+
+/// Computes a SDF from a list of contours. The returned vectors are a `dim` by `dim`
+/// matrix of signed distances. The output represents the signed distances to the contours
+/// within [0, 1] x [0, 1]
+pub fn compute_sdf(contours: &[Contour], dim: usize) -> Vec<Vec<f32>> {
+    let scale: f32 = 1.0 / (dim as f32);
+    let windings: Vec<i32> = contours.iter().map(|c| c.winding() as i32).collect();
+
+    (0..dim)
+        .map(|y| {
+            let py = (y as f32 + 0.5) * scale;
+            (0..dim)
+                .map(|x| {
+                    if contours.len() == 0 {
+                        return 1.0f32;
+                    }
+
+                    let px = (x as f32 + 0.5) * scale;
+                    let p = Vector::new(px, py);
+
+                    let mut neg_dist = 1e24f32;
+                    let mut pos_dist = -1e24f32;
+                    let mut winding = 0;
+                    let mut contour_distances = Vec::new();
+                    contour_distances.reserve(contours.len());
+
+                    for (i, contour) in contours.iter().enumerate() {
+                        let mut contour_min = EdgeDistance::new();
+
+                        for elem in contour.elements.iter() {
+                            let (d, na) = elem.distance(p.to_point());
+
+                            if d < contour_min.dist {
+                                contour_min.dist = d;
+                                contour_min.edge = Some(&elem);
+                                contour_min.nearest_approach = na;
+                            }
+                        }
+
+                        // contour_min.to_pseudodistance(p);
+                        let cmdd = contour_min.dist.distance;
+
+                        contour_distances.push(cmdd);
+
+                        if windings[i] > 0 && cmdd >= 0.0 && cmdd.abs() < pos_dist.abs() {
+                            pos_dist = cmdd;
+                        }
+                        if windings[i] < 0 && cmdd <= 0.0 && cmdd.abs() < neg_dist.abs() {
+                            neg_dist = cmdd;
+                        }
+                    }
+
+                    assert!(contour_distances.len() == windings.len());
+
+                    let mut md = -1e24;
+                    if pos_dist >= 0.0 && pos_dist.abs() <= neg_dist.abs() {
+                        md = pos_dist;
+                        winding = 1;
+                        for (d, w) in contour_distances.iter().zip(windings.iter()) {
+                            if *w > 0 && *d > md && d.abs() < neg_dist.abs() {
+                                md = *d;
+                            }
+                        }
+                    } else if neg_dist <= 0.0 && neg_dist.abs() <= pos_dist.abs() {
+                        md = neg_dist;
+                        winding = -1;
+                        for (d, w) in contour_distances.iter().zip(windings.iter()) {
+                            if *w < 0 && *d < md && d.abs() < pos_dist.abs() {
+                                md = *d;
+                            }
+                        }
+                    }
+                    for (c, w) in contour_distances.iter().zip(windings.iter()) {
+                        if *w != winding && c.abs() < md.abs() {
+                            md = *c;
+                        }
+                    }
+
+                    md / 0.5
+                })
+                .collect()
+        })
+        .collect()
+}
diff --git a/kayak_font/src/ttf_parser.rs b/kayak_font/src/ttf_parser.rs
new file mode 100644
index 0000000..4c8607c
--- /dev/null
+++ b/kayak_font/src/ttf_parser.rs
@@ -0,0 +1,69 @@
+use lyon_geom::math::Point;
+use lyon_path::Segment;
+
+use crate::{ColorFlags, Contour, PathCollector, PathElement};
+
+impl ttf_parser::OutlineBuilder for PathCollector {
+    fn move_to(&mut self, x: f32, y: f32) {
+        let to = Point::new(x, y);
+        self.pen = to;
+        self.contour_start = to;
+    }
+
+    fn line_to(&mut self, x: f32, y: f32) {
+        let to = Point::new(x, y) * self.scale;
+        self.elements.push(PathElement::new(
+            Segment::Line(lyon_geom::LineSegment { from: self.pen, to }),
+            ColorFlags::WHITE,
+        ));
+        self.pen = to;
+    }
+
+    fn quad_to(&mut self, x1: f32, y1: f32, x: f32, y: f32) {
+        let ctrl = Point::new(x1, y1) * self.scale;
+        let to = Point::new(x, y) * self.scale;
+        self.elements.push(PathElement::new(
+            Segment::Quadratic(lyon_geom::QuadraticBezierSegment {
+                from: self.pen,
+                to,
+                ctrl,
+            }),
+            ColorFlags::WHITE,
+        ));
+        self.pen = to;
+    }
+
+    fn curve_to(&mut self, x1: f32, y1: f32, x2: f32, y2: f32, x: f32, y: f32) {
+        let ctrl1 = Point::new(x1, y1) * self.scale;
+        let ctrl2 = Point::new(x2, y2) * self.scale;
+        let to = Point::new(x, y) * self.scale;
+        self.elements.push(PathElement::new(
+            Segment::Cubic(lyon_geom::CubicBezierSegment {
+                from: self.pen,
+                to,
+                ctrl1,
+                ctrl2,
+            }),
+            ColorFlags::WHITE,
+        ));
+
+        self.pen = to;
+    }
+
+    fn close(&mut self) {
+        if (self.pen - self.contour_start).length() > 1E-14 {
+            self.elements.push(PathElement::new(
+                Segment::Line(lyon_geom::LineSegment {
+                    from: self.pen * self.scale,
+                    to: self.contour_start * self.scale,
+                }),
+                ColorFlags::WHITE,
+            ));
+        }
+
+        self.pen = self.contour_start;
+        let elements = std::mem::replace(&mut self.elements, Vec::new());
+
+        self.contours.push(Contour { elements });
+    }
+}
diff --git a/kayak_font/src/utils.rs b/kayak_font/src/utils.rs
new file mode 100644
index 0000000..5e8e35f
--- /dev/null
+++ b/kayak_font/src/utils.rs
@@ -0,0 +1,61 @@
+use lyon_path::math::Vector;
+
+use crate::path_element::PathElement;
+
+/// Represents a distance to an edge segment
+#[derive(Copy, Clone)]
+pub(crate) struct EdgeDistance<'a> {
+    pub(crate) dist: AugmentedDistance,
+    pub(crate) edge: Option<&'a PathElement>,
+    pub(crate) nearest_approach: f32,
+}
+
+impl<'a> EdgeDistance<'a> {
+    /// Create a new edge point, initialized to infinite distance
+    pub(crate) fn new() -> Self {
+        Self {
+            dist: AugmentedDistance::new(-1e24, 0.0),
+            edge: None,
+            nearest_approach: 0.0,
+        }
+    }
+
+    pub(crate) fn to_pseudodistance(&mut self, p: Vector) {
+        match self.edge {
+            Some(edge) => self.dist = edge.to_psuedodistance(self.dist, p, self.nearest_approach),
+            None => {}
+        }
+    }
+}
+
+/// A signed distance, augmented with the cosine of the angle
+/// between the tangent of the edge and the vector from the
+/// point of nearest approach to the measured point.
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub struct AugmentedDistance {
+    /// The actual distance
+    pub(crate) distance: f32,
+    /// The cosine of the angle between the tangent vector of the path segment
+    /// at the point of closest approach and the vector from the point of
+    /// closest approach to the point to which distance was measured. This is used to
+    dot: f32,
+}
+
+impl AugmentedDistance {
+    pub(crate) fn new(distance: f32, dot: f32) -> Self {
+        Self { distance, dot }
+    }
+}
+
+impl std::cmp::PartialOrd for AugmentedDistance {
+    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+        use std::cmp::Ordering;
+
+        match self.distance.abs().partial_cmp(&other.distance.abs()) {
+            Some(Ordering::Less) => Some(Ordering::Less),
+            Some(Ordering::Greater) => Some(Ordering::Greater),
+            Some(Ordering::Equal) => self.dot.partial_cmp(&other.dot),
+            None => None,
+        }
+    }
+}
diff --git a/kayak_render_macros/Cargo.toml b/kayak_render_macros/Cargo.toml
new file mode 100644
index 0000000..8707f9a
--- /dev/null
+++ b/kayak_render_macros/Cargo.toml
@@ -0,0 +1,17 @@
+[package]
+name = "kayak_render_macros"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+proc-macro = true
+
+[dependencies]
+syn = { version = "1.0", features = ["full"] }
+quote = "1.0"
+proc-macro2 = "1.0"
+proc-macro-error = "1.0"
+
+[dev-dependencies]
+kayak_core = { path = "../kayak_core", version = "0.1.0" }
+pretty_assertions = "0.3.4"
diff --git a/kayak_render_macros/examples/main.rs b/kayak_render_macros/examples/main.rs
new file mode 100644
index 0000000..75d7ccc
--- /dev/null
+++ b/kayak_render_macros/examples/main.rs
@@ -0,0 +1,70 @@
+use kayak_core::{context::KayakContext, styles::Style, Children, Index};
+use kayak_core::{derivative::*, Fragment, Widget};
+use kayak_render_macros::rsx;
+
+#[derive(Derivative)]
+#[derivative(Debug, PartialEq)]
+#[allow(dead_code)]
+struct Test {
+    id: Index,
+    styles: Option<Style>,
+    foo: u32,
+    #[derivative(Debug = "ignore", PartialEq = "ignore")]
+    children: Children,
+}
+
+impl Widget for Test {
+    fn get_id(&self) -> Index {
+        todo!()
+    }
+
+    fn set_id(&mut self, _id: Index) {
+        todo!()
+    }
+
+    fn get_styles(&self) -> Option<Style> {
+        todo!()
+    }
+
+    fn render(&mut self, _context: &mut KayakContext) {
+        todo!()
+    }
+}
+
+fn main() {
+    let mut context = KayakContext::new();
+    {
+        let context = &mut context;
+        let foo = 10;
+        let test_styles = Style::default();
+        let parent_id: Option<Index> = None;
+        rsx! {
+            <Fragment>
+                <Test foo={10}>
+                    <Test foo={1}>
+                        <Test foo={5}>
+                            <Test foo={foo} styles={Some(test_styles)}>
+                                {}
+                            </Test>
+                        </Test>
+                    </Test>
+                </Test>
+            </Fragment>
+        };
+
+        let foo = 10;
+        let test_styles = Style::default();
+
+        let parent_id: Option<Index> = None;
+        rsx! {
+            <Fragment>
+                <Test foo={foo} styles={Some(test_styles)}>
+                    {}
+                </Test>
+                <Test foo={5} styles={Some(test_styles)}>
+                    {}
+                </Test>
+            </Fragment>
+        }
+    }
+}
diff --git a/kayak_render_macros/src/arc_function.rs b/kayak_render_macros/src/arc_function.rs
new file mode 100644
index 0000000..bc5c1ad
--- /dev/null
+++ b/kayak_render_macros/src/arc_function.rs
@@ -0,0 +1,28 @@
+use proc_macro2::TokenStream;
+use quote::quote;
+
+pub fn build_arc_function(
+    widget_name: TokenStream,
+    children_quotes: TokenStream,
+    has_parent: bool,
+    index: usize,
+) -> TokenStream {
+    let parent = if has_parent {
+        quote! { parent_id }
+    } else {
+        quote! { None }
+    };
+
+    quote! {
+        let #widget_name = #children_quotes;
+        let (should_rerender, child_id) =
+            context
+                .widget_manager
+                .create_widget(#index, #widget_name, #parent);
+        if should_rerender {
+            let mut child_widget = context.widget_manager.take(child_id);
+            child_widget.render(context);
+            context.widget_manager.repossess(child_widget);
+        }
+    }
+}
diff --git a/kayak_render_macros/src/attribute.rs b/kayak_render_macros/src/attribute.rs
new file mode 100644
index 0000000..5cedf71
--- /dev/null
+++ b/kayak_render_macros/src/attribute.rs
@@ -0,0 +1,95 @@
+use quote::quote;
+use std::hash::{Hash, Hasher};
+
+use syn::{
+    ext::IdentExt,
+    parse::{Parse, ParseStream, Result},
+    spanned::Spanned,
+};
+
+pub type AttributeKey = syn::punctuated::Punctuated<syn::Ident, syn::Token![-]>;
+
+#[derive(Debug, Clone)]
+pub enum Attribute {
+    Punned(AttributeKey),
+    WithValue(AttributeKey, syn::Block),
+}
+
+impl Attribute {
+    pub fn ident(&self) -> &AttributeKey {
+        match self {
+            Self::Punned(ident) | Self::WithValue(ident, _) => ident,
+        }
+    }
+
+    pub fn value_tokens(&self) -> proc_macro2::TokenStream {
+        match self {
+            Self::WithValue(_, value) => {
+                if value.stmts.len() == 1 {
+                    let first = &value.stmts[0];
+                    quote!(#first)
+                } else {
+                    quote!(#value)
+                }
+            }
+            Self::Punned(ident) => quote!(#ident),
+        }
+    }
+
+    pub fn idents(&self) -> Vec<&syn::Ident> {
+        self.ident().iter().collect::<Vec<_>>()
+    }
+
+    pub(crate) fn validate(self) -> Result<Self> {
+        if self.idents().len() < 2 {
+            Ok(self)
+        } else {
+            let alternative_name = self
+                .idents()
+                .iter()
+                .map(|x| x.to_string())
+                .collect::<Vec<_>>()
+                .join("_");
+
+            let error_message = format!(
+                "Can't use dash-delimited values on custom components. Did you mean `{}`?",
+                alternative_name
+            );
+
+            Err(syn::Error::new(self.ident().span(), error_message))
+        }
+    }
+}
+
+impl PartialEq for Attribute {
+    fn eq(&self, other: &Self) -> bool {
+        let self_idents: Vec<_> = self.ident().iter().collect();
+        let other_idents: Vec<_> = other.ident().iter().collect();
+        self_idents == other_idents
+    }
+}
+
+impl Eq for Attribute {}
+
+impl Hash for Attribute {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        let ident = self.idents();
+        Hash::hash(&ident, state)
+    }
+}
+
+impl Parse for Attribute {
+    fn parse(input: ParseStream) -> Result<Self> {
+        let name = AttributeKey::parse_separated_nonempty_with(input, syn::Ident::parse_any)?;
+        let not_punned = input.peek(syn::Token![=]);
+
+        if !not_punned {
+            return Ok(Self::Punned(name));
+        }
+
+        input.parse::<syn::Token![=]>()?;
+        let value = input.parse::<syn::Block>()?;
+
+        Ok(Self::WithValue(name, value))
+    }
+}
diff --git a/kayak_render_macros/src/child.rs b/kayak_render_macros/src/child.rs
new file mode 100644
index 0000000..ed2c17f
--- /dev/null
+++ b/kayak_render_macros/src/child.rs
@@ -0,0 +1,58 @@
+use quote::{quote, ToTokens};
+use syn::parse::{Parse, ParseStream, Result};
+
+use crate::widget::Widget;
+
+#[derive(Debug, Clone)]
+pub enum Child {
+    Widget(Widget),
+    RawBlock(syn::Block),
+}
+
+impl ToTokens for Child {
+    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
+        match self {
+            Self::Widget(widget) => widget.to_tokens(tokens),
+            Self::RawBlock(block) => {
+                let ts = if block.stmts.len() == 1 {
+                    let first = &block.stmts[0];
+                    quote!(#first)
+                } else {
+                    quote!(#block)
+                };
+                ts.to_tokens(tokens);
+            }
+        }
+    }
+}
+
+impl Parse for Child {
+    fn parse(input: ParseStream) -> Result<Self> {
+        match Widget::custom_parse(input, true, true) {
+            Ok(widget) => Ok(Self::Widget(widget)),
+            Err(_) => {
+                let block = input.parse::<syn::Block>()?;
+                Ok(Self::RawBlock(block))
+            }
+        }
+    }
+}
+
+pub fn walk_block_to_variable(block: &syn::Block) -> Option<proc_macro2::TokenStream> {
+    if let Some(statement) = block.stmts.first() {
+        return walk_statement(statement);
+    }
+
+    return None;
+}
+
+pub fn walk_statement(statement: &syn::Stmt) -> Option<proc_macro2::TokenStream> {
+    match statement {
+        syn::Stmt::Expr(expr) => match expr {
+            syn::Expr::Call(call) => Some(call.args.to_token_stream()),
+            syn::Expr::Path(path) => Some(path.to_token_stream()),
+            _ => None,
+        },
+        _ => None,
+    }
+}
diff --git a/kayak_render_macros/src/children.rs b/kayak_render_macros/src/children.rs
new file mode 100644
index 0000000..db5093c
--- /dev/null
+++ b/kayak_render_macros/src/children.rs
@@ -0,0 +1,219 @@
+use crate::{
+    arc_function::build_arc_function,
+    attribute::Attribute,
+    child::{walk_block_to_variable, Child},
+};
+use quote::{quote, ToTokens};
+use syn::parse::{Parse, ParseStream, Result};
+
+#[derive(Debug, Clone)]
+pub struct Children {
+    pub nodes: Vec<Child>,
+}
+
+impl Children {
+    pub fn new(nodes: Vec<Child>) -> Self {
+        Children { nodes }
+    }
+
+    pub fn len(&self) -> usize {
+        self.nodes.len()
+    }
+
+    pub fn get_clonable_attributes(&self, index: usize) -> Vec<proc_macro2::TokenStream> {
+        let mut tokens = Vec::new();
+
+        let regular_tokens: Vec<_> = match &self.nodes[index] {
+            Child::Widget(widget) => widget
+                .attributes
+                .attributes
+                .iter()
+                .filter_map(|attr| match attr {
+                    Attribute::WithValue(_, block) => walk_block_to_variable(block),
+                    _ => None,
+                })
+                .collect(),
+            _ => vec![],
+        };
+        tokens.extend(regular_tokens);
+
+        let children_tokens: Vec<proc_macro2::TokenStream> = match &self.nodes[index] {
+            Child::Widget(widget) => (0..widget.children.nodes.len())
+                .into_iter()
+                .map(|child_id| widget.children.get_clonable_attributes(child_id))
+                .flatten()
+                .collect(),
+            _ => vec![],
+        };
+
+        tokens.extend(children_tokens);
+
+        tokens.dedup_by(|a, b| a.to_string().eq(&b.to_string()));
+
+        tokens
+    }
+
+    pub fn as_option_of_tuples_tokens(&self) -> proc_macro2::TokenStream {
+        let children_quotes: Vec<_> = self
+            .nodes
+            .iter()
+            .map(|child| {
+                quote! { #child }
+            })
+            .collect();
+
+        match children_quotes.len() {
+            0 => quote! { Option::<()>::None },
+            1 => {
+                let child = if children_quotes[0].to_string() == "{ }" {
+                    quote! { None }
+                } else {
+                    let children_attributes: Vec<_> = self.get_clonable_attributes(0);
+
+                    let cloned_attrs = quote! {
+                        #(let #children_attributes = #children_attributes.clone();)*;
+                    };
+                    if children_quotes[0].to_string() == "children" {
+                        quote! {
+                            #(#children_quotes)*.clone()
+                        }
+                    } else {
+                        let children_builder = build_arc_function(
+                            quote! { child_widget },
+                            quote! { #(#children_quotes),* },
+                            true,
+                            0,
+                        );
+                        quote! {
+                            Some(std::sync::Arc::new(move |parent_id: Option<kayak_core::Index>, context: &mut kayak_core::context::KayakContext| {
+                                #cloned_attrs
+                                #children_builder
+                            }))
+                        }
+                    }
+                };
+                quote! {
+                    #child
+                }
+            }
+            _ => {
+                let mut iter = children_quotes.iter();
+
+                let first = iter.next().unwrap();
+                let second = iter.next().unwrap();
+
+                let first = build_arc_function(quote! { child1 }, first.clone(), true, 0);
+                let second = build_arc_function(quote! { child2 }, second.clone(), true, 1);
+
+                let children_attributes0: Vec<_> = self.get_clonable_attributes(0);
+                let children_attributes1: Vec<_> = self.get_clonable_attributes(1);
+                let (children_attributes0, children_attributes1, matching) =
+                    handle_tuple_attributes(&children_attributes0, &children_attributes1);
+
+                let base_matching: Vec<proc_macro2::TokenStream> = matching
+                    .iter()
+                    .map(|a| {
+                        format!("base_{}", a.to_string())
+                            .to_string()
+                            .parse()
+                            .unwrap()
+                    })
+                    .collect();
+
+                let base_clone = quote! {
+                    #(let #base_matching = #matching.clone();)*
+                };
+
+                let base_clones_inner = quote! {
+                    #(let #matching = #base_matching.clone();)*
+                };
+
+                let cloned_attrs0 = quote! {
+                    #(let #children_attributes0 = #children_attributes0.clone();)*
+                };
+                let cloned_attrs1 = quote! {
+                    #(let #children_attributes1 = #children_attributes1.clone();)*
+                };
+
+                let tuple_of_tuples = iter.fold(
+                    quote! {
+                        #base_clone
+                        #cloned_attrs0
+                        #base_clones_inner
+                        #first
+                        #base_clones_inner
+                        #cloned_attrs1
+                        #second
+                    },
+                    |renderable, current| quote!((#renderable, #current)),
+                );
+
+                quote! {
+                    Some(std::sync::Arc::new(move |parent_id: Option<kayak_core::Index>, context: &mut kayak_core::context::KayakContext| {
+                        #tuple_of_tuples
+                    }))
+                }
+            }
+        }
+    }
+}
+
+impl Parse for Children {
+    fn parse(input: ParseStream) -> Result<Self> {
+        let mut nodes = vec![];
+
+        while !input.peek(syn::Token![<]) || !input.peek2(syn::Token![/]) {
+            let child = input.parse::<Child>()?;
+            nodes.push(child);
+        }
+
+        Ok(Self::new(nodes))
+    }
+}
+
+impl ToTokens for Children {
+    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
+        self.as_option_of_tuples_tokens().to_tokens(tokens);
+    }
+}
+
+// Takes two incoming attribute streams like: "styles foo bar" and "styles" and resolves
+// them into three separate lists like: "foo bar", "", and "styles"
+fn handle_tuple_attributes(
+    a: &Vec<proc_macro2::TokenStream>,
+    b: &Vec<proc_macro2::TokenStream>,
+) -> (
+    Vec<proc_macro2::TokenStream>,
+    Vec<proc_macro2::TokenStream>,
+    Vec<proc_macro2::TokenStream>,
+) {
+    let mut stream1: Vec<String> = a.iter().map(|a| a.to_string()).collect();
+    let mut stream2: Vec<String> = b.iter().map(|b| b.to_string()).collect();
+    let matching1: Vec<&String> = stream1
+        .iter()
+        .filter(|a| stream2.iter().any(|b| *a == b))
+        .collect();
+    let matching2: Vec<&String> = stream2
+        .iter()
+        .filter(|a| stream1.iter().any(|b| *a == b))
+        .collect();
+    let mut matching: Vec<String> = Vec::new();
+    matching.extend(matching1.iter().map(|x| (*x).clone()).collect::<Vec<_>>());
+    matching.extend(matching2.iter().map(|x| (*x).clone()).collect::<Vec<_>>());
+    matching.sort_unstable();
+    matching.dedup_by(|a, b| a.eq(&b));
+
+    stream1 = stream1
+        .into_iter()
+        .filter(|a| !matching.iter().any(|b| a == b))
+        .collect();
+    stream2 = stream2
+        .into_iter()
+        .filter(|a| !matching.iter().any(|b| a == b))
+        .collect();
+
+    let matching = matching.iter().map(|m| m.parse().unwrap()).collect();
+    let stream1 = stream1.iter().map(|m| m.parse().unwrap()).collect();
+    let stream2 = stream2.iter().map(|m| m.parse().unwrap()).collect();
+    (stream1, stream2, matching)
+}
diff --git a/kayak_render_macros/src/function_component.rs b/kayak_render_macros/src/function_component.rs
new file mode 100644
index 0000000..55c82f3
--- /dev/null
+++ b/kayak_render_macros/src/function_component.rs
@@ -0,0 +1,192 @@
+use proc_macro::TokenStream;
+use proc_macro_error::emit_error;
+use quote::{quote, ToTokens};
+use syn::spanned::Spanned;
+
+pub fn create_function_component(f: syn::ItemFn) -> TokenStream {
+    let struct_name = f.sig.ident;
+    let (impl_generics, ty_generics, where_clause) = f.sig.generics.split_for_impl();
+    let inputs = f.sig.inputs;
+    let block = f.block;
+    let vis = f.vis;
+
+    let mut input_names: Vec<_> = inputs
+        .iter()
+        .filter_map(|argument| match argument {
+            syn::FnArg::Typed(typed) => {
+                let typed_info = typed.ty.to_token_stream().to_string();
+                let attr_info = typed.pat.to_token_stream().to_string();
+                if (typed_info.contains("KayakContext") && !typed_info.contains("Fn"))
+                    || (attr_info.contains("styles") && typed_info.contains("Style"))
+                {
+                    None
+                } else {
+                    Some(typed)
+                }
+            }
+            syn::FnArg::Receiver(rec) => {
+                emit_error!(rec.span(), "Don't use `self` on components");
+                None
+            }
+        })
+        .map(|value| {
+            let pat = &value.pat;
+            quote!(#pat)
+        })
+        .collect();
+
+    // let missing_names = vec!["styles"];
+    // missing_names.iter().for_each(|missing| {
+    //     if !input_names
+    //         .iter()
+    //         .any(|input| input.to_string() == missing.to_string())
+    //     {
+    //         input_names.push(quote! { #missing });
+    //     }
+    // });
+
+    let mut input_block_names: Vec<_> = inputs
+        .iter()
+        .filter(|input| {
+            let input = (quote! { #input }).to_string();
+            !(input.contains("parent_styles")
+                || (input.contains("KayakContext") && !input.contains("Fn")))
+        })
+        .map(|item| quote! { #item })
+        .collect();
+    input_block_names.iter_mut().for_each(|input| {
+        let input_string = (quote! { #input }).to_string();
+        if input_string.contains("children : Children") {
+            *input = quote! {
+                 #[derivative(Debug = "ignore", PartialEq = "ignore")]
+                 pub children: Children
+            };
+        } else {
+            *input = quote! {
+                pub #input
+            }
+        }
+    });
+
+    let missing_struct_inputs = vec![
+        (
+            vec![
+                "styles : Option < Style >",
+                "styles : Option< kayak_core :: styles :: Style >",
+            ],
+            quote! {
+                pub styles: Option<kayak_core::styles::Style>
+            },
+        ),
+        (
+            vec!["children : Children"],
+            quote! {
+                #[derivative(Debug = "ignore", PartialEq = "ignore")]
+                pub children: kayak_core::Children
+            },
+        ),
+    ];
+
+    for (names, token) in missing_struct_inputs {
+        if !input_block_names.iter().any(|block_name| {
+            names
+                .iter()
+                .any(|name| block_name.to_string().contains(name))
+        }) {
+            input_block_names.push(token);
+        } else {
+        }
+    }
+
+    let inputs_block = quote!(
+        #(#input_block_names),*
+    );
+
+    if !input_names
+        .iter()
+        .any(|item_name| item_name.to_string().contains("children"))
+    {
+        input_names.push(quote! {
+            children
+        });
+    }
+
+    let inputs_reading_ref = if inputs.len() == 0 {
+        quote! {
+            let #struct_name { children, styles, .. } = self;
+        }
+    } else {
+        quote!(
+            let #struct_name { #(#input_names),*, styles, .. } = self;
+        )
+    };
+
+    TokenStream::from(quote! {
+        use kayak_core::derivative::*;
+
+        #[derive(Derivative)]
+        #[derivative(Debug, PartialEq)]
+        #vis struct #struct_name #impl_generics {
+            pub id: ::kayak_core::Index,
+            #inputs_block
+        }
+
+        impl #impl_generics ::kayak_core::Widget for #struct_name #ty_generics #where_clause {
+            fn get_id(&self) -> ::kayak_core::Index {
+                self.id
+            }
+
+            fn set_id(&mut self, id: ::kayak_core::Index) {
+                self.id = id;
+            }
+
+            fn get_styles(&self) -> Option<::kayak_core::styles::Style> {
+                self.styles.clone()
+            }
+
+            fn render(&mut self, context: &mut ::kayak_core::context::KayakContext) {
+                dbg!(stringify!(Rendering widget: #struct_name));
+                let parent_id = self.get_id();
+                context.set_current_id(parent_id);
+                let parent_id = Some(parent_id);
+                #inputs_reading_ref
+                let children = children.clone();
+                #block
+            }
+        }
+
+        // impl #impl_generics ::kayak_core::Render for #struct_name #ty_generics #where_clause {
+        //     fn render_into(&self, nodes: &mut Vec<::kayak_core::Node>, context: ::std::sync::Arc<::std::sync::RwLock<::kayak_core::KayakContext>>, parent_styles: Option<kayak_core::Style>) -> Option<usize> {
+        //         let _ = rsx! {
+        //             <>{}</>
+        //         }; // Used to fake out the compiler into thinking we require rsx! still.
+        //         let result = {
+        //             #inputs_reading_ref
+        //             let mut styles = styles.clone();
+        //             let result = if let Ok(mut context) = context.write() {
+        //                 context.set_current_id(self.component_id);
+        //                 #ref_block
+        //             } else { panic!("Couldn't get write lock for context!"); };
+
+        //             (result, styles)
+        //         };
+        //         let child_index = ::kayak_core::Render::render_into(&result.0, nodes, context, result.1.clone());
+        //         let mut builder = ::kayak_core::NodeBuilder::empty()
+        //             .with_id(self.component_id)
+        //             .with_children(vec![
+        //                 child_index
+        //             ].iter().filter_map(|x| *x).collect());
+        //         if let Some(styles) = result.1 {
+        //             let new_styles = if let Some(parent_styles) = parent_styles {
+        //                 styles // parent_styles.merge(&styles)
+        //             } else { styles };
+        //             builder = builder.with_styles(new_styles)
+        //         }
+        //         let node = builder.build();
+        //         let node_index = nodes.len();
+        //         nodes.push(node);
+        //         Some(node_index)
+        // }
+        // }
+    })
+}
diff --git a/kayak_render_macros/src/lib.rs b/kayak_render_macros/src/lib.rs
new file mode 100644
index 0000000..dcedd3d
--- /dev/null
+++ b/kayak_render_macros/src/lib.rs
@@ -0,0 +1,100 @@
+extern crate proc_macro;
+
+mod function_component;
+mod tags;
+
+mod arc_function;
+mod attribute;
+mod partial_eq;
+mod widget;
+mod widget_attributes;
+mod child;
+mod children;
+
+use partial_eq::impl_dyn_partial_eq;
+use proc_macro::TokenStream;
+use proc_macro_error::proc_macro_error;
+use quote::quote;
+use syn::{parse_macro_input, parse_quote, token::Comma};
+
+use crate::widget::Widget;
+
+// use crate::prebuilt::element::Element;
+
+#[proc_macro]
+#[proc_macro_error]
+pub fn render(input: TokenStream) -> TokenStream {
+    let mut input = input.into_iter();
+    let context = proc_macro2::TokenStream::from(TokenStream::from(input.next().unwrap()));
+    let comma_input = TokenStream::from(input.next().unwrap());
+    let _ = parse_macro_input!(comma_input as Comma);
+    let rsx_data = proc_macro2::TokenStream::from_iter(
+        input.map(|token_tree| proc_macro2::TokenStream::from(TokenStream::from(token_tree))),
+    );
+    let el = proc_macro2::TokenStream::from(rsx(TokenStream::from(rsx_data)));
+    let result = quote! { ::kayak_core::Render::render_into(&#el, #context, None) };
+    TokenStream::from(result)
+}
+
+/// Generate a renderable component tree, before rendering it
+#[proc_macro]
+#[proc_macro_error]
+pub fn rsx(input: TokenStream) -> TokenStream {
+    let el = parse_macro_input!(input as Widget);
+    let result = quote! { #el };
+    TokenStream::from(result)
+}
+
+// #[proc_macro]
+// #[proc_macro_error]
+// pub fn rsx_create(input: TokenStream) -> TokenStream {
+//     let el = parse_macro_input!(input as WidgetElement);
+//     let result = quote! { #el };
+//     TokenStream::from(result)
+// }
+
+// #[proc_macro]
+// #[proc_macro_error]
+// pub fn rsx_update(input: TokenStream) -> TokenStream {
+//     let el = parse_macro_input!(input as Element);
+//     let result = quote! { #el };
+//     TokenStream::from(result)
+// }
+
+#[proc_macro_attribute]
+#[proc_macro_error]
+pub fn widget(_attr: TokenStream, item: TokenStream) -> TokenStream {
+    let f = parse_macro_input!(item as syn::ItemFn);
+    function_component::create_function_component(f)
+}
+
+#[proc_macro_derive(DynPartialEq)]
+pub fn dyn_partial_eq_macro_derive(input: TokenStream) -> TokenStream {
+    let ast = syn::parse(input).unwrap();
+
+    impl_dyn_partial_eq(&ast)
+}
+
+#[proc_macro_attribute]
+pub fn dyn_partial_eq(_: TokenStream, input: TokenStream) -> TokenStream {
+    let mut input = parse_macro_input!(input as syn::ItemTrait);
+
+    let name = &input.ident;
+
+    let bound: syn::TypeParamBound = parse_quote! {
+      DynPartialEq
+    };
+
+    input.supertraits.push(bound);
+
+    (quote! {
+      #input
+
+      impl core::cmp::PartialEq for Box<dyn #name> {
+        fn eq(&self, other: &Self) -> bool {
+          self.box_eq(other.as_any())
+        }
+      }
+    })
+    .into()
+}
diff --git a/kayak_render_macros/src/partial_eq.rs b/kayak_render_macros/src/partial_eq.rs
new file mode 100644
index 0000000..aa26500
--- /dev/null
+++ b/kayak_render_macros/src/partial_eq.rs
@@ -0,0 +1,16 @@
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+use quote::quote;
+
+pub fn impl_dyn_partial_eq(ast: &syn::DeriveInput) -> TokenStream {
+  let name = &ast.ident;
+  let gen = quote! {
+      impl DynPartialEq for #name {
+          fn box_eq(&self, other: &dyn core::any::Any) -> bool {
+            other.downcast_ref::<Self>().map_or(false, |a| self == a)
+          }
+      }
+  };
+  gen.into()
+}
diff --git a/kayak_render_macros/src/tags.rs b/kayak_render_macros/src/tags.rs
new file mode 100644
index 0000000..fffe931
--- /dev/null
+++ b/kayak_render_macros/src/tags.rs
@@ -0,0 +1,78 @@
+use crate::widget_attributes::WidgetAttributes;
+use proc_macro_error::abort;
+use quote::quote;
+use syn::parse::{Parse, ParseStream, Result};
+use syn::spanned::Spanned;
+
+pub struct OpenTag {
+    pub name: syn::Path,
+    pub attributes: WidgetAttributes,
+    pub self_closing: bool,
+    pub is_custom_element: bool,
+}
+
+fn name_or_fragment(maybe_name: Result<syn::Path>) -> syn::Path {
+    maybe_name.unwrap_or_else(|_| syn::parse_str::<syn::Path>("::kayak_core::Fragment").unwrap())
+}
+
+fn is_custom_element_name(path: &syn::Path) -> bool {
+    match path.get_ident() {
+        None => true,
+        Some(ident) => {
+            let name = ident.to_string();
+            let first_letter = name.get(0..1).unwrap();
+            first_letter.to_uppercase() == first_letter
+        }
+    }
+}
+
+impl Parse for OpenTag {
+    fn parse(input: ParseStream) -> Result<Self> {
+        input.parse::<syn::Token![<]>()?;
+        let maybe_name = syn::Path::parse_mod_style(input);
+        let name = name_or_fragment(maybe_name);
+        let is_custom_element = is_custom_element_name(&name);
+        let attributes = WidgetAttributes::custom_parse(input)?;
+        let self_closing = input.parse::<syn::Token![/]>().is_ok();
+        input.parse::<syn::Token![>]>()?;
+
+        Ok(Self {
+            name,
+            attributes,
+            self_closing,
+            is_custom_element,
+        })
+    }
+}
+
+pub struct ClosingTag {
+    name: syn::Path,
+}
+
+impl ClosingTag {
+    pub fn validate(&self, open_tag: &OpenTag) {
+        let open_tag_path = &open_tag.name;
+        let open_tag_path_str = quote!(#open_tag_path).to_string();
+        let self_path = &self.name;
+        let self_path_str = quote!(#self_path).to_string();
+        if self_path_str != open_tag_path_str {
+            abort!(
+                self.name.span(),
+                "Expected closing tag for: <{}>",
+                &open_tag_path_str
+            );
+        }
+    }
+}
+
+impl Parse for ClosingTag {
+    fn parse(input: ParseStream) -> Result<Self> {
+        input.parse::<syn::Token![<]>()?;
+        input.parse::<syn::Token![/]>()?;
+        let maybe_name = input.parse::<syn::Path>();
+        input.parse::<syn::Token![>]>()?;
+        Ok(Self {
+            name: name_or_fragment(maybe_name),
+        })
+    }
+}
diff --git a/kayak_render_macros/src/widget.rs b/kayak_render_macros/src/widget.rs
new file mode 100644
index 0000000..96d0c70
--- /dev/null
+++ b/kayak_render_macros/src/widget.rs
@@ -0,0 +1,97 @@
+use proc_macro2::TokenStream;
+use quote::quote;
+use quote::ToTokens;
+use syn::parse::{Parse, ParseStream, Result};
+
+use crate::arc_function::build_arc_function;
+use crate::children::Children;
+use crate::tags::ClosingTag;
+use crate::{tags::OpenTag, widget_attributes::WidgetAttributes};
+
+#[derive(Debug, Clone)]
+pub struct Widget {
+    name: syn::Path,
+    pub attributes: WidgetAttributes,
+    pub children: Children,
+    declaration: TokenStream,
+}
+
+impl Parse for Widget {
+    fn parse(input: ParseStream) -> Result<Self> {
+        Self::custom_parse(input, false, true)
+    }
+}
+
+impl Widget {
+    pub fn is_custom_element(name: &syn::Path) -> bool {
+        match name.get_ident() {
+            None => true,
+            Some(ident) => {
+                let name = ident.to_string();
+                let first_letter = name.get(0..1).unwrap();
+                first_letter.to_uppercase() == first_letter
+            }
+        }
+    }
+
+    pub fn custom_parse(input: ParseStream, as_prop: bool, has_parent: bool) -> Result<Widget> {
+        let open_tag = input.parse::<OpenTag>()?;
+
+        let children = if open_tag.self_closing {
+            Children::new(vec![])
+        } else {
+            let children = input.parse::<Children>()?;
+            let closing_tag = input.parse::<ClosingTag>()?;
+            closing_tag.validate(&open_tag);
+            children
+        };
+
+        let name = open_tag.name;
+        let declaration = if Self::is_custom_element(&name) {
+            let attrs = &open_tag.attributes.for_custom_element(&children);
+            let attrs = attrs.to_token_stream();
+            // let builder = quote! {
+            //     let built_widget = #name #attrs;
+            //     let (should_rerender, child_id) =
+            //         context
+            //             .widget_manager
+            //             .create_widget(0, built_widget, Some(parent_id));
+            //     if should_rerender {
+            //         let mut child_widget = context.widget_manager.take(child_id);
+            //         child_widget.render(context);
+            //         context.widget_manager.repossess(child_widget);
+            //     }
+            // };
+            // quote! {
+            //     #builder
+            // }
+            if !as_prop {
+                let attrs = quote! { #name #attrs };
+                let widget_block =
+                    build_arc_function(quote! { built_widget }, attrs, has_parent, 0);
+                quote! {
+                    #widget_block
+                }
+            } else {
+                quote! {
+                    #name #attrs
+                }
+            }
+        } else {
+            panic!("Couldn't find widget!");
+        };
+
+        Ok(Widget {
+            name,
+            attributes: open_tag.attributes,
+            children,
+            declaration,
+        })
+    }
+}
+
+impl ToTokens for Widget {
+    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
+        self.declaration.to_tokens(tokens);
+    }
+}
diff --git a/kayak_render_macros/src/widget_attributes.rs b/kayak_render_macros/src/widget_attributes.rs
new file mode 100644
index 0000000..3f1c9db
--- /dev/null
+++ b/kayak_render_macros/src/widget_attributes.rs
@@ -0,0 +1,108 @@
+use proc_macro_error::emit_error;
+use quote::{quote, ToTokens};
+use std::collections::HashSet;
+use syn::{
+    ext::IdentExt,
+    parse::{Parse, ParseStream, Result},
+    spanned::Spanned,
+};
+
+use crate::{attribute::Attribute, children::Children};
+
+#[derive(Debug, Clone)]
+pub struct WidgetAttributes {
+    pub attributes: HashSet<Attribute>,
+}
+
+impl WidgetAttributes {
+    pub fn new(attributes: HashSet<Attribute>) -> Self {
+        Self { attributes }
+    }
+
+    pub fn for_custom_element<'c>(&self, children: &'c Children) -> CustomWidgetAttributes<'_, 'c> {
+        CustomWidgetAttributes {
+            attributes: &self.attributes,
+            children,
+        }
+    }
+
+    pub fn custom_parse(input: ParseStream) -> Result<Self> {
+        let mut parsed_self = input.parse::<Self>()?;
+        let new_attributes: HashSet<Attribute> = parsed_self
+            .attributes
+            .drain()
+            .filter_map(|attribute| match attribute.validate() {
+                Ok(x) => Some(x),
+                Err(err) => {
+                    emit_error!(err.span(), "Invalid attribute: {}", err);
+                    None
+                }
+            })
+            .collect();
+
+        Ok(WidgetAttributes::new(new_attributes))
+    }
+}
+
+impl Parse for WidgetAttributes {
+    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
+        let mut attributes: HashSet<Attribute> = HashSet::new();
+        while input.peek(syn::Ident::peek_any) {
+            let attribute = input.parse::<Attribute>()?;
+            let ident = attribute.ident();
+            if attributes.contains(&attribute) {
+                emit_error!(
+                    ident.span(),
+                    "There is a previous definition of the {} attribute",
+                    quote!(#ident)
+                );
+            }
+            attributes.insert(attribute);
+        }
+        Ok(WidgetAttributes::new(attributes))
+    }
+}
+
+pub struct CustomWidgetAttributes<'a, 'c> {
+    attributes: &'a HashSet<Attribute>,
+    children: &'c Children,
+}
+
+impl<'a, 'c> ToTokens for CustomWidgetAttributes<'a, 'c> {
+    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
+        let mut attrs: Vec<_> = self
+            .attributes
+            .iter()
+            .map(|attribute| {
+                let ident = attribute.ident();
+                let value = attribute.value_tokens();
+
+                quote! {
+                    #ident: #value
+                }
+            })
+            .collect();
+
+        if self.children.len() > 0 {
+            let children_tuple = self.children.as_option_of_tuples_tokens();
+            attrs.push(quote! {
+                children: #children_tuple
+            });
+        }
+        let quoted = if attrs.len() == 0 {
+            quote!({ id: kayak_core::Index::default(), styles: None, children: None })
+        } else {
+            if !self
+                .attributes
+                .iter()
+                .any(|attribute| attribute.ident().to_token_stream().to_string() == "styles")
+            {
+                quote!({ #(#attrs),*, id: kayak_core::Index::default(), styles: None })
+            } else {
+                quote!({ #(#attrs),*, id: kayak_core::Index::default() })
+            }
+        };
+
+        quoted.to_tokens(tokens);
+    }
+}
diff --git a/resources/Roboto-Regular.ttf b/resources/Roboto-Regular.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..2b6392ffe8712b9c5450733320cd220d6c0f4bce
GIT binary patch
literal 171272
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

literal 0
HcmV?d00001

diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..fa4be9f
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,7 @@
+pub mod components {
+    pub use kayak_components::*;
+}
+
+pub mod core {
+    pub use kayak_core::*;
+}
-- 
GitLab