diff --git a/Elm.cabal b/Elm.cabal
--- a/Elm.cabal
+++ b/Elm.cabal
@@ -1,5 +1,5 @@
 Name:                Elm
-Version:             0.11
+Version:             0.13
 Synopsis:            The Elm language module.
 Description:         Elm aims to make client-side web-development more pleasant.
                      It is a statically/strongly typed, functional reactive
@@ -14,20 +14,20 @@
 
 Author:              Evan Czaplicki
 Maintainer:          info@elm-lang.org
-Copyright:           Copyright: (c) 2011-2013 Evan Czaplicki
+Copyright:           Copyright: (c) 2011-2014 Evan Czaplicki
 
 Category:            Compiler, Language
 
 Build-type:          Simple
 
-Extra-source-files:  changelog.txt
+Extra-source-files:  changelog.md
 Data-dir:            data
 Data-files:          elm-runtime.js interfaces.data docs.json
 Cabal-version:       >=1.9
 
 source-repository head
   type:     git
-  location: git://github.com/evancz/Elm.git
+  location: git://github.com/elm-lang/Elm.git
 
 Library
   exposed-modules:     Elm.Internal.Dependencies,
@@ -37,28 +37,36 @@
                        Elm.Internal.Utils,
                        Elm.Internal.Version
   Hs-Source-Dirs:      compiler
-  other-modules:       SourceSyntax.Declaration,
-                       SourceSyntax.Expression,
-                       SourceSyntax.Helpers,
-                       SourceSyntax.Literal,
-                       SourceSyntax.Location,
-                       SourceSyntax.Module,
-                       SourceSyntax.Pattern,
-                       SourceSyntax.PrettyPrint,
-                       SourceSyntax.Type,
+  other-modules:       AST.Annotation,
+                       AST.Declaration,
+                       AST.Expression.General,
+                       AST.Expression.Source,
+                       AST.Expression.Valid,
+                       AST.Expression.Canonical,
+                       AST.Helpers,
+                       AST.Literal,
+                       AST.Module,
+                       AST.Pattern,
+                       AST.PrettyPrint,
+                       AST.Type,
+                       AST.Variable,
                        Generate.JavaScript,
                        Generate.JavaScript.Helpers,
                        Generate.JavaScript.Ports,
-                       Generate.Noscript,
+                       Generate.JavaScript.Variable,
                        Generate.Markdown,
                        Generate.Html,
                        Generate.Cases,
                        Transform.Canonicalize,
+                       Transform.Canonicalize.Environment,
+                       Transform.Canonicalize.Setup,
+                       Transform.Canonicalize.Type,
+                       Transform.Canonicalize.Variable,
                        Transform.Check,
                        Transform.Expression,
                        Transform.Declaration,
                        Transform.Definition,
-                       Transform.SafeNames,
+                       Transform.Interface,
                        Transform.SortDefinitions,
                        Transform.Substitute,
                        Metadata.Prelude,
@@ -71,8 +79,6 @@
                        Parse.Parse,
                        Parse.Pattern,
                        Parse.Type,
-                       Type.Alias,
-                       Type.Constrain.Declaration,
                        Type.Constrain.Expression,
                        Type.Constrain.Literal,
                        Type.Constrain.Pattern,
@@ -94,53 +100,64 @@
                        Build.Utils,
                        Paths_Elm
 
-  Build-depends:       aeson,
+  Build-depends:       aeson >= 0.7 && < 0.9,
+                       aeson-pretty >= 0.7 && < 0.8,
                        base >=4.2 && <5,
-                       binary >= 0.6.4.0,
-                       blaze-html == 0.5.* || == 0.6.*,
-                       blaze-markup,
-                       bytestring,
-                       cmdargs,
-                       containers >= 0.3,
-                       directory,
-                       filepath,
-                       indents,
-                       language-ecmascript >=0.15 && < 1.0,
-                       mtl >= 2,
-                       pandoc >= 1.10,
-                       parsec >= 3.1.1,
-                       pretty,
-                       text,
-                       transformers >= 0.2,
-                       union-find,
-                       unordered-containers
+                       binary >= 0.7.0.0 && < 0.8,
+                       blaze-html >= 0.5 && < 0.8,
+                       blaze-markup >= 0.5.1 && < 0.7,
+                       bytestring >= 0.9 && < 0.11,
+                       cheapskate >= 0.1 && < 0.2,
+                       cmdargs >= 0.7 && < 0.11,
+                       containers >= 0.3 && < 0.6,
+                       directory >= 1.0 && < 2.0,
+                       filepath >= 1 && < 2.0,
+                       highlighting-kate >= 0.5 && < 0.6,
+                       indents >= 0.3 && < 0.4,
+                       language-ecmascript >=0.15 && < 0.17,
+                       language-glsl >= 0.0.2 && < 0.2,
+                       mtl >= 2 && < 3,
+                       parsec >= 3.1.1 && < 3.5,
+                       pretty >= 1.0 && < 2.0,
+                       text >= 1 && < 2,
+                       transformers >= 0.2 && < 0.5,
+                       union-find >= 0.2 && < 0.3,
+                       unordered-containers >= 0.1 && < 0.3
 
 Executable elm
   Main-is:             Compiler.hs
   ghc-options:         -threaded -O2
   Hs-Source-Dirs:      compiler
-  other-modules:       SourceSyntax.Declaration,
-                       SourceSyntax.Expression,
-                       SourceSyntax.Helpers,
-                       SourceSyntax.Literal,
-                       SourceSyntax.Location,
-                       SourceSyntax.Module,
-                       SourceSyntax.Pattern,
-                       SourceSyntax.PrettyPrint,
-                       SourceSyntax.Type,
+  other-modules:       AST.Annotation,
+                       AST.Declaration,
+                       AST.Expression.General,
+                       AST.Expression.Source,
+                       AST.Expression.Valid,
+                       AST.Expression.Canonical,
+                       AST.Helpers,
+                       AST.Literal,
+                       AST.Module,
+                       AST.Pattern,
+                       AST.PrettyPrint,
+                       AST.Type,
+                       AST.Variable,
                        Generate.JavaScript,
                        Generate.JavaScript.Helpers,
                        Generate.JavaScript.Ports,
-                       Generate.Noscript,
+                       Generate.JavaScript.Variable,
                        Generate.Markdown,
                        Generate.Html,
                        Generate.Cases,
                        Transform.Canonicalize,
+                       Transform.Canonicalize.Environment,
+                       Transform.Canonicalize.Setup,
+                       Transform.Canonicalize.Type,
+                       Transform.Canonicalize.Variable,
                        Transform.Check,
                        Transform.Expression,
                        Transform.Declaration,
                        Transform.Definition,
-                       Transform.SafeNames,
+                       Transform.Interface,
                        Transform.SortDefinitions,
                        Transform.Substitute,
                        Metadata.Prelude,
@@ -153,8 +170,6 @@
                        Parse.Parse,
                        Parse.Pattern,
                        Parse.Type,
-                       Type.Alias,
-                       Type.Constrain.Declaration,
                        Type.Constrain.Expression,
                        Type.Constrain.Literal,
                        Type.Constrain.Pattern,
@@ -176,39 +191,43 @@
                        Build.Utils,
                        Paths_Elm
 
-  Build-depends:       aeson,
+  Build-depends:       aeson >= 0.7 && < 0.9,
+                       aeson-pretty >= 0.7 && < 0.8,
                        base >=4.2 && <5,
-                       binary >= 0.6.4.0,
-                       blaze-html == 0.5.* || == 0.6.*,
-                       blaze-markup == 0.5.1.*,
-                       bytestring,
-                       cmdargs,
-                       containers >= 0.3,
-                       directory,
-                       filepath,
-                       indents,
-                       language-ecmascript >=0.15 && < 1.0,
-                       mtl >= 2,
-                       pandoc >= 1.10,
-                       parsec >= 3.1.1,
-                       pretty,
-                       text,
-                       transformers >= 0.2,
-                       union-find,
-                       unordered-containers
+                       binary >= 0.7.0.0 && < 0.8,
+                       blaze-html >= 0.5 && < 0.8,
+                       blaze-markup >= 0.5.1 && < 0.7,
+                       bytestring >= 0.9 && < 0.11,
+                       cheapskate >= 0.1 && < 0.2,
+                       cmdargs >= 0.7 && < 0.11,
+                       containers >= 0.3 && < 0.6,
+                       directory >= 1.0 && < 2.0,
+                       filepath >= 1 && < 2.0,
+                       highlighting-kate >= 0.5 && < 0.6,
+                       indents >= 0.3 && < 0.4,
+                       language-ecmascript >=0.15 && < 0.17,
+                       language-glsl >= 0.0.2 && < 0.2,
+                       mtl >= 2 && < 3,
+                       parsec >= 3.1.1 && < 3.5,
+                       pretty >= 1.0 && < 2.0,
+                       text >= 1 && < 2,
+                       transformers >= 0.2 && < 0.5,
+                       union-find >= 0.2 && < 0.3,
+                       unordered-containers >= 0.1 && < 0.3
 
 Executable elm-doc
   Main-is:             Docs.hs
   Hs-Source-Dirs:      compiler
-  other-modules:       SourceSyntax.Declaration,
-                       SourceSyntax.Expression,
-                       SourceSyntax.Helpers,
-                       SourceSyntax.Literal,
-                       SourceSyntax.Location,
-                       SourceSyntax.Module,
-                       SourceSyntax.Pattern,
-                       SourceSyntax.PrettyPrint,
-                       SourceSyntax.Type,
+  other-modules:       AST.Annotation,
+                       AST.Declaration,
+                       AST.Expression.General,
+                       AST.Helpers,
+                       AST.Literal,
+                       AST.Module,
+                       AST.Pattern,
+                       AST.PrettyPrint,
+                       AST.Type,
+                       AST.Variable,
                        Parse.Binop,
                        Parse.Declaration,
                        Parse.Expression,
@@ -218,60 +237,72 @@
                        Parse.Pattern,
                        Parse.Type
 
-  Build-depends:       aeson,
-                       aeson-pretty,
+  Build-depends:       aeson >= 0.7 && < 0.9,
+                       aeson-pretty >= 0.7 && < 0.8,
                        base >=4.2 && <5,
-                       binary >= 0.6.4.0,
-                       bytestring,
-                       cmdargs,
-                       containers >= 0.3,
-                       directory,
-                       filepath,
-                       indents,
-                       mtl >= 2,
-                       pandoc >= 1.10,
-                       parsec >= 3.1.1,
-                       pretty,
-                       text,
-                       union-find
+                       binary >= 0.7.0.0 && < 0.8,
+                       bytestring >= 0.9 && < 0.11,
+                       cmdargs >= 0.7 && < 0.11,
+                       containers >= 0.3 && < 0.6,
+                       directory >= 1.0 && < 2.0,
+                       filepath >= 1 && < 2.0,
+                       indents >= 0.3 && < 0.4,
+                       language-glsl >= 0.0.2 && < 0.2,
+                       mtl >= 2 && < 3,
+                       parsec >= 3.1.1 && < 3.5,
+                       pretty >= 1.0 && < 2.0,
+                       text >= 1 && < 2,
+                       transformers >= 0.2 && < 0.5,
+                       union-find >= 0.2 && < 0.3
 
-Test-Suite test-elm
+Test-Suite compiler-tests
   Type:            exitcode-stdio-1.0
-  Hs-Source-Dirs:  tests, compiler
-  Main-is:         Main.hs
+  Hs-Source-Dirs:  tests/compiler, compiler
+  Main-is:         CompilerTest.hs
   other-modules:   Tests.Compiler
                    Tests.Property
                    Tests.Property.Arbitrary
-                   SourceSyntax.Helpers
-                   SourceSyntax.Literal
-                   SourceSyntax.PrettyPrint
-  build-depends:   base,
-                   directory,
-                   Elm,
-                   test-framework,
-                   test-framework-hunit,
-                   test-framework-quickcheck2,
-                   HUnit,
-                   pretty,
+                   AST.Helpers
+                   AST.Literal
+                   AST.PrettyPrint
+  build-depends:   test-framework > 0.8 && < 0.9,
+                   test-framework-hunit >= 0.3 && < 0.4,
+                   test-framework-quickcheck2 >= 0.3 && < 0.4,
+                   HUnit >= 1.1 && < 2,
                    QuickCheck >= 2 && < 3,
-                   filemanip,
-                   aeson,
+                   aeson >= 0.7 && < 0.9,
+                   aeson-pretty >= 0.7 && < 0.8,
                    base >=4.2 && <5,
-                   binary >= 0.6.4.0,
-                   blaze-html == 0.5.* || == 0.6.*,
-                   blaze-markup == 0.5.1.*,
-                   bytestring,
-                   cmdargs,
-                   containers >= 0.3,
-                   directory,
-                   filepath,
-                   indents,
-                   language-ecmascript >=0.15 && < 1.0,
-                   mtl >= 2,
-                   pandoc >= 1.10,
-                   parsec >= 3.1.1,
-                   pretty,
-                   text,
-                   transformers >= 0.2,
-                   union-find,
-                   unordered-containers
+                   binary >= 0.7.0.0 && < 0.8,
+                   blaze-html >= 0.5 && < 0.8,
+                   blaze-markup >= 0.5.1 && < 0.7,
+                   bytestring >= 0.9 && < 0.11,
+                   cheapskate >= 0.1 && < 0.2,
+                   cmdargs >= 0.7 && < 0.11,
+                   containers >= 0.3 && < 0.6,
+                   directory >= 1.0 && < 2.0,
+                   Elm,
+                   filemanip >= 0.3.5 && < 0.4,
+                   filepath >= 1 && < 2.0,
+                   highlighting-kate >= 0.5 && < 0.6,
+                   indents >= 0.3 && < 0.4,
+                   language-ecmascript >=0.15 && < 0.17,
+                   language-glsl >= 0.0.2 && < 0.2,
+                   mtl >= 2 && < 3,
+                   parsec >= 3.1.1 && < 3.5,
+                   pretty >= 1.0 && < 2.0,
+                   process,
+                   text >= 1 && < 2,
+                   transformers >= 0.2 && < 0.5,
+                   union-find >= 0.2 && < 0.3,
+                   unordered-containers >= 0.1 && < 0.3
+
+Test-Suite library-tests
+  Type:            exitcode-stdio-1.0
+  Hs-Source-Dirs:  tests/libraries
+  Main-is:         LibraryTest.hs
+  build-depends:   base >= 4.2 && <5,
+                   directory >= 1.0 && < 2.0,
+                   Elm,
+                   filepath >= 1 && < 2.0,
+                   process >= 1 && < 2.0
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2012-2013, Evan Czaplicki
+Copyright (c) 2012-2014, Evan Czaplicki
 
 All rights reserved.
 
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,55 +1,40 @@
+{-# OPTIONS_GHC -W #-}
 import Distribution.Simple
 import Distribution.Simple.LocalBuildInfo
 import Distribution.Simple.Setup
 import Distribution.PackageDescription
 
-import System.Cmd
 import System.Directory
 import System.FilePath
 import System.IO
 import System.Process
 
-import Control.Monad
 import qualified Data.Binary as Binary
 import qualified Data.ByteString.Lazy as BS
 import qualified Data.List as List
 
--- Part 1
--- ------
--- Add a build callout
--- We need to build elm-doc and run it because that generates the file "docs.json"
--- needs by Libraries.hs which is part of the elm library and executable
--- Unfort. there seems to be no way to tell cabal that:
---   (a) elm-doc generates docs.json, and
---   (b) elm (library) depends on docs.json
--- Therefore, we either use make instead (or a script), or hack around in cabal
-
--- Part 2
--- ------
--- Add a post-build callout.
--- We need to build the runtime.js after we've built elm (because we use elm to generate some of the JavaScript),
--- but before cabal does the install file copy step
+-- OVERVIEW
+-- --------
+-- Add a post-build callout that compiles the standard libraries with the new
+-- compiler before cabal copies static files to actually install things.
 
--- Assumptions
--- Elm.cabal expects the generated files to end up in dist/data
--- git won't look in dist + cabal will clean it
-rtsDir :: LocalBuildInfo -> FilePath
-rtsDir lbi = "data"
+assetsDir :: FilePath
+assetsDir = "data"
 
-tempDir :: LocalBuildInfo -> FilePath
-tempDir lbi = "temp"
+tempDir :: FilePath
+tempDir = "temp"
 
 -- The runtime is called:
-rts :: LocalBuildInfo -> FilePath
-rts lbi = rtsDir lbi </> "elm-runtime.js"
+runtime :: FilePath
+runtime = assetsDir </> "elm-runtime.js"
 
 -- The runtime is called:
-docs :: LocalBuildInfo -> FilePath
-docs lbi = rtsDir lbi </> "docs.json"
+docs :: FilePath
+docs = assetsDir </> "docs.json"
 
 -- The interfaces for the Standard Libraries live in:
-interfaces :: LocalBuildInfo -> FilePath
-interfaces lbi = rtsDir lbi </> "interfaces.data"
+interfaces :: FilePath
+interfaces = assetsDir </> "interfaces.data"
 
 elm :: LocalBuildInfo -> FilePath
 elm lbi = buildDir lbi </> "elm" </> "elm"
@@ -65,63 +50,47 @@
 main = defaultMainWithHooks simpleUserHooks { postBuild = myPostBuild }
 
 
--- Build
 
--- note(1): We use to include docs.json directly into LoadLibraries at compile time
--- If docs.json is used in other (template) haskell files, they should be copied
--- and compiled in a separate directory (eg, dist/copiedSrc).
--- This is to make sure they are re-compiled on docs.json changes.
--- Copying is a better solution than 'touch'ing the source files
--- (touch is non-portable and confusing wrt RCS).
-
--- In the PackageDescription, the list of stuff to build is held in library
--- (in a Maybe) and the executables list.  We want a PackageDescription that
--- only mentions the executable 'name'
-filterExe :: String -> PackageDescription -> PackageDescription
-filterExe name pd = pd {
-    library = Nothing,
-    executables = filter (\x -> (exeName x == name)) (executables pd)
-    }
-
-
 -- Post Build
 
 myPostBuild :: Args -> BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()
-myPostBuild as bfs pd lbi = do
+myPostBuild args flags packageDescription lbi = do
     putStrLn "Custom build step: compiling standard libraries"
     (elmos, elmis) <- compileLibraries lbi
     putStrLn "Custom build step: build interfaces.data"
-    buildInterfaces lbi elmis
+    buildInterfaces elmis
     putStrLn "Custom build step: build elm-runtime.js"
-    buildRuntime lbi elmos
+    buildRuntime elmos
     putStrLn "Custom build step: build docs.json"
-    buildDocs lbi
-    removeDirectoryRecursive (tempDir lbi)
+    buildDocs
+    removeDirectoryRecursive tempDir
     removeDirectoryRecursive ("libraries" </> "docs")
-    postBuild simpleUserHooks as bfs pd lbi
+    postBuild simpleUserHooks args flags packageDescription lbi
 
 
 compileLibraries lbi = do
-  let temp = tempDir lbi                    -- temp
-      rts  = rtsDir  lbi                    -- data
-  createDirectoryIfMissing True temp
-  createDirectoryIfMissing True rts
-  out_c <- canonicalizePath temp            -- temp (root folder)
+  createDirectoryIfMissing True tempDir
+  createDirectoryIfMissing True assetsDir
+  out_c <- canonicalizePath tempDir         -- temp (root folder)
   elm_c <- canonicalizePath (elm lbi)       -- dist/build/elm/elm
   doc_c <- canonicalizePath (document lbi)  -- dist/build/elm-doc/elm-doc
-  rtd_c <- canonicalizePath rts             -- data
+  rtd_c <- canonicalizePath assetsDir       -- data
 
   let make file = do
-        -- replace 'system' call with 'runProcess' which handles args better
-        -- and allows env variable "Elm_datadir" which is used by LoadLibraries
-        -- to find docs.json
-        let args = [ "--only-js", "--make", "--no-prelude"
-                   , "--cache-dir="++out_c, "--build-dir="++out_c, file ]
-            arg = Just [("Elm_datadir", rtd_c)]
+        let args =
+              [ "--only-js"
+              , "--make"
+              , "--no-prelude"
+              , "--cache-dir=" ++ out_c
+              , "--build-dir=" ++ out_c
+              , file
+              ]
+        let arg = Just [("Elm_datadir", rtd_c)]
         handle <- runProcess elm_c args Nothing arg Nothing Nothing Nothing
-        exitCode <- waitForProcess handle
+        _exitCode <- waitForProcess handle
         return ( out_c </> replaceExtension file "elmo"
-               , out_c </> replaceExtension file "elmi")
+               , out_c </> replaceExtension file "elmi"
+               )
 
   setCurrentDirectory "libraries"
   paths <- getFiles ".elm" "."
@@ -130,11 +99,10 @@
   setCurrentDirectory ".."
   return files
 
-buildInterfaces :: LocalBuildInfo -> [FilePath] -> IO ()
-buildInterfaces lbi elmis = do
-  createDirectoryIfMissing True (rtsDir lbi)
-  let ifaces = interfaces lbi
-  ifaceHandle <- openBinaryFile ifaces WriteMode
+buildInterfaces :: [FilePath] -> IO ()
+buildInterfaces elmis = do
+  createDirectoryIfMissing True assetsDir
+  ifaceHandle <- openBinaryFile interfaces WriteMode
   BS.hPut ifaceHandle (Binary.encode (length elmis))
   let append file = do
         handle <- openBinaryFile file ReadMode
@@ -144,26 +112,26 @@
   mapM_ append elmis
   hClose ifaceHandle
 
-buildRuntime :: LocalBuildInfo -> [FilePath] -> IO ()
-buildRuntime lbi elmos = do
-  createDirectoryIfMissing True (rtsDir lbi)
-  let rts' = rts lbi
-  writeFile rts' "var Elm = {}; Elm.Native = {}; Elm.Native.Graphics = {};\n\
-                 \var ElmRuntime = {}; ElmRuntime.Render = {};\n"
-  mapM_ (appendTo rts') =<< getFiles ".js" "libraries"
-  mapM_ (appendTo rts') elmos
-  mapM_ (appendTo rts') =<< getFiles ".js" "runtime"
+buildRuntime :: [FilePath] -> IO ()
+buildRuntime elmos = do
+  createDirectoryIfMissing True assetsDir
+  writeFile runtime
+      "'use strict';\n\
+      \var Elm = {}; Elm.Native = {}; Elm.Native.Graphics = {};\n\
+      \var ElmRuntime = {}; ElmRuntime.Render = {};\n"
+  mapM_ (appendTo runtime) =<< getFiles ".js" "libraries"
+  mapM_ (appendTo runtime) elmos
+  mapM_ (appendTo runtime) =<< getFiles ".js" "runtime"
 
-buildDocs :: LocalBuildInfo -> IO ()
-buildDocs lbi = do
-  createDirectoryIfMissing True (rtsDir lbi)
-  let docs' = docs lbi
-  writeFile docs' "[\n"
+buildDocs :: IO ()
+buildDocs = do
+  createDirectoryIfMissing True assetsDir
+  writeFile docs "[\n"
   json <- getFiles ".json" ("libraries" </> "docs")
-  let appends = map (appendTo docs') json
-      addCommas = List.intersperse (appendFile docs' ",\n")
+  let appends = map (appendTo docs) json
+      addCommas = List.intersperse (appendFile docs ",\n")
   sequence_ (addCommas appends)
-  appendFile docs' "\n]"
+  appendFile docs "\n]"
 
 getFiles ext dir = do
   contents <- map (dir </>) `fmap` getDirectoryContents dir
diff --git a/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,344 @@
+
+## 0.13
+
+#### Improvements:
+
+  * Type aliases in port types 
+  * Add Keyboard.alt and Keyboard.meta
+  * Add Debug.crash, Debug.watch, Debug.watchSummary, and Debug.trace
+  * Add List.indexedMap and List.filterMap
+  * Add Maybe.map
+  * Add Basics.negate
+  * Add (>>) to Basics as in F#
+  * Add --bundle-runtime flag which creates stand-alone Elm programs
+  * Error on ambiguious use of imported variables
+  * Replace dependency on Pandoc with cheapskate+kate
+  * Better architecture for compiler. Uses types to make compilation pipeline
+    safer, setting things up for giving programmatic access to the AST to
+    improve editor and IDE support.
+
+#### Breaking Changes:
+
+  * Rename (.) to (<<) as in F#
+  * Rename Basics.id to Basics.identity
+  * Rename Basics.div to (//)
+  * Rename Basics.mod to (%)
+  * Remove Maybe.justs for (List.filterMap identity)
+  * Remove List.and for (List.foldl (&&) True)
+  * Remove List.or  for (List.foldl (||) False)
+  * Unambiguous syntax for importing ADTs and type aliases
+  * sqrt and logBase both only work on Floats now
+
+## 0.12.3
+
+  * Minor changes to support webgl as a separate library
+  * Switch from HSV to HSL
+  * Programmatic access to colors with toHsl and toRgb
+
+## 0.12.1
+
+#### Improvements:
+
+  * New Array library (thanks entirely to @Xashili)
+  * Json.Value can flow through ports
+  * Improve speed and stack usage in List library (thanks to @maxsnew)
+  * Add Dict.filter and Dict.partition (thanks to @hdgarrood)
+
+#### Breaking Changes:
+
+  * Revamp Json library, simpler with better names
+  * Revamp JavaScript.Experimental library to have slightly better names
+  * Remove JavaScript library which was made redundant by ports
+
+## 0.12
+
+#### Breaking Changes:
+
+  * Overhaul Graphics.Input library (inspired by Spiros Eliopoulos and Jeff Smitts)
+  * Overhaul Text library to accomodate new Graphics.Input.Field
+    library and make the API more consistent overall
+  * Overhaul Regex library (inspired by Attila Gazso)
+  * Change syntax for "import open List" to "import List (..)"
+  * Improved JSON format for types generated by elm-doc
+  * Remove problematic Mouse.isClicked signal
+  * Revise the semantics of keepWhen and dropWhen to only update when
+    the filtered signal changes (thanks Max New and Janis Voigtländer)
+
+#### Improvements:
+
+  * Add Graphics.Input.Field for customizable text fields
+  * Add Trampoline library (thanks to @maxsnew and @timthelion) 
+  * Add Debug library (inspired by @timthelion)
+  * Drastically improved performance on markdown parsing (thanks to @Dandandan) 
+  * Add Date.fromTime function
+  * Use pointer-events to detect hovers on layered elements (thanks to @Xashili)
+  * Fix bugs in Bitwise library
+  * Fix bug when exporting Maybe values through ports
+
+## 0.11
+
+  * Ports, a new FFI that is more general and much nicer to use
+  * Basic compiler tests (thanks to Max New)
+
+## 0.10.1
+
+  * sort, sortBy, sortWith (thanks to Max Goldstein)
+  * elm-repl
+  * Bitwise library
+  * Regex library
+  * Improve Transform2D library (thanks to Michael Søndergaard)
+
+## 0.10
+
+  * Native strings
+  * Tango colors
+  * custom precedence and associativity for infix operators
+  * elm-doc released with new documentation format
+  * Realiasing in type errors
+  * Rename Matrix2D => Transform2D
+  * Add Random.floatList (thank you Max GoldStein)
+  * Fix remove function in Dict (thank you Max New)
+  * Start using language-ecmascript for JS generation
+  * Make compatable with cabal-1.18 (thank you Justin Leitgeb)
+  * All functions with 10+ arguments (thanks to Max New)
+
+## 0.9.1
+
+  * Allow custom precedence and associativity for user-defined infix ops
+  * Realias types before printing
+  * Switch to Tango color scheme, adding a bunch of nice colors
+  * add the greyscale function for easily producing greys
+  * Check the type of main
+  * Fix miscellaneous bugs in type checker
+  * Switch name of Matrix2D to Transform2D
+
+## 0.9
+
+Build Improvements:
+  * Major speed improvements to type-checker
+  * Type-checker should catch _all_ type errors now
+  * Module-level compilation, only re-compile if necessary
+  * Import types and type aliases between modules
+  * Intermediate files are generated to avoid unneeded recompilation
+    and shorten compile time. These files go in ElmFiles/ by default
+  * Generated files are placed in ElmFiles/ by default, replicating
+    the directory structure of your source code.
+
+Error Messages:
+  * Cross-module type errors
+  * Errors for undefined values
+  * Pretty printing of expressions and types
+ 
+Syntax:
+  * Pattern matching on literals
+  * Pattern aliases with `as` (Andrew)
+  * Unary negation
+  * Triple-quoted multi-line strings
+  * Type annotations in let expressions (Andrew)
+  * Record Constructors
+  * Record type aliases can be closed on the zeroth column
+  * (,,) syntax in types
+  * Allow infix op definitions without args: (*) = add
+  * Unparenthesized if, let, case, lambda at end of binary expressions
+
+elm-server:
+  * Build multi-module projects
+  * Report all errors in browser
+
+Libraries:
+  * Detect hovering over any Element
+  * Set alpha of arbitrary forms in collages
+  * Switch Text.height to use px instead of em
+
+Bug Fixes:
+  * Many bug fixes for collage, especially when rendering Elements.
+
+Website:
+  * Hot-swapping
+  * Much faster page load with pre-compiled Elm files (Max New)
+
+
+
+
+forgot to fill this in again...
+
+
+## 0.7.2
+
+* Add a WebSockets library.
+* Add support for the mathematical looking operator for function composition (U+2218).
+
+
+forgot to fill this in for a while...
+
+
+## 0.5.0
+
+* Add Dict, Set, and Automaton libraries!
+
+* Add (,,) notation for creating tuples.
+
+* Redo HTTP library, allowing any kind of request and more flexibility.
+
+* Remove the library prefixes `Data.`, `Graphics.`, and `Signal.` because
+  they were more confusing than helpful.
+
+* Better type error reporting for ambiguous uses of variables and for
+  variables in aliased modules.
+
+* Add `readInt` and `readFloat` functions.
+* Add `complement` function to compute complementary colors.
+* Ensure that `String` is treated as an alias of `[Char]`.
+
+* Fix bug in pattern parsing. `A B _ _` was parsed as `A (B _ _)`.
+* Make pattern matching a bit more compact in generated code.
+* Make generated JS more readable.
+
+* The Haskell API exports the absolute path to the Elm runtime
+  system (with the corresponding version number). This makes it easier
+  to run Elm programs with less setup.
+
+
+
+## 0.4.0
+
+This version is all about graphics: nicer API with more features and major
+efficiency improvements. I am really excited about this release!
+
+* Add native Markdown support. You can now embed markdown directly in .elm files
+  and it is used as an `Element`. Syntax is `[markdown| ... |]` where `...` is
+  formatted as described [here](http://daringfireball.net/projects/markdown/).
+  Content can span multiple lines too.
+
+* Drastically improve the `collage` interface. You can now move, rotate, and scale
+  the following forms:
+  - Elements (any Element you want can be turned into a Form with `toForm`)
+  - Images
+  - Shapes (shapes can be textured now too)
+  - Lines
+  This will make it way easier to make games in Elm. Games can now include text,
+  gifs, videos, and any other Element you can think of.
+
+* Add `--minify` flag, to minify JS code.
+
+* Significantly improve performance of pattern matching.
+
+* Compiler performs beta-reduction in some simple cases.
+
+* The rendering section of the Elm runtume-system (RTS) has been totally rewritten,
+  making screen refreshes use fewer cycles, less memory, and cause less garbage-collection.
+
+
+
+## 0.3.6
+
+* Add JSON library.
+
+* Type-error messages improved. Gives better context for error, making them
+  easier to find. Better messages for runtime errors as well (errors that
+  the type checker cannot find yet).
+
+* Add Comparable super-type which allows the comparision of any values
+  of type {Int,Float,Char,String}. Now possible to make Set and Map libraries.
+
+* Parser now handles decimal numbers.
+
+* Added many new functions for manipulating numbers:
+  - truncate, round, floor, ceiling :: Float -> Int
+  - toFloat :: Int -> Float
+  - (^) :: Number -> Number -> Number
+  - e :: Float
+
+* Foreign import/export statements no longer have to preceed all other
+  variable and datatype definitions. They can be mixed in, making things
+  a bit more readable/natural.
+
+* Bug fixes:
+  - The `toText` function did not escape strings properly
+  - Correct `castJSTupleToTupleN` family of functions
+  - `foldr1` took the leftmost element as the base case instead of the rightmost
+  - Fix minor display issue in latest version of Chrome.
+  - Fix behavior of [ lo .. hi ] syntax (now [4..0] == [], not [0]).
+
+
+
+## 0.3.5
+
+* Add JavaScript event interface. Allows Elm to import and export JS values
+  and events. This makes it possible to import and export Elements, so users
+  can use JS techniques and libraries if necessary. Conversion between JS
+  and Elm values happens with functions from here:
+    http://localhost:8000/docs/Foreign/JavaScript.elm
+    http://localhost:8000/docs/Foreign/JavaScript/Experimental.elm
+
+* Add new flags to help with JavaScript event interface.
+
+* Add three built-in event listeners (elm_title, elm_log, elm_redirect) that
+  make it possible to make some common/simple imperative actions without
+  having to worry about writing the JS yourself. For example:
+        foreign export jsevent "elm_title"
+            title :: Signal JSString
+  will update the page's title to the current value of the title signal.
+  Empty strings are ignored. "elm_redirect" and "elm_log" events work much
+  the same way, except that "elm_log" does not skip empty strings.
+
+* Add new Signal functions:
+    count       :: Signal a -> Signal Int
+    keepIf      :: (a -> Bool) -> a -> Signal a -> Signal a
+    dropIf      :: (a -> Bool) -> a -> Signal a -> Signal a
+    keepWhen    :: Signal Bool -> a -> Signal a -> Signal a
+    dropWhen    :: Signal Bool -> a -> Signal a -> Signal a
+    dropRepeats :: Signal a -> Signal a
+    sampleOn    :: Signal a -> Signal b -> Signal b
+    clicks      :: Signal ()
+  The keep and drop functions make it possible to filter events, which
+  was not possible in prior releases. More documentation:
+  http://elm-lang.org/docs/Signal/Signal.elm
+
+* Add examples of JS event interface and new signal functions:
+  https://github.com/evancz/Elm/tree/master/Examples/elm-js
+
+* Use more compressed format for strings. Should make strings 10-12 times
+  more space efficient than in previous releases. Anecdotal evidence:
+  Elm's home page is now 70% of its previous size.
+
+* Add new function to Data.List:
+    last :: [a] -> a
+
+* Fix parenthesization bug with binary operators.
+
+
+
+## 0.3.0
+
+Major Changes (Read this part!)
+-------------------------------
+
+* Add a basic module system.
+* Elm's JavaScript runtime is now distributed with the elm package.
+  Previously it was available for download as an unversioned JavaScript
+  file (elm-mini.js). It is now installed with the elm compiler as
+  elm-runtime-0.3.0.js. Be sure to serve the Elm runtime system that matches
+  the version of the compiler used to generate JavaScript. When working
+  locally, the compiler will automatically use your local copy of this file.
+* BREAKING CHANGE: rgb and rgba (in the color module) now take their red,
+  green, and blue components as integers between 0 and 255 inclusive.
+* Improve error messages for parse errors and runtime errors.
+
+
+New Functions and Other Additions
+---------------------------------
+
+* Add support for keyboard events: Keyboard.Raw
+* Add buttons in Signal.Input:
+  button :: String -> (Element, Signal Bool)
+* Add new basic element (an empty rectangle, good for adding spaces):
+  rectangle :: Int -> Int -> Element
+* Add (an awkwardly named) way to display right justified text: rightedText
+* Add two basic libraries: Data.Char and Data.Maybe
+* Add some new colors: magenta, yellow, cyan, gray, grey
+* Add functions to Data.List module: take, drop
+* Add functions to Prelude (the default imports):
+  fst, snd, curry, uncurry, and a bunch of list functions
+* Add --make, --separate-js, and --only-js flags to help compile
+  with the new module system.
diff --git a/changelog.txt b/changelog.txt
deleted file mode 100644
--- a/changelog.txt
+++ /dev/null
@@ -1,265 +0,0 @@
-
-## 0.11
-
-  * Lazy and Lazy.Stream (thanks to Max New)
-  * sortBy, sortWith (thanks to Max Goldstein)
-  * elm-repl
-  * Markdown interpolation
-  * Bitwise library
-  * Regex library
-  * Improve Transform2D library (thanks to Michael Søndergaard)
-
-## 0.10
-
-  * Native strings
-  * Tango colors
-  * custom precedence and associativity for infix operators
-  * elm-doc released with new documentation format
-  * Realiasing in type errors
-  * Rename Matrix2D => Transform2D
-  * Add Random.floatList (thank you Max GoldStein)
-  * Fix remove function in Dict (thank you Max New)
-  * Start using language-ecmascript for JS generation
-  * Make compatable with cabal-1.18 (thank you Justin Leitgeb)
-  * All functions with 10+ arguments (thanks to Max New)
-
-## 0.9.1
-
-  * Allow custom precedence and associativity for user-defined infix ops
-  * Realias types before printing
-  * Switch to Tango color scheme, adding a bunch of nice colors
-  * add the greyscale function for easily producing greys
-  * Check the type of main
-  * Fix miscellaneous bugs in type checker
-  * Switch name of Matrix2D to Transform2D
-
-## 0.9
-
-Build Improvements:
-  * Major speed improvements to type-checker
-  * Type-checker should catch _all_ type errors now
-  * Module-level compilation, only re-compile if necessary
-  * Import types and type aliases between modules
-  * Intermediate files are generated to avoid unneeded recompilation
-    and shorten compile time. These files go in ElmFiles/ by default
-  * Generated files are placed in ElmFiles/ by default, replicating
-    the directory structure of your source code.
-
-Error Messages:
-  * Cross-module type errors
-  * Errors for undefined values
-  * Pretty printing of expressions and types
- 
-Syntax:
-  * Pattern matching on literals
-  * Pattern aliases with `as` (Andrew)
-  * Unary negation
-  * Triple-quoted multi-line strings
-  * Type annotations in let expressions (Andrew)
-  * Record Constructors
-  * Record type aliases can be closed on the zeroth column
-  * (,,) syntax in types
-  * Allow infix op definitions without args: (*) = add
-  * Unparenthesized if, let, case, lambda at end of binary expressions
-
-elm-server:
-  * Build multi-module projects
-  * Report all errors in browser
-
-Libraries:
-  * Detect hovering over any Element
-  * Set alpha of arbitrary forms in collages
-  * Switch Text.height to use px instead of em
-
-Bug Fixes:
-  * Many bug fixes for collage, especially when rendering Elements.
-
-Website:
-  * Hot-swapping
-  * Much faster page load with pre-compiled Elm files (Max New)
-
-
-
-
-forgot to fill this in again...
-
-
-## 0.7.2
-
-* Add a WebSockets library.
-* Add support for the mathematical looking operator for function composition (U+2218).
-
-
-forgot to fill this in for a while...
-
-
-## 0.5.0
-
-* Add Dict, Set, and Automaton libraries!
-
-* Add (,,) notation for creating tuples.
-
-* Redo HTTP library, allowing any kind of request and more flexibility.
-
-* Remove the library prefixes `Data.`, `Graphics.`, and `Signal.` because
-  they were more confusing than helpful.
-
-* Better type error reporting for ambiguous uses of variables and for
-  variables in aliased modules.
-
-* Add `readInt` and `readFloat` functions.
-* Add `complement` function to compute complementary colors.
-* Ensure that `String` is treated as an alias of `[Char]`.
-
-* Fix bug in pattern parsing. `A B _ _` was parsed as `A (B _ _)`.
-* Make pattern matching a bit more compact in generated code.
-* Make generated JS more readable.
-
-* The Haskell API exports the absolute path to the Elm runtime
-  system (with the corresponding version number). This makes it easier
-  to run Elm programs with less setup.
-
-
-
-## 0.4.0
-
-This version is all about graphics: nicer API with more features and major
-efficiency improvements. I am really excited about this release!
-
-* Add native Markdown support. You can now embed markdown directly in .elm files
-  and it is used as an `Element`. Syntax is `[markdown| ... |]` where `...` is
-  formatted as described [here](http://daringfireball.net/projects/markdown/).
-  Content can span multiple lines too.
-
-* Drastically improve the `collage` interface. You can now move, rotate, and scale
-  the following forms:
-  - Elements (any Element you want can be turned into a Form with `toForm`)
-  - Images
-  - Shapes (shapes can be textured now too)
-  - Lines
-  This will make it way easier to make games in Elm. Games can now include text,
-  gifs, videos, and any other Element you can think of.
-
-* Add `--minify` flag, to minify JS code.
-
-* Significantly improve performance of pattern matching.
-
-* Compiler performs beta-reduction in some simple cases.
-
-* The rendering section of the Elm runtume-system (RTS) has been totally rewritten,
-  making screen refreshes use fewer cycles, less memory, and cause less garbage-collection.
-
-
-
-## 0.3.6
-
-* Add JSON library.
-
-* Type-error messages improved. Gives better context for error, making them
-  easier to find. Better messages for runtime errors as well (errors that
-  the type checker cannot find yet).
-
-* Add Comparable super-type which allows the comparision of any values
-  of type {Int,Float,Char,String}. Now possible to make Set and Map libraries.
-
-* Parser now handles decimal numbers.
-
-* Added many new functions for manipulating numbers:
-  - truncate, round, floor, ceiling :: Float -> Int
-  - toFloat :: Int -> Float
-  - (^) :: Number -> Number -> Number
-  - e :: Float
-
-* Foreign import/export statements no longer have to preceed all other
-  variable and datatype definitions. They can be mixed in, making things
-  a bit more readable/natural.
-
-* Bug fixes:
-  - The `toText` function did not escape strings properly
-  - Correct `castJSTupleToTupleN` family of functions
-  - `foldr1` took the leftmost element as the base case instead of the rightmost
-  - Fix minor display issue in latest version of Chrome.
-  - Fix behavior of [ lo .. hi ] syntax (now [4..0] == [], not [0]).
-
-
-
-## 0.3.5
-
-* Add JavaScript event interface. Allows Elm to import and export JS values
-  and events. This makes it possible to import and export Elements, so users
-  can use JS techniques and libraries if necessary. Conversion between JS
-  and Elm values happens with functions from here:
-    http://localhost:8000/docs/Foreign/JavaScript.elm
-    http://localhost:8000/docs/Foreign/JavaScript/Experimental.elm
-
-* Add new flags to help with JavaScript event interface.
-
-* Add three built-in event listeners (elm_title, elm_log, elm_redirect) that
-  make it possible to make some common/simple imperative actions without
-  having to worry about writing the JS yourself. For example:
-        foreign export jsevent "elm_title"
-            title :: Signal JSString
-  will update the page's title to the current value of the title signal.
-  Empty strings are ignored. "elm_redirect" and "elm_log" events work much
-  the same way, except that "elm_log" does not skip empty strings.
-
-* Add new Signal functions:
-    count       :: Signal a -> Signal Int
-    keepIf      :: (a -> Bool) -> a -> Signal a -> Signal a
-    dropIf      :: (a -> Bool) -> a -> Signal a -> Signal a
-    keepWhen    :: Signal Bool -> a -> Signal a -> Signal a
-    dropWhen    :: Signal Bool -> a -> Signal a -> Signal a
-    dropRepeats :: Signal a -> Signal a
-    sampleOn    :: Signal a -> Signal b -> Signal b
-    clicks      :: Signal ()
-  The keep and drop functions make it possible to filter events, which
-  was not possible in prior releases. More documentation:
-  http://elm-lang.org/docs/Signal/Signal.elm
-
-* Add examples of JS event interface and new signal functions:
-  https://github.com/evancz/Elm/tree/master/Examples/elm-js
-
-* Use more compressed format for strings. Should make strings 10-12 times
-  more space efficient than in previous releases. Anecdotal evidence:
-  Elm's home page is now 70% of its previous size.
-
-* Add new function to Data.List:
-    last :: [a] -> a
-
-* Fix parenthesization bug with binary operators.
-
-
-
-## 0.3.0
-
-Major Changes (Read this part!)
--------------------------------
-
-* Add a basic module system.
-* Elm's JavaScript runtime is now distributed with the elm package.
-  Previously it was available for download as an unversioned JavaScript
-  file (elm-mini.js). It is now installed with the elm compiler as
-  elm-runtime-0.3.0.js. Be sure to serve the Elm runtime system that matches
-  the version of the compiler used to generate JavaScript. When working
-  locally, the compiler will automatically use your local copy of this file.
-* BREAKING CHANGE: rgb and rgba (in the color module) now take their red,
-  green, and blue components as integers between 0 and 255 inclusive.
-* Improve error messages for parse errors and runtime errors.
-
-
-New Functions and Other Additions
----------------------------------
-
-* Add support for keyboard events: Keyboard.Raw
-* Add buttons in Signal.Input:
-  button :: String -> (Element, Signal Bool)
-* Add new basic element (an empty rectangle, good for adding spaces):
-  rectangle :: Int -> Int -> Element
-* Add (an awkwardly named) way to display right justified text: rightedText
-* Add two basic libraries: Data.Char and Data.Maybe
-* Add some new colors: magenta, yellow, cyan, gray, grey
-* Add functions to Data.List module: take, drop
-* Add functions to Prelude (the default imports):
-  fst, snd, curry, uncurry, and a bunch of list functions
-* Add --make, --separate-js, and --only-js flags to help compile
-  with the new module system.
diff --git a/compiler/AST/Annotation.hs b/compiler/AST/Annotation.hs
new file mode 100644
--- /dev/null
+++ b/compiler/AST/Annotation.hs
@@ -0,0 +1,74 @@
+{-# OPTIONS_GHC -W #-}
+module AST.Annotation where
+
+import qualified Text.Parsec.Pos as Parsec
+import qualified Text.PrettyPrint as P
+import AST.PrettyPrint
+
+data Annotated annotation expr = A annotation expr
+    deriving (Show)
+
+data Region
+    = Span Position Position P.Doc
+    | None P.Doc
+    deriving (Show)
+
+data Position = Position
+    { line :: Int
+    , column :: Int
+    } deriving (Show)
+
+type Located expr = Annotated Region expr
+
+none e = A (None (pretty e)) e
+noneNoDocs e = A (None P.empty) e
+
+at :: (Pretty expr) => Parsec.SourcePos -> Parsec.SourcePos -> expr
+   -> Annotated Region expr
+at start end e =
+    A (Span (position start) (position end) (pretty e)) e
+    where
+      position loc = Position (Parsec.sourceLine loc) (Parsec.sourceColumn loc)
+
+merge (A s1 _) (A s2 _) e =
+    A (span (pretty e)) e
+    where
+      span = case (s1,s2) of
+               (Span start _ _, Span _ end _) -> Span start end
+               (Span start end _, _) -> Span start end
+               (_, Span start end _) -> Span start end
+               (_, _) -> None
+
+mergeOldDocs (A s1 _) (A s2 _) e =
+    A span e
+    where
+      span = case (s1,s2) of
+               (Span start _ d1, Span _ end d2) ->
+                   Span start end (P.vcat [d1, P.text "\n", d2])
+
+               (Span _ _ _, _) -> s1
+               (_, Span _ _ _) -> s2
+               (_, _) -> None P.empty
+
+sameAs :: Annotated a expr -> expr' -> Annotated a expr'
+sameAs (A annotation _) expr = A annotation expr
+
+getRegionDocs region =
+    case region of
+      Span _ _ doc -> doc
+      None doc -> doc
+
+instance Pretty Region where
+  pretty span = 
+      case span of
+        None _ -> P.empty
+        Span start end _ ->
+            P.text $
+            case line start == line end of
+              False -> "between lines " ++ show (line start) ++ " and " ++ show (line end)
+              True -> "on line " ++ show (line end) ++ ", column " ++
+                      show (column start) ++ " to " ++ show (column end)
+
+instance Pretty e => Pretty (Annotated a e) where
+  pretty (A _ e) = pretty e
+
diff --git a/compiler/AST/Declaration.hs b/compiler/AST/Declaration.hs
new file mode 100644
--- /dev/null
+++ b/compiler/AST/Declaration.hs
@@ -0,0 +1,106 @@
+{-# OPTIONS_GHC -Wall #-}
+module AST.Declaration where
+
+import Data.Binary
+import qualified AST.Expression.Source as Source
+import qualified AST.Expression.Valid as Valid
+import qualified AST.Expression.Canonical as Canonical
+import qualified AST.Type as T
+import qualified AST.Variable as Var
+import AST.PrettyPrint
+import Text.PrettyPrint as P
+
+data Declaration' port def var
+    = Definition def
+    | Datatype String [String] [(String, [T.Type var])]
+    | TypeAlias String [String] (T.Type var)
+    | Port port
+    | Fixity Assoc Int String
+      deriving (Show)
+
+data Assoc = L | N | R
+    deriving (Eq)
+
+data RawPort
+    = PPAnnotation String T.RawType
+    | PPDef String Source.Expr
+      deriving (Show)
+
+data Port expr var
+    = Out String expr (T.Type var)
+    | In String (T.Type var)
+      deriving (Show)
+
+type SourceDecl    = Declaration' RawPort Source.Def Var.Raw
+type ValidDecl     = Declaration' (Port Valid.Expr Var.Raw) Valid.Def Var.Raw
+type CanonicalDecl = Declaration' (Port Canonical.Expr Var.Canonical)
+                                  Canonical.Def
+                                  Var.Canonical
+
+portName :: Port expr var -> String
+portName port =
+    case port of
+      Out name _ _ -> name
+      In name _ -> name
+
+instance Show Assoc where
+    show assoc =
+        case assoc of
+          L -> "left"
+          N -> "non"
+          R -> "right"
+
+instance Binary Assoc where
+    get = do n <- getWord8
+             return $ case n of
+                0 -> L
+                1 -> N
+                2 -> R
+                _ -> error "Error reading valid associativity from serialized string"
+
+    put assoc = putWord8 $ case assoc of { L -> 0 ; N -> 1 ; R -> 2 }
+
+instance (Pretty port, Pretty def, Pretty var, Var.ToString var) =>
+    Pretty (Declaration' port def var) where
+  pretty decl =
+    case decl of
+      Definition def -> pretty def
+
+      Datatype tipe tvars ctors ->
+          P.hang (P.text "data" <+> P.text tipe <+> P.hsep (map P.text tvars)) 4
+               (P.sep $ zipWith join ("=" : repeat "|") ctors)
+          where
+            join c ctor = P.text c <+> prettyCtor ctor
+            prettyCtor (name, tipes) =
+                P.hang (P.text name) 2 (P.sep (map T.prettyParens tipes))
+
+      TypeAlias name tvars tipe ->
+          P.hang (P.text "type" <+> name' <+> P.equals) 4 (pretty tipe)
+          where
+            name' = P.text name <+> P.hsep (map P.text tvars)
+
+      Port port -> pretty port
+
+      Fixity assoc prec op -> P.text "infix" <> assoc' <+> P.int prec <+> P.text op
+          where
+            assoc' = case assoc of
+                       L -> P.text "l"
+                       N -> P.empty
+                       R -> P.text "r"
+
+instance Pretty RawPort where
+  pretty port =
+    case port of
+      PPAnnotation name tipe -> prettyPort name ":"  tipe
+      PPDef        name expr -> prettyPort name "=" expr
+
+instance (Pretty expr, Pretty var, Var.ToString var) => Pretty (Port expr var) where
+  pretty port =
+    case port of
+      In name tipe -> prettyPort name ":" tipe
+      Out name expr tipe -> P.vcat [ prettyPort name ":" tipe
+                                   , prettyPort name "=" expr ]
+          
+
+prettyPort :: (Pretty a) => String -> String -> a -> Doc
+prettyPort name op e = P.text "port" <+> P.text name <+> P.text op <+> pretty e
diff --git a/compiler/AST/Expression/Canonical.hs b/compiler/AST/Expression/Canonical.hs
new file mode 100644
--- /dev/null
+++ b/compiler/AST/Expression/Canonical.hs
@@ -0,0 +1,30 @@
+{-# OPTIONS_GHC -Wall #-}
+
+module AST.Expression.Canonical where
+
+import AST.PrettyPrint
+import Text.PrettyPrint as P
+import qualified AST.Expression.General as General
+import AST.Type (CanonicalType)
+import qualified AST.Annotation as Annotation
+import qualified AST.Pattern as Pattern
+import qualified AST.Variable as Var
+
+
+{-| Canonicalized expressions. All variables are fully resolved to the module
+they came from.
+-}
+type Expr = General.Expr Annotation.Region Def Var.Canonical
+type Expr' = General.Expr' Annotation.Region Def Var.Canonical
+
+data Def = Definition Pattern.CanonicalPattern Expr (Maybe CanonicalType)
+    deriving (Show)
+
+instance Pretty Def where
+  pretty (Definition pattern expr maybeTipe) =
+      P.vcat [ annotation, definition ]
+      where
+        definition = pretty pattern <+> P.equals <+> pretty expr
+        annotation = case maybeTipe of
+                       Nothing -> P.empty
+                       Just tipe -> pretty pattern <+> P.colon <+> pretty tipe
diff --git a/compiler/AST/Expression/General.hs b/compiler/AST/Expression/General.hs
new file mode 100644
--- /dev/null
+++ b/compiler/AST/Expression/General.hs
@@ -0,0 +1,195 @@
+{-# OPTIONS_GHC -Wall #-}
+
+{-| The Abstract Syntax Tree (AST) for expressions comes in a couple formats.
+The first is the fully general version and is labeled with a prime (Expr').
+The others are specialized versions of the AST that represent specific phases
+of the compilation process. I expect there to be more phases as we begin to
+enrich the AST with more information.
+-}
+module AST.Expression.General where
+
+import AST.PrettyPrint
+import Text.PrettyPrint as P
+import AST.Type (Type)
+
+import qualified AST.Annotation as Annotation
+import qualified AST.Helpers as Help
+import qualified AST.Literal as Literal
+import qualified AST.Pattern as Pattern
+import qualified AST.Variable as Var
+
+---- GENERAL AST ----
+
+{-| This is a fully general Abstract Syntax Tree (AST) for expressions. It has
+"type holes" that allow us to enrich the AST with additional information as we
+move through the compilation process. The type holes are used to represent:
+
+  ann: Annotations for arbitrary expressions. Allows you to add information
+       to the AST like position in source code or inferred types.
+
+  def: Definition style. The source syntax separates type annotations and
+       definitions, but after parsing we check that they are well formed and
+       collapse them.
+
+  var: Representation of variables. Starts as strings, but is later enriched
+       with information about what module a variable came from.
+
+-}
+type Expr annotation definition variable =
+    Annotation.Annotated annotation (Expr' annotation definition variable)
+
+data Expr' ann def var
+    = Literal Literal.Literal
+    | Var var
+    | Range (Expr ann def var) (Expr ann def var)
+    | ExplicitList [Expr ann def var]
+    | Binop var (Expr ann def var) (Expr ann def var)
+    | Lambda (Pattern.Pattern var) (Expr ann def var)
+    | App (Expr ann def var) (Expr ann def var)
+    | MultiIf [(Expr ann def var,Expr ann def var)]
+    | Let [def] (Expr ann def var)
+    | Case (Expr ann def var) [(Pattern.Pattern var, Expr ann def var)]
+    | Data String [Expr ann def var]
+    | Access (Expr ann def var) String
+    | Remove (Expr ann def var) String
+    | Insert (Expr ann def var) String (Expr ann def var)
+    | Modify (Expr ann def var) [(String, Expr ann def var)]
+    | Record [(String, Expr ann def var)]
+    | Markdown String String [Expr ann def var]
+    -- for type checking and code gen only
+    | PortIn String (Type var)
+    | PortOut String (Type var) (Expr ann def var)
+    | GLShader String String Literal.GLShaderTipe
+    deriving (Show)
+
+
+---- UTILITIES ----
+
+rawVar :: String -> Expr' ann def Var.Raw
+rawVar x = Var (Var.Raw x)
+
+localVar :: String -> Expr' ann def Var.Canonical
+localVar x = Var (Var.Canonical Var.Local x)
+
+tuple :: [Expr ann def var] -> Expr' ann def var
+tuple es = Data ("_Tuple" ++ show (length es)) es
+
+delist :: Expr ann def var -> [Expr ann def var]
+delist (Annotation.A _ (Data "::" [h,t])) = h : delist t
+delist _ = []
+
+saveEnvName :: String
+saveEnvName = "_save_the_environment!!!"
+
+dummyLet :: (Pretty def) => [def] -> Expr Annotation.Region def Var.Canonical
+dummyLet defs = 
+     Annotation.none $ Let defs (Annotation.none $ Var (Var.builtin saveEnvName))
+
+instance (Pretty def, Pretty var, Var.ToString var) => Pretty (Expr' ann def var) where
+  pretty expr =
+   case expr of
+     Literal lit -> pretty lit
+
+     Var x -> pretty x
+
+     Range e1 e2 -> P.brackets (pretty e1 <> P.text ".." <> pretty e2)
+
+     ExplicitList es -> P.brackets (commaCat (map pretty es))
+
+     Binop op (Annotation.A _ (Literal (Literal.IntNum 0))) e
+         | Var.toString op == "-" ->
+             P.text "-" <> prettyParens e
+
+     Binop op e1 e2 -> P.sep [ prettyParens e1 <+> P.text op'', prettyParens e2 ]
+         where
+           op' = Var.toString op
+           op'' = if Help.isOp op' then op' else "`" ++ op' ++ "`"
+
+     Lambda p e -> P.text "\\" <> args <+> P.text "->" <+> pretty body
+         where
+           (ps,body) = collectLambdas (Annotation.A undefined $ Lambda p e)
+           args = P.sep (map Pattern.prettyParens ps)
+
+     App _ _ -> P.hang func 2 (P.sep args)
+         where
+           func:args = map prettyParens (collectApps (Annotation.A undefined expr))
+
+     MultiIf branches -> P.text "if" $$ nest 3 (vcat $ map iff branches)
+         where
+           iff (b,e) = P.text "|" <+> P.hang (pretty b <+> P.text "->") 2 (pretty e)
+
+     Let defs e ->
+         P.sep [ P.hang (P.text "let") 4 (P.vcat (map pretty defs))
+               , P.text "in" <+> pretty e ]
+
+     Case e pats ->
+         P.hang pexpr 2 (P.vcat (map pretty' pats))
+         where
+           pexpr = P.sep [ P.text "case" <+> pretty e, P.text "of" ]
+           pretty' (p,b) = pretty p <+> P.text "->" <+> pretty b
+
+     Data "::" [hd,tl] -> pretty hd <+> P.text "::" <+> pretty tl
+     Data "[]" [] -> P.text "[]"
+     Data name es
+         | Help.isTuple name -> P.parens (commaCat (map pretty es))
+         | otherwise -> P.hang (P.text name) 2 (P.sep (map prettyParens es))
+
+     Access e x -> prettyParens e <> P.text "." <> variable x
+
+     Remove e x -> P.braces (pretty e <+> P.text "-" <+> variable x)
+
+     Insert (Annotation.A _ (Remove e y)) x v ->
+         P.braces $ P.hsep [ pretty e, P.text "-", variable y, P.text "|"
+                           , variable x, P.equals, pretty v ]
+
+     Insert e x v ->
+         P.braces (pretty e <+> P.text "|" <+> variable x <+> P.equals <+> pretty v)
+
+     Modify e fs ->
+         P.braces $ P.hang (pretty e <+> P.text "|")
+                           4
+                           (commaSep $ map field fs)
+       where
+         field (k,v) = variable k <+> P.text "<-" <+> pretty v
+
+     Record fs ->
+         P.braces $ P.nest 2 (commaSep $ map field fs)
+       where
+         field (x,e) = variable x <+> P.equals <+> pretty e
+
+     Markdown _ _ _ -> P.text "[markdown| ... |]"
+
+     GLShader _ _ _ -> P.text "[glsl| ... |]"
+
+     PortIn name _ -> P.text $ "<port:" ++ name ++ ">"
+
+     PortOut _ _ signal -> pretty signal
+
+collectApps :: Expr ann def var -> [Expr ann def var]
+collectApps annExpr@(Annotation.A _ expr) =
+  case expr of
+    App a b -> collectApps a ++ [b]
+    _ -> [annExpr]
+
+collectLambdas :: Expr ann def var -> ([Pattern.Pattern var], Expr ann def var)
+collectLambdas lexpr@(Annotation.A _ expr) =
+  case expr of
+    Lambda pattern body ->
+        let (ps, body') = collectLambdas body
+        in  (pattern : ps, body')
+
+    _ -> ([], lexpr)
+
+prettyParens :: (Pretty def, Pretty var, Var.ToString var) => Expr ann def var -> Doc
+prettyParens (Annotation.A _ expr) = parensIf needed (pretty expr)
+  where
+    needed =
+      case expr of
+        Binop _ _ _ -> True
+        Lambda _ _  -> True
+        App _ _     -> True
+        MultiIf _   -> True
+        Let _ _     -> True
+        Case _ _    -> True
+        Data name (_:_) -> not (name == "::" || Help.isTuple name)
+        _ -> False
diff --git a/compiler/AST/Expression/Source.hs b/compiler/AST/Expression/Source.hs
new file mode 100644
--- /dev/null
+++ b/compiler/AST/Expression/Source.hs
@@ -0,0 +1,32 @@
+{-# OPTIONS_GHC -Wall #-}
+
+module AST.Expression.Source where
+
+import AST.PrettyPrint
+import Text.PrettyPrint as P
+import qualified AST.Expression.General as General
+import AST.Type (RawType)
+import qualified AST.Variable as Var
+import qualified AST.Annotation as Annotation
+import qualified AST.Pattern as Pattern
+
+
+{-| Expressions created by the parser. These use a split representation of type
+annotations and definitions, which is how they appear in source code and how
+they are parsed.
+-}
+type Expr = General.Expr Annotation.Region Def Var.Raw
+type Expr' = General.Expr' Annotation.Region Def Var.Raw
+
+data Def
+    = Definition Pattern.RawPattern Expr
+    | TypeAnnotation String RawType
+    deriving (Show)
+
+instance Pretty Def where
+  pretty def =
+   case def of
+     TypeAnnotation name tipe ->
+         variable name <+> P.colon <+> pretty tipe
+     Definition pattern expr ->
+         pretty pattern <+> P.equals <+> pretty expr
diff --git a/compiler/AST/Expression/Valid.hs b/compiler/AST/Expression/Valid.hs
new file mode 100644
--- /dev/null
+++ b/compiler/AST/Expression/Valid.hs
@@ -0,0 +1,31 @@
+{-# OPTIONS_GHC -Wall #-}
+
+module AST.Expression.Valid where
+
+import AST.PrettyPrint
+import Text.PrettyPrint as P
+import qualified AST.Expression.General as General
+import AST.Type (RawType)
+import qualified AST.Variable as Var
+import qualified AST.Annotation as Annotation
+import qualified AST.Pattern as Pattern
+
+
+{-| "Normal" expressions. When the compiler checks that type annotations and
+ports are all paired with definitions in the appropriate order, it collapses
+them into a Def that is easier to work with in later phases of compilation.
+-}
+type Expr = General.Expr Annotation.Region Def Var.Raw
+type Expr' = General.Expr' Annotation.Region Def Var.Raw
+
+data Def = Definition Pattern.RawPattern Expr (Maybe RawType)
+    deriving (Show)
+
+instance Pretty Def where
+  pretty (Definition pattern expr maybeTipe) =
+      P.vcat [ annotation, definition ]
+      where
+        definition = pretty pattern <+> P.equals <+> pretty expr
+        annotation = case maybeTipe of
+                       Nothing -> P.empty
+                       Just tipe -> pretty pattern <+> P.colon <+> pretty tipe
diff --git a/compiler/AST/Helpers.hs b/compiler/AST/Helpers.hs
new file mode 100644
--- /dev/null
+++ b/compiler/AST/Helpers.hs
@@ -0,0 +1,27 @@
+{-# OPTIONS_GHC -Wall #-}
+module AST.Helpers where
+
+import qualified Data.Char as Char
+
+splitDots :: String -> [String]
+splitDots = go []
+  where
+    go vars str =
+        case break (=='.') str of
+          (x,_:rest) | isOp x -> vars ++ [x ++ '.' : rest]
+                     | otherwise -> go (vars ++ [x]) rest
+          (x,[]) -> vars ++ [x]
+
+brkt :: String -> String
+brkt s = "{ " ++ s ++ " }"
+
+isTuple :: String -> Bool
+isTuple name =
+    take 6 name == "_Tuple" && all Char.isDigit (drop 6 name)
+
+isOp :: String -> Bool
+isOp = all isSymbol
+
+isSymbol :: Char -> Bool
+isSymbol c =
+    Char.isSymbol c || elem c "+-/*=.$<>:&|^?%#@~!"
diff --git a/compiler/AST/Literal.hs b/compiler/AST/Literal.hs
new file mode 100644
--- /dev/null
+++ b/compiler/AST/Literal.hs
@@ -0,0 +1,43 @@
+{-# OPTIONS_GHC -Wall #-}
+module AST.Literal where
+
+import AST.PrettyPrint
+import Data.Map (Map)
+import qualified Text.PrettyPrint as PP
+
+data Literal = IntNum Int
+             | FloatNum Double
+             | Chr Char
+             | Str String
+             | Boolean Bool
+             deriving (Eq, Ord, Show)
+
+instance Pretty Literal where
+  pretty literal =
+    case literal of
+      IntNum n -> PP.int n
+      FloatNum n -> PP.double n
+      Chr c -> PP.text . show $ c
+      Str s -> PP.text . show $ s
+      Boolean bool -> PP.text (show bool)
+
+data GLTipe = Int | Float | V2 | V3 | V4 | M4 | Texture
+  deriving (Show)
+
+glTipeName :: GLTipe -> String
+glTipeName glTipe =
+    case glTipe of
+      Int     -> "Int"
+      Float   -> "Float"
+      V2      -> "Math.Vector2.Vec2"
+      V3      -> "Math.Vector3.Vec3"
+      V4      -> "Math.Vector4.Vec4"
+      M4      -> "Math.Matrix4.Mat4"
+      Texture -> "Graphics.WebGL.Texture"
+
+data GLShaderTipe = GLShaderTipe
+    { attribute :: Map String GLTipe
+    , uniform :: Map String GLTipe
+    , varying :: Map String GLTipe
+    } deriving (Show)
+
diff --git a/compiler/AST/Module.hs b/compiler/AST/Module.hs
new file mode 100644
--- /dev/null
+++ b/compiler/AST/Module.hs
@@ -0,0 +1,128 @@
+{-# OPTIONS_GHC -W #-}
+module AST.Module where
+
+import Data.Binary
+import qualified Data.List as List
+import qualified Data.Map as Map
+import Control.Applicative ((<$>),(<*>))
+
+import qualified AST.Expression.Canonical as Canonical
+import qualified AST.Declaration as Decl
+import qualified AST.Type as Type
+import qualified AST.Variable as Var
+
+import AST.PrettyPrint
+import Text.PrettyPrint as P
+
+import qualified Elm.Internal.Version as Version
+
+data Module exs body = Module
+    { names   :: [String]
+    , path    :: FilePath
+    , exports :: exs
+    , imports :: [(String, ImportMethod)]
+    , body    :: body
+    }
+
+getName :: Module exs body -> String
+getName modul =
+    List.intercalate "." (names modul)
+
+data CanonicalBody = CanonicalBody
+    { program   :: Canonical.Expr
+    , types     :: Types
+    , fixities  :: [(Decl.Assoc, Int, String)]
+    , aliases   :: Aliases
+    , datatypes :: ADTs
+    , ports     :: [String]
+    }
+
+type SourceModule    = Module (Var.Listing Var.Value) [Decl.SourceDecl]
+type ValidModule     = Module (Var.Listing Var.Value) [Decl.ValidDecl]
+type CanonicalModule = Module [Var.Value] CanonicalBody
+
+type Interfaces = Map.Map String Interface
+
+type Types   = Map.Map String Type.CanonicalType
+type Aliases = Map.Map String ( [String], Type.CanonicalType )
+type ADTs    = Map.Map String (AdtInfo String)
+
+type AdtInfo v = ( [String], [(v, [Type.CanonicalType])] )
+type CanonicalAdt = (Var.Canonical, AdtInfo Var.Canonical)
+
+data Interface = Interface
+    { iVersion  :: Version.Version
+    , iExports  :: [Var.Value]
+    , iTypes    :: Types
+    , iImports  :: [(String, ImportMethod)]
+    , iAdts     :: ADTs
+    , iAliases  :: Aliases
+    , iFixities :: [(Decl.Assoc, Int, String)]
+    , iPorts    :: [String]
+    }
+
+toInterface :: CanonicalModule -> Interface
+toInterface modul =
+    let body' = body modul in
+    Interface
+    { iVersion  = Version.elmVersion
+    , iExports  = exports modul
+    , iTypes    = types body'
+    , iImports  = imports modul
+    , iAdts     = datatypes body'
+    , iAliases  = aliases body'
+    , iFixities = fixities body'
+    , iPorts    = ports body'
+    }
+
+instance Binary Interface where
+  get = Interface <$> get <*> get <*> get <*> get <*> get <*> get <*> get <*> get
+  put modul = do
+      put (iVersion modul)
+      put (iExports modul)
+      put (iTypes modul)
+      put (iImports modul)
+      put (iAdts modul)
+      put (iAliases modul)
+      put (iFixities modul)
+      put (iPorts modul)
+
+data ImportMethod
+    = As !String
+    | Open !(Var.Listing Var.Value)
+
+open :: ImportMethod
+open = Open (Var.openListing)
+
+importing :: [Var.Value] -> ImportMethod
+importing xs = Open (Var.Listing xs False)
+
+instance Binary ImportMethod where
+    put method =
+        case method of
+          As alias     -> putWord8 0 >> put alias
+          Open listing -> putWord8 1 >> put listing
+
+    get = do tag <- getWord8
+             case tag of
+               0 -> As   <$> get
+               1 -> Open <$> get
+               _ -> error "Error reading valid ImportMethod type from serialized string"
+
+instance (Pretty exs, Pretty body) => Pretty (Module exs body) where
+  pretty (Module names _ exs ims body) =
+      P.vcat [modul, P.text "", prettyImports, P.text "", pretty body]
+    where 
+      modul = P.text "module" <+> name <+> pretty exs <+> P.text "where"
+      name = P.text (List.intercalate "." names)
+
+      prettyImports = P.vcat $ map prettyMethod ims
+
+prettyMethod :: (String, ImportMethod) -> Doc
+prettyMethod (name, method) =
+    case method of
+      As alias
+          | name == alias -> P.empty
+          | otherwise     -> P.text "as" <+> P.text alias
+
+      Open listing -> pretty listing
diff --git a/compiler/AST/Pattern.hs b/compiler/AST/Pattern.hs
new file mode 100644
--- /dev/null
+++ b/compiler/AST/Pattern.hs
@@ -0,0 +1,79 @@
+{-# OPTIONS_GHC -Wall #-}
+module AST.Pattern where
+
+import qualified AST.Helpers as Help
+import AST.PrettyPrint
+import Text.PrettyPrint as PP
+import qualified Data.Set as Set
+
+import qualified AST.Variable as Var
+import AST.Literal as Literal
+
+data Pattern var
+    = Data var [Pattern var]
+    | Record [String]
+    | Alias String (Pattern var)
+    | Var String
+    | Anything
+    | Literal Literal.Literal
+    deriving (Eq, Ord, Show)
+
+type RawPattern = Pattern Var.Raw
+type CanonicalPattern = Pattern Var.Canonical
+
+cons :: RawPattern -> RawPattern -> RawPattern
+cons h t = Data (Var.Raw "::") [h,t]
+
+nil :: RawPattern
+nil = Data (Var.Raw "[]") []
+
+list :: [RawPattern] -> RawPattern
+list = foldr cons nil
+
+tuple :: [RawPattern] -> RawPattern
+tuple es = Data (Var.Raw ("_Tuple" ++ show (length es))) es
+
+boundVarList :: Pattern var -> [String]
+boundVarList = Set.toList . boundVars
+
+boundVars :: Pattern var -> Set.Set String
+boundVars pattern =
+    case pattern of
+      Var x -> Set.singleton x
+      Alias x p -> Set.insert x (boundVars p)
+      Data _ ps -> Set.unions (map boundVars ps)
+      Record fields -> Set.fromList fields
+      Anything -> Set.empty
+      Literal _ -> Set.empty
+
+
+instance Var.ToString var => Pretty (Pattern var) where
+  pretty pattern =
+   case pattern of
+     Var x -> variable x
+     Literal lit -> pretty lit
+     Record fs -> PP.braces (commaCat $ map variable fs)
+     Alias x p -> prettyParens p <+> PP.text "as" <+> variable x
+     Anything -> PP.text "_"
+     Data name [hd,tl] | Var.toString name == "::" ->
+         parensIf isCons (pretty hd) <+> PP.text "::" <+> pretty tl
+       where
+         isCons = case hd of
+                    Data ctor _ -> Var.toString ctor == "::"
+                    _ -> False
+
+     Data name ps
+         | Help.isTuple name' -> PP.parens . commaCat $ map pretty ps
+         | otherwise          -> hsep (PP.text name' : map prettyParens ps)
+         where
+           name' = Var.toString name
+
+prettyParens :: Var.ToString var => Pattern var -> Doc
+prettyParens pattern = 
+    parensIf needsThem (pretty pattern)
+  where
+    needsThem =
+      case pattern of
+        Data name (_:_) | not (Help.isTuple (Var.toString name)) -> True
+        Alias _ _ -> True
+        _ -> False
diff --git a/compiler/AST/PrettyPrint.hs b/compiler/AST/PrettyPrint.hs
new file mode 100644
--- /dev/null
+++ b/compiler/AST/PrettyPrint.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE FlexibleInstances #-}
+module AST.PrettyPrint where
+
+import Control.Monad.Trans.Error
+import Text.PrettyPrint as P
+import qualified AST.Helpers as Help
+
+class Pretty a where
+  pretty :: a -> Doc
+
+instance Pretty Doc where
+  pretty doc = doc
+
+instance Pretty String where
+  pretty = P.text
+
+renderPretty :: (Pretty a) => a -> String
+renderPretty e = render (pretty e)
+
+commaCat docs = cat (punctuate comma docs)
+commaSep docs = sep (punctuate comma docs)
+
+parensIf :: Bool -> Doc -> Doc
+parensIf bool doc = if bool then parens doc else doc
+
+variable :: String -> Doc
+variable x =
+    if Help.isOp x then parens (text x) else text x
+
+eightyCharLines :: Int -> String -> String
+eightyCharLines indent message = answer
+    where
+      (answer,_,_) = foldl step (spaces, indent-1, "") chunks
+
+      chunks = map (\w -> (w, length w)) (words message)
+      spaces = replicate indent ' '
+      step (sentence, slen, space) (word, wlen)
+          | slen + wlen > 79 = (sentence ++ "\n" ++ spaces ++ word, indent + wlen, " ")
+          | otherwise        = (sentence ++ space ++ word, slen + wlen + length space, " ")
+
+instance ErrorList Doc where
+    listMsg str = [ P.text str ]
diff --git a/compiler/AST/Type.hs b/compiler/AST/Type.hs
new file mode 100644
--- /dev/null
+++ b/compiler/AST/Type.hs
@@ -0,0 +1,138 @@
+{-# OPTIONS_GHC -W #-}
+module AST.Type where
+
+import Control.Applicative ((<$>), (<*>))
+import Data.Binary
+import qualified Data.Map as Map
+
+import qualified AST.Variable as Var
+import AST.PrettyPrint
+import qualified AST.Helpers as Help
+import Text.PrettyPrint as P
+
+data Type var
+    = Lambda (Type var) (Type var)
+    | Var String
+    | Type var
+    | App (Type var) [Type var]
+    | Record [(String, Type var)] (Maybe (Type var))
+    | Aliased Var.Canonical (Type var)
+    deriving (Eq,Show)
+
+type RawType = Type Var.Raw
+type CanonicalType = Type Var.Canonical
+
+fieldMap :: [(String,a)] -> Map.Map String [a]
+fieldMap fields =
+    foldl (\r (x,t) -> Map.insertWith (++) x [t] r) Map.empty fields
+
+recordOf :: [(String, Type var)] -> Type var
+recordOf fields = Record fields Nothing
+
+listOf :: RawType -> RawType
+listOf t = App (Type (Var.Raw "_List")) [t]
+
+tupleOf :: [RawType] -> RawType
+tupleOf ts = App (Type t) ts
+  where
+    t = Var.Raw ("_Tuple" ++ show (length ts))
+
+instance (Var.ToString var, Pretty var) => Pretty (Type var) where
+  pretty tipe =
+    case tipe of
+      Lambda _ _ -> P.sep [ t, P.sep (map (P.text "->" <+>) ts) ]
+        where
+          t:ts = map prettyLambda (collectLambdas tipe)
+          prettyLambda t = case t of
+                             Lambda _ _ -> P.parens (pretty t)
+                             _ -> pretty t
+
+      Var x -> P.text x
+
+      Type var ->
+          let v = Var.toString var in
+          P.text (if v == "_Tuple0" then "()" else v)
+
+      App f args ->
+          case (f,args) of
+            (Type name, [t])
+                | Var.toString name == "_List" -> P.brackets (pretty t)
+
+            (Type name, _)
+                | Help.isTuple (Var.toString name) ->
+                    P.parens . P.sep . P.punctuate P.comma $ map pretty args
+
+            _ -> P.hang (pretty f) 2 (P.sep $ map prettyParens args)
+
+      Record _ _ ->
+          P.braces $ case flattenRecord tipe of
+                       (fields, Nothing) -> prettyFields fields
+                       (fields, Just x) ->
+                           P.hang (P.text x <+> P.text "|") 4 (prettyFields fields)
+          where
+            prettyField (f,t) = P.text f <+> P.text ":" <+> pretty t
+            prettyFields fields = commaSep (map prettyField fields)
+
+      Aliased name t ->
+          let t' = pretty t in
+          if show t' `elem` ["Int", "Float", "String", "Char", "Bool"]
+            then t'
+            else pretty name
+
+collectLambdas :: Type var -> [Type var]
+collectLambdas tipe =
+  case tipe of
+    Lambda arg body -> arg : collectLambdas body
+    _ -> [tipe]
+
+prettyParens :: (Var.ToString var, Pretty var) => Type var -> Doc
+prettyParens tipe = parensIf (needed tipe) (pretty tipe)
+  where
+    needed t =
+      case t of
+        Aliased _ t' -> needed t'
+
+        Lambda _ _ -> True
+
+        App (Type name) [_] | Var.toString name == "_List"     -> False
+        App (Type name) _   | Help.isTuple (Var.toString name) -> False
+        App t' [] -> needed t'
+        App _ _ -> True
+
+        _ -> False
+
+flattenRecord :: Type var -> ( [(String, Type var)], Maybe String )
+flattenRecord tipe =
+    case tipe of
+      Var x -> ([], Just x)
+
+      Record fields Nothing -> (fields, Nothing)
+
+      Record fields (Just ext) ->
+          let (fields',ext') = flattenRecord ext
+          in  (fields' ++ fields, ext')
+
+      Aliased _ tipe' -> flattenRecord tipe'
+
+      _ -> error "Trying to flatten ill-formed record."
+
+instance Binary var => Binary (Type var) where
+  put tipe =
+      case tipe of
+        Lambda t1 t2  -> putWord8 0 >> put t1 >> put t2
+        Var x         -> putWord8 1 >> put x
+        Type name     -> putWord8 2 >> put name
+        App t1 t2     -> putWord8 3 >> put t1 >> put t2
+        Record fs ext -> putWord8 4 >> put fs >> put ext
+        Aliased var t -> putWord8 5 >> put var >> put t
+
+  get = do
+      n <- getWord8
+      case n of
+        0 -> Lambda <$> get <*> get
+        1 -> Var <$> get
+        2 -> Type <$> get
+        3 -> App <$> get <*> get
+        4 -> Record <$> get <*> get
+        5 -> Aliased <$> get <*> get
+        _ -> error "Error reading a valid type from serialized string"
diff --git a/compiler/AST/Variable.hs b/compiler/AST/Variable.hs
new file mode 100644
--- /dev/null
+++ b/compiler/AST/Variable.hs
@@ -0,0 +1,152 @@
+{-# OPTIONS_GHC -W #-}
+module AST.Variable where
+
+import Data.Binary
+import Control.Applicative ((<$>), (<*>))
+import Text.PrettyPrint as P
+import qualified AST.Helpers as Help
+import AST.PrettyPrint
+
+newtype Raw = Raw String
+    deriving (Eq,Ord,Show)
+
+data Home
+    = BuiltIn
+    | Module !String
+    | Local
+    deriving (Eq,Ord,Show)
+
+data Canonical = Canonical
+    { home :: !Home
+    , name :: !String
+    } deriving (Eq,Ord,Show)
+
+local :: String -> Canonical
+local x = Canonical Local x
+
+builtin :: String -> Canonical
+builtin x = Canonical BuiltIn x
+
+-- To help with pattern matching on some common canonical variables:
+is :: String -> String -> Canonical -> Bool
+is home name var =
+    var == Canonical (Module home) name
+
+isJson :: Canonical -> Bool
+isJson = is "Json" "Value"
+
+isMaybe :: Canonical -> Bool
+isMaybe = is "Maybe" "Maybe"
+
+isArray :: Canonical -> Bool
+isArray = is "Array" "Array"
+
+isSignal :: Canonical -> Bool
+isSignal = is "Signal" "Signal"
+
+isList :: Canonical -> Bool
+isList v = v == Canonical BuiltIn "_List"
+
+isTuple :: Canonical -> Bool
+isTuple v =
+    case v of
+      Canonical BuiltIn name -> Help.isTuple name
+      _ -> False
+
+isPrimitive :: Canonical -> Bool
+isPrimitive v =
+    case v of
+      Canonical BuiltIn name -> name `elem` ["Int","Float","String","Bool"]
+      _ -> False
+
+isPrim :: String -> Canonical -> Bool
+isPrim prim v =
+    case v of
+      Canonical BuiltIn name -> name == prim
+      _ -> False
+
+isText :: Canonical -> Bool
+isText = is "Text" "Text"
+
+class ToString a where
+  toString :: a -> String
+
+instance ToString Raw where
+  toString (Raw x) = x
+
+instance ToString Canonical where
+  toString (Canonical home name) =
+    case home of
+      BuiltIn -> name
+      Module path -> path ++ "." ++ name
+      Local -> name
+
+-- | A listing of values. Something like (a,b,c) or (..) or (a,b,..)
+data Listing a = Listing
+    { _explicits :: [a]
+    , _open :: Bool
+    } deriving (Eq,Ord,Show)
+
+openListing :: Listing a
+openListing = Listing [] True
+
+-- | A value that can be imported or exported
+data Value
+    = Value !String
+    | Alias !String
+    | ADT !String !(Listing String)
+    deriving (Eq,Ord,Show)
+
+instance Pretty Raw where
+    pretty (Raw var) = variable var
+
+instance Pretty Canonical where
+    pretty var = P.text (toString var)
+
+instance Pretty a => Pretty (Listing a) where
+  pretty (Listing explicits open) =
+      P.parens (commaCat (map pretty explicits ++ dots))
+      where
+        dots = [if open then P.text ".." else P.empty]
+
+instance Pretty Value where
+  pretty portable =
+    case portable of
+      Value name -> P.text name
+      Alias name -> P.text name
+      ADT name ctors ->
+          P.text name <> pretty (ctors { _explicits = map P.text (_explicits ctors) })
+
+instance Binary Canonical where
+    put (Canonical home name) =
+        case home of
+          BuiltIn     -> putWord8 0 >> put name
+          Module path -> putWord8 1 >> put path >> put name
+          Local       -> putWord8 2 >> put name
+
+    get = do tag <- getWord8
+             case tag of
+               0 -> Canonical BuiltIn <$> get
+               1 -> Canonical . Module <$> get <*> get
+               2 -> Canonical Local <$> get
+               _ -> error "Unexpected tag when deserializing canonical variable"
+
+instance Binary Value where
+    put portable =
+        case portable of
+          Value name     -> putWord8 0 >> put name
+          Alias name     -> putWord8 1 >> put name
+          ADT name ctors -> putWord8 2 >> put name >> put ctors
+
+    get = do tag <- getWord8
+             case tag of
+               0 -> Value <$> get
+               1 -> Alias <$> get
+               2 -> ADT <$> get <*> get
+               _ -> error "Error reading valid import/export information from serialized string"
+
+instance (Binary a) => Binary (Listing a) where
+    put (Listing explicits open) =
+        put explicits >> put open
+
+    get = Listing <$> get <*> get
diff --git a/compiler/Build/Dependencies.hs b/compiler/Build/Dependencies.hs
--- a/compiler/Build/Dependencies.hs
+++ b/compiler/Build/Dependencies.hs
@@ -1,58 +1,57 @@
 {-# OPTIONS_GHC -W #-}
-module Build.Dependencies (getSortedDependencies, readDeps) where
+module Build.Dependencies (Recipe(..), getBuildRecipe, readDeps) where
 
-import Control.Applicative
 import Control.Monad.Error
 import qualified Control.Monad.State as State
-import qualified Data.Aeson as Json
-import qualified Data.ByteString.Lazy.Char8 as BSC
 import qualified Data.Graph as Graph
 import qualified Data.List as List
 import qualified Data.Map as Map
-import qualified Data.Maybe as Maybe
 import qualified Data.Set as Set
 import System.Directory
 import System.FilePath as FP
 
-import Build.Print (failure)
-
-import qualified SourceSyntax.Module as Module
+import qualified AST.Module as Module
 import qualified Parse.Parse as Parse
 import qualified Elm.Internal.Paths as Path
 import qualified Elm.Internal.Name as N
+import qualified Elm.Internal.Version as V
 import qualified Elm.Internal.Dependencies as Deps
 
-getSortedDependencies :: [FilePath] -> Module.Interfaces -> FilePath -> IO [String]
-getSortedDependencies srcDirs builtIns root =
-    do extras <- extraDependencies
-       let allSrcDirs = srcDirs ++ Maybe.fromMaybe [] extras
-       result <- runErrorT $ readAllDeps allSrcDirs builtIns root
-       case result of
-         Right deps -> sortDeps deps
-         Left err -> failure $ err ++ if Maybe.isJust extras then "" else msg
-             where msg = "\nYou may need to create a " ++
-                         Path.dependencyFile ++
-                         " file if you\nare trying to use a 3rd party library."
+data Recipe = Recipe
+    { _elmFiles :: [FilePath]
+    , _jsFiles :: [FilePath]
+    }
 
-extraDependencies :: IO (Maybe [FilePath])
-extraDependencies =
-    do exists <- doesFileExist Path.dependencyFile
-       if not exists then return Nothing else Just <$> getPaths
-    where
-      getPaths = do
-        raw <- BSC.readFile Path.dependencyFile
-        case Json.eitherDecode raw of
-          Right (Deps.Mini deps) -> mapM validate deps
-          Left err ->
-              failure $ "Error reading the " ++ Path.dependencyFile ++ " file:\n" ++ err
+getBuildRecipe :: [FilePath] -> Module.Interfaces -> FilePath -> ErrorT String IO Recipe
+getBuildRecipe srcDirs builtIns root =
+  do directories <- getDependencies
+     jsFiles <- nativeFiles ("." : directories)
+     let allSrcDirs = srcDirs ++ directories
+     nodes <- collectDependencies allSrcDirs builtIns root
+     elmFiles <- sortElmFiles nodes
+     return (Recipe elmFiles jsFiles)
 
-      validate (name,version) = do
-        let path = Path.dependencyDirectory </> toPath name version
-        exists <- doesDirectoryExist path
-        if exists then return path else failure (notFound name version)
+-- | Based on the projects elm_dependencies.json, find all of the paths and
+--   dependency information we might need.
+getDependencies :: ErrorT String IO [FilePath]
+getDependencies =
+    do exists <- liftIO $ doesFileExist Path.dependencyFile
+       if not exists then return [] else getPaths
+    where
+      getPaths :: ErrorT String IO [FilePath]
+      getPaths =
+        Deps.withDeps Path.dependencyFile $ \deps ->
+            mapM getPath (Deps.dependencies deps)
 
-      toPath name version = N.toFilePath name </> show version
+      getPath :: (N.Name, V.Version) -> ErrorT String IO FilePath
+      getPath (name,version) = do
+        let path = Path.dependencyDirectory </> N.toFilePath name </> show version
+        exists <- liftIO $ doesDirectoryExist path
+        if exists
+          then return path
+          else throwError (notFound name version)
 
+      notFound :: N.Name -> V.Version -> String
       notFound name version =
           unlines
           [ "Your " ++ Path.dependencyFile ++ " file says you depend on library"
@@ -61,58 +60,92 @@
           , ""
           , "    elm-get install " ++ show name ++ " " ++ show version ]
 
-type Deps = (FilePath, String, [String])
+nativeFiles :: [FilePath] -> ErrorT String IO [FilePath]
+nativeFiles directories =
+  do exists <- liftIO $ doesFileExist Path.dependencyFile
+     if not exists
+       then return []
+       else concat `fmap` mapM getNativeFiles directories
+  where
+    getNativeFiles dir =
+        Deps.withDeps (dir </> Path.dependencyFile) $ \deps ->
+            return (map (toPath dir) (Deps.native deps))
 
-sortDeps :: [Deps] -> IO [String]
-sortDeps depends =
+    toPath dir moduleName =
+        dir </> joinPath (split moduleName) <.> "js"
+        
+split :: String -> [String]
+split moduleName = go [] moduleName
+  where
+    go paths str =
+        case break (=='.') str of
+          (path, _:rest) -> go (paths ++ [path]) rest
+          (path, [])     -> paths ++ [path]
+
+type DependencyNode = (FilePath, String, [String])
+
+sortElmFiles :: [DependencyNode] -> ErrorT String IO [FilePath]
+sortElmFiles depends =
     if null mistakes
       then return (concat sccs)
-      else failure $ msg ++ unlines (map show mistakes)
+      else throwError $ msg ++ unlines (map show mistakes)
   where
     sccs = map Graph.flattenSCC $ Graph.stronglyConnComp depends
 
     mistakes = filter (\scc -> length scc > 1) sccs
     msg = "A cyclical module dependency or was detected in:\n"
 
-readAllDeps :: [FilePath] -> Module.Interfaces -> FilePath -> ErrorT String IO [Deps]
-readAllDeps srcDirs builtIns root =
-  do let ifaces = (Set.fromList . Map.keys) builtIns
-     State.evalStateT (go ifaces root) Set.empty
+collectDependencies :: [FilePath] -> Module.Interfaces -> FilePath
+                    -> ErrorT String IO [DependencyNode]
+collectDependencies srcDirs rawBuiltIns filePath =
+    State.evalStateT (go Nothing filePath) Set.empty
   where
-    go :: Set.Set String -> FilePath -> State.StateT (Set.Set String) (ErrorT String IO) [Deps]
-    go builtIns root = do
-      root'        <- lift $ findSrcFile srcDirs root
-      (name, deps) <- lift $ readDeps root'
+    builtIns :: Set.Set String
+    builtIns = Set.fromList $ Map.keys rawBuiltIns
+
+    go :: Maybe String -> FilePath -> State.StateT (Set.Set String) (ErrorT String IO) [DependencyNode]
+    go parentModuleName filePath = do
+      filePath' <- lift $ findSrcFile parentModuleName srcDirs filePath
+      (moduleName, deps) <- lift $ readDeps filePath'
       seen <- State.get
       let realDeps = Set.difference (Set.fromList deps) builtIns
           newDeps = Set.difference (Set.filter (not . isNative) realDeps) seen
-      State.put (Set.insert name (Set.union newDeps seen))
-      rest <- mapM (go builtIns . toFilePath) (Set.toList newDeps)
-      return ((makeRelative "." root', name, Set.toList realDeps) : concat rest)
+      State.put (Set.insert moduleName (Set.union newDeps seen))
+      rest <- mapM (go (Just moduleName) . toFilePath) (Set.toList newDeps)
+      return ((makeRelative "." filePath', moduleName, Set.toList realDeps) : concat rest)
 
 readDeps :: FilePath -> ErrorT String IO (String, [String])
 readDeps path = do
   txt <- lift $ readFile path
   case Parse.dependencies txt of
+    Right o  -> return o
     Left err -> throwError $ msg ++ show err
       where msg = "Error resolving dependencies in " ++ path ++ ":\n"
-    Right o  -> return o
 
-findSrcFile :: [FilePath] -> FilePath -> ErrorT String IO FilePath
-findSrcFile dirs path = foldr tryDir notFound dirs
+findSrcFile :: Maybe String -> [FilePath] -> FilePath -> ErrorT String IO FilePath
+findSrcFile parentModuleName dirs path =
+    foldr tryDir notFound dirs
   where
-    notFound = throwError $ unlines
-        [ "Could not find file: " ++ path
-        , "    If it is not in the root directory of your project, use"
-        , "    --src-dir to declare additional locations for source files."
-        , "    If it is part of a 3rd party library, it needs to be declared"
-        , "    as a dependency in the " ++ Path.dependencyFile ++ " file." ]
     tryDir dir next = do
       let path' = dir </> path
       exists <- liftIO $ doesFileExist path'
       if exists
         then return path'
         else next
+
+    parentModuleName' =
+        case parentModuleName of
+          Just name -> "module '" ++ name ++ "'"
+          Nothing -> "the main module"
+
+    notFound = throwError $ unlines
+        [ "When finding the imports declared in " ++ parentModuleName' ++ ", could not find file: " ++ path
+        , "    If you created this module, but it is in a subdirectory that does not"
+        , "    exactly match the module name, you may need to use the --src-dir flag."
+        , ""
+        , "    If it is part of a 3rd party library, it needs to be declared"
+        , "    as a dependency in your project's " ++ Path.dependencyFile ++ " file."
+        ]
 
 isNative :: String -> Bool
 isNative name = List.isPrefixOf "Native." name
diff --git a/compiler/Build/File.hs b/compiler/Build/File.hs
--- a/compiler/Build/File.hs
+++ b/compiler/Build/File.hs
@@ -23,8 +23,7 @@
 import qualified Build.Utils            as Utils
 import qualified Generate.JavaScript    as JS
 import qualified Parse.Module           as Parser
-import qualified SourceSyntax.Module    as M
-import qualified Transform.Canonicalize as Canonical
+import qualified AST.Module             as Module
 
 -- Reader: Runtime flags, always accessible
 -- Writer: Remember the last module to be accessed
@@ -33,10 +32,10 @@
 type Build a = BuildT IO a
 
 -- Interfaces, remembering if something was recompiled
-type BInterfaces = Map.Map String (Bool, M.ModuleInterface)
+type BInterfaces = Map.Map String (Bool, Module.Interface)
 
-evalBuild :: Flag.Flags -> M.Interfaces -> Build ()
-          -> IO (Map.Map String M.ModuleInterface, Maybe String)
+evalBuild :: Flag.Flags -> Module.Interfaces -> Build ()
+          -> IO (Map.Map String Module.Interface, Maybe String)
 evalBuild flags interfaces build =
   do (ifaces, moduleNames) <- execRWST build flags (fmap notUpdated interfaces)
      return (fmap snd ifaces, getLast moduleNames)
@@ -45,7 +44,7 @@
 
 -- | Builds a list of files, returning the moduleName of the last one.
 --   Returns \"\" if the list is empty
-build :: Flag.Flags -> M.Interfaces -> [FilePath] -> IO String
+build :: Flag.Flags -> Module.Interfaces -> [FilePath] -> IO String
 build flags interfaces files =
   do (ifaces, topName) <- evalBuild flags interfaces (buildAll files)
      let removeTopName = Maybe.maybe id Map.delete topName
@@ -56,7 +55,7 @@
         | null ports = return ()
         | otherwise  = Print.failure msg
         where
-          ports = M.iPorts iface
+          ports = Module.iPorts iface
           msg = concat
             [ "Port Error: ports may only appear in the main module, but\n"
             , "    sub-module ", name, " declares the following port"
@@ -123,9 +122,7 @@
   iface <- liftIO $ Interface.load (Utils.elmi flags filePath)
   case Interface.isValid filePath iface of
     Right (name, interface) ->
-      do binterfaces <- get
-         let interfaces = snd <$> binterfaces
-         liftIO $ when (Flag.print_types flags) (Print.interfaceTypes interfaces interface)
+      do liftIO $ when (Flag.print_types flags) (Print.types (Module.iTypes interface))
          update name interface False
 
     Left err -> liftIO $ Print.failure err
@@ -142,16 +139,17 @@
        createDirectoryIfMissing True (Flag.cache_dir flags)
        createDirectoryIfMissing True (Flag.build_dir flags)
 
-     metaModule <- 
+     canonicalModule <- 
        liftIO $ case Source.build (Flag.no_prelude flags) interfaces source of
            Right modul -> return modul
            Left errors -> do Print.errors errors
                              exitFailure
 
-     liftIO $ when (Flag.print_types flags) $ Print.metaTypes interfaces metaModule
+     liftIO $ when (Flag.print_types flags) $ do
+       Print.types (Module.types (Module.body canonicalModule))
   
-     let newInters = Canonical.interface name $ M.metaToInterface metaModule
-     generateCache name newInters metaModule
+     let newInters = Module.toInterface canonicalModule
+     generateCache name newInters canonicalModule
      update name newInters True
 
   where
@@ -164,15 +162,15 @@
                                   , replicate (max 1 (20 - length name)) ' '
                                   , "( " ++ filePath ++ " )" ]
 
-    generateCache name interfs metaModule = do
+    generateCache name interfs canonicalModule = do
       flags <- ask
       liftIO $ do
         createDirectoryIfMissing True . dropFileName $ Utils.elmi flags filePath
-        writeFile (Utils.elmo flags filePath) (JS.generate metaModule)
+        writeFile (Utils.elmo flags filePath) (JS.generate canonicalModule)
         withBinaryFile (Utils.elmi flags filePath) WriteMode $ \handle ->
           L.hPut handle (Binary.encode (name, interfs))
 
-update :: String -> M.ModuleInterface -> Bool -> Build ()
+update :: String -> Module.Interface -> Bool -> Build ()
 update name inter wasUpdated =
   do modify (Map.insert name (wasUpdated, inter))
      tell (Last . Just $ name)
diff --git a/compiler/Build/Flags.hs b/compiler/Build/Flags.hs
--- a/compiler/Build/Flags.hs
+++ b/compiler/Build/Flags.hs
@@ -7,7 +7,9 @@
 data Flags = Flags
     { make :: Bool
     , files :: [FilePath]
-    , runtime :: Maybe FilePath
+    , set_runtime :: Maybe FilePath
+    , get_runtime :: Bool
+    , bundle_runtime :: Bool
     , only_js :: Bool
     , print_types :: Bool
     , scripts :: [FilePath]
@@ -17,28 +19,45 @@
     , src_dir :: [FilePath]
     }
     deriving (Data,Typeable,Show,Eq)
-             
+
+flags :: Flags             
 flags = Flags
   { files = def &= args &= typ "FILES"
+
   , make = False
-           &= help "automatically compile dependencies."
+      &= help "automatically compile dependencies."
+
   , only_js = False
-              &= help "Compile only to JavaScript."
+      &= help "Compile only to JavaScript."
+
   , no_prelude = False
-                 &= help "Do not import Prelude by default, used only when compiling standard libraries."
+      &= help "Do not import Prelude by default, used only when compiling standard libraries."
+
   , scripts = [] &= typFile
-              &= help "Load JavaScript files in generated HTML. Files will be included in the given order."
-  , runtime = Nothing &= typFile
-              &= help "Specify a custom location for Elm's runtime system."
+      &= help "Load JavaScript files in generated HTML. Files will be included in the given order."
+
+  , set_runtime = Nothing &= typFile
+      &= help "Specify a custom location for Elm's runtime system."
+
+  , get_runtime = False
+      &= help "Print the absolute path to the default Elm runtime."
+
+  , bundle_runtime = False
+      &= help "Bundle the runtime with the generated html or js to create a standalone file."
+
   , cache_dir = "cache" &= typFile
-                &= help "Directory for files cached to make builds faster. Defaults to cache/ directory."
+      &= help "Directory for files cached to make builds faster. Defaults to cache/ directory."
+
   , build_dir = "build" &= typFile
-                &= help "Directory for generated HTML and JS files. Defaults to build/ directory."
+      &= help "Directory for generated HTML and JS files. Defaults to build/ directory."
+
   , src_dir = ["."] &= typFile
-              &= help "Additional source directories besides project root. Searched when using --make"
+      &= help "Additional source directories besides project root. Searched when using --make"
+
   , print_types = False
-                  &= help "Print out infered types of top-level definitions."
+      &= help "Print out inferred types of top-level definitions."
+
   } &= help "Compile Elm programs to HTML, CSS, and JavaScript."
     &= helpArg [explicit, name "help", name "h"]
     &= versionArg [explicit, name "version", name "v", summary (show Version.elmVersion)]
-    &= summary ("The Elm Compiler " ++ show Version.elmVersion ++ ", (c) Evan Czaplicki 2011-2013")
+    &= summary ("The Elm Compiler " ++ show Version.elmVersion ++ ", (c) Evan Czaplicki 2011-2014")
diff --git a/compiler/Build/Interface.hs b/compiler/Build/Interface.hs
--- a/compiler/Build/Interface.hs
+++ b/compiler/Build/Interface.hs
@@ -7,7 +7,7 @@
 import qualified Build.Print as Print
 import qualified Elm.Internal.Version as Version
 import System.Directory (doesFileExist)
-import SourceSyntax.Module
+import AST.Module as Module
 
 load :: Binary.Binary a => FilePath -> IO a
 load filePath =
@@ -28,7 +28,7 @@
         , "    Please remove the file and try again."
         ]
 
-isValid :: FilePath -> (String, ModuleInterface) -> Either String (String, ModuleInterface)
+isValid :: FilePath -> (String, Module.Interface) -> Either String (String, Module.Interface)
 isValid filePath (name, interface) =
     let version = iVersion interface in
     if version == Version.elmVersion
diff --git a/compiler/Build/Print.hs b/compiler/Build/Print.hs
--- a/compiler/Build/Print.hs
+++ b/compiler/Build/Print.hs
@@ -5,30 +5,20 @@
 
 import qualified Data.Map as Map
 import qualified Data.List as List
-import qualified SourceSyntax.Module as M
-import qualified SourceSyntax.PrettyPrint as Pretty
-import qualified Type.Alias as Alias
+import qualified AST.Module as Module
+import qualified AST.PrettyPrint as Pretty
 import qualified Text.PrettyPrint as P
 
-metaTypes :: Map.Map String M.ModuleInterface -> M.MetadataModule -> IO ()
-metaTypes interfaces meta =
-    types interfaces (M.types meta) (M.aliases meta) (M.imports meta)
-
-interfaceTypes :: Map.Map String M.ModuleInterface -> M.ModuleInterface -> IO ()
-interfaceTypes interfaces iface =
-    types interfaces (M.iTypes iface) (M.iAliases iface) (M.iImports iface)
-
-types interfaces types' aliases imports =
+types :: Module.Types -> IO ()
+types ts =
     do putStrLn ""
-       mapM_ printType (Map.toList types')
+       mapM_ printType (Map.toList ts)
        putStrLn ""
     where
-      rules = Alias.rules interfaces aliases imports
-
       printType (n,t) = do
         print $ P.hsep [ Pretty.variable n
                        , P.text ":"
-                       , Pretty.pretty (Alias.realias rules t) ]
+                       , Pretty.pretty t ]
 
 errors :: [P.Doc] -> IO ()
 errors errs =
diff --git a/compiler/Build/Source.hs b/compiler/Build/Source.hs
--- a/compiler/Build/Source.hs
+++ b/compiler/Build/Source.hs
@@ -2,58 +2,34 @@
 module Build.Source (build) where
 
 import qualified Data.Map as Map
-import qualified Data.Set as Set
-import System.FilePath as FP
 import Text.PrettyPrint (Doc)
 
-import SourceSyntax.Declaration
-import SourceSyntax.Module
-import qualified SourceSyntax.Expression as Expr
-import qualified SourceSyntax.Pattern as Pattern
-import qualified SourceSyntax.Type as Type
+import qualified AST.Module as Module
 import qualified Parse.Parse as Parse
 import qualified Metadata.Prelude as Prelude
 import qualified Transform.Check as Check
-import qualified Transform.SortDefinitions as SD
 import qualified Type.Inference as TI
-import qualified Type.Constrain.Declaration as TcDecl
 import qualified Transform.Canonicalize as Canonical
 
-build :: Bool -> Interfaces -> String -> Either [Doc] MetadataModule
+build :: Bool -> Module.Interfaces -> String -> Either [Doc] Module.CanonicalModule
 build noPrelude interfaces source =
-  do let add = Prelude.add noPrelude
-         infixes = Map.fromList . map (\(assoc,lvl,op) -> (op,(lvl,assoc)))
-                 . concatMap iFixities $ Map.elems interfaces
+  do let infixes = Map.fromList . map (\(assoc,lvl,op) -> (op,(lvl,assoc)))
+                 . concatMap Module.iFixities $ Map.elems interfaces
 
-     Module names exs ims decls <- do
-           modul@(Module _ _ _ decls) <- add `fmap` Parse.program infixes source
-           case Check.mistakes decls of
-             [] -> return modul
-             ms -> Left ms
+     -- Parse the source code and validate that it is well formed.
+     validModule <- do
+       modul <- Prelude.add noPrelude `fmap` Parse.program infixes source
+       case Check.mistakes (Module.body modul) of
+         [] -> return modul
+         ms -> Left ms
 
-     let exports'
-             | null exs =
-                 let get = Set.toList . Pattern.boundVars in
-                 concat [ get pattern | Definition (Expr.Definition pattern _ _) <- decls ] ++
-                 concat [ map fst ctors | Datatype _ _ ctors <- decls ] ++
-                 [ name | TypeAlias name _ (Type.Record _ _) <- decls ]
-             | otherwise = exs
+     -- Canonicalize all variables, pinning down where they came from.
+     canonicalModule <- Canonical.module' interfaces validModule
 
-     metaModule <- Canonical.metadataModule interfaces $
-         MetadataModule
-         { names = names
-         , path = FP.joinPath names
-         , exports = exports'
-         , imports = ims
-           -- reorder AST into strongly connected components
-         , program = SD.sortDefs . Expr.dummyLet $ TcDecl.toExpr decls
-         , types = Map.empty
-         , datatypes = [ (name,vars,ctors) | Datatype name vars ctors <- decls ]
-         , fixities = [ (assoc,level,op) | Fixity assoc level op <- decls ]
-         , aliases = [ (name,tvs,tipe) | TypeAlias name tvs tipe <- decls ]
-         , ports = [ portName port | Port port <- decls ]
-         }
+     -- Run type inference on the program.
+     types <- TI.infer interfaces canonicalModule
 
-     types <- TI.infer interfaces metaModule
+     -- Add the real list of tyes
+     let body = (Module.body canonicalModule) { Module.types = types }
 
-     return $ metaModule { types = types }
+     return $ canonicalModule { Module.body = body }
diff --git a/compiler/Build/Utils.hs b/compiler/Build/Utils.hs
--- a/compiler/Build/Utils.hs
+++ b/compiler/Build/Utils.hs
@@ -1,8 +1,14 @@
 {-# OPTIONS_GHC -W #-}
 module Build.Utils where
 
+import Control.Monad.Error
+import System.Directory (doesFileExist)
+import System.Environment (getEnv)
 import System.FilePath ((</>), replaceExtension)
+import System.IO.Error (tryIOError)
 import qualified Build.Flags as Flag
+import qualified Build.Print as Print
+import qualified Paths_Elm as This
 
 buildPath :: Flag.Flags -> FilePath -> String -> FilePath
 buildPath flags filePath ext =
@@ -19,3 +25,40 @@
 elmi :: Flag.Flags -> FilePath -> FilePath
 elmi flags filePath =
     cachePath flags filePath "elmi"
+
+-- |The absolute path to a data file
+getDataFile :: FilePath -> IO FilePath
+getDataFile name = do
+  path <- This.getDataFileName name
+  exists <- doesFileExist path
+  if exists
+    then return path
+    else do
+      environment <- tryIOError (getEnv "ELM_HOME")
+      case environment of
+        Right env -> return (env </> "compiler" </> name)
+        Left _ ->
+          fail $ unlines
+            [ "Unable to find the ELM_HOME environment variable when searching"
+            , "for the " ++ name ++ " file."
+            , ""
+            , "If you installed Elm Platform with the Mac or Windows installer, it looks like"
+            , "ELM_HOME was not set automatically. Look up how to set environment variables"
+            , "on your platform and set ELM_HOME to the directory that contains Elm's static"
+            , "files:"
+            , ""
+            , "  * On Mac it is /usr/local/share/elm"
+            , "  * On Windows it is one of the following:"
+            , "      C:/Program Files/Elm Platform/0.13/share"
+            , "      C:/Program Files (x86)/Elm Platform/0.13/share"
+            , ""
+            , "If it seems like a more complex issue, please report it here:"
+            , "    <https://github.com/elm-lang/elm-platform/issues>"
+            ]
+
+run :: ErrorT String IO a -> IO a
+run command = do
+  either <- runErrorT command
+  case either of
+    Left err -> Print.failure err
+    Right result -> return result
diff --git a/compiler/Compiler.hs b/compiler/Compiler.hs
--- a/compiler/Compiler.hs
+++ b/compiler/Compiler.hs
@@ -1,16 +1,17 @@
 {-# OPTIONS_GHC -W #-}
 module Main where
 
-import Control.Monad (foldM)
+import Control.Monad (foldM, when)
 import qualified Data.Maybe as Maybe
 import Text.Blaze.Html.Renderer.String (renderHtml)
 import qualified Data.ByteString.Lazy.Char8 as BS
 import qualified System.Console.CmdArgs as CmdArgs
 import System.Directory
+import System.Exit (exitSuccess)
 import System.FilePath
 import GHC.Conc
 
-import Build.Dependencies (getSortedDependencies)
+import Build.Dependencies (getBuildRecipe, Recipe(..))
 import qualified Generate.Html as Html
 import qualified Metadata.Prelude as Prelude
 import qualified Build.Utils as Utils
@@ -24,29 +25,34 @@
 
 compileArgs :: Flag.Flags -> IO ()
 compileArgs flags =
-    case Flag.files flags of
-      [] -> putStrLn "Usage: elm [OPTIONS] [FILES]\nFor more help: elm --help"
-      fs -> mapM_ (build flags) fs
+  do when (Flag.get_runtime flags) $ do
+       putStrLn Path.runtime
+       exitSuccess
+     case Flag.files flags of
+       [] -> putStrLn "Usage: elm [OPTIONS] [FILES]\nFor more help: elm --help"
+       fs -> mapM_ (build flags) fs
 
 build :: Flag.Flags -> FilePath -> IO ()
 build flags rootFile =
     do let noPrelude = Flag.no_prelude flags
        builtIns <- Prelude.interfaces noPrelude
 
-       files <- if Flag.make flags
-                then getSortedDependencies (Flag.src_dir flags) builtIns rootFile
-                else return [rootFile]
+       (Recipe elmFiles jsFiles) <-
+           if Flag.make flags
+             then Utils.run (getBuildRecipe (Flag.src_dir flags) builtIns rootFile)
+             else return (Recipe [rootFile] [])
 
-       moduleName <- File.build flags builtIns files
+       moduleName <- File.build flags builtIns elmFiles
 
-       js <- foldM appendToOutput BS.empty files
+       let elmos = map (Utils.elmo flags) elmFiles
+       js <- foldM appendToOutput BS.empty (elmos ++ jsFiles)
 
        (extension, code) <-
            if Flag.only_js flags
            then do putStr "Generating JavaScript ... "
-                   return ("js", js)
+                   makeJs js
            else do putStr "Generating HTML ... "
-                   return (makeHtml js moduleName)
+                   makeHtml js moduleName
 
        let targetFile = Utils.buildPath flags rootFile extension
        createDirectoryIfMissing True (takeDirectory targetFile)
@@ -56,12 +62,28 @@
     where
       appendToOutput :: BS.ByteString -> FilePath -> IO BS.ByteString
       appendToOutput js filePath = do
-        src <- BS.readFile (Utils.elmo flags filePath)
+        src <- BS.readFile filePath
         return (BS.append src js)
 
-      sources js = map Html.Link (Flag.scripts flags) ++ [ Html.Source js ]
+      getRuntime :: IO Html.JSSource
+      getRuntime =
+          let runtimePath = Maybe.fromMaybe Path.runtime (Flag.set_runtime flags) in
+          case Flag.bundle_runtime flags of
+            False -> return (Html.Link runtimePath)
+            True  -> Html.Source `fmap` BS.readFile runtimePath
 
-      makeHtml js moduleName = ("html", BS.pack $ renderHtml html)
-          where
-            rtsPath = Maybe.fromMaybe Path.runtime (Flag.runtime flags)
-            html = Html.generate rtsPath (takeBaseName rootFile) (sources js) moduleName ""
+      makeJs :: BS.ByteString -> IO (String, BS.ByteString)
+      makeJs js =
+        do runtime <- getRuntime
+           case runtime of
+             Html.Link _ -> return ("js", js)
+             Html.Source rts -> return ("js", BS.append rts js)
+
+      makeHtml :: BS.ByteString -> String -> IO (String, BS.ByteString)
+      makeHtml js moduleName =
+        do runtime <- getRuntime
+           return ("html", BS.pack $ renderHtml (html runtime))
+        where
+          sources js = map Html.Link (Flag.scripts flags) ++ [ Html.Source js ]
+          html runtime =
+              Html.generate runtime (takeBaseName rootFile) (sources js) moduleName ""
diff --git a/compiler/Docs.hs b/compiler/Docs.hs
--- a/compiler/Docs.hs
+++ b/compiler/Docs.hs
@@ -1,3 +1,4 @@
+{-# OPTIONS_GHC -W #-}
 {-# LANGUAGE OverloadedStrings, DeriveDataTypeable #-}
 module Main where
 
@@ -8,17 +9,20 @@
 import System.IO
 
 import Control.Applicative ((<$>))
+import Control.Arrow (second)
 import Data.Aeson
 import Data.Aeson.Encode.Pretty
+import Data.Aeson.Types (Pair)
 import qualified Data.List as List
 import qualified Data.Map as Map
 import qualified Data.ByteString.Lazy as BS
 import qualified Data.Text as Text
 
-import SourceSyntax.Helpers (isSymbol)
-import SourceSyntax.Type (Type(..))
-import qualified SourceSyntax.Expression as E
-import qualified SourceSyntax.Declaration as D
+import qualified AST.Helpers as Help
+import qualified AST.Type as T
+import qualified AST.Declaration as D
+import qualified AST.Expression.Source as Src
+import qualified AST.Variable as Var
 
 import Text.Parsec hiding (newline,spaces)
 import Parse.Declaration (alias,datatype,infixDecl)
@@ -30,20 +34,24 @@
     { files :: [FilePath] }
     deriving (Data,Typeable,Show,Eq)
 
+defaultFlags :: Flags
 defaultFlags = Flags
   { files = def &= args &= typ "FILES"
   } &= help "Generate documentation for Elm"
     &= summary ("Generate documentation for Elm, (c) Evan Czaplicki")
 
+main :: IO ()
 main = do
   flags <- cmdArgs defaultFlags
-  mapM parseFile (files flags)
+  mapM_ parseFile (files flags)
 
+config :: Config
 config = Config { confIndent = 2, confCompare = keyOrder keys }
   where
-    keys = ["name","document","comment","raw","aliases","datatypes"
+    keys = ["tag","name","document","comment","raw","aliases","datatypes"
            ,"values","typeVariables","type","constructors"]
 
+parseFile :: FilePath -> IO ()
 parseFile path = do
   source <- readFile path
   case iParse docs source of
@@ -58,9 +66,9 @@
 
 docs :: IParser Value
 docs = do
-  (name, exports, structure) <- moduleDocs
+  (name, _exports, structure) <- moduleDocs
   things <- document
-  return $ documentToJson name exports structure things
+  return $ documentToJson name structure things
 
 docComment :: IParser String
 docComment = do
@@ -69,6 +77,7 @@
   let reversed = dropWhile (`elem` " \n\r") . drop 2 $ reverse contents
   return $ dropWhile (==' ') (reverse reversed)
 
+moduleDocs :: IParser (String, Var.Listing Var.Value, String)
 moduleDocs = do
   optional freshLine
   (names,exports) <- moduleDef
@@ -77,10 +86,10 @@
   structure <- docComment
   return (List.intercalate "." names, exports, structure)
 
-document :: IParser [(String, D.ParseDeclaration, String)]
+document :: IParser [(String, D.SourceDecl, String)]
 document = onFreshLines (\t ts -> ts ++ [t]) [] docThing
 
-docThing :: IParser (String, D.ParseDeclaration, String)
+docThing :: IParser (String, D.SourceDecl, String)
 docThing = uncommentable <|> commented <|> uncommented ""
     where
       uncommentable = do
@@ -97,31 +106,35 @@
         return (comment, def, src)
 
 
-documentToJson name exports structure things =
-    object $ [ "name"      .= name
-             , "document"  .= structure
-             , "values"    .= toList values
-             , "aliases"   .= toList aliases
-             , "datatypes" .= toList adts
-             ]
+documentToJson :: String -> String -> [(String, D.SourceDecl, String)] -> Value
+documentToJson name structure things =
+    object
+        [ "name"      .= name
+        , "document"  .= structure
+        , "values"    .= toList values
+        , "aliases"   .= toList aliases
+        , "datatypes" .= toList adts
+        ]
   where
-    (values, aliases, adts) = collect Map.empty Map.empty Map.empty Map.empty things
+    (values, aliases, adts) =
+        collect Map.empty Map.empty Map.empty Map.empty things
     
-    toList dict = map object . Map.elems $ filterPublics dict
+    toList :: Map.Map String [Pair] -> [Value]
+    toList dict =
+        map object (Map.elems dict)
 
-    exportMap = Map.fromList (zip exports exports)
-    filterPublics dict =
-        case Map.null exportMap of
-          True -> dict
-          False -> Map.filterWithKey (\k _ -> Map.member k exportMap) dict
+type Pairs = Map.Map String [Pair]
 
+collect :: Map.Map String (D.Assoc, Int) -> Pairs -> Pairs -> Pairs
+        -> [(String, D.SourceDecl, String)]
+        -> (Pairs, Pairs, Pairs)
 collect infixes types aliases adts things =
     case things of
       [] -> (Map.union customOps nonCustomOps, aliases, adts)
           where
             nonCustomOps = Map.mapWithKey addDefaultInfix $ Map.difference types infixes
             addDefaultInfix name pairs
-                | all isSymbol name = addInfix (D.L, 9 :: Int) pairs
+                | all Help.isSymbol name = addInfix (D.L, 9 :: Int) pairs
                 | otherwise = pairs
 
             customOps = Map.intersectionWith addInfix infixes types
@@ -129,35 +142,83 @@
                 [ "associativity" .= show assoc, "precedence" .= prec ] ++ pairs
 
       (comment, decl, source) : rest ->
+          let insert name fields dict = Map.insert name (obj name fields) dict
+              obj name fields =
+                  [ "name" .= name
+                  , "raw" .= source
+                  , "comment" .= comment
+                  ] ++ fields
+          in
           case decl of
-            D.Fixity assoc prec name ->
-                collect (Map.insert name (assoc,prec) infixes) types aliases adts rest
-            D.Definition (E.TypeAnnotation name tipe) ->
-                collect infixes (insert name [ "type" .= tipe ] types) aliases adts rest
-            D.TypeAlias name vars tipe ->
-                let fields = ["typeVariables" .= vars, "type" .= tipe ]
-                in  collect infixes types (insert name fields aliases) adts rest
+            D.Definition def ->
+                case def of
+                  Src.TypeAnnotation name tipe ->
+                      collect infixes (insert name [ "type" .= tipe ] types) aliases adts rest
+
+                  Src.Definition _ _ ->
+                      collect infixes types aliases adts rest
+
             D.Datatype name vars ctors ->
-                let tipe = Data name (map Var vars)
-                    fields = ["typeVariables" .= vars
-                             , "constructors" .= map (ctorToJson tipe) ctors ]
+                let tipe = T.App (T.Type (Var.Raw name)) (map T.Var vars)
+                    fields = [ "typeVariables" .= vars
+                             , "constructors" .= map (ctorToJson tipe) ctors
+                             ]
                 in  collect infixes types aliases (insert name fields adts) rest
-          where
-            insert name fields dict = Map.insert name (obj name fields) dict
-            obj name fields =
-                [ "name" .= name, "raw" .= source, "comment" .= comment ] ++ fields
 
-instance ToJSON Type where
-    toJSON tipe =
-        case tipe of
-          Lambda t1 t2 -> toJSON [ "->", toJSON t1, toJSON t2 ]
-          Var x -> toJSON x
-          Data name ts -> toJSON (toJSON name : map toJSON ts)
-          Record fields ext -> object $ map (\(n,t) -> Text.pack n .= toJSON t) fields'
-              where fields' = case ext of
-                                Nothing -> fields
-                                Just x -> ("_", Var x) : fields
+            D.TypeAlias name vars tipe ->
+                let fields = [ "typeVariables" .= vars, "type" .= tipe ]
+                in  collect infixes types (insert name fields aliases) adts rest
 
+            D.Port _ ->
+                collect infixes types aliases adts rest
+
+            D.Fixity assoc prec name ->
+                collect (Map.insert name (assoc,prec) infixes) types aliases adts rest
+
+
+instance Var.ToString var => ToJSON (T.Type var) where
+  toJSON tipe =
+      object (getFields tipe)
+    where
+      getFields tipe =
+          case tipe of
+            T.Lambda _ _ ->
+                let tipes = T.collectLambdas tipe in
+                [ "tag" .= ("function" :: Text.Text)
+                , "args" .= toJSON (init tipes)
+                , "result" .= toJSON (last tipes)
+                ]
+
+            T.Var x ->
+                [ "tag" .= ("var" :: Text.Text)
+                , "name" .= toJSON x
+                ]
+
+            T.Type name ->
+                [ "tag" .= ("adt" :: Text.Text)
+                , "name" .= toJSON (Var.toString name)
+                , "args" .= ([] :: [()])
+                ]
+
+            T.App (T.Type name) ts -> 
+                [ "tag" .= ("adt" :: Text.Text)
+                , "name" .= toJSON (Var.toString name)
+                , "args" .= map toJSON ts
+                ]
+
+            T.App _ _ -> error "This is an unexpected error with elm-doc, please report it at <https://github.com/elm-lang/Elm/issues>"
+             
+            T.Record fields ext ->
+                [ "tag" .= ("record" :: Text.Text)
+                , "fields" .= toJSON (map (toJSON . second toJSON) fields)
+                , "extension" .= toJSON ext
+                ]
+
+            T.Aliased _ t ->
+                getFields t
+
+ctorToJson :: T.RawType -> (String, [T.RawType]) -> Value
 ctorToJson tipe (ctor, tipes) =
     object [ "name" .= ctor
-           , "type" .= foldr Lambda tipe tipes ]
+           , "type" .= foldr T.Lambda tipe tipes
+           ]
diff --git a/compiler/Elm/Internal/Dependencies.hs b/compiler/Elm/Internal/Dependencies.hs
--- a/compiler/Elm/Internal/Dependencies.hs
+++ b/compiler/Elm/Internal/Dependencies.hs
@@ -2,12 +2,18 @@
 module Elm.Internal.Dependencies where
 
 import Control.Applicative
+import Control.Arrow (first)
 import Control.Monad.Error
 import qualified Control.Exception as E
 import Data.Aeson
+import Data.Aeson.Types (Parser)
+import Data.Aeson.Encode.Pretty
+import Data.Maybe (fromMaybe)
 import qualified Data.List as List
 import qualified Data.ByteString.Lazy as BS
 import qualified Data.HashMap.Strict as Map
+import qualified Data.Text as T
+
 import qualified Elm.Internal.Name as N
 import qualified Elm.Internal.Version as V
 import qualified Elm.Internal.Paths as Path
@@ -20,15 +26,28 @@
     , license :: String
     , repo :: String
     , exposed :: [String]
+    , native :: [String]
     , elmVersion :: V.Version
     , dependencies :: [(N.Name,V.Version)]
-    } deriving Show
-
-data MiniDeps = Mini [(N.Name,V.Version)]
+    } deriving (Show, Eq, Ord)
 
-instance FromJSON MiniDeps where
-    parseJSON (Object obj) = Mini <$> getDependencies obj
-    parseJSON _ = mzero
+instance ToJSON Deps where
+  toJSON d =
+      object $
+      [ "version"         .= version d
+      , "summary"         .= summary d
+      , "description"     .= description d
+      , "license"         .= license d
+      , "repository"      .= repo d
+      , "exposed-modules" .= exposed d
+      , "elm-version"     .= elmVersion d
+      , "dependencies"    .= (jsonDeps . dependencies $ d)
+      ] ++ nativeModules
+    where
+      jsonDeps = Map.fromList . map (first (T.pack . show))
+      nativeModules
+          | null (native d) = []
+          | otherwise       = [ "native-modules" .= native d ]
 
 instance FromJSON Deps where
     parseJSON (Object obj) =
@@ -48,15 +67,18 @@
                      Right nm -> return nm
 
            exposed <- get obj "exposed-modules" "a list of modules exposed to users"
+           
+           native <- fromMaybe [] <$> (obj .:? "native-modules")
 
            elmVersion <- get obj "elm-version" "the version of the Elm compiler you are using"
 
            deps <- getDependencies obj
 
-           return $ Deps name version summary desc license repo exposed elmVersion deps
+           return $ Deps name version summary desc license repo exposed native elmVersion deps
 
     parseJSON _ = mzero
 
+getDependencies :: Object -> Parser [(N.Name, V.Version)]
 getDependencies obj = 
     toDeps =<< get obj "dependencies" "a listing of your project's dependencies"
     where
@@ -67,7 +89,7 @@
                 (Nothing, _) -> fail $ N.errorMsg f
                 (_, Nothing) -> fail $ "invalid version number " ++ v
 
-
+get :: FromJSON a => Object -> T.Text -> String -> Parser a
 get obj field desc =
     do maybe <- obj .:? field
        case maybe of
@@ -96,12 +118,12 @@
             \like <https://github.com/USER/PROJECT.git> where USER is your GitHub name\n\
             \and PROJECT is the repo you want to upload."
 
-withDeps :: (Deps -> a) -> FilePath -> ErrorT String IO a
-withDeps handle path =
+withDeps :: FilePath -> (Deps -> ErrorT String IO a) -> ErrorT String IO a
+withDeps path handle =
     do json <- readPath
        case eitherDecode json of
          Left err -> throwError $ "Error reading file " ++ path ++ ":\n    " ++ err
-         Right ds -> return (handle ds)
+         Right ds -> handle ds
     where
       readPath :: ErrorT String IO BS.ByteString
       readPath = do
@@ -110,8 +132,25 @@
         case result of
           Right bytes -> return bytes
           Left _ -> throwError $
-                    "could not find file " ++ path ++
-                    "\n    You may need to create a dependency file for your project."
+                    "could not find " ++ path ++ " file. You may need to create one.\n" ++
+                    "    For an example of how to fill in the dependencies file, check out\n" ++
+                    "    <https://github.com/evancz/automaton/blob/master/elm_dependencies.json>"
 
 depsAt :: FilePath -> ErrorT String IO Deps
-depsAt = withDeps id
+depsAt filePath = withDeps filePath return
+
+-- | Encode dependencies in a canonical JSON format
+prettyJSON :: Deps -> BS.ByteString
+prettyJSON = encodePretty' config
+  where config = defConfig { confCompare = order }
+        order = keyOrder [ "name"
+                         , "version"
+                         , "summary"
+                         , "description"
+                         , "license"
+                         , "repo"
+                         , "exposed-modules"
+                         , "native-modules"
+                         , "elm-version"
+                         , "dependencies"
+                         ]
diff --git a/compiler/Elm/Internal/Name.hs b/compiler/Elm/Internal/Name.hs
--- a/compiler/Elm/Internal/Name.hs
+++ b/compiler/Elm/Internal/Name.hs
@@ -10,7 +10,7 @@
 import Data.Typeable
 
 data Name = Name { user :: String, project :: String }
-    deriving (Typeable,Eq)
+    deriving (Typeable,Eq, Ord)
 
 instance Binary Name where
   get = Name <$> get <*> get
diff --git a/compiler/Elm/Internal/Paths.hs b/compiler/Elm/Internal/Paths.hs
--- a/compiler/Elm/Internal/Paths.hs
+++ b/compiler/Elm/Internal/Paths.hs
@@ -1,7 +1,8 @@
+{-# OPTIONS_GHC -Wall #-}
 module Elm.Internal.Paths where
 
-import System.IO.Unsafe
-import qualified Paths_Elm as This
+import Build.Utils (getDataFile)
+import System.IO.Unsafe (unsafePerformIO)
 
 -- |Name of directory for all of a project's dependencies.
 dependencyDirectory :: FilePath
@@ -15,9 +16,9 @@
 {-# NOINLINE runtime #-}
 -- |The absolute path to Elm's runtime system.
 runtime :: FilePath
-runtime = unsafePerformIO $ This.getDataFileName "elm-runtime.js"
+runtime = unsafePerformIO $ getDataFile "elm-runtime.js"
 
 {-# NOINLINE docs #-}
 -- |The absolute path to Elm's core library documentation.
 docs :: FilePath
-docs = unsafePerformIO $ This.getDataFileName "docs.json"
+docs = unsafePerformIO $ getDataFile "docs.json"
diff --git a/compiler/Elm/Internal/Utils.hs b/compiler/Elm/Internal/Utils.hs
--- a/compiler/Elm/Internal/Utils.hs
+++ b/compiler/Elm/Internal/Utils.hs
@@ -1,12 +1,13 @@
 {- | This module exports functions for compiling Elm to JS.
 -}
-module Elm.Internal.Utils (compile, moduleName) where
+module Elm.Internal.Utils (compile, moduleName, nameAndImports) where
 
 import qualified Data.List as List
 import qualified Generate.JavaScript as JS
 import qualified Build.Source as Source
 import qualified Parse.Module as Parser
-import qualified SourceSyntax.Module as M
+import qualified AST.Module as M
+import Parse.Parse (dependencies)
 import qualified Text.PrettyPrint as P
 import qualified Metadata.Prelude as Prelude
 import System.IO.Unsafe
@@ -25,4 +26,10 @@
 
 -- |This function extracts the module name of a given source program.
 moduleName :: String -> Maybe String
-moduleName = Parser.getModuleName
+moduleName = Parser.getModuleName
+
+-- |This function extracts the module name and imported modules from a given
+--  source program.
+nameAndImports :: String -> Maybe (String, [String])
+nameAndImports src =
+    either (const Nothing) Just (dependencies src)
diff --git a/compiler/Generate/Cases.hs b/compiler/Generate/Cases.hs
--- a/compiler/Generate/Cases.hs
+++ b/compiler/Generate/Cases.hs
@@ -1,129 +1,211 @@
+{-# OPTIONS_GHC -W #-}
 module Generate.Cases (toMatch, Match (..), Clause (..), matchSubst, newVar) where
 
 import Control.Applicative ((<$>))
 import Control.Arrow (first)
-import Control.Monad.State
+import Control.Monad.State (State)
+import qualified Control.Monad.State as State
 import Data.List (groupBy,sortBy)
 import Data.Maybe (fromMaybe)
 
-import SourceSyntax.Location
-import SourceSyntax.Literal
-import SourceSyntax.Pattern
-import SourceSyntax.Expression
-import Transform.Substitute
-
+import qualified AST.Annotation as A
+import qualified AST.Expression.General as Expr
+import qualified AST.Expression.Canonical as Canonical
+import qualified AST.Literal as Literal
+import qualified AST.Pattern as P
+import qualified AST.Variable as Var
+import Transform.Substitute (subst)
 
-toMatch :: [(Pattern, LExpr)] -> State Int (String, Match)
+toMatch :: [(P.CanonicalPattern, Canonical.Expr)] -> State Int (String, Match)
 toMatch patterns = do
   v <- newVar
   (,) v <$> match [v] (map (first (:[])) patterns) Fail
 
+
 newVar :: State Int String
-newVar = do n <- get
-            modify (+1)
-            return $ "_v" ++ show n
+newVar =
+  do  n <- State.get
+      State.modify (+1)
+      return $ "_v" ++ show n
 
+
 data Match
     = Match String [Clause] Match
     | Break
     | Fail
-    | Other LExpr
+    | Other Canonical.Expr
     | Seq [Match]
       deriving Show
 
+
 data Clause =
-    Clause (Either String Literal) [String] Match
+    Clause (Either Var.Canonical Literal.Literal) [String] Match
     deriving Show
 
+
+type Case =
+    ([P.CanonicalPattern], Canonical.Expr)
+
+
 matchSubst :: [(String,String)] -> Match -> Match
-matchSubst _ Break = Break
-matchSubst _ Fail = Fail
-matchSubst pairs (Seq ms) = Seq (map (matchSubst pairs) ms)
-matchSubst pairs (Other (L s e)) =
-    Other . L s $ foldr ($) e $ map (\(x,y) -> subst x (Var y)) pairs
-matchSubst pairs (Match n cs m) =
-    Match (varSubst n) (map clauseSubst cs) (matchSubst pairs m)
-        where varSubst v = fromMaybe v (lookup v pairs)
-              clauseSubst (Clause c vs m) =
-                  Clause c (map varSubst vs) (matchSubst pairs m)
+matchSubst pairs match =
+    case match of
+      Break -> Break
 
+      Fail -> Fail
+      
+      Seq ms ->
+          Seq (map (matchSubst pairs) ms)
+      
+      Other (A.A a e) ->
+          Other . A.A a $ foldr ($) e $ map (\(x,y) -> subst x (Expr.localVar y)) pairs
+      
+      Match n cs m ->
+          Match (varSubst n) (map clauseSubst cs) (matchSubst pairs m)
+        where
+          varSubst v = fromMaybe v (lookup v pairs)
+          clauseSubst (Clause c vs m) =
+              Clause c (map varSubst vs) (matchSubst pairs m)
+
+
+isCon :: ([P.Pattern var], expr) -> Bool
+isCon ([] , _) = noMatch "isCon"
 isCon (p:_, _) =
-  case p of
-    PData _ _  -> True
-    PLiteral _ -> True
-    _          -> False
+    case p of
+      P.Data _ _  -> True
+      P.Literal _ -> True
+      _           -> False
 
+
+isVar :: ([P.Pattern var], expr) -> Bool
 isVar p = not (isCon p)
 
-match :: [String] -> [([Pattern],LExpr)] -> Match -> State Int Match
-match [] [] def = return def
-match [] [([],e)] Fail  = return $ Other e
-match [] [([],e)] Break = return $ Other e
-match [] cs def = return $ Seq (map (Other . snd) cs ++ [def])
-match vs@(v:_) cs def
-    | all isVar cs' = matchVar vs cs' def
-    | all isCon cs' = matchCon vs cs' def
-    | otherwise     = matchMix vs cs' def
-  where
-    cs' = map (dealias v) cs
 
-dealias v c@(p:ps, L s e) =
+match :: [String] -> [Case] -> Match -> State Int Match
+match variables cases match =
+    case (variables, cases, match) of
+      ([], [], _) ->
+          return match
+
+      ([], [([], expr)], Fail) ->
+          return $ Other expr
+
+      ([], [([], expr)], Break) ->
+          return $ Other expr
+
+      ([], _, _) ->
+          return $ Seq (map (Other . snd) cases ++ [match])
+
+      (var:_, _, _)
+          | all isVar cases' -> matchVar variables cases' match
+          | all isCon cases' -> matchCon variables cases' match
+          | otherwise        -> matchMix variables cases' match
+          where
+            cases' = map (dealias var) cases
+
+
+dealias :: String -> Case -> Case
+dealias _ ([], _) = noMatch "dealias"
+dealias v c@(p:ps, A.A a e) =
     case p of
-      PAlias x pattern -> (pattern:ps, L s $ subst x (Var v) e)
+      P.Alias x pattern -> (pattern:ps, A.A a $ subst x (Expr.localVar v) e)
       _ -> c
 
-matchVar :: [String] -> [([Pattern],LExpr)] -> Match -> State Int Match
-matchVar (v:vs) cs def = match vs (map subVar cs) def
+
+matchVar :: [String] -> [Case] -> Match -> State Int Match
+matchVar [] _ _ = noMatch "matchVar"
+matchVar (v:vs) cs def =
+    match vs (map subVar cs) def
   where
-    subVar (p:ps, (L s e)) = (ps, L s $ subOnePattern p e)
-        where
-          subOnePattern pattern e =
+    subVar ([], _) = noMatch "matchVar.subVar"
+    subVar (p:ps, (A.A a expr)) =
+        (ps, A.A a $ subOnePattern p expr)
+      where
+        subOnePattern pattern expr =
             case pattern of
-              PVar x     -> subst x (Var v) e
-              PAnything  -> e
-              PRecord fs ->
-                 foldr (\x -> subst x (Access (L s (Var v)) x)) e fs
+              P.Anything -> expr
 
-matchCon :: [String] -> [([Pattern],LExpr)] -> Match -> State Int Match
-matchCon (v:vs) cs def = (flip (Match v) def) <$> mapM toClause css
-    where
-      css = groupBy eq (sortBy cmp cs)
+              P.Var x ->
+                  subst x (Expr.localVar v) expr
 
-      cmp (p1:_,_) (p2:_,_) =
-        case (p1,p2) of
-          (PData n1 _, PData n2 _) -> compare n1 n2
-          _ -> compare p1 p2
+              P.Record fs ->
+                 foldr (\x -> subst x (Expr.Access (A.A a (Expr.localVar v)) x)) expr fs
 
-      eq (p1:_,_) (p2:_,_) =
-        case (p1,p2) of
-          (PData n1 _, PData n2 _) -> n1 == n2
-          _ -> p1 == p2
+              _ -> noMatch "matchVar.subVar"
 
-      toClause cs =
-        case head cs of
-          (PData name _ : _, _) -> matchClause (Left name) (v:vs) cs Break
-          (PLiteral lit : _, _) -> matchClause (Right lit) (v:vs) cs Break
 
-matchClause :: Either String Literal
-            -> [String]
-            -> [([Pattern],LExpr)]
-            -> Match
+matchCon :: [String] -> [Case] -> Match -> State Int Match
+matchCon variables cases match =
+    case variables of
+      [] -> noMatch "matchCon"
+
+      var : _vars ->
+          flip (Match var) match <$> mapM toClause caseGroups
+        where
+          caseGroups :: [[Case]]
+          caseGroups =
+              groupBy eq (sortBy cmp cases)
+
+          eq :: Case -> Case -> Bool
+          eq (patterns1, _) (patterns2, _) =
+              case (patterns1, patterns2) of
+                (pattern1:_, pattern2:_) ->
+                    case (pattern1, pattern2) of
+                      (P.Data name1 _, P.Data name2 _) -> name1 == name2
+                      (_, _) -> pattern1 == pattern2
+                (_, _) -> noMatch "matchCon.eq"
+
+          cmp :: Case -> Case -> Ordering
+          cmp (patterns1, _) (patterns2, _) =
+              case (patterns1, patterns2) of
+                (pattern1:_, pattern2:_) ->
+                    case (pattern1, pattern2) of
+                      (P.Data name1 _, P.Data name2 _) -> compare name1 name2
+                      (_, _) -> compare pattern1 pattern2
+                (_, _) -> noMatch "matchCon.cmp"
+
+          toClause :: [Case] -> State Int Clause
+          toClause cases =
+              case head cases of
+                (P.Data name _ : _, _) ->
+                    matchClause (Left name) variables cases Break
+
+                (P.Literal lit : _, _) ->
+                    matchClause (Right lit) variables cases Break
+
+                _ -> noMatch "matchCon"
+
+
+matchClause :: Either Var.Canonical Literal.Literal -> [String] -> [Case] -> Match
             -> State Int Clause
-matchClause c (_:vs) cs def =
+matchClause _ [] _ _ = noMatch "matchClause"
+matchClause c (_:vs) cs mtch =
     do vs' <- getVars
-       Clause c vs' <$> match (vs' ++ vs) (map flatten cs) def
+       Clause c vs' <$> match (vs' ++ vs) (map flatten cs) mtch
     where
-
+      flatten ([], _) = noMatch "matchClause.flatten"
       flatten (p:ps, e) =
           case p of
-            PData _ ps' -> (ps' ++ ps, e)
-            PLiteral _  -> (ps, e)
+            P.Data _ ps' -> (ps' ++ ps, e)
+            P.Literal _  -> (ps, e)
+            _ -> noMatch "matchClause.flatten"
 
+      getVars :: State Int [String]
       getVars =
           case head cs of
-            (PData _ ps : _, _) -> forM ps (const newVar)
-            (PLiteral _ : _, _) -> return []
+            (P.Data _ ps : _, _) -> State.forM ps (const newVar)
+            (P.Literal _ : _, _) -> return []
+            _ -> noMatch "matchClause.getVars"
 
-matchMix :: [String] -> [([Pattern],LExpr)] -> Match -> State Int Match
-matchMix vs cs def = foldM (flip $ match vs) def (reverse css)
-    where css = groupBy (\p1 p2 -> isCon p1 == isCon p2) cs
+
+matchMix :: [String] -> [Case] -> Match -> State Int Match
+matchMix vs cs def =
+    State.foldM (flip $ match vs) def (reverse css)
+  where
+    css = groupBy (\p1 p2 -> isCon p1 == isCon p2) cs
+
+
+noMatch :: String -> a
+noMatch name =
+    error $ "unexpected pattern in '" ++ name ++
+            "' function. Report a compiler issue to <https://github.com/elm-lang/Elm>."
diff --git a/compiler/Generate/Html.hs b/compiler/Generate/Html.hs
--- a/compiler/Generate/Html.hs
+++ b/compiler/Generate/Html.hs
@@ -17,13 +17,13 @@
           H.script ! A.type_ "text/javascript" $
            preEscapedToMarkup $ BS.unpack src
 
-generate :: FilePath -> String -> [JSSource] -> String -> String -> H.Html
-generate libLoc title scripts moduleName noscript =
+generate :: JSSource -> String -> [JSSource] -> String -> String -> H.Html
+generate runtime title scripts moduleName noscript =
     H.docTypeHtml $ do 
       H.head $ do
         H.meta ! A.charset "UTF-8"
         H.title . H.toHtml $ title
-        makeScript (Link libLoc)
+        makeScript runtime
         mapM_ makeScript scripts
       H.body $ do
         H.script ! A.type_ "text/javascript" $
diff --git a/compiler/Generate/JavaScript.hs b/compiler/Generate/JavaScript.hs
--- a/compiler/Generate/JavaScript.hs
+++ b/compiler/Generate/JavaScript.hs
@@ -1,65 +1,75 @@
 {-# OPTIONS_GHC -W #-}
 module Generate.JavaScript (generate) where
 
-import Control.Arrow (first,(***))
 import Control.Applicative ((<$>),(<*>))
+import Control.Arrow (first,(***))
 import Control.Monad.State
 import qualified Data.List as List
 import qualified Data.Map as Map
 import qualified Data.Set as Set
+import Language.ECMAScript3.PrettyPrint
+import Language.ECMAScript3.Syntax
 
-import Generate.JavaScript.Helpers
+import Generate.JavaScript.Helpers as Help
 import qualified Generate.Cases as Case
 import qualified Generate.JavaScript.Ports as Port
+import qualified Generate.JavaScript.Variable as Var
 import qualified Generate.Markdown as MD
-import qualified SourceSyntax.Helpers as Help
-import SourceSyntax.Literal
-import SourceSyntax.Pattern as Pattern
-import SourceSyntax.Location
-import SourceSyntax.Expression
-import SourceSyntax.Module
-import Language.ECMAScript3.Syntax
-import Language.ECMAScript3.PrettyPrint
-import qualified Transform.SafeNames as MakeSafe
 
+import AST.Annotation
+import AST.Module
+import AST.Expression.General
+import qualified AST.Expression.Canonical as Canonical
+import qualified AST.Module as Module
+import qualified AST.Helpers as Help
+import AST.Literal
+import qualified AST.Pattern as P
+import qualified AST.Variable as Var
+
 varDecl :: String -> Expression () -> VarDecl ()
 varDecl x expr =
     VarDecl () (var x) (Just expr)
 
-include :: String -> String -> VarDecl ()
-include alias moduleName =
-    varDecl alias (obj (moduleName ++ ".make") <| ref "_elm")
-
-internalImports :: String -> Statement ()
+internalImports :: String -> [VarDecl ()]
 internalImports name =
-    VarDeclStmt () 
-    [ varDecl "_N" (obj "Elm.Native")
-    , include "_U" "_N.Utils"
-    , include "_L" "_N.List"
-    , include "_E" "_N.Error"
-    , include "_J" "_N.JavaScript"
-    , varDecl "$moduleName" (string name)
+    [ varDecl "_N" (obj ["Elm","Native"])
+    , include "_U" "Utils"
+    , include "_L" "List" 
+    , include "_A" "Array"
+    , include "_E" "Error"
+    , varDecl Help.localModuleName (string name)
     ]
+    where
+      include :: String -> String -> VarDecl ()
+      include alias modul =
+          varDecl alias (obj ["_N", modul, "make"] <| ref "_elm")
 
+_Utils :: String -> Expression ()
+_Utils x = obj ["_U", x]
+
+_List :: String -> Expression ()
+_List x = obj ["_L", x]
+
 literal :: Literal -> Expression ()
 literal lit =
   case lit of
-    Chr c -> obj "_U.chr" <| string [c]
+    Chr c -> _Utils "chr" <| string [c]
     Str s -> string s
     IntNum   n -> IntLit () n
     FloatNum n -> NumLit () n
     Boolean  b -> BoolLit () b
 
-expression :: LExpr -> State Int (Expression ())
-expression (L span expr) =
+expression :: Canonical.Expr -> State Int (Expression ())
+expression (A region expr) =
     case expr of
-      Var x -> return $ ref x
+      Var var -> return $ Var.canonical var
+
       Literal lit -> return $ literal lit
 
       Range lo hi ->
           do lo' <- expression lo
              hi' <- expression hi
-             return $ obj "_L.range" `call` [lo',hi']
+             return $ _List "range" `call` [lo',hi']
 
       Access e x ->
           do e' <- expression e
@@ -67,35 +77,34 @@
 
       Remove e x ->
           do e' <- expression e
-             return $ obj "_U.remove" `call` [string x, e']
+             return $ _Utils "remove" `call` [string x, e']
 
       Insert e x v ->
           do v' <- expression v
              e' <- expression e
-             return $ obj "_U.insert" `call` [string x, v', e']
+             return $ _Utils "insert" `call` [string x, v', e']
 
       Modify e fs ->
           do e' <- expression e
              fs' <- forM fs $ \(f,v) -> do
                       v' <- expression v
                       return $ ArrayLit () [string f, v']
-             return $ obj "_U.replace" `call` [ArrayLit () fs', e']
+             return $ _Utils "replace" `call` [ArrayLit () fs', e']
 
       Record fields ->
           do fields' <- forM fields $ \(f,e) -> do
                           (,) f <$> expression e
              let fieldMap = List.foldl' combine Map.empty fields'
-             return $ ObjectLit () $ (PropId () (var "_"), hidden fieldMap) : visible fieldMap
+             return $ ObjectLit () $ (prop "_", hidden fieldMap) : visible fieldMap
           where
             combine r (k,v) = Map.insertWith (++) k [v] r
-            prop = PropId () . var
             hidden fs = ObjectLit () . map (prop *** ArrayLit ()) .
                         Map.toList . Map.filter (not . null) $ Map.map tail fs
             visible fs = map (first prop) . Map.toList $ Map.map head fs
 
-      Binop op e1 e2 -> binop span op e1 e2
+      Binop op e1 e2 -> binop region op e1 e2
 
-      Lambda p e@(L s _) ->
+      Lambda p e@(A ann _) ->
           do (args, body) <- foldM depattern ([], innerBody) (reverse patterns)
              body' <- expression body
              return $ case length args < 2 || length args > 9 of
@@ -104,13 +113,14 @@
           where
             depattern (args, body) pattern =
                 case pattern of
-                  PVar x -> return (args ++ [x], body)
+                  P.Var x -> return (args ++ [ Var.varName x ], body)
                   _ -> do arg <- Case.newVar
-                          return (args ++ [arg], L s (Case (L s (Var arg)) [(pattern, body)]))
+                          return ( args ++ [arg]
+                                 , A ann (Case (A ann (localVar arg)) [(pattern, body)]))
 
             (patterns, innerBody) = collect [p] e
 
-            collect patterns lexpr@(L _ expr) =
+            collect patterns lexpr@(A _ expr) =
                 case expr of
                   Lambda p e -> collect (p:patterns) e
                   _ -> (patterns, lexpr)
@@ -127,7 +137,7 @@
             (func, args) = getArgs e1 [e2]
             getArgs func args =
                 case func of
-                  (L _ (App f arg)) -> getArgs f (arg : args)
+                  (A _ (App f arg)) -> getArgs f (arg : args)
                   _ -> (func, args)
 
       Let defs e ->
@@ -137,29 +147,32 @@
              return $ function [] (stmts ++ [ ret exp ]) `call` []
 
       MultiIf branches ->
-        do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
-           return $ case last branches of
-             (L _ (Var "Basics.otherwise"), _) -> safeIfs branches'
-             (L _ (Literal (Boolean True)), _) -> safeIfs branches'
-             _ -> ifs branches' (obj "_E.If" `call` [ ref "$moduleName", string (show span) ])
-        where
-          safeIfs branches = ifs (init branches) (snd (last branches))
-          ifs branches finally = foldr iff finally branches
-          iff (if', then') else' = CondExpr () if' then' else'
+          do branches' <- forM branches $ \(b,e) -> (,) <$> expression b <*> expression e
+             return $ case last branches of
+               (A _ (Var (Var.Canonical (Var.Module "Basics") "otherwise")), _) ->
+                   safeIfs branches'
+               (A _ (Literal (Boolean True)), _) -> safeIfs branches'
+               _ -> ifs branches' (throw "If" region)
+          where
+            safeIfs branches = ifs (init branches) (snd (last branches))
+            ifs branches finally = foldr iff finally branches
+            iff (if', then') else' = CondExpr () if' then' else'
 
       Case e cases ->
           do (tempVar,initialMatch) <- Case.toMatch cases
              (revisedMatch, stmt) <-
                  case e of
-                   L _ (Var x) -> return (Case.matchSubst [(tempVar,x)] initialMatch, [])
-                   _ -> do e' <- expression e
-                           return (initialMatch, [VarDeclStmt () [varDecl tempVar e']])
-             match' <- match span revisedMatch
+                   A _ (Var (Var.Canonical Var.Local x)) ->
+                       return (Case.matchSubst [(tempVar, Var.varName x)] initialMatch, [])
+                   _ ->
+                       do e' <- expression e
+                          return (initialMatch, [VarDeclStmt () [varDecl tempVar e']])
+             match' <- match region revisedMatch
              return (function [] (stmt ++ match') `call` [])
 
       ExplicitList es ->
           do es' <- mapM expression es
-             return $ obj "_J.toList" <| ArrayLit () es'
+             return $ _List "fromArray" <| ArrayLit () es'
 
       Data name es ->
           do es' <- mapM expression es
@@ -170,87 +183,97 @@
 
       Markdown uid doc es ->
           do es' <- mapM expression es
-             return $ obj "Text.markdown" `call` (string md : string uid : es')
+             return $ Var.value "Text" "markdown" `call` (string md : string uid : es')
           where
             pad = "<div style=\"height:0;width:0;\">&nbsp;</div>"
             md = pad ++ MD.toHtml doc ++ pad
 
+      GLShader _uid src _tipe ->
+        return $ ObjectLit () [(PropString () "src", literal (Str src))]
+          
       PortIn name tipe ->
-          return $ obj "Native.Ports.portIn" `call` [ string name, Port.incoming tipe ]
+          return $ Var.value "Native.Ports" "portIn" `call`
+                     [ string name, Port.incoming tipe ]
 
       PortOut name tipe value ->
           do value' <- expression value
-             return $ obj "Native.Ports.portOut" `call`
+             return $ Var.value "Native.Ports" "portOut" `call`
                         [ string name, Port.outgoing tipe, value' ]
 
-definition :: Def -> State Int [Statement ()]
-definition (Definition pattern expr@(L span _) _) = do
+definition :: Canonical.Def -> State Int [Statement ()]
+definition (Canonical.Definition pattern expr@(A region _) _) = do
   expr' <- expression expr
   let assign x = varDecl x expr'
   case pattern of
-    PVar x
+    P.Var x
         | Help.isOp x ->
             let op = LBracket () (ref "_op") (string x) in
             return [ ExprStmt () $ AssignExpr () OpAssign op expr' ]
         | otherwise ->
-            return [ VarDeclStmt () [ assign x ] ]
+            return [ VarDeclStmt () [ assign (Var.varName x) ] ]
 
-    PRecord fields ->
-        let setField f = varDecl f (dotSep ["$",f]) in
+    P.Record fields ->
+        let setField f = varDecl f (obj ["$",f]) in
         return [ VarDeclStmt () (assign "$" : map setField fields) ]
 
-    PData name patterns | vars /= Nothing ->
+    P.Data (Var.Canonical _ name) patterns | vars /= Nothing ->
         return [ VarDeclStmt () (setup (zipWith decl (maybe [] id vars) [0..])) ]
         where
           vars = getVars patterns
           getVars patterns =
               case patterns of
-                PVar x : rest -> (x:) `fmap` getVars rest
+                P.Var x : rest -> (Var.varName x :) `fmap` getVars rest
                 [] -> Just []
                 _ -> Nothing
 
-          decl x n = varDecl x (dotSep ["$","_" ++ show n])
+          decl x n = varDecl x (obj ["$","_" ++ show n])
           setup vars
               | Help.isTuple name = assign "$" : vars
-              | otherwise = assign "$raw" : safeAssign : vars
+              | otherwise = assign "_raw" : safeAssign : vars
 
-          safeAssign = varDecl "$" (CondExpr () if' (obj "$raw") exception)
-          if' = InfixExpr () OpStrictEq (obj "$raw.ctor") (string name)
-          exception = obj "_E.Case" `call` [ref "$moduleName", string (show span)]
+          safeAssign = varDecl "$" (CondExpr () if' (ref "_raw") exception)
+          if' = InfixExpr () OpStrictEq (obj ["_raw","ctor"]) (string name)
+          exception = Help.throw "Case" region
 
     _ ->
         do defs' <- concat <$> mapM toDef vars
-           return (VarDeclStmt () [assign "$"] : defs')
+           return (VarDeclStmt () [assign "_"] : defs')
         where
-          vars = Set.toList $ Pattern.boundVars pattern
-          mkVar = L span . Var
-          toDef y = let expr =  L span $ Case (mkVar "$") [(pattern, mkVar y)]
-                    in  definition $ Definition (PVar y) expr Nothing
+          vars = P.boundVarList pattern
+          mkVar = A region . localVar
+          toDef y = let expr =  A region $ Case (mkVar "_") [(pattern, mkVar y)]
+                    in  definition $ Canonical.Definition (P.Var y) expr Nothing
 
-match :: SrcSpan -> Case.Match -> State Int [Statement ()]
-match span mtch =
+match :: Region -> Case.Match -> State Int [Statement ()]
+match region mtch =
   case mtch of
     Case.Match name clauses mtch' ->
-        do (isChars, clauses') <- unzip <$> mapM (clause span name) clauses
-           mtch'' <- match span mtch'
+        do (isChars, clauses') <- unzip <$> mapM (clause region name) clauses
+           mtch'' <- match region mtch'
            return (SwitchStmt () (format isChars (access name)) clauses' : mtch'')
         where
           isLiteral p = case p of
                           Case.Clause (Right _) _ _ -> True
                           _ -> False
-          access name = if any isLiteral clauses then ref name else dotSep [name,"ctor"]
+
+          access name
+              | any isLiteral clauses = obj [name]
+              | otherwise = obj (Help.splitDots name ++ ["ctor"])
+
           format isChars e
               | or isChars = InfixExpr () OpAdd e (string "")
               | otherwise = e
 
     Case.Fail ->
-        return [ ExprStmt () (obj "_E.Case" `call` [ref "$moduleName", string (show span)]) ]
+        return [ ExprStmt () (Help.throw "Case" region) ]
 
     Case.Break -> return [BreakStmt () Nothing]
+
     Case.Other e ->
         do e' <- expression e
            return [ ret e' ]
-    Case.Seq ms -> concat <$> mapM (match span) (dropEnd [] ms)
+
+    Case.Seq ms -> concat <$> mapM (match region) (dropEnd [] ms)
         where
           dropEnd acc [] = acc
           dropEnd acc (m:ms) =
@@ -258,9 +281,9 @@
                 Case.Other _ -> acc ++ [m]
                 _ -> dropEnd (acc ++ [m]) ms
 
-clause :: SrcSpan -> String -> Case.Clause -> State Int (Bool, CaseClause ())
-clause span variable (Case.Clause value vars mtch) =
-    (,) isChar . CaseClause () pattern <$> match span (Case.matchSubst (zip vars vars') mtch)
+clause :: Region -> String -> Case.Clause -> State Int (Bool, CaseClause ())
+clause region variable (Case.Clause value vars mtch) =
+    (,) isChar . CaseClause () pattern <$> match region (Case.matchSubst (zip vars vars') mtch)
   where
     vars' = map (\n -> variable ++ "._" ++ show n) [0..]
     (isChar, pattern) =
@@ -269,97 +292,133 @@
           _ -> (,) False $ case value of
                              Right (Boolean b) -> BoolLit () b
                              Right lit -> literal lit
-                             Left name -> string $ case List.elemIndices '.' name of
-                                                     [] -> name
-                                                     is -> drop (last is + 1) name
+                             Left (Var.Canonical _ name) ->
+                                 string name
 
-flattenLets :: [Def] -> LExpr -> ([Def], LExpr)
-flattenLets defs lexpr@(L _ expr) =
+flattenLets :: [Canonical.Def] -> Canonical.Expr -> ([Canonical.Def], Canonical.Expr)
+flattenLets defs lexpr@(A _ expr) =
     case expr of
       Let ds body -> flattenLets (defs ++ ds) body
       _ -> (defs, lexpr)
 
-generate :: MetadataModule -> String 
-generate unsafeModule =
-    show . prettyPrint $ setup (Just "Elm") (names modul ++ ["make"]) ++
-             [ assign ("Elm" : names modul ++ ["make"]) (function ["_elm"] programStmts) ]
+generate :: CanonicalModule -> String 
+generate modul =
+    show . prettyPrint $ setup "Elm" (names ++ ["make"]) ++
+             [ assign ("Elm" : names ++ ["make"]) (function ["_elm"] programStmts) ]
   where
-    modul = MakeSafe.metadataModule unsafeModule
-    thisModule = dotSep ("_elm" : names modul ++ ["values"])
+    names :: [String]
+    names = Module.names modul
+
+    thisModule :: Expression ()
+    thisModule = obj ("_elm" : names ++ ["values"])
+
+    programStmts :: [Statement ()]
     programStmts =
         concat
-        [ setup (Just "_elm") (names modul ++ ["values"])
+        [ [ ExprStmt () (string "use strict") ]
+        , setup "_elm" (names ++ ["values"])
         , [ IfSingleStmt () thisModule (ret thisModule) ]
-        , [ internalImports (List.intercalate "." (names modul)) ]
-        , concatMap jsImport . Set.toList . Set.fromList . map fst $ imports modul
-        , [ assign ["_op"] (ObjectLit () []) ]
-        , concat $ evalState (mapM definition . fst . flattenLets [] $ program modul) 0
+        , [ VarDeclStmt () localVars ]
+        , body
         , [ jsExports ]
         , [ ret thisModule ]
         ]
 
-    jsExports = assign ("_elm" : names modul ++ ["values"]) (ObjectLit () exs)
+    localVars :: [VarDecl ()]
+    localVars = varDecl "_op" (ObjectLit () []) :
+                internalImports (Module.getName modul) ++
+                explicitImports
+      where
+        explicitImports :: [VarDecl ()]
+        explicitImports =
+            map jsImport . Set.toList . Set.fromList . map fst $ Module.imports modul
+
+        jsImport :: String -> VarDecl ()
+        jsImport name =
+            varDecl (Var.moduleName name) $
+                obj ("Elm" : Help.splitDots name ++ ["make"]) <| ref "_elm"
+
+    body :: [Statement ()]
+    body = concat $ evalState defs 0
+      where
+        defs = mapM definition . fst . flattenLets [] $ Module.program (Module.body modul)
+
+    setup namespace path = map create paths
+      where
+        create name = assign name (InfixExpr () OpLOr (obj name) (ObjectLit () []))
+        paths = drop 2 . init . List.inits $ namespace : path
+
+    jsExports = assign ("_elm" : names ++ ["values"]) (ObjectLit () exs)
         where
-          exs = map entry . filter (not . Help.isOp) $ "_op" : exports modul
-          entry x = (PropId () (var x), ref x)
+          exs = map entry $ "_op" : concatMap extract (exports modul)
+          entry x = (prop x, ref x)
+          extract value =
+              case value of
+                Var.Alias _ -> []
+                Var.Value x | Help.isOp x -> []
+                            | otherwise   -> [Var.varName x]
+                Var.ADT _ (Var.Listing ctors _) -> map Var.varName ctors
           
     assign path expr =
              case path of
                [x] -> VarDeclStmt () [ varDecl x expr ]
                _   -> ExprStmt () $
-                      AssignExpr () OpAssign (LDot () (dotSep (init path)) (last path)) expr
-
-    jsImport modul = setup Nothing path ++ [ include ]
-        where
-          path = split modul
-          include = assign path $ dotSep ("Elm" : path ++ ["make"]) <| ref "_elm"
+                      AssignExpr () OpAssign (LDot () (obj (init path)) (last path)) expr
 
-    setup namespace path = map create paths
-        where
-          create name = assign name (InfixExpr () OpLOr (dotSep name) (ObjectLit () []))
-          paths = case namespace of
-                    Nothing -> tail . init $ List.inits path
-                    Just nmspc -> drop 2 . init . List.inits $ nmspc : path
+binop :: Region -> Var.Canonical -> Canonical.Expr -> Canonical.Expr
+      -> State Int (Expression ())
+binop region func@(Var.Canonical home op) e1 e2 =
+    case (home, op) of
+      (Var.Module "Basics", ">>") ->
+          do es <- mapM expression (collectLeftAssoc [e2] e1)
+             return $ ["$"] ==> List.foldl' (\e f -> f <| e) (ref "$") es
 
-binop :: SrcSpan -> String -> LExpr -> LExpr -> State Int (Expression ())
-binop span op e1 e2 =
-    case op of
-      "Basics.." ->
-          do es <- mapM expression (e1 : collect [] e2)
+      (Var.Module "Basics", "<<") ->
+          do es <- mapM expression (e1 : collectRightAssoc [] e2)
              return $ ["$"] ==> foldr (<|) (ref "$") es
-      "Basics.<|" ->
+
+      (Var.Module "Basics", "<|") ->
           do e2' <- expression e2
-             es <- mapM expression (collect [] e1)
+             es <- mapM expression (collectRightAssoc [] e1)
              return $ foldr (<|) e2' es
-      "List.++" ->
+
+      (Var.Module "List", "++") ->
           do e1' <- expression e1
              e2' <- expression e2
-             return $ obj "_L.append" `call` [e1', e2']
-      "::" -> expression (L span (Data "::" [e1,e2]))
-      _ ->
+             return $ _List "append" `call` [e1', e2']
+
+      (Var.BuiltIn, "::") ->
+          expression (A region (Data "::" [e1,e2]))
+
+      (Var.Module "Basics", _) ->
           do e1' <- expression e1
              e2' <- expression e2
-             return $ case Map.lookup op opDict of
+             return $ case Map.lookup op basicOps of
                         Just f -> f e1' e2'
-                        Nothing -> ref "A2" `call` [ func, e1', e2' ]
+                        Nothing -> ref "A2" `call` [ Var.canonical func, e1', e2' ]
+
+      _ ->
+          do e1' <- expression e1
+             e2' <- expression e2
+             return (ref "A2" `call` [ Var.canonical func, e1', e2' ])
+
   where
-    collect es e =
+    collectRightAssoc es e =
         case e of
-          L _ (Binop op e1 e2) | op == "Basics.." -> collect (es ++ [e1]) e2
+          A _ (Binop (Var.Canonical (Var.Module "Basics") "<<") e1 e2) ->
+              collectRightAssoc (es ++ [e1]) e2
           _ -> es ++ [e]
 
-    func | Help.isOp operator = BracketRef () (dotSep (init parts ++ ["_op"])) (string operator)
-         | otherwise     = dotSep parts
-        where
-          parts = split op
-          operator = last parts
-
-    opDict = Map.fromList (infixOps ++ specialOps)
+    collectLeftAssoc es e =
+        case e of
+          A _ (Binop (Var.Canonical (Var.Module "Basics") ">>") e1 e2) ->
+              collectLeftAssoc (e2 : es) e1
+          _ -> e : es
 
-    specialOp str func = [ (str, func), ("Basics." ++ str, func) ]
-    infixOp str op = specialOp str (InfixExpr () op)
+    basicOps = Map.fromList (infixOps ++ specialOps)
 
-    infixOps = concat
+    infixOps =
+        let infixOp str op = (str, InfixExpr () op) in
         [ infixOp "+"  OpAdd
         , infixOp "-"  OpSub
         , infixOp "*"  OpMul
@@ -368,16 +427,16 @@
         , infixOp "||" OpLOr
         ]
 
-    specialOps = concat
-        [ specialOp "^"   $ \a b -> obj "Math.pow" `call` [a,b]
-        , specialOp "|>"  $ flip (<|)
-        , specialOp "=="  $ \a b -> obj "_U.eq" `call` [a,b]
-        , specialOp "/="  $ \a b -> PrefixExpr () PrefixLNot (obj "_U.eq" `call` [a,b])
-        , specialOp "<"   $ cmp OpLT 0
-        , specialOp ">"   $ cmp OpGT 0
-        , specialOp "<="  $ cmp OpLT 1
-        , specialOp ">="  $ cmp OpGT (-1)
-        , specialOp "div" $ \a b -> InfixExpr () OpBOr (InfixExpr () OpDiv a b) (IntLit () 0)
+    specialOps =
+        [ (,) "^"  $ \a b -> obj ["Math","pow"] `call` [a,b]
+        , (,) "|>" $ flip (<|)
+        , (,) "==" $ \a b -> _Utils "eq" `call` [a,b]
+        , (,) "/=" $ \a b -> PrefixExpr () PrefixLNot (_Utils "eq" `call` [a,b])
+        , (,) "<"  $ cmp OpLT 0
+        , (,) ">"  $ cmp OpGT 0
+        , (,) "<=" $ cmp OpLT 1
+        , (,) ">=" $ cmp OpGT (-1)
+        , (,) "//" $ \a b -> InfixExpr () OpBOr (InfixExpr () OpDiv a b) (IntLit () 0)
         ]
 
-    cmp op n a b = InfixExpr () op (obj "_U.cmp" `call` [a,b]) (IntLit () n)
+    cmp op n a b = InfixExpr () op (_Utils "cmp" `call` [a,b]) (IntLit () n)
diff --git a/compiler/Generate/JavaScript/Helpers.hs b/compiler/Generate/JavaScript/Helpers.hs
--- a/compiler/Generate/JavaScript/Helpers.hs
+++ b/compiler/Generate/JavaScript/Helpers.hs
@@ -1,37 +1,66 @@
 {-# OPTIONS_GHC -W #-}
 module Generate.JavaScript.Helpers where
 
-import qualified SourceSyntax.Helpers as Help
+import AST.Annotation (Region)
+import qualified AST.PrettyPrint as PP
 import Language.ECMAScript3.Syntax
 
-split :: String -> [String]
-split = go []
-  where
-    go vars str =
-        case break (=='.') str of
-          (x,_:rest) | Help.isOp x -> vars ++ [x ++ '.' : rest]
-                     | otherwise -> go (vars ++ [x]) rest
-          (x,[]) -> vars ++ [x]
+-- Creating Variables
 
+var :: String -> Id ()
 var name = Id () name
+
+ref :: String -> Expression ()
 ref name = VarRef () (var name)
+
+prop :: String -> Prop ()
 prop name = PropId () (var name)
-f <| x = CallExpr () f [x]
-ret e = ReturnStmt () (Just e)
-args ==> e = FuncExpr () Nothing (map var args) [ ret e ]
-function args stmts = FuncExpr () Nothing (map var args) stmts
-call = CallExpr ()
+
 string = StringLit ()
 
-dotSep vars =
+obj :: [String] -> Expression ()
+obj vars =
     case vars of
       x:xs -> foldl (DotRef ()) (ref x) (map var xs)
       [] -> error "dotSep must be called on a non-empty list of variables"
 
-obj = dotSep . split
+-- Specific Utilities
 
+localModuleName :: String
+localModuleName = "$moduleName"
+
+throw :: String -> Region -> Expression ()
+throw kind region =
+    obj ["_E",kind] `call` [ ref localModuleName, string (PP.renderPretty region) ]
+
+-- Function Calls
+
+(<|) :: Expression () -> Expression () -> Expression ()
+(<|) f x = CallExpr () f [x]
+
+ret :: Expression () -> Statement ()
+ret e = ReturnStmt () (Just e)
+
+(==>) :: [String] -> Expression () -> Expression ()
+(==>) args e = FuncExpr () Nothing (map var args) [ ret e ]
+
+function :: [String] -> [Statement ()] -> Expression ()
+function args stmts = FuncExpr () Nothing (map var args) stmts
+
+call :: Expression () -> [Expression ()] -> Expression ()
+call = CallExpr ()
+
+-- Checks
+
+equal :: Expression () -> Expression () -> Expression ()
 equal a b = InfixExpr () OpStrictEq a b
+
+instanceof :: String -> Expression () -> Expression ()
 instanceof tipe x =
     InfixExpr () OpLAnd (typeof "object" x) (InfixExpr () OpInstanceof x (ref tipe))
+
+typeof :: String -> Expression () -> Expression ()
 typeof tipe x = equal (PrefixExpr () PrefixTypeof x) (string tipe)
+
+member :: String -> Expression () -> Expression ()
 member field x = InfixExpr () OpIn (string field) x
diff --git a/compiler/Generate/JavaScript/Ports.hs b/compiler/Generate/JavaScript/Ports.hs
--- a/compiler/Generate/JavaScript/Ports.hs
+++ b/compiler/Generate/JavaScript/Ports.hs
@@ -2,8 +2,9 @@
 module Generate.JavaScript.Ports (incoming, outgoing) where
 
 import Generate.JavaScript.Helpers
-import qualified SourceSyntax.Helpers as Help
-import SourceSyntax.Type as T
+import qualified Generate.JavaScript.Variable as V
+import AST.Type as T
+import qualified AST.Variable as Var
 import Language.ECMAScript3.Syntax
 
 data JSType = JSNumber | JSBoolean | JSString | JSArray | JSObject [String]
@@ -14,76 +15,107 @@
     CondExpr () (jsFold OpLOr checks x) continue throw
   where
     jsFold op checks value = foldl1 (InfixExpr () op) (map ($value) checks)
-    throw = obj "_E.raise" <| InfixExpr () OpAdd msg x
+    throw = obj ["_E","raise"] <| InfixExpr () OpAdd msg x
     msg = string ("invalid input, expecting " ++ show jsType ++ " but got ")
-    checks = case jsType of
-               JSNumber  -> [typeof "number"]
-               JSBoolean -> [typeof "boolean"]
-               JSString  -> [typeof "string", instanceof "String"]
-               JSArray   -> [instanceof "Array"]
-               JSObject fields -> [jsFold OpLAnd (typeof "object" : map member fields)]
+    checks =
+        case jsType of
+          JSNumber  -> [typeof "number"]
+          JSBoolean -> [typeof "boolean"]
+          JSString  -> [typeof "string", instanceof "String"]
+          JSArray   -> [(obj ["_U","isJSArray"] <|)]
+          JSObject fields -> [jsFold OpLAnd (typeof "object" : map member fields)]
 
-incoming :: Type -> Expression ()
+incoming :: CanonicalType -> Expression ()
 incoming tipe =
   case tipe of
-    Data "Signal.Signal" [t] ->
-        obj "Native.Ports.incomingSignal" <| incoming t
+    Aliased _ t -> incoming t
+
+    App (Type v) [t]
+        | Var.isSignal v -> V.value "Native.Ports" "incomingSignal" <| incoming t
+
     _ -> ["v"] ==> inc tipe (ref "v")
 
-inc :: Type -> Expression () -> Expression ()
+inc :: CanonicalType -> Expression () -> Expression ()
 inc tipe x =
-     case tipe of
+    case tipe of
       Lambda _ _ -> error "functions should not be allowed through input ports"
       Var _ -> error "type variables should not be allowed through input ports"
-      Data ctor []
-          | ctor == "Int"    -> elm JSNumber
-          | ctor == "Float"  -> elm JSNumber
-          | ctor == "Bool"   -> elm JSBoolean
-          | ctor == "String" -> elm JSString
-          | ctor == "JavaScript.JSNumber" -> js JSNumber
-          | ctor == "JavaScript.JSBool"   -> js JSBoolean
-          | ctor == "JavaScript.JSString" -> js JSString
+      Aliased _ t ->
+          inc t x
+
+      Type (Var.Canonical Var.BuiltIn name)
+          | name == "Int"    -> from JSNumber
+          | name == "Float"  -> from JSNumber
+          | name == "Bool"   -> from JSBoolean
+          | name == "String" -> from JSString
           where
-            elm checks = check x checks (obj ("_J.to" ++ ctor) <| x)
-            js checks = check x checks x
+            from checks = check x checks x
 
-      Data ctor [t]
-          | ctor == "Maybe.Maybe" ->
-              CondExpr () (equal x (NullLit ()))
-                          (obj "Maybe.Nothing")
-                          (obj "Maybe.Just" <| inc t x)
+      Type name
+          | Var.isJson name -> V.value "Native.Json" "fromJS" <| x
+          | Var.isTuple name -> incomingTuple [] x
+          | otherwise -> error "bad type got to incoming port generation code"
 
-          | ctor == "_List" ->
-              check x JSArray (obj "_J.toList" <| array)
-              where
-                array = DotRef () x (var "map") <| incoming t
+      App f args ->
+          case f : args of
+            Type name : [t]
+                | Var.isMaybe name ->
+                    CondExpr ()
+                        (equal x (NullLit ()))
+                        (V.value "Maybe" "Nothing")
+                        (V.value "Maybe" "Just" <| inc t x)
 
-      Data ctor ts | Help.isTuple ctor -> check x JSArray tuple
-          where
-            tuple = ObjectLit () $ (PropId () (var "ctor"), string ctor) : values
-            values = zipWith convert [0..] ts
-            convert n t = ( PropId () $ var ('_':show n)
-                          , inc t (BracketRef () x (IntLit () n)))
+                | Var.isList name ->
+                    check x JSArray (obj ["_L","fromArray"] <| array)
 
-      Data _ _ -> error "bad ADT got to port generation code"
+                | Var.isArray name ->
+                    check x JSArray (obj ["_A","fromJSArray"] <| array)
+                where
+                  array = DotRef () x (var "map") <| incoming t
 
-      Record _ (Just _) -> error "bad record got to port generation code"
+            Type name : ts
+                | Var.isTuple name -> incomingTuple ts x
 
-      Record fields Nothing -> check x (JSObject (map fst fields)) object
+            _ -> error "bad ADT got to incoming port generation code"
+
+      Record _ (Just _) ->
+          error "bad record got to incoming port generation code"
+
+      Record fields Nothing ->
+          check x (JSObject (map fst fields)) object
           where
-            object = ObjectLit () $ (PropId () (var "_"), ObjectLit () []) : keys
+            object = ObjectLit () $ (prop "_", ObjectLit () []) : keys
             keys = map convert fields
-            convert (f,t) = (PropId () (var f), inc t (DotRef () x (var f)))
+            convert (f,t) = (prop f, inc t (DotRef () x (var f)))
 
+incomingTuple :: [CanonicalType] -> Expression () -> Expression ()
+incomingTuple types x =
+    check x JSArray (ObjectLit () fields)
+  where
+    fields = (prop "ctor", ctor) : zipWith convert [0..] types
+
+    ctor = string ("_Tuple" ++ show (length types))
+
+    convert n t =
+        ( prop ('_':show n)
+        , inc t (BracketRef () x (IntLit () n))
+        )
+
+outgoing :: CanonicalType -> Expression ()
 outgoing tipe =
   case tipe of
-    Data "Signal.Signal" [t] ->
-        obj "Native.Ports.outgoingSignal" <| outgoing t
+    Aliased _ t -> outgoing t
+
+    App (Type v) [t]
+        | Var.isSignal v -> V.value "Native.Ports" "outgoingSignal" <| outgoing t
+
     _ -> ["v"] ==> out tipe (ref "v")
 
-out :: Type -> Expression () -> Expression ()
+out :: CanonicalType -> Expression () -> Expression ()
 out tipe x =
     case tipe of
+      Aliased _ t -> out t x
+
       Lambda _ _
           | numArgs > 1 && numArgs < 10 ->
               func (ref ('A':show numArgs) `call` (x:values))
@@ -93,35 +125,46 @@
             numArgs = length ts - 1
             args = map (\n -> '_' : show n) [0..]
             values = zipWith inc (init ts) (map ref args)
-            func body = function (take numArgs args)
-                        [ VarDeclStmt () [VarDecl () (var "_r") (Just body)]
-                        , ret (out (last ts) (ref "_r"))
-                        ]
+            func body =
+                function (take numArgs args)
+                    [ VarDeclStmt () [VarDecl () (var "_r") (Just body)]
+                    , ret (out (last ts) (ref "_r"))
+                    ]
 
       Var _ -> error "type variables should not be allowed through input ports"
-      Data ctor []
-          | ctor `elem` ["Int","Float","Bool","String"] -> obj ("_J.from" ++ ctor) <| x
-          | ctor `elem` jsPrims -> x
-          where
-            jsPrims = map ("JavaScript.JS"++) ["Number","Bool","String"]
 
-      Data ctor [t]
-          | ctor == "Maybe.Maybe" ->
-              CondExpr () (equal (DotRef () x (var "ctor")) (string "Nothing"))
-                          (NullLit ())
-                          (DotRef () x (var "_0"))
+      Type (Var.Canonical Var.BuiltIn name)
+          | name `elem` ["Int","Float","Bool","String"] -> x
 
-          | ctor == "_List" ->
-              DotRef () (obj "_J.fromList" <| x) (var "map") <| outgoing t
+      Type name
+          | Var.isJson name -> V.value "Native.Json" "toJS" <| x
+          | Var.isTuple name -> ArrayLit () []
+          | otherwise -> error "bad type got to outgoing port generation code"
 
-      Data ctor ts | Help.isTuple ctor ->
-          ArrayLit () $ zipWith convert [0..] ts
-          where
-            convert n t = out t $ DotRef () x $ var ('_':show n)
+      App f args ->
+          case f : args of
+            Type name : [t]
+                | Var.isMaybe name ->
+                    CondExpr ()
+                        (equal (DotRef () x (var "ctor")) (string "Nothing"))
+                        (NullLit ())
+                        (out t (DotRef () x (var "_0")))
 
-      Data _ _ -> error "bad ADT got to port generation code"
+                | Var.isArray name ->
+                    DotRef () (obj ["_A","toJSArray"] <| x) (var "map") <| outgoing t
 
-      Record _ (Just _) -> error "bad record got to port generation code"
+                | Var.isList name ->
+                    DotRef () (obj ["_L","toArray"] <| x) (var "map") <| outgoing t
+
+            Type name : ts
+                | Var.isTuple name ->
+                    let convert n t = out t $ DotRef () x $ var ('_':show n)
+                    in  ArrayLit () $ zipWith convert [0..] ts
+
+            _ -> error "bad ADT got to outgoing port generation code"
+
+      Record _ (Just _) ->
+          error "bad record got to outgoing port generation code"
 
       Record fields Nothing ->
           ObjectLit () keys
diff --git a/compiler/Generate/JavaScript/Variable.hs b/compiler/Generate/JavaScript/Variable.hs
new file mode 100644
--- /dev/null
+++ b/compiler/Generate/JavaScript/Variable.hs
@@ -0,0 +1,53 @@
+{-# OPTIONS_GHC -W #-}
+module Generate.JavaScript.Variable where
+
+import qualified AST.Helpers as Help
+import qualified AST.Variable as Var
+import qualified Data.Set as Set
+import qualified Generate.JavaScript.Helpers as JS
+import qualified Language.ECMAScript3.Syntax as JS
+
+swap :: Char -> Char -> Char -> Char
+swap from to c = if c == from then to else c
+
+canonical :: Var.Canonical -> JS.Expression ()
+canonical (Var.Canonical home name) =
+  case Help.isOp name of
+    True  -> JS.BracketRef () (JS.obj (home' ++ ["_op"])) (JS.string name)
+    False -> JS.obj (home' ++ [ varName name ])
+  where
+    home' =
+      case home of
+        Var.Local       -> []
+        Var.BuiltIn     -> []
+        Var.Module path -> [ moduleName path ]
+
+moduleName :: String -> String
+moduleName x = '$' : map (swap '.' '$') x
+
+varName :: String -> String
+varName x = map (swap '\'' '$') x'
+    where
+      x' = if Set.member x jsReserveds then '$' : x else x
+
+value :: String -> String -> JS.Expression ()
+value home name =
+    canonical (Var.Canonical (Var.Module home) name)
+
+jsReserveds :: Set.Set String
+jsReserveds = Set.fromList
+    [ "null", "undefined", "Nan", "Infinity", "true", "false", "eval"
+    , "arguments", "int", "byte", "char", "goto", "long", "final", "float"
+    , "short", "double", "native", "throws", "boolean", "abstract", "volatile"
+    , "transient", "synchronized", "function", "break", "case", "catch"
+    , "continue", "debugger", "default", "delete", "do", "else", "finally"
+    , "for", "function", "if", "in", "instanceof", "new", "return", "switch"
+    , "this", "throw", "try", "typeof", "var", "void", "while", "with", "class"
+    , "const", "enum", "export", "extends", "import", "super", "implements"
+    , "interface", "let", "package", "private", "protected", "public"
+    , "static", "yield"
+    -- reserved by the Elm runtime system
+    , "Elm", "ElmRuntime"
+    , "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"
+    , "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9"
+    ]
diff --git a/compiler/Generate/Markdown.hs b/compiler/Generate/Markdown.hs
--- a/compiler/Generate/Markdown.hs
+++ b/compiler/Generate/Markdown.hs
@@ -1,39 +1,42 @@
 module Generate.Markdown where
 
-import Text.Pandoc
+import qualified Cheapskate as CS
+import qualified Cheapskate.Html as CS
 import qualified Data.Set as Set
+import qualified Data.Text as Text
+import qualified Text.Blaze.Html.Renderer.String as Blaze
+import qualified Text.Highlighting.Kate as Kate
 
+import Debug.Trace
+
+(|>) :: a -> (a -> b) -> b
+x |> f = f x
+
 toHtml :: String -> String
-toHtml = writeHtmlString writeOptions . readMarkdown readOptions
+toHtml rawMarkdown =
+    Text.pack rawMarkdown
+        |> CS.markdown options
+        |> CS.walk highlightCode
+        |> CS.renderDoc
+        |> Blaze.renderHtml
 
-readOptions =
-    def { readerExtensions  = elmExtensions
-        , readerApplyMacros = False
-        }
+options :: CS.Options
+options =
+    CS.Options
+    { CS.sanitize = False
+    , CS.allowRawHtml = True
+    , CS.preserveHardBreaks = False
+    , CS.debug = False
+    }
 
-writeOptions =
-    def { writerExtensions = elmExtensions
-        , writerHighlight = True
-        }
+highlightCode :: CS.Block -> CS.Block
+highlightCode block =
+    case block of
+      CS.CodeBlock (CS.CodeAttr lang _info) src ->
+        Kate.highlightAs (Text.unpack lang) (Text.unpack src)
+            |> Kate.formatHtmlBlock Kate.defaultFormatOpts
+            |> Blaze.renderHtml
+            |> Text.pack
+            |> CS.HtmlBlock
 
-elmExtensions :: Set.Set Extension
-elmExtensions = Set.fromList
-  [ Ext_raw_html
-  , Ext_fenced_code_blocks
-  , Ext_fenced_code_attributes
-  , Ext_backtick_code_blocks
-  , Ext_inline_code_attributes
-  , Ext_markdown_in_html_blocks
-  , Ext_escaped_line_breaks
-  , Ext_fancy_lists
-  , Ext_startnum
-  , Ext_definition_lists
-  , Ext_example_lists
-  , Ext_all_symbols_escapable
-  , Ext_intraword_underscores
-  , Ext_blank_before_blockquote
-  , Ext_blank_before_header
-  , Ext_auto_identifiers
-  , Ext_header_attributes
-  , Ext_implicit_header_references
-  ]
+      _ -> block
diff --git a/compiler/Generate/Noscript.hs b/compiler/Generate/Noscript.hs
deleted file mode 100644
--- a/compiler/Generate/Noscript.hs
+++ /dev/null
@@ -1,68 +0,0 @@
-module Generate.Noscript (noscript) where
-
-import Data.List (isInfixOf)
-import qualified SourceSyntax.Declaration as D
-import SourceSyntax.Expression
-import SourceSyntax.Literal
-import SourceSyntax.Location
-import SourceSyntax.Module
-import qualified Generate.Markdown as MD
-
-noscript :: Extract def => Module def -> String
-noscript modul = concat (extract modul)
-
-class Extract a where
-  extract :: a -> [String]
-
-instance Extract def => Extract (Module def) where
-  extract (Module _ _ _ stmts) =
-      map (\s -> "<p>" ++ s ++ "</p>") (concatMap extract stmts)
-
-instance Extract def => Extract (D.Declaration' port def) where
-  extract (D.Definition d) = extract d
-  extract _ = []
-
-instance Extract Def where
-  extract (Definition _ e _)   = extract e
-
-instance Extract e => Extract (Located e) where
-  extract (L _ e) = extract e
-
-instance Extract def => Extract (Expr' def) where
-  extract expr =
-    let f = extract in
-    case expr of
-      Literal (Str s) -> [s]
-      Binop op e1 e2 -> case (op, f e1, f e2) of
-                          ("++", [s1], [s2]) -> [s1 ++ s2]
-                          (_   , ss1 , ss2 ) -> ss1 ++ ss2
-      Lambda v e -> f e
-      App (L _ (App (L _ (App (L _ (Var func)) w)) h)) src
-          | "image" `isInfixOf` func -> extractImage src
-      App (L _ (App (L _ (Var func)) src)) txt
-          | "link" `isInfixOf` func -> extractLink src txt
-      App (L _ (Var func)) e
-          | "header"    `isInfixOf` func -> tag "h1" e
-          | "bold"      `isInfixOf` func -> tag "b" e
-          | "italic"    `isInfixOf` func -> tag "i" e
-          | "monospace" `isInfixOf` func -> tag "code" e
-      App e1 e2 -> f e1 ++ f e2
-      Let defs e -> concatMap extract defs ++ f e
-      Var _ -> []
-      Case e cases -> concatMap (f . snd) cases
-      Data _ es -> concatMap f es
-      MultiIf es -> concatMap (f . snd) es
-      Markdown _ md _ -> [ MD.toHtml md ]
-      _ -> []
-
-extractLink src txt =
-    case (extract src, extract txt) of
-      ([s1],[s2]) -> [ "<a href=\"" ++ s1 ++ "\">" ++ s2 ++ "</a>" ]
-      ( ss1, ss2) -> ss1 ++ ss2
-
-extractImage src =
-    case extract src of
-      [s] -> ["<img src=\"" ++ s ++ "\">"]
-      ss  -> ss
-
-tag t e = map (\s -> concat [ "<", t, ">", s, "</", t, ">" ]) (extract e)
diff --git a/compiler/Metadata/Prelude.hs b/compiler/Metadata/Prelude.hs
--- a/compiler/Metadata/Prelude.hs
+++ b/compiler/Metadata/Prelude.hs
@@ -2,36 +2,103 @@
 module Metadata.Prelude (interfaces, add) where
 
 import qualified Data.Map as Map
+import qualified Data.Set as Set
 import qualified Control.Exception as E
-import qualified Paths_Elm as Path
 import System.Exit
 import System.IO
-import SourceSyntax.Module
+import AST.Module as Module
+import qualified AST.Variable as Var
 import qualified Build.Interface as Interface
+import Build.Utils (getDataFile)
 
-add :: Bool -> Module def -> Module def
-add noPrelude (Module name exs ims decls) = Module name exs (customIms ++ ims) decls
-    where
-      customIms = if noPrelude then [] else concatMap addModule prelude
 
-      addModule (n, method) = case lookup n ims of
-                                Nothing     -> [(n, method)]
-                                Just (As _) -> [(n, method)]
-                                Just _      -> []
+-- DEFINITION OF THE PRELUDE
 
-prelude :: [(String, ImportMethod)]
-prelude = string : text ++ map (\n -> (n, Hiding [])) modules
+type ImportDict =
+    Map.Map String ([String], Var.Listing Var.Value)
+
+prelude :: ImportDict
+prelude = Map.unions [ string, text, maybe, openImports ]
   where
-    text = map ((,) "Text") [ As "Text", Hiding ["link", "color", "height"] ]
-    string = ("String", As "String")
-    modules = [ "Basics", "Signal", "List", "Maybe", "Time", "Prelude"
-              , "Graphics.Element", "Color", "Graphics.Collage", "Native.Ports" ]
+    importing :: String -> [Var.Value] -> ImportDict
+    importing name values =
+        Map.singleton name ([], Var.Listing values False)
 
+    openImports :: ImportDict
+    openImports =
+        Map.fromList $ map (\name -> (name, ([], Var.openListing))) $
+        [ "Basics", "Signal", "List", "Time", "Color"
+        , "Graphics.Element", "Graphics.Collage"
+        , "Native.Ports", "Native.Json"
+        ]
+
+    maybe :: ImportDict
+    maybe = importing "Maybe" [ Var.ADT "Maybe" Var.openListing ]
+
+    string :: ImportDict
+    string = importing "String" [Var.Value "show"]
+
+    text :: ImportDict
+    text = importing "Text" (Var.ADT "Text" (Var.Listing [] False) : values)
+      where
+        values =
+            map Var.Value
+            [ "toText", "leftAligned", "rightAligned", "centered", "justified"
+            , "plainText", "asText", "typeface", "monospace", "bold", "italic"
+            ]
+
+
+-- ADDING PRELUDE TO A MODULE
+
+add :: Bool -> Module exs body -> Module exs body
+add noPrelude (Module moduleName path exports imports decls) =
+    Module moduleName path exports ammendedImports decls
+  where
+    ammendedImports =
+      importDictToList $
+        foldr addImport (if noPrelude then Map.empty else prelude) imports
+
+importDictToList :: ImportDict -> [(String, ImportMethod)]
+importDictToList dict =
+    concatMap toImports (Map.toList dict)
+  where
+    toImports (name, (qualifiers, listing@(Var.Listing explicits open))) =
+        map (\qualifier -> (name, As qualifier)) qualifiers
+        ++
+        if open || not (null explicits)
+          then [(name, Open listing)]
+          else []
+
+addImport :: (String, ImportMethod) -> ImportDict -> ImportDict
+addImport (name, method) importDict =
+    Map.alter mergeMethods name importDict
+  where
+    mergeMethods :: Maybe ([String], Var.Listing Var.Value)
+                 -> Maybe ([String], Var.Listing Var.Value)
+    mergeMethods entry =
+      let (qualifiers, listing) =
+              case entry of
+                Nothing -> ([], Var.Listing [] False)
+                Just v -> v
+      in
+          case method of
+            As qualifier -> Just (qualifier : qualifiers, listing)
+            Open newListing ->
+                Just (qualifiers, mergeListings newListing listing)
+
+    mergeListings (Var.Listing explicits1 open1) (Var.Listing explicits2 open2) =
+        Var.Listing
+          (Set.toList (Set.fromList (explicits1 ++ explicits2)))
+          (open1 || open2)
+
+
+-- EXTRACT INTERFACES FROM STATIC FILE
+
 interfaces :: Bool -> IO Interfaces
 interfaces noPrelude =
     if noPrelude
-    then return $ Map.empty
-    else safeReadDocs =<< Path.getDataFileName "interfaces.data"
+    then return Map.empty
+    else safeReadDocs =<< getDataFile "interfaces.data"
 
 safeReadDocs :: FilePath -> IO Interfaces
 safeReadDocs name =
@@ -40,14 +107,14 @@
       hPutStrLn stderr $ unlines $
          [ "Error reading types for standard library from file " ++ name
          , "    If you are using a stable version of Elm, please report an issue at"
-         , "    <http://github.com/evancz/Elm/issues> specifying version numbers for"
+         , "    <http://github.com/elm-lang/Elm/issues> specifying version numbers for"
          , "    Elm and your OS." ]
       exitFailure
 
 readDocs :: FilePath -> IO Interfaces
 readDocs filePath = do
   interfaces <- Interface.load filePath
-  case mapM (Interface.isValid filePath) (interfaces :: [(String, ModuleInterface)]) of
+  case mapM (Interface.isValid filePath) (interfaces :: [(String, Module.Interface)]) of
     Left err -> do
       hPutStrLn stderr err
       exitFailure
diff --git a/compiler/Parse/Binop.hs b/compiler/Parse/Binop.hs
--- a/compiler/Parse/Binop.hs
+++ b/compiler/Parse/Binop.hs
@@ -1,12 +1,15 @@
+{-# OPTIONS_GHC -W #-}
 module Parse.Binop (binops, OpTable) where
 
 import Control.Applicative ((<$>))
-import Data.List (intercalate)
+import qualified Data.List as List
 import qualified Data.Map as Map
 
-import SourceSyntax.Location (merge)
-import qualified SourceSyntax.Expression as E
-import SourceSyntax.Declaration (Assoc(..))
+import AST.Annotation (merge)
+import AST.Declaration (Assoc(..))
+import AST.Expression.General (Expr'(Binop))
+import qualified AST.Expression.Source as Source
+import qualified AST.Variable as Var
 import Text.Parsec
 import Parse.Helpers
 
@@ -16,13 +19,13 @@
 opAssoc :: OpTable -> String -> Assoc
 opAssoc table op = snd $ Map.findWithDefault (9,L) op table
 
-hasLevel :: OpTable -> Int -> (String, E.LParseExpr) -> Bool
+hasLevel :: OpTable -> Int -> (String, Source.Expr) -> Bool
 hasLevel table n (op,_) = opLevel table op == n
 
-binops :: IParser E.LParseExpr
-       -> IParser E.LParseExpr
+binops :: IParser Source.Expr
+       -> IParser Source.Expr
        -> IParser String
-       -> IParser E.LParseExpr
+       -> IParser Source.Expr
 binops term last anyOp =
     do e <- term
        table <- getState
@@ -38,9 +41,9 @@
 
 split :: OpTable
       -> Int
-      -> E.LParseExpr
-      -> [(String, E.LParseExpr)]
-      -> IParser E.LParseExpr
+      -> Source.Expr
+      -> [(String, Source.Expr)]
+      -> IParser Source.Expr
 split _ _ e []  = return e
 split table n e eops = do
   assoc <- getAssoc table n eops
@@ -49,26 +52,26 @@
   case assoc of R -> joinR es ops
                 _ -> joinL es ops
 
-splitLevel :: OpTable -> Int -> E.LParseExpr -> [(String, E.LParseExpr)]
-           -> [IParser E.LParseExpr]
+splitLevel :: OpTable -> Int -> Source.Expr -> [(String, Source.Expr)]
+           -> [IParser Source.Expr]
 splitLevel table n e eops =
     case break (hasLevel table n) eops of
-      (lops, (op,e'):rops) ->
+      (lops, (_op,e'):rops) ->
           split table (n+1) e lops : splitLevel table n e' rops
       (lops, []) -> [ split table (n+1) e lops ]
 
-joinL :: [E.LParseExpr] -> [String] -> IParser E.LParseExpr
+joinL :: [Source.Expr] -> [String] -> IParser Source.Expr
 joinL [e] [] = return e
-joinL (a:b:es) (op:ops) = joinL (merge a b (E.Binop op a b) : es) ops
+joinL (a:b:es) (op:ops) = joinL (merge a b (Binop (Var.Raw op) a b) : es) ops
 joinL _ _ = failure "Ill-formed binary expression. Report a compiler bug."
 
-joinR :: [E.LParseExpr] -> [String] -> IParser E.LParseExpr
+joinR :: [Source.Expr] -> [String] -> IParser Source.Expr
 joinR [e] [] = return e
 joinR (a:b:es) (op:ops) = do e <- joinR (b:es) ops
-                             return (merge a e (E.Binop op a e))
+                             return (merge a e (Binop (Var.Raw op) a e))
 joinR _ _ = failure "Ill-formed binary expression. Report a compiler bug."
 
-getAssoc :: OpTable -> Int -> [(String,E.LParseExpr)] -> IParser Assoc
+getAssoc :: OpTable -> Int -> [(String,Source.Expr)] -> IParser Assoc
 getAssoc table n eops
     | all (==L) assocs = return L
     | all (==R) assocs = return R 
@@ -79,5 +82,5 @@
         assocs = map (opAssoc table . fst) levelOps
         msg problem =
             concat [ "Conflicting " ++ problem ++ " for binary operators ("
-                   , intercalate ", " (map fst eops), "). "
+                   , List.intercalate ", " (map fst eops), "). "
                    , "Consider adding parentheses to disambiguate." ]
diff --git a/compiler/Parse/Declaration.hs b/compiler/Parse/Declaration.hs
--- a/compiler/Parse/Declaration.hs
+++ b/compiler/Parse/Declaration.hs
@@ -7,16 +7,15 @@
 import Parse.Helpers
 import qualified Parse.Expression as Expr
 import qualified Parse.Type as Type
-import qualified SourceSyntax.Declaration as D
-
+import qualified AST.Declaration as D
 
-declaration :: IParser D.ParseDeclaration
+declaration :: IParser D.SourceDecl
 declaration = alias <|> datatype <|> infixDecl <|> port <|> definition
 
-definition :: IParser D.ParseDeclaration
+definition :: IParser D.SourceDecl
 definition = D.Definition <$> Expr.def
 
-alias :: IParser D.ParseDeclaration
+alias :: IParser D.SourceDecl
 alias = do
   reserved "type" <?> "type alias (type Point = {x:Int, y:Int})"
   forcedWS
@@ -26,7 +25,7 @@
   tipe <- Type.expr
   return (D.TypeAlias name args tipe)
 
-datatype :: IParser D.ParseDeclaration
+datatype :: IParser D.SourceDecl
 datatype = do
   reserved "data" <?> "datatype definition (data T = A | B | ...)"
   forcedWS
@@ -37,7 +36,7 @@
   return $ D.Datatype name args tcs
 
 
-infixDecl :: IParser D.ParseDeclaration
+infixDecl :: IParser D.SourceDecl
 infixDecl = do
   assoc <- choice [ reserved "infixl" >> return D.L
                   , reserved "infix"  >> return D.N
@@ -48,7 +47,7 @@
   D.Fixity assoc (read [n]) <$> anyOp
 
 
-port :: IParser D.ParseDeclaration
+port :: IParser D.SourceDecl
 port =
   do try (reserved "port")
      whitespace
diff --git a/compiler/Parse/Expression.hs b/compiler/Parse/Expression.hs
--- a/compiler/Parse/Expression.hs
+++ b/compiler/Parse/Expression.hs
@@ -5,46 +5,48 @@
 import Text.Parsec hiding (newline,spaces)
 import Text.Parsec.Indent
 
-import Parse.Helpers
-import qualified Parse.Pattern as Pattern
-import qualified Parse.Type as Type
 import Parse.Binop
+import Parse.Helpers as Help
 import Parse.Literal
+import qualified Parse.Pattern as Pattern
+import qualified Parse.Type as Type
 
-import SourceSyntax.Location as Location
-import SourceSyntax.Pattern hiding (tuple,list)
-import qualified SourceSyntax.Literal as Literal
-import SourceSyntax.Expression
+import AST.Annotation as Annotation
+import AST.Expression.General
+import qualified AST.Expression.Source as Source
+import qualified AST.Literal as L
+import qualified AST.Pattern as P
+import qualified AST.Variable as Var
 
 
 --------  Basic Terms  --------
 
-varTerm :: IParser ParseExpr
+varTerm :: IParser Source.Expr'
 varTerm = toVar <$> var <?> "variable"
 
-toVar :: String -> ParseExpr
-toVar v = case v of "True"  -> Literal (Literal.Boolean True)
-                    "False" -> Literal (Literal.Boolean False)
-                    _       -> Var v
+toVar :: String -> Source.Expr'
+toVar v = case v of "True"  -> Literal (L.Boolean True)
+                    "False" -> Literal (L.Boolean False)
+                    _       -> rawVar v
 
-accessor :: IParser ParseExpr
+accessor :: IParser Source.Expr'
 accessor = do
   (start, lbl, end) <- located (try (string "." >> rLabel))
-  let loc e = Location.at start end e
-  return (Lambda (PVar "_") (loc $ Access (loc $ Var "_") lbl))
+  let loc e = Annotation.at start end e
+  return (Lambda (P.Var "_") (loc $ Access (loc $ rawVar "_") lbl))
 
-negative :: IParser ParseExpr
+negative :: IParser Source.Expr'
 negative = do
   (start, nTerm, end) <-
       located (try (char '-' >> notFollowedBy (char '.' <|> char '-')) >> term)
-  let loc e = Location.at start end e
-  return (Binop "-" (loc $ Literal (Literal.IntNum 0)) nTerm)
+  let loc e = Annotation.at start end e
+  return (Binop (Var.Raw "-") (loc $ Literal (L.IntNum 0)) nTerm)
 
 
 --------  Complex Terms  --------
 
-listTerm :: IParser ParseExpr
-listTerm = markdown' <|> braces (try range <|> ExplicitList <$> commaSep expr)
+listTerm :: IParser Source.Expr'
+listTerm = markdown' <|> shader' <|> braces (try range <|> ExplicitList <$> commaSep expr)
   where
     range = do
       lo <- expr
@@ -54,98 +56,106 @@
     markdown' = do
       pos <- getPosition
       let uid = show (sourceLine pos) ++ ":" ++ show (sourceColumn pos)
-      (rawText, exprs) <- markdown (interpolation uid)
+      (rawText, exprs) <- Help.markdown (interpolation uid)
       return (Markdown uid (filter (/='\r') rawText) exprs)
 
+    shader' = do
+      pos <- getPosition
+      let uid = show (sourceLine pos) ++ ":" ++ show (sourceColumn pos)
+      (rawSrc, tipe) <- Help.shader
+      return $ GLShader uid (filter (/='\r') rawSrc) tipe
+
     span uid index =
-        "<span id=\"md-" ++ uid ++ "-" ++ show index ++ "\">{{ markdown interpolation is in the pipeline, but still needs more testing }}</span>"
+        "<span id=\"md-" ++ uid ++ "-" ++ show index ++
+        "\">{{ markdown interpolation is in the pipeline, but still needs more testing }}</span>"
 
-    interpolation uid md exprs = do
+    interpolation uid exprs = do
       try (string "{{")
       e <- padded expr
       string "}}"
-      return (md ++ span uid (length exprs), exprs ++ [e])
+      return (span uid (length exprs), exprs ++ [e])
 
-parensTerm :: IParser LParseExpr
+parensTerm :: IParser Source.Expr
 parensTerm = try (parens opFn) <|> parens (tupleFn <|> parened)
   where
     opFn = do
       (start, op, end) <- located anyOp
-      let loc = Location.at start end
-      return . loc . Lambda (PVar "x") . loc . Lambda (PVar "y") . loc $
-             Binop op (loc $ Var "x") (loc $ Var "y")
+      let loc = Annotation.at start end
+      return . loc . Lambda (P.Var "x") . loc . Lambda (P.Var "y") . loc $
+             Binop (Var.Raw op) (loc (rawVar "x")) (loc (rawVar "y"))
 
     tupleFn = do
       let comma = char ',' <?> "comma ','"
       (start, commas, end) <- located (comma >> many (whitespace >> comma))
       let vars = map (('v':) . show) [ 0 .. length commas + 1 ]
-          loc = Location.at start end
+          loc = Annotation.at start end
       return $ foldr (\x e -> loc $ Lambda x e)
-                 (loc . tuple $ map (loc . Var) vars) (map PVar vars)
+                 (loc . tuple $ map (loc . rawVar) vars) (map P.Var vars)
     
     parened = do
       (start, es, end) <- located (commaSep expr)
       return $ case es of
                  [e] -> e
-                 _   -> Location.at start end (tuple es)
+                 _   -> Annotation.at start end (tuple es)
 
-recordTerm :: IParser LParseExpr
+recordTerm :: IParser Source.Expr
 recordTerm = brackets $ choice [ misc, addLocation record ]
-    where field = do
-              label <- rLabel
-              patterns <- spacePrefix Pattern.term
-              padded equals
-              body <- expr
-              return (label, makeFunction patterns body)
+    where
+      field = do
+        label <- rLabel
+        patterns <- spacePrefix Pattern.term
+        padded equals
+        body <- expr
+        return (label, makeFunction patterns body)
               
-          record = Record <$> commaSep field
+      record = Record <$> commaSep field
 
-          change = do
-              lbl <- rLabel
-              padded (string "<-")
-              (,) lbl <$> expr
+      change = do
+        lbl <- rLabel
+        padded (string "<-")
+        (,) lbl <$> expr
 
-          remove r = addLocation (string "-" >> whitespace >> Remove r <$> rLabel)
+      remove r = addLocation (string "-" >> whitespace >> Remove r <$> rLabel)
 
-          insert r = addLocation $ do
-                       string "|" >> whitespace
-                       Insert r <$> rLabel <*> (padded equals >> expr)
+      insert r = addLocation $ do
+                   string "|" >> whitespace
+                   Insert r <$> rLabel <*> (padded equals >> expr)
 
-          modify r = addLocation
-                     (string "|" >> whitespace >> Modify r <$> commaSep1 change)
+      modify r =
+          addLocation (string "|" >> whitespace >> Modify r <$> commaSep1 change)
 
-          misc = try $ do
-            record <- addLocation (Var <$> rLabel)
-            opt <- padded (optionMaybe (remove record))
-            case opt of
-              Just e  -> try (insert e) <|> return e
-              Nothing -> try (insert record) <|> try (modify record)
+      misc = try $ do
+               record <- addLocation (rawVar <$> rLabel)
+               opt <- padded (optionMaybe (remove record))
+               case opt of
+                 Just e  -> try (insert e) <|> return e
+                 Nothing -> try (insert record) <|> try (modify record)
                         
 
-term :: IParser LParseExpr
+term :: IParser Source.Expr
 term =  addLocation (choice [ Literal <$> literal, listTerm, accessor, negative ])
     <|> accessible (addLocation varTerm <|> parensTerm <|> recordTerm)
     <?> "basic term (4, x, 'c', etc.)"
 
 --------  Applications  --------
 
-appExpr :: IParser LParseExpr
+appExpr :: IParser Source.Expr
 appExpr = do
   t <- term
   ts <- constrainedSpacePrefix term $ \str ->
             if null str then notFollowedBy (char '-') else return ()
   return $ case ts of
              [] -> t
-             _  -> foldl' (\f x -> Location.merge f x $ App f x) t ts
+             _  -> foldl' (\f x -> Annotation.merge f x $ App f x) t ts
 
 --------  Normal Expressions  --------
 
-binaryExpr :: IParser LParseExpr
+binaryExpr :: IParser Source.Expr
 binaryExpr = binops appExpr lastExpr anyOp
   where lastExpr = addLocation (choice [ ifExpr, letExpr, caseExpr ])
                 <|> lambdaExpr
 
-ifExpr :: IParser ParseExpr
+ifExpr :: IParser Source.Expr'
 ifExpr = reserved "if" >> whitespace >> (normal <|> multiIf)
     where
       normal = do
@@ -155,13 +165,13 @@
         whitespace <?> "an 'else' branch" ; reserved "else" <?> "an 'else' branch" ; whitespace
         elseBranch <- expr
         return $ MultiIf [(bool, thenBranch),
-                          (Location.sameAs elseBranch (Literal . Literal.Boolean $ True), elseBranch)]
+                          (Annotation.sameAs elseBranch (Literal . L.Boolean $ True), elseBranch)]
       multiIf = MultiIf <$> spaceSep1 iff
           where iff = do string "|" ; whitespace
                          b <- expr ; padded arrow
                          (,) b <$> expr
 
-lambdaExpr :: IParser LParseExpr
+lambdaExpr :: IParser Source.Expr
 lambdaExpr = do char '\\' <|> char '\x03BB' <?> "anonymous function"
                 whitespace
                 args <- spaceSep1 Pattern.term
@@ -169,17 +179,17 @@
                 body <- expr
                 return (makeFunction args body)
 
-defSet :: IParser [ParseDef]
+defSet :: IParser [Source.Def]
 defSet = block (do d <- def ; whitespace ; return d)
 
-letExpr :: IParser ParseExpr
+letExpr :: IParser Source.Expr'
 letExpr = do
   reserved "let" ; whitespace
   defs <- defSet
   padded (reserved "in")
   Let defs <$> expr
 
-caseExpr :: IParser ParseExpr
+caseExpr :: IParser Source.Expr'
 caseExpr = do
   reserved "case"; e <- padded expr; reserved "of"; whitespace
   Case e <$> (with <|> without)
@@ -189,50 +199,50 @@
           with    = brackets (semiSep1 (case_ <?> "cases { x -> ... }"))
           without = block (do c <- case_ ; whitespace ; return c)
 
-expr :: IParser LParseExpr
+expr :: IParser Source.Expr
 expr = addLocation (choice [ ifExpr, letExpr, caseExpr ])
     <|> lambdaExpr
     <|> binaryExpr 
     <?> "an expression"
 
-defStart :: IParser [Pattern]
+defStart :: IParser [P.RawPattern]
 defStart =
     choice [ do p1 <- try Pattern.term
                 infics p1 <|> func p1
-           , func =<< (PVar <$> parens symOp)
+           , func =<< (P.Var <$> parens symOp)
            , (:[]) <$> Pattern.expr
            ] <?> "the definition of a variable (x = ...)"
     where
       func pattern =
           case pattern of
-            PVar _ -> (pattern:) <$> spacePrefix Pattern.term
+            P.Var _ -> (pattern:) <$> spacePrefix Pattern.term
             _ -> do try (lookAhead (whitespace >> string "="))
                     return [pattern]
 
       infics p1 = do
         o:p <- try (whitespace >> anyOp)
         p2  <- (whitespace >> Pattern.term)
-        return $ if o == '`' then [ PVar $ takeWhile (/='`') p, p1, p2 ]
-                             else [ PVar (o:p), p1, p2 ]
+        return $ if o == '`' then [ P.Var $ takeWhile (/='`') p, p1, p2 ]
+                             else [ P.Var (o:p), p1, p2 ]
 
-makeFunction :: [Pattern] -> LParseExpr -> LParseExpr
-makeFunction args body@(L s _) =
-    foldr (\arg body' -> L s $ Lambda arg body') body args
+makeFunction :: [P.RawPattern] -> Source.Expr -> Source.Expr
+makeFunction args body@(A ann _) =
+    foldr (\arg body' -> A ann $ Lambda arg body') body args
 
-definition :: IParser ParseDef
+definition :: IParser Source.Def
 definition = withPos $ do
   (name:args) <- defStart
   padded equals
   body <- expr
-  return . Def name $ makeFunction args body
+  return . Source.Definition name $ makeFunction args body
 
-typeAnnotation :: IParser ParseDef
-typeAnnotation = TypeAnnotation <$> try start <*> Type.expr
+typeAnnotation :: IParser Source.Def
+typeAnnotation = Source.TypeAnnotation <$> try start <*> Type.expr
   where
     start = do
       v <- lowVar <|> parens symOp
       padded hasType
       return v
 
-def :: IParser ParseDef
+def :: IParser Source.Def
 def = typeAnnotation <|> definition
diff --git a/compiler/Parse/Helpers.hs b/compiler/Parse/Helpers.hs
--- a/compiler/Parse/Helpers.hs
+++ b/compiler/Parse/Helpers.hs
@@ -6,17 +6,21 @@
 import Control.Monad
 import Control.Monad.State
 import Data.Char (isUpper)
-import qualified Data.Set as Set
 import qualified Data.Map as Map
+import qualified Language.GLSL.Parser as GLP
+import Language.GLSL.Syntax as GLS
 import Text.Parsec hiding (newline,spaces,State)
 import Text.Parsec.Indent
 import qualified Text.Parsec.Token as T
 
-import SourceSyntax.Helpers as Help
-import SourceSyntax.Location as Location
-import SourceSyntax.Expression
-import SourceSyntax.PrettyPrint
-import SourceSyntax.Declaration (Assoc)
+import AST.Annotation as Annotation
+import AST.Declaration (Assoc)
+import AST.Expression.General
+import qualified AST.Expression.Source as Source
+import AST.Helpers as Help
+import AST.Literal as Literal
+import AST.PrettyPrint
+import qualified AST.Variable as Variable
 
 reserveds = [ "if", "then", "else"
             , "case", "of"
@@ -25,25 +29,8 @@
             , "module", "where"
             , "import", "as", "hiding", "open"
             , "export", "foreign"
-            , "deriving", "port" ]
-
-jsReserveds :: Set.Set String
-jsReserveds = Set.fromList
-    [ "null", "undefined", "Nan", "Infinity", "true", "false", "eval"
-    , "arguments", "int", "byte", "char", "goto", "long", "final", "float"
-    , "short", "double", "native", "throws", "boolean", "abstract", "volatile"
-    , "transient", "synchronized", "function", "break", "case", "catch"
-    , "continue", "debugger", "default", "delete", "do", "else", "finally"
-    , "for", "function", "if", "in", "instanceof", "new", "return", "switch"
-    , "this", "throw", "try", "typeof", "var", "void", "while", "with", "class"
-    , "const", "enum", "export", "extends", "import", "super", "implements"
-    , "interface", "let", "package", "private", "protected", "public"
-    , "static", "yield"
-    -- reserved by the Elm runtime system
-    , "Elm", "ElmRuntime"
-    , "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"
-    , "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9"
-    ]
+            , "deriving", "port"
+            ]
 
 expecting = flip (<?>)
 
@@ -78,9 +65,11 @@
 innerVarChar = alphaNum <|> char '_' <|> char '\'' <?> "" 
 
 makeVar :: IParser Char -> IParser String
-makeVar p = do v <- (:) <$> p <*> many innerVarChar
-               guard (v `notElem` reserveds)
-               return v
+makeVar p = do
+  v <- (:) <$> p <*> many innerVarChar
+  if v `elem` reserveds
+    then fail $ "unexpected keyword '" ++ v ++ "', variables cannot be keywords"
+    else return v
 
 reserved :: String -> IParser String
 reserved word =
@@ -168,7 +157,8 @@
                    char b <?> "closing '" ++ [b] ++ "'" ; return out
 
 surround a z name p = do
-  char a ; v <- padded p
+  char a
+  v <- padded p
   char z <?> unwords ["closing", name, show z]
   return v
 
@@ -181,10 +171,10 @@
 brackets :: IParser a -> IParser a
 brackets = surround '{' '}' "bracket"
 
-addLocation :: (Pretty a) => IParser a -> IParser (Location.Located a)
+addLocation :: (Pretty a) => IParser a -> IParser (Annotation.Located a)
 addLocation expr = do
   (start, e, end) <- located expr
-  return (Location.at start end e)
+  return (Annotation.at start end e)
 
 located :: IParser a -> IParser (SourcePos, a, SourcePos)
 located p = do
@@ -193,10 +183,10 @@
   end <- getPosition
   return (start, e, end)
 
-accessible :: IParser LParseExpr -> IParser LParseExpr
+accessible :: IParser Source.Expr -> IParser Source.Expr
 accessible expr = do
   start <- getPosition
-  ce@(L _ e) <- expr
+  ce@(A _ e) <- expr
   let rest f = do
         let dot = char '.' >> notFollowedBy (char '.')
         access <- optionMaybe (try dot <?> "field access (e.g. List.map)")
@@ -205,10 +195,12 @@
           Just _  -> accessible $ do
                        v <- var <?> "field access (e.g. List.map)"
                        end <- getPosition
-                       return (Location.at start end (f v))
-  case e of Var (c:cs) | isUpper c -> rest (\v -> Var (c:cs ++ '.':v))
-                       | otherwise -> rest (Access ce)
-            _ -> rest (Access ce)
+                       return (Annotation.at start end (f v))
+  case e of
+    Var (Variable.Raw (c:cs))
+        | isUpper c -> rest (\v -> rawVar (c:cs ++ '.':v))
+        | otherwise -> rest (Access ce)
+    _ -> rest (Access ce)
 
 
 spaces :: IParser String
@@ -268,7 +260,7 @@
       ignore p = const () <$> p
       filler = choice [ try (ignore chr) <|> ignore str
                       , ignore multiComment
-                      , ignore (markdown (\_ _ -> mzero))
+                      , ignore (markdown (\_ -> mzero))
                       , ignore anyChar
                       ]
       go = choice [ Just <$> end
@@ -301,16 +293,62 @@
                 True -> return []
                 False -> (:) <$> anyChar <*> go
 
-markdown :: (String -> [a] -> IParser (String, [a])) -> IParser (String, [a])
-markdown interpolation = try (string "[markdown|") >> closeMarkdown "" []
+markdown :: ([a] -> IParser (String, [a])) -> IParser (String, [a])
+markdown interpolation =
+    do try (string "[markdown|")
+       closeMarkdown id []
     where
-      closeMarkdown md stuff =
+      closeMarkdown markdownBuilder stuff =
           choice [ do try (string "|]")
-                      return (md, stuff)
-                 , uncurry closeMarkdown =<< interpolation md stuff
+                      return (markdownBuilder "", stuff)
+                 , do (markdown,stuff') <- interpolation stuff
+                      closeMarkdown (markdownBuilder . (markdown++)) stuff'
                  , do c <- anyChar
-                      closeMarkdown (md ++ [c]) stuff
+                      closeMarkdown (markdownBuilder . (c:)) stuff
                  ]
+
+shader :: IParser (String, Literal.GLShaderTipe)
+shader =
+  do try (string "[glsl|")
+     rawSrc <- closeShader id
+     case glSource rawSrc of
+       Left err -> parserFail . show $ err
+       Right tipe -> return (rawSrc, tipe)
+  where
+    closeShader builder = choice
+      [ do try (string "|]")
+           return (builder "")
+      , do c <- anyChar
+           closeShader (builder . (c:))
+      ]
+
+glSource :: String -> Either ParseError Literal.GLShaderTipe
+glSource src =
+  case GLP.parse src of
+    Right (TranslationUnit decls) ->
+      Right . foldr addGLinput emptyDecls . join . map extractGLinputs $ decls
+    Left e -> Left e
+  where 
+    emptyDecls = Literal.GLShaderTipe Map.empty Map.empty Map.empty
+    addGLinput (qual,tipe,name) glDecls = case qual of
+        Attribute -> glDecls { attribute = Map.insert name tipe $ attribute glDecls }
+        Uniform -> glDecls { uniform = Map.insert name tipe $ uniform glDecls }
+        Varying -> glDecls { varying = Map.insert name tipe $ varying glDecls }
+        _ -> error "Should never happen due to below filter"
+    extractGLinputs decl = case decl of
+        Declaration (InitDeclaration (TypeDeclarator (FullType (Just (TypeQualSto qual)) (TypeSpec _prec (TypeSpecNoPrecision tipe _mexpr1)))) [InitDecl name _mexpr2 _mexpr3]) ->
+            if elem qual [Attribute, Varying, Uniform] 
+            then case tipe of 
+                GLS.Int -> return (qual,Literal.Int,name)
+                GLS.Float -> return (qual,Literal.Float,name)
+                GLS.Vec2 -> return (qual,V2,name)
+                GLS.Vec3 -> return (qual,V3,name) 
+                GLS.Vec4 -> return (qual,V4,name)
+                GLS.Mat4 -> return (qual,M4,name)
+                GLS.Sampler2D -> return (qual,Texture,name)
+                _ -> []
+            else []
+        _ -> []
 
 --str :: IParser String
 str = expecting "String" $ do
diff --git a/compiler/Parse/Literal.hs b/compiler/Parse/Literal.hs
--- a/compiler/Parse/Literal.hs
+++ b/compiler/Parse/Literal.hs
@@ -1,22 +1,40 @@
-{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
+{-# OPTIONS_GHC -W #-}
 module Parse.Literal (literal) where
 
 import Control.Applicative ((<$>))
 import Text.Parsec hiding (newline,spaces)
 import Parse.Helpers
-import SourceSyntax.Literal
+import AST.Literal
 
 literal :: IParser Literal
-literal = num <|> (Str <$> str) <|> (Chr <$> chr)
+literal = num <|> (Str <$> str) <|> (Chr <$> chr) <?> "literal"
 
 num :: IParser Literal
-num = fmap toLit (preNum <?> "number")
-    where toLit n | '.' `elem` n = FloatNum (read n)
-                  | otherwise = IntNum (read n)
-          preNum  = concat <$> sequence [ option "" minus, many1 digit, option "" postNum ]
-          postNum = do try $ lookAhead (string "." >> digit)
-                       string "."
-                       ('.':) <$> many1 digit
-          minus = try $ do string "-"
-                           lookAhead digit
-                           return "-"
+num = toLit <$> (number <?> "number")
+  where
+    toLit n
+        | any (`elem` ".eE") n = FloatNum (read n)
+        | otherwise            = IntNum (read n)    
+
+    number = concat <$> sequence
+             [ option "" minus
+             , many1 digit
+             , option "" decimals
+             , option "" exponent ]
+
+    minus = try $ do
+              string "-"
+              lookAhead digit
+              return "-"
+
+    decimals = do
+      try $ lookAhead (string "." >> digit)
+      string "."
+      n <- many1 digit
+      return ('.' : n)
+
+    exponent = do
+      string "e" <|> string "E"
+      op <- option "" (string "+" <|> string "-")
+      n <- many1 digit
+      return ('e' : op ++ n)
diff --git a/compiler/Parse/Module.hs b/compiler/Parse/Module.hs
--- a/compiler/Parse/Module.hs
+++ b/compiler/Parse/Module.hs
@@ -5,10 +5,8 @@
 import Text.Parsec hiding (newline,spaces)
 
 import Parse.Helpers
-import SourceSyntax.Module (ImportMethod(..), Imports)
-
-varList ::  IParser [String]
-varList = parens $ commaSep1 (var <|> parens symOp)
+import AST.Module (ImportMethod(..))
+import AST.Variable (Listing(..), Value(..), openListing)
 
 getModuleName :: String -> Maybe String
 getModuleName source =
@@ -21,34 +19,58 @@
         (names, _) <- moduleDef
         return (intercalate "." names)
 
-moduleDef :: IParser ([String], [String])
+moduleDef :: IParser ([String], Listing Value)
 moduleDef = do
   try (reserved "module")
   whitespace
   names <- dotSep1 capVar <?> "name of module"
   whitespace
-  exports <- option [] varList
+  exports <- option (Listing [] True) (listing value)
   whitespace <?> "reserved word 'where'"
   reserved "where"
   return (names, exports)
 
-imports :: IParser Imports
+imports :: IParser [(String, ImportMethod)]
 imports = option [] ((:) <$> import' <*> many (try (freshLine >> import')))
 
 import' :: IParser (String, ImportMethod)
 import' =
   do reserved "import"
      whitespace
-     open <- optionMaybe (reserved "open")
-     whitespace
      name <- intercalate "." <$> dotSep1 capVar
-     case open of
-       Just _ -> return (name, Hiding [])
-       Nothing -> let how = try (whitespace >> (as' <|> importing'))
-                  in  (,) name <$> option (As name) how
+     (,) name <$> option (As name) method
   where
+    method :: IParser ImportMethod
+    method = as' <|> importing'
+
     as' :: IParser ImportMethod
-    as' = reserved "as" >> whitespace >> As <$> capVar <?> "alias for module"
+    as' = do
+      try (whitespace >> reserved "as")
+      whitespace
+      As <$> capVar <?> "alias for module"
 
     importing' :: IParser ImportMethod
-    importing' = Importing <$> varList <?> "listing of imported values (x,y,z)"
+    importing' = Open <$> listing value
+
+listing :: IParser a -> IParser (Listing a)
+listing item =
+  do try (whitespace >> char '(')
+     whitespace
+     listing <- choice [ const openListing <$> string ".."
+                       , Listing <$> commaSep1 item <*> return False
+                       ] <?> "listing of values (x,y,z)"
+     whitespace
+     char ')'
+     return listing
+
+value :: IParser Value
+value = val <|> tipe
+    where
+      val = Value <$> (lowVar <|> parens symOp)
+
+      tipe = do
+        name <- capVar
+        maybeCtors <- optionMaybe (listing capVar)
+        case maybeCtors of
+          Nothing -> return (Alias name)
+          Just ctors -> return (ADT name ctors)
diff --git a/compiler/Parse/Parse.hs b/compiler/Parse/Parse.hs
--- a/compiler/Parse/Parse.hs
+++ b/compiler/Parse/Parse.hs
@@ -7,8 +7,9 @@
 import Text.Parsec hiding (newline,spaces)
 import qualified Text.PrettyPrint as P
 
-import qualified SourceSyntax.Declaration as D
-import qualified SourceSyntax.Module as M
+import qualified AST.Declaration as D
+import qualified AST.Module as M
+import qualified AST.Variable as Var
 import Parse.Helpers
 import Parse.Declaration (infixDecl)
 import Parse.Module
@@ -22,21 +23,24 @@
 decls = do d <- Decl.declaration <?> "at least one datatype or variable definition"
            (d:) <$> many freshDef
 
-program :: OpTable -> String -> Either [P.Doc] (M.Module D.Declaration)
+program :: OpTable -> String -> Either [P.Doc] M.ValidModule
 program table src =
-    do (M.Module names exs ims parseDecls) <- setupParserWithTable table programParser src
-       decls <- either (\err -> Left [P.text err]) Right (combineAnnotations parseDecls)
-       return $ M.Module names exs ims decls
+    do (M.Module names filePath exs ims parseDecls) <-
+           setupParserWithTable table programParser src
+       decls <-
+           either (\err -> Left [P.text err]) Right (combineAnnotations parseDecls)
+       return $ M.Module names filePath exs ims decls
 
-programParser :: IParser (M.Module D.ParseDeclaration)
+programParser :: IParser M.SourceModule
 programParser =
     do optional freshLine
-       (names,exports) <- option (["Main"],[]) (moduleDef `followedBy` freshLine)
+       (names,exports) <-
+           option (["Main"], Var.openListing) (moduleDef `followedBy` freshLine)
        is <- (do try (lookAhead $ reserved "import")
                  imports `followedBy` freshLine) <|> return []
        declarations <- decls
        optional freshLine ; optional spaces ; eof
-       return $ M.Module names exports is declarations
+       return $ M.Module names "" exports is declarations
 
 dependencies :: String -> Either [P.Doc] (String, [String])
 dependencies =
diff --git a/compiler/Parse/Pattern.hs b/compiler/Parse/Pattern.hs
--- a/compiler/Parse/Pattern.hs
+++ b/compiler/Parse/Pattern.hs
@@ -3,57 +3,60 @@
 
 import Control.Applicative ((<$>))
 import Data.Char (isUpper)
-import Data.List (intercalate)
+import qualified Data.List as List
 import Text.Parsec hiding (newline,spaces,State)
 
 import Parse.Helpers
 import Parse.Literal
-import SourceSyntax.Literal
-import SourceSyntax.Pattern hiding (tuple, list)
-import qualified SourceSyntax.Pattern as Pattern
+import AST.Literal
+import qualified AST.Pattern as P
+import qualified AST.Variable as Var
 
-basic :: IParser Pattern
+basic :: IParser P.RawPattern
 basic = choice
-    [ char '_' >> return PAnything
+    [ char '_' >> return P.Anything
     , do v <- var
          return $ case v of
-                    "True"          -> PLiteral (Boolean True)
-                    "False"         -> PLiteral (Boolean False)
-                    c:_ | isUpper c -> PData v []
-                    _               -> PVar v
-    , PLiteral <$> literal
+                    "True"          -> P.Literal (Boolean True)
+                    "False"         -> P.Literal (Boolean False)
+                    c:_ | isUpper c -> P.Data (Var.Raw v) []
+                    _               -> P.Var v
+    , P.Literal <$> literal
     ]
 
-asPattern :: Pattern -> IParser Pattern
+asPattern :: P.RawPattern -> IParser P.RawPattern
 asPattern pattern = do
   var <- optionMaybe (try (whitespace >> reserved "as" >> whitespace >> lowVar))
   return $ case var of
-             Just v -> PAlias v pattern
+             Just v -> P.Alias v pattern
              Nothing -> pattern
 
-record :: IParser Pattern
-record = PRecord <$> brackets (commaSep1 lowVar)
+record :: IParser P.RawPattern
+record = P.Record <$> brackets (commaSep1 lowVar)
 
-tuple :: IParser Pattern
-tuple = do ps <- parens (commaSep expr)
-           return $ case ps of { [p] -> p; _ -> Pattern.tuple ps }
+tuple :: IParser P.RawPattern
+tuple = do
+  ps <- parens (commaSep expr)
+  return $ case ps of
+             [p] -> p
+             _ -> P.tuple ps
 
-list :: IParser Pattern
-list = Pattern.list <$> braces (commaSep expr)
+list :: IParser P.RawPattern
+list = P.list <$> braces (commaSep expr)
 
-term :: IParser Pattern
+term :: IParser P.RawPattern
 term =
      (choice [ record, tuple, list, basic ]) <?> "pattern"
 
-patternConstructor :: IParser Pattern
+patternConstructor :: IParser P.RawPattern
 patternConstructor = do
-  v <- intercalate "." <$> dotSep1 capVar
+  v <- List.intercalate "." <$> dotSep1 capVar
   case v of
-    "True"  -> return $ PLiteral (Boolean True)
-    "False" -> return $ PLiteral (Boolean False)
-    _       -> PData v <$> spacePrefix term
+    "True"  -> return $ P.Literal (Boolean True)
+    "False" -> return $ P.Literal (Boolean False)
+    _       -> P.Data (Var.Raw v) <$> spacePrefix term
 
-expr :: IParser Pattern
+expr :: IParser P.RawPattern
 expr = do
   patterns <- consSep1 (patternConstructor <|> term)
-  asPattern (foldr1 Pattern.cons patterns) <?> "pattern"
+  asPattern (foldr1 P.cons patterns) <?> "pattern"
diff --git a/compiler/Parse/Type.hs b/compiler/Parse/Type.hs
--- a/compiler/Parse/Type.hs
+++ b/compiler/Parse/Type.hs
@@ -5,22 +5,23 @@
 import Data.List (intercalate)
 import Text.Parsec
 
-import SourceSyntax.Type as T
+import qualified AST.Type as T
+import qualified AST.Variable as Var
 import Parse.Helpers
 
-tvar :: IParser T.Type
+tvar :: IParser T.RawType
 tvar = T.Var <$> lowVar <?> "type variable"
 
-list :: IParser T.Type
-list = listOf <$> braces expr
+list :: IParser T.RawType
+list = T.listOf <$> braces expr
 
-tuple :: IParser T.Type
+tuple :: IParser T.RawType
 tuple = do ts <- parens (commaSep expr)
            return $ case ts of
                       [t] -> t
-                      _   -> tupleOf ts
+                      _   -> T.tupleOf ts
 
-record :: IParser T.Type
+record :: IParser T.RawType
 record =
   do char '{' ; whitespace
      rcrd <- extended <|> normal
@@ -33,7 +34,7 @@
     extended = do
       ext <- try (lowVar <* (whitespace >> string "|"))
       whitespace
-      flip T.Record (Just ext) <$> commaSep1 field
+      flip T.Record (Just (T.Var ext)) <$> commaSep1 field
 
     field = do
       lbl <- rLabel
@@ -43,25 +44,28 @@
 capTypeVar :: IParser String
 capTypeVar = intercalate "." <$> dotSep1 capVar
 
-constructor0 :: IParser T.Type
+constructor0 :: IParser T.RawType
 constructor0 =
   do name <- capTypeVar
-     return (T.Data name [])
+     return (T.Type (Var.Raw name))
 
-term :: IParser T.Type
+term :: IParser T.RawType
 term = list <|> tuple <|> record <|> tvar <|> constructor0
 
-app :: IParser T.Type
+app :: IParser T.RawType
 app =
-  do name <- capTypeVar <|> try tupleCtor <?> "type constructor"
+  do f <- constructor0 <|> try tupleCtor <?> "type constructor"
      args <- spacePrefix term
-     return (T.Data name args)
+     return $ case args of
+                [] -> f
+                _  -> T.App f args
   where
     tupleCtor = do
       n <- length <$> parens (many (char ','))
-      return $ "_Tuple" ++ show (if n == 0 then 0 else n+1)
+      let ctor = "_Tuple" ++ show (if n == 0 then 0 else n+1)
+      return (T.Type (Var.Raw ctor))
 
-expr :: IParser T.Type
+expr :: IParser T.RawType
 expr =
   do t1 <- app <|> term
      arr <- optionMaybe $ try (whitespace >> arrow)
@@ -69,6 +73,6 @@
        Just _  -> T.Lambda t1 <$> (whitespace >> expr)
        Nothing -> return t1
 
-constructor :: IParser (String, [T.Type])
+constructor :: IParser (String, [T.RawType])
 constructor = (,) <$> (capTypeVar <?> "another type constructor")
                   <*> spacePrefix term
diff --git a/compiler/SourceSyntax/Declaration.hs b/compiler/SourceSyntax/Declaration.hs
deleted file mode 100644
--- a/compiler/SourceSyntax/Declaration.hs
+++ /dev/null
@@ -1,99 +0,0 @@
-{-# OPTIONS_GHC -Wall #-}
-module SourceSyntax.Declaration where
-
-import Data.Binary
-import qualified SourceSyntax.Expression as Expr
-import qualified SourceSyntax.Type as T
-import SourceSyntax.PrettyPrint
-import Text.PrettyPrint as P
-
-data Declaration' port def
-    = Definition def
-    | Datatype String [String] [(String,[T.Type])]
-    | TypeAlias String [String] T.Type
-    | Port port
-    | Fixity Assoc Int String
-      deriving (Show)
-
-data Assoc = L | N | R
-    deriving (Eq)
-
-data ParsePort
-    = PPAnnotation String T.Type
-    | PPDef String Expr.LParseExpr
-      deriving (Show)
-
-data Port
-    = Out String Expr.LExpr T.Type
-    | In String T.Type
-      deriving (Show)
-
-portName :: Port -> String
-portName port =
-    case port of
-      Out name _ _ -> name
-      In name _ -> name
-
-type ParseDeclaration = Declaration' ParsePort Expr.ParseDef
-type Declaration = Declaration' Port Expr.Def
-
-instance Show Assoc where
-    show assoc =
-        case assoc of
-          L -> "left"
-          N -> "non"
-          R -> "right"
-
-instance Binary Assoc where
-    get = do n <- getWord8
-             return $ case n of
-                0 -> L
-                1 -> N
-                2 -> R
-                _ -> error "Error reading valid associativity from serialized string"
-
-    put assoc = putWord8 $ case assoc of { L -> 0 ; N -> 1 ; R -> 2 }
-
-instance (Pretty port, Pretty def) => Pretty (Declaration' port def) where
-  pretty decl =
-    case decl of
-      Definition def -> pretty def
-
-      Datatype tipe tvars ctors ->
-          P.hang (P.text "data" <+> P.text tipe <+> P.hsep (map P.text tvars)) 4
-               (P.sep $ zipWith join ("=" : repeat "|") ctors)
-          where
-            join c ctor = P.text c <+> prettyCtor ctor
-            prettyCtor (name, tipes) =
-                P.hang (P.text name) 2 (P.sep (map T.prettyParens tipes))
-
-      TypeAlias name tvars tipe ->
-          P.hang (P.text "type" <+> name' <+> P.equals) 4 (pretty tipe)
-          where
-            name' = P.text name <+> P.hsep (map P.text tvars)
-
-      Port port -> pretty port
-
-      Fixity assoc prec op -> P.text "infix" <> assoc' <+> P.int prec <+> P.text op
-          where
-            assoc' = case assoc of
-                       L -> P.text "l"
-                       N -> P.empty
-                       R -> P.text "r"
-
-instance Pretty ParsePort where
-  pretty port =
-    case port of
-      PPAnnotation name tipe -> prettyPort name ":"  tipe
-      PPDef        name expr -> prettyPort name "=" expr
-
-instance Pretty Port where
-  pretty port =
-    case port of
-      In name tipe -> prettyPort name ":" tipe
-      Out name expr tipe -> P.vcat [ prettyPort name ":" tipe
-                                   , prettyPort name "=" expr ]
-          
-
-prettyPort :: (Pretty a) => String -> String -> a -> Doc
-prettyPort name op e = P.text "port" <+> P.text name <+> P.text op <+> pretty e
diff --git a/compiler/SourceSyntax/Expression.hs b/compiler/SourceSyntax/Expression.hs
deleted file mode 100644
--- a/compiler/SourceSyntax/Expression.hs
+++ /dev/null
@@ -1,203 +0,0 @@
-{-# OPTIONS_GHC -Wall #-}
-
-{-| The Abstract Syntax Tree (AST) for expressions comes in a couple formats.
-The first is the fully general version and is labeled with a prime (Expr').
-The others are specialized versions of the AST that represent specific phases
-of the compilation process. I expect there to be more phases as we begin to
-enrich the AST with more information.
--}
-module SourceSyntax.Expression where
-
-import SourceSyntax.PrettyPrint
-import Text.PrettyPrint as P
-import qualified SourceSyntax.Helpers as Help
-import qualified SourceSyntax.Location as Location
-import qualified SourceSyntax.Pattern as Pattern
-import qualified SourceSyntax.Type as SrcType
-import qualified SourceSyntax.Literal as Literal
-
----- GENERAL AST ----
-
-{-| This is a located expression, meaning it is tagged with info about where it
-came from in the source code. Expr' is defined in terms of LExpr' so that the
-location information does not need to be an extra field on every constructor.
--}
-type LExpr' def = Location.Located (Expr' def)
-
-{-| This is a fully general Abstract Syntax Tree (AST) for expressions. It has
-"type holes" that allow us to enrich the AST with additional information as we
-move through the compilation process. The type holes let us show these
-structural changes in the types. The only type hole right now is:
-
-  def: Parsing allows two kinds of definitions (type annotations or definitions),
-       but later checks will see that they are well formed and combine them.
-
--}
-data Expr' def
-    = Literal Literal.Literal
-    | Var String
-    | Range (LExpr' def) (LExpr' def)
-    | ExplicitList [LExpr' def]
-    | Binop String (LExpr' def) (LExpr' def)
-    | Lambda Pattern.Pattern (LExpr' def)
-    | App (LExpr' def) (LExpr' def)
-    | MultiIf [(LExpr' def,LExpr' def)]
-    | Let [def] (LExpr' def)
-    | Case (LExpr' def) [(Pattern.Pattern, LExpr' def)]
-    | Data String [LExpr' def]
-    | Access (LExpr' def) String
-    | Remove (LExpr' def) String
-    | Insert (LExpr' def) String (LExpr' def)
-    | Modify (LExpr' def) [(String, LExpr' def)]
-    | Record [(String, LExpr' def)]
-    | Markdown String String [LExpr' def]
-    -- for type checking and code gen only
-    | PortIn String SrcType.Type
-    | PortOut String SrcType.Type (LExpr' def)
-
-
----- SPECIALIZED ASTs ----
-
-{-| Expressions created by the parser. These use a split representation of type
-annotations and definitions, which is how they appear in source code and how
-they are parsed.
--}
-type ParseExpr = Expr' ParseDef
-type LParseExpr = LExpr' ParseDef
-
-data ParseDef
-    = Def Pattern.Pattern LParseExpr
-    | TypeAnnotation String SrcType.Type
-      deriving (Show)
-
-{-| "Normal" expressions. When the compiler checks that type annotations and
-ports are all paired with definitions in the appropriate order, it collapses
-them into a Def that is easier to work with in later phases of compilation.
--}
-type LExpr = LExpr' Def
-type Expr = Expr' Def
-
-data Def = Definition Pattern.Pattern LExpr (Maybe SrcType.Type)
-    deriving (Show)
-
-
----- UTILITIES ----
-
-tuple :: [LExpr' def] -> Expr' def
-tuple es = Data ("_Tuple" ++ show (length es)) es
-
-delist :: LExpr' def -> [LExpr' def]
-delist (Location.L _ (Data "::" [h,t])) = h : delist t
-delist _ = []
-
-saveEnvName :: String
-saveEnvName = "_save_the_environment!!!"
-
-dummyLet :: Pretty def => [def] -> LExpr' def
-dummyLet defs = 
-     Location.none $ Let defs (Location.none $ Var saveEnvName)
-
-instance Pretty def => Show (Expr' def) where
-  show = render . pretty
-
-instance Pretty def => Pretty (Expr' def) where
-  pretty expr =
-   case expr of
-     Literal lit -> pretty lit
-     Var x -> variable x
-     Range e1 e2 -> P.brackets (pretty e1 <> P.text ".." <> pretty e2)
-     ExplicitList es -> P.brackets (commaCat (map pretty es))
-     Binop "-" (Location.L _ (Literal (Literal.IntNum 0))) e ->
-         P.text "-" <> prettyParens e
-     Binop op e1 e2 -> P.sep [ prettyParens e1 <+> P.text op', prettyParens e2 ]
-         where op' = if Help.isOp op then op else "`" ++ op ++ "`"
-     Lambda p e -> P.text "\\" <> args <+> P.text "->" <+> pretty body
-         where
-           (ps,body) = collectLambdas (Location.none $ Lambda p e)
-           args = P.sep (map Pattern.prettyParens ps)
-     App _ _ -> P.hang func 2 (P.sep args)
-         where func:args = map prettyParens (collectApps (Location.none expr))
-     MultiIf branches ->  P.text "if" $$ nest 3 (vcat $ map iff branches)
-         where
-           iff (b,e) = P.text "|" <+> P.hang (pretty b <+> P.text "->") 2 (pretty e)
-     Let defs e ->
-         P.sep [ P.hang (P.text "let") 4 (P.vcat (map pretty defs))
-               , P.text "in" <+> pretty e ]
-     Case e pats ->
-         P.hang pexpr 2 (P.vcat (map pretty' pats))
-         where
-           pexpr = P.sep [ P.text "case" <+> pretty e, P.text "of" ]
-           pretty' (p,b) = pretty p <+> P.text "->" <+> pretty b
-     Data "::" [hd,tl] -> pretty hd <+> P.text "::" <+> pretty tl
-     Data "[]" [] -> P.text "[]"
-     Data name es
-         | Help.isTuple name -> P.parens (commaCat (map pretty es))
-         | otherwise -> P.hang (P.text name) 2 (P.sep (map prettyParens es))
-     Access e x -> prettyParens e <> P.text "." <> variable x
-     Remove e x -> P.braces (pretty e <+> P.text "-" <+> variable x)
-     Insert (Location.L _ (Remove e y)) x v ->
-         P.braces (pretty e <+> P.text "-" <+> variable y <+> P.text "|" <+> variable x <+> P.equals <+> pretty v)
-     Insert e x v ->
-         P.braces (pretty e <+> P.text "|" <+> variable x <+> P.equals <+> pretty v)
-
-     Modify e fs ->
-         P.braces $ P.hang (pretty e <+> P.text "|")
-                           4
-                           (commaSep $ map field fs)
-       where
-         field (k,v) = variable k <+> P.text "<-" <+> pretty v
-
-     Record fs ->
-         P.braces $ P.nest 2 (commaSep $ map field fs)
-       where
-         field (x,e) = variable x <+> P.equals <+> pretty e
-
-     Markdown _ _ _ -> P.text "[markdown| ... |]"
-
-     PortIn name _ -> P.text $ "<port:" ++ name ++ ">"
-
-     PortOut _ _ signal -> pretty signal
-
-instance Pretty ParseDef where
-  pretty def =
-   case def of
-     TypeAnnotation name tipe ->
-         variable name <+> P.colon <+> pretty tipe
-     Def pattern expr ->
-         pretty pattern <+> P.equals <+> pretty expr
-
-instance Pretty Def where
-  pretty (Definition pattern expr maybeTipe) =
-      P.vcat [ annotation, definition ]
-      where
-        definition = pretty pattern <+> P.equals <+> pretty expr
-        annotation = case maybeTipe of
-                       Nothing -> P.empty
-                       Just tipe -> pretty pattern <+> P.colon <+> pretty tipe
-
-collectApps :: LExpr' def -> [LExpr' def]
-collectApps lexpr@(Location.L _ expr) =
-  case expr of
-    App a b -> collectApps a ++ [b]
-    _ -> [lexpr]
-
-collectLambdas :: LExpr' def -> ([Pattern.Pattern], LExpr' def)
-collectLambdas lexpr@(Location.L _ expr) =
-  case expr of
-    Lambda pattern body -> (pattern : ps, body')
-        where (ps, body') = collectLambdas body
-    _ -> ([], lexpr)
-
-prettyParens :: (Pretty def) => LExpr' def -> Doc
-prettyParens (Location.L _ expr) = parensIf needed (pretty expr)
-  where
-    needed =
-      case expr of
-        Binop _ _ _ -> True
-        Lambda _ _  -> True
-        App _ _     -> True
-        MultiIf _   -> True
-        Let _ _     -> True
-        Case _ _    -> True
-        Data name (_:_) -> name /= "::"
-        _ -> False
diff --git a/compiler/SourceSyntax/Helpers.hs b/compiler/SourceSyntax/Helpers.hs
deleted file mode 100644
--- a/compiler/SourceSyntax/Helpers.hs
+++ /dev/null
@@ -1,18 +0,0 @@
-{-# OPTIONS_GHC -Wall #-}
-module SourceSyntax.Helpers where
-
-import qualified Data.Char as Char
-
-brkt :: String -> String
-brkt s = "{ " ++ s ++ " }"
-
-isTuple :: String -> Bool
-isTuple name =
-    take 6 name == "_Tuple" && all Char.isDigit (drop 6 name)
-
-isOp :: String -> Bool
-isOp = all isSymbol
-
-isSymbol :: Char -> Bool
-isSymbol c =
-    Char.isSymbol c || elem c "+-/*=.$<>:&|^?%#@~!"
diff --git a/compiler/SourceSyntax/Literal.hs b/compiler/SourceSyntax/Literal.hs
deleted file mode 100644
--- a/compiler/SourceSyntax/Literal.hs
+++ /dev/null
@@ -1,21 +0,0 @@
-{-# OPTIONS_GHC -Wall #-}
-module SourceSyntax.Literal where
-
-import SourceSyntax.PrettyPrint
-import qualified Text.PrettyPrint as PP
-
-data Literal = IntNum Int
-             | FloatNum Double
-             | Chr Char
-             | Str String
-             | Boolean Bool
-             deriving (Eq, Ord, Show)
-
-instance Pretty Literal where
-  pretty literal =
-    case literal of
-      IntNum n -> PP.int n
-      FloatNum n -> PP.double n
-      Chr c -> PP.text . show $ c
-      Str s -> PP.text . show $ s
-      Boolean bool -> PP.text (show bool)
diff --git a/compiler/SourceSyntax/Location.hs b/compiler/SourceSyntax/Location.hs
deleted file mode 100644
--- a/compiler/SourceSyntax/Location.hs
+++ /dev/null
@@ -1,58 +0,0 @@
-module SourceSyntax.Location where
-
-import Text.PrettyPrint
-import SourceSyntax.PrettyPrint
-import qualified Text.Parsec.Pos as Parsec
-
-data SrcPos = Pos { line :: Int, column :: Int }
-    deriving (Eq, Ord)
-
-data SrcSpan = Span SrcPos SrcPos String | NoSpan String
-    deriving (Eq, Ord)
-
-data Located e = L SrcSpan e
-    deriving (Eq, Ord)
-
-none e = L (NoSpan (render $ pretty e)) e
-noneNoDocs = L (NoSpan "")
-
-at start end e = L (Span (Pos (Parsec.sourceLine start) (Parsec.sourceColumn start))
-                         (Pos (Parsec.sourceLine end  ) (Parsec.sourceColumn end  ))
-                         (render $ pretty e)) e
-
-merge (L s1 _) (L s2 _) e = L (span (render $ pretty e)) e
-    where span = case (s1,s2) of
-                   (Span start _ _, Span _ end _) -> Span start end
-                   (Span start end _, _) -> Span start end
-                   (_, Span start end _) -> Span start end
-                   (_, _) -> NoSpan
-
-mergeOldDocs (L s1 _) (L s2 _) e = L span e
-    where span = case (s1,s2) of
-                   (Span start _ d1, Span _ end d2) -> Span start end (d1 ++ "\n\n" ++ d2)
-                   (Span _ _ _, _) -> s1
-                   (_, Span _ _ _) -> s2
-                   (_, _) -> NoSpan ""
-
-sameAs (L s _) = L s
-
-
-instance Show SrcPos where
-    show (Pos r c) = show r ++ "," ++ show c
-
-instance Show SrcSpan where
-  show span = 
-      case span of
-        NoSpan _ -> ""
-        Span start end _ ->
-            case line start == line end of
-              False -> "between lines " ++ show (line start) ++ " and " ++ show (line end)
-              True -> "on line " ++ show (line end) ++ ", column " ++
-                      show (column start) ++ " to " ++ show (column end)
-
-instance Show e => Show (Located e) where
-  show (L _ e) = show e
-
-instance Pretty a => Pretty (Located a) where
-  pretty (L _ e) = pretty e
-
diff --git a/compiler/SourceSyntax/Module.hs b/compiler/SourceSyntax/Module.hs
deleted file mode 100644
--- a/compiler/SourceSyntax/Module.hs
+++ /dev/null
@@ -1,89 +0,0 @@
-{-# OPTIONS_GHC -Wall #-}
-module SourceSyntax.Module where
-
-import Data.Binary
-import qualified Data.Map as Map
-import Control.Applicative ((<$>), (<*>))
-
-import SourceSyntax.Expression (LExpr)
-import SourceSyntax.Declaration
-import SourceSyntax.Type
-
-import qualified Elm.Internal.Version as Version
-
-data Module def =
-    Module [String] Exports Imports [def]
-    deriving (Show)
-
-type Exports = [String]
-
-type Imports = [(String, ImportMethod)]
-data ImportMethod = As String | Importing [String] | Hiding [String]
-                    deriving (Eq, Ord, Show)
-
-instance Binary ImportMethod where
-    put method =
-        let put' n info = putWord8 n >> put info in
-        case method of
-          As s         -> put' 0 s
-          Importing ss -> put' 1 ss
-          Hiding ss    -> put' 2 ss
-
-    get = do tag <- getWord8
-             case tag of
-               0 -> As        <$> get
-               1 -> Importing <$> get
-               2 -> Hiding    <$> get
-               _ -> error "Error reading valid ImportMethod type from serialized string"
-
-data MetadataModule =
-    MetadataModule
-    { names     :: [String]
-    , path      :: FilePath
-    , exports   :: [String]
-    , imports   :: [(String, ImportMethod)]
-    , program   :: LExpr
-    , types     :: Map.Map String Type
-    , fixities  :: [(Assoc, Int, String)]
-    , aliases   :: [Alias]
-    , datatypes :: [ADT]
-    , ports     :: [String]
-    } deriving Show
-
-type Interfaces = Map.Map String ModuleInterface
-type ADT = (String, [String], [(String,[Type])])
-type Alias = (String, [String], Type)
-
-data ModuleInterface =
-    ModuleInterface
-    { iVersion  :: Version.Version
-    , iTypes    :: Map.Map String Type
-    , iImports  :: [(String, ImportMethod)]
-    , iAdts     :: [ADT]
-    , iAliases  :: [Alias]
-    , iFixities :: [(Assoc, Int, String)]
-    , iPorts    :: [String]
-    } deriving Show
-
-metaToInterface :: MetadataModule -> ModuleInterface
-metaToInterface metaModule =
-    ModuleInterface
-    { iVersion  = Version.elmVersion
-    , iTypes    = types metaModule
-    , iImports  = imports metaModule
-    , iAdts     = datatypes metaModule
-    , iAliases  = aliases metaModule
-    , iFixities = fixities metaModule
-    , iPorts = ports metaModule
-    }
-
-instance Binary ModuleInterface where
-  get = ModuleInterface <$> get <*> get <*> get <*> get <*> get <*> get <*> get
-  put modul = do
-      put (iVersion modul)
-      put (iTypes modul)
-      put (iImports modul)
-      put (iAdts modul)
-      put (iAliases modul)
-      put (iFixities modul)
-      put (iPorts modul)
diff --git a/compiler/SourceSyntax/Pattern.hs b/compiler/SourceSyntax/Pattern.hs
deleted file mode 100644
--- a/compiler/SourceSyntax/Pattern.hs
+++ /dev/null
@@ -1,65 +0,0 @@
-{-# OPTIONS_GHC -Wall #-}
-module SourceSyntax.Pattern where
-
-import qualified SourceSyntax.Helpers as Help
-import SourceSyntax.PrettyPrint
-import Text.PrettyPrint as PP
-import qualified Data.Set as Set
-import SourceSyntax.Literal as Literal
-
-data Pattern = PData String [Pattern]
-             | PRecord [String]
-             | PAlias String Pattern
-             | PVar String
-             | PAnything
-             | PLiteral Literal.Literal
-               deriving (Eq, Ord, Show)
-
-cons :: Pattern -> Pattern -> Pattern
-cons h t = PData "::" [h,t]
-
-nil :: Pattern
-nil = PData "[]" []
-
-list :: [Pattern] -> Pattern
-list     = foldr cons nil
-
-tuple :: [Pattern] -> Pattern
-tuple es = PData ("_Tuple" ++ show (length es)) es
-
-boundVars :: Pattern -> Set.Set String
-boundVars pattern =
-    case pattern of
-      PVar x -> Set.singleton x
-      PAlias x p -> Set.insert x (boundVars p)
-      PData _ ps -> Set.unions (map boundVars ps)
-      PRecord fields -> Set.fromList fields
-      PAnything -> Set.empty
-      PLiteral _ -> Set.empty
-
-
-instance Pretty Pattern where
-  pretty pattern =
-   case pattern of
-     PVar x -> variable x
-     PLiteral lit -> pretty lit
-     PRecord fs -> PP.braces (commaCat $ map variable fs)
-     PAlias x p -> prettyParens p <+> PP.text "as" <+> variable x
-     PAnything -> PP.text "_"
-     PData "::" [hd,tl] -> parensIf isCons (pretty hd) <+> PP.text "::" <+> pretty tl
-       where isCons = case hd of
-                        PData "::" _ -> True
-                        _ -> False
-     PData name ps ->
-        if Help.isTuple name then
-            PP.parens . commaCat $ map pretty ps
-        else hsep (PP.text name : map prettyParens ps)
-
-prettyParens :: Pattern -> Doc
-prettyParens pattern = parensIf needsThem (pretty pattern)
-  where
-    needsThem =
-      case pattern of
-        PData name (_:_) | not (Help.isTuple name) -> True
-        PAlias _ _ -> True
-        _ -> False
diff --git a/compiler/SourceSyntax/PrettyPrint.hs b/compiler/SourceSyntax/PrettyPrint.hs
deleted file mode 100644
--- a/compiler/SourceSyntax/PrettyPrint.hs
+++ /dev/null
@@ -1,34 +0,0 @@
-
-module SourceSyntax.PrettyPrint where
-
-import Text.PrettyPrint
-import qualified SourceSyntax.Helpers as Help
-
-class Pretty a where
-  pretty :: a -> Doc
-
-instance Pretty () where
-  pretty () = empty
-
-commaCat docs = cat (punctuate comma docs)
-commaSep docs = sep (punctuate comma docs)
-
-parensIf bool doc = if bool then parens doc else doc
-
-variable x =
-    if Help.isOp x then parens (text x)
-                   else text (reprime x)
-
-reprime :: String -> String
-reprime = map (\c -> if c == '$' then '\'' else c)
-
-eightyCharLines :: Int -> String -> String
-eightyCharLines indent message = answer
-    where
-      (answer,_,_) = foldl step (spaces, indent-1, "") chunks
-
-      chunks = map (\w -> (w, length w)) (words message)
-      spaces = replicate indent ' '
-      step (sentence, slen, space) (word, wlen)
-          | slen + wlen > 79 = (sentence ++ "\n" ++ spaces ++ word, indent + wlen, " ")
-          | otherwise        = (sentence ++ space ++ word, slen + wlen + length space, " ")
diff --git a/compiler/SourceSyntax/Type.hs b/compiler/SourceSyntax/Type.hs
deleted file mode 100644
--- a/compiler/SourceSyntax/Type.hs
+++ /dev/null
@@ -1,92 +0,0 @@
-{-# OPTIONS_GHC -W #-}
-module SourceSyntax.Type where
-
-import Data.Binary
-import qualified Data.Map as Map
-import qualified SourceSyntax.Helpers as Help
-import Control.Applicative ((<$>), (<*>))
-import SourceSyntax.PrettyPrint
-import Text.PrettyPrint as P
-
-data Type = Lambda Type Type
-          | Var String
-          | Data String [Type]
-          | Record [(String,Type)] (Maybe String)
-            deriving (Eq)
-
-fieldMap :: [(String,a)] -> Map.Map String [a]
-fieldMap fields =
-    foldl (\r (x,t) -> Map.insertWith (++) x [t] r) Map.empty fields
-
-recordOf :: [(String,Type)] -> Type
-recordOf fields = Record fields Nothing
-
-listOf :: Type -> Type
-listOf t = Data "_List" [t]
-
-tupleOf :: [Type] -> Type
-tupleOf ts = Data ("_Tuple" ++ show (length ts)) ts
-
-instance Show Type where
-  show = render . pretty
-
-instance Pretty Type where
-  pretty tipe =
-    case tipe of
-      Lambda _ _ -> P.sep [ t, P.sep (map (P.text "->" <+>) ts) ]
-        where
-          t:ts = map prettyLambda (collectLambdas tipe)
-          prettyLambda t = case t of
-                             Lambda _ _ -> P.parens (pretty t)
-                             _ -> pretty t
-
-      Var x -> P.text x
-      Data "_List" [t] -> P.brackets (pretty t)
-      Data name tipes
-          | Help.isTuple name -> P.parens . P.sep . P.punctuate P.comma $ map pretty tipes
-          | otherwise -> P.hang (P.text name) 2 (P.sep $ map prettyParens tipes)
-      Record fields ext ->
-          P.braces $ case ext of
-                       Nothing -> prettyFields
-                       Just x -> P.hang (P.text x <+> P.text "|") 4 prettyFields
-          where
-            prettyField (f,t) = P.text f <+> P.text ":" <+> pretty t
-            prettyFields = commaSep . map prettyField $ fields
-
-collectLambdas :: Type -> [Type]
-collectLambdas tipe =
-  case tipe of
-    Lambda arg body -> arg : collectLambdas body
-    _ -> [tipe]
-
-prettyParens :: Type -> Doc
-prettyParens tipe = parensIf needed (pretty tipe)
-  where
-    needed =
-      case tipe of
-        Lambda _ _ -> True
-        Data "_List" [_] -> False
-        Data _ [] -> False
-        Data _ _ -> True
-        _ -> False
-
-instance Binary Type where
-  put tipe =
-      case tipe of
-        Lambda t1 t2 ->
-            putWord8 0 >> put t1 >> put t2
-        Var x ->
-            putWord8 1 >> put x
-        Data ctor tipes ->
-            putWord8 2 >> put ctor >> put tipes
-        Record fs ext ->
-            putWord8 3 >> put fs >> put ext
-
-  get = do
-      n <- getWord8
-      case n of
-        0 -> Lambda <$> get <*> get
-        1 -> Var <$> get
-        2 -> Data <$> get <*> get
-        3 -> Record <$> get <*> get
-        _ -> error "Error reading a valid type from serialized string"
diff --git a/compiler/Transform/Canonicalize.hs b/compiler/Transform/Canonicalize.hs
--- a/compiler/Transform/Canonicalize.hs
+++ b/compiler/Transform/Canonicalize.hs
@@ -1,183 +1,276 @@
 {-# OPTIONS_GHC -W #-}
-module Transform.Canonicalize (interface, metadataModule) where
+module Transform.Canonicalize (module') where
 
-import Control.Arrow ((***))
-import Control.Applicative (Applicative,(<$>),(<*>))
-import Control.Monad.Identity
-import qualified Data.Traversable as T
+import Control.Applicative ((<$>),(<*>))
+import Control.Monad.Error (runErrorT, throwError)
+import Control.Monad.State (runState)
+import qualified Data.List as List
 import qualified Data.Map as Map
 import qualified Data.Set as Set
-import qualified Data.List as List
-import qualified Data.Either as Either
-import SourceSyntax.Module
-import SourceSyntax.Expression
-import SourceSyntax.Location as Loc
-import qualified SourceSyntax.Pattern as P
-import qualified SourceSyntax.Type as Type
+import qualified Data.Traversable as T
+
+import AST.Expression.General (Expr'(..), dummyLet)
+import qualified AST.Expression.Valid as Valid
+import qualified AST.Expression.Canonical as Canonical
+
+import AST.Module (CanonicalBody(..))
+import qualified AST.Module as Module
+import qualified AST.Type as Type
+import qualified AST.Variable as Var
+import qualified AST.Annotation as A
+import qualified AST.Declaration as D
+import AST.PrettyPrint (pretty, commaSep)
+import qualified AST.Pattern as P
 import Text.PrettyPrint as P
 
-interface :: String -> ModuleInterface -> ModuleInterface
-interface moduleName iface =
-    ModuleInterface
-    { iVersion = iVersion iface
-    , iTypes = Map.mapKeys prefix (Map.map renameType' (iTypes iface))
-    , iImports = iImports iface
-    , iAdts = map (both prefix renameCtors) (iAdts iface)
-    , iAliases = map (both prefix renameType') (iAliases iface)
-    , iFixities = iFixities iface -- cannot have canonicalized operators while parsing
-    , iPorts = iPorts iface
-    }
+import Transform.Canonicalize.Environment as Env
+import qualified Transform.Canonicalize.Setup as Setup
+import qualified Transform.Canonicalize.Type as Canonicalize
+import qualified Transform.Canonicalize.Variable as Canonicalize
+import qualified Transform.SortDefinitions as Transform
+import qualified Transform.Declaration as Transform
+
+module' :: Module.Interfaces -> Module.ValidModule -> Either [Doc] Module.CanonicalModule
+module' interfaces modul =
+    filterImports <$> modul'
   where
-    both f g (a,b,c) = (f a, b, g c)
-    prefix name = moduleName ++ "." ++ name
+    (modul', usedModules) =
+        runState (runErrorT (moduleHelp interfaces modul)) Set.empty
 
-    pair name = (name, moduleName ++ "." ++ name)
-    canon (name,_,_) = pair name
-    canons = Map.fromList $ concat
-             [ map canon (iAdts iface), map canon (iAliases iface) ]
+    filterImports m =
+        let used (name,_) = Set.member name usedModules
+        in  m { Module.imports = filter used (Module.imports m) }
 
-    renameCtors ctors =
-        map (prefix *** map renameType') ctors
-    renameType' =
-        runIdentity . renameType (\name -> return $ Map.findWithDefault name name canons)
+moduleHelp :: Module.Interfaces -> Module.ValidModule
+           -> Canonicalizer [Doc] Module.CanonicalModule
+moduleHelp interfaces modul@(Module.Module _ _ exports _ decls) =
+  do env <- Setup.environment interfaces modul
+     canonicalDecls <- mapM (declaration env) decls
+     exports' <- resolveExports locals exports
+     return $ modul { Module.exports = exports'
+                    , Module.body    = body canonicalDecls
+                    }
+  where
+    locals :: [Var.Value]
+    locals = concatMap declToValue decls
 
-renameType :: (Applicative m, Monad m) => (String -> m String) -> Type.Type -> m Type.Type
-renameType renamer tipe =
-    let rnm = renameType renamer in
-    case tipe of
-      Type.Lambda a b -> Type.Lambda <$> rnm a <*> rnm b
-      Type.Var _ -> return tipe
-      Type.Data name ts -> Type.Data <$> renamer name <*> mapM rnm ts
-      Type.Record fields ext -> Type.Record <$> mapM rnm' fields <*> return ext
-          where rnm' (f,t) = (,) f <$> rnm t
+    body :: [D.CanonicalDecl] -> Module.CanonicalBody
+    body decls =
+      Module.CanonicalBody
+         { program =
+               let expr = Transform.toExpr (Module.getName modul) decls
+               in  Transform.sortDefs (dummyLet expr)
+         , types = Map.empty
+         , datatypes =
+             Map.fromList [ (name,(vars,ctors)) | D.Datatype name vars ctors <- decls ]
+         , fixities =
+             [ (assoc,level,op) | D.Fixity assoc level op <- decls ]
+         , aliases =
+             Map.fromList [ (name,(tvs,alias)) | D.TypeAlias name tvs alias <- decls ]
+         , ports =
+             [ D.portName port | D.Port port <- decls ]
+         }
 
-metadataModule :: Interfaces -> MetadataModule -> Either [Doc] MetadataModule
-metadataModule ifaces modul =
-  do case filter (\m -> Map.notMember m ifaces) (map fst realImports) of
-       [] -> Right ()
-       missings -> Left [ P.text $ "The following imports were not found: " ++ List.intercalate ", " missings ]
-     program' <- rename initialEnv (program modul)
-     aliases' <- mapM (three3 renameType') (aliases modul)
-     datatypes' <- mapM (three3 (mapM (two2 (mapM renameType')))) (datatypes modul)
-     return $ modul { program = program'
-                    , aliases = aliases'
-                    , datatypes = datatypes' }
-  where
-    two2 f (a,b) = (,) a <$> f b
-    three3 f (a,b,c) = (,,) a b <$> f c
-    renameType' =
-        Either.either (\err -> Left [P.text err]) return . renameType (replace "type" initialEnv)
+resolveExports :: [Var.Value] -> Var.Listing Var.Value -> Canonicalizer [Doc] [Var.Value]
+resolveExports fullList (Var.Listing partialList open) =
+    if open
+      then return fullList
+      else do
+        valueExports <- getValueExports
+        aliasExports <- concat `fmap` mapM getAliasExport aliases
+        adtExports <- mapM getAdtExport adts
+        return $ valueExports ++ aliasExports ++ adtExports
+    where
+      (allValues, allAliases, allAdts) = splitValues fullList
 
-    get1 (a,_,_) = a
-    canon (name, importMethod) =
-        let pair pre var = (pre ++ drop (length name + 1) var, var)
-            iface = ifaces Map.! name
-            allNames = concat [ Map.keys (iTypes iface)
-                              , map get1 (iAliases iface)
-                              , concat [ n : map fst ctors | (n,_,ctors) <- iAdts iface ] ]
-        in  case importMethod of
-              As alias -> map (pair (alias ++ ".")) allNames
-              Hiding vars -> map (pair "") $ filter (flip Set.notMember vs) allNames
-                  where vs = Set.fromList vars
-              Importing vars -> map (pair "") $ filter (flip Set.member vs) allNames
-                  where vs = Set.fromList $ map (\v -> name ++ "." ++ v) vars
+      (values, aliases, adts) = splitValues partialList
 
-    two n = (n,n)
-    localEnv = map two (map get1 (aliases modul) ++ map get1 (datatypes modul))
-    globalEnv =
-        map two $ ["_List",saveEnvName,"::","[]","Int","Float","Char","Bool","String"] ++
-                  map (\n -> "_Tuple" ++ show (n :: Int)) [0..9]
-    realImports = filter (not . List.isPrefixOf "Native." . fst) (imports modul)
-    initialEnv = Map.fromList (concatMap canon realImports ++ localEnv ++ globalEnv)
+      getValueExports =
+        case Set.toList (Set.difference values' allValues') of
+          [] -> return (map Var.Value values)
+          xs -> notFound xs
+        where
+          allValues' = Set.fromList allValues
+          values' = Set.fromList values
 
-type Env = Map.Map String String
+      getAliasExport alias
+          | alias `elem` allAliases =
+              let recordConstructor =
+                      if alias `elem` allValues then [Var.Value alias] else []
+              in
+                  return $ Var.Alias alias : recordConstructor
 
-extend :: Env -> P.Pattern -> Env
-extend env pattern = Map.union (Map.fromList (zip xs xs)) env
-    where xs = Set.toList (P.boundVars pattern)
+          | otherwise =
+              case List.find (\(name, _ctors) -> name == alias) allAdts of
+                Nothing -> notFound [alias]
+                Just (name, _ctor) ->
+                    return [Var.ADT name (Var.Listing [] False)]
 
+      getAdtExport (name, Var.Listing ctors open) =
+        case lookup name allAdts of
+          Nothing -> notFound [name]
+          Just (Var.Listing allCtors _)
+            | open -> return $ Var.ADT name (Var.Listing allCtors False)
+            | otherwise ->
+                case filter (`notElem` allCtors) ctors of
+                  [] -> return $ Var.ADT name (Var.Listing ctors False)
+                  unfoundCtors -> notFound unfoundCtors
 
-replace :: String -> Env -> String -> Either String String
-replace variable env v =
-    if List.isPrefixOf "Native." v then return v else
-    case Map.lookup v env of
-      Just v' -> return v'
-      Nothing -> Left $ "Could not find " ++ variable ++ " '" ++ v ++ "'." ++ msg
+      notFound xs =
+          throwError [ P.text "Export Error: trying to export non-existent values:" <+>
+                       commaSep (map pretty xs)
+                     ]
+
+{-| Split a list of values into categories so we can work with them
+independently.
+-}
+splitValues :: [Var.Value] -> ([String], [String], [(String, Var.Listing String)])
+splitValues mixedValues =
+  case mixedValues of
+    [] -> ([], [], [])
+    x:xs ->
+      let (values, aliases, adts) = splitValues xs in
+      case x of
+        Var.Value name -> (name : values, aliases, adts)
+        Var.Alias name -> (values, name : aliases, adts)
+        Var.ADT name listing ->
+            (values, aliases, (name, listing) : adts)
+
+
+
+declToValue :: D.ValidDecl -> [Var.Value]
+declToValue decl =
+    case decl of
+      D.Definition (Valid.Definition pattern _ _) ->
+          map Var.Value (P.boundVarList pattern)
+
+      D.Datatype name _tvs ctors ->
+          [ Var.ADT name (Var.Listing (map fst ctors) False) ]
+
+      D.TypeAlias name _ tipe ->
+          case tipe of
+            Type.Record _ _ ->
+                [ Var.Alias name, Var.Value name ]
+            _ -> [ Var.Alias name ]
+
+      _ -> []
+
+declaration :: Environment -> D.ValidDecl -> Canonicalizer [Doc] D.CanonicalDecl
+declaration env decl =
+    let canonicalize kind context pattern env v =
+            let ctx = P.text ("Error in " ++ context) <+> pretty pattern <> P.colon
+                throw err = P.vcat [ ctx, P.text err ]
+            in 
+                Env.onError throw (kind env v)
+    in
+    case decl of
+      D.Definition (Valid.Definition p e t) ->
+          do p' <- canonicalize pattern "definition" p env p
+             e' <- expression env e
+             t' <- T.traverse (canonicalize Canonicalize.tipe "definition" p env) t
+             return $ D.Definition (Canonical.Definition p' e' t')
+
+      D.Datatype name tvars ctors ->
+          D.Datatype name tvars <$> mapM canonicalize' ctors
           where
-            matches = filter (List.isInfixOf v) (Map.keys env)
-            msg = if null matches then "" else
-                      "\nClose matches include: " ++ List.intercalate ", " matches
+            canonicalize' (ctor,args) =
+                (,) ctor <$> mapM (canonicalize Canonicalize.tipe "datatype" name env) args
 
-rename :: Env -> LExpr -> Either [Doc] LExpr
-rename env (L s expr) =
-    let rnm = rename env
-        throw err = Left [ P.text $ "Error " ++ show s ++ "\n" ++ err ]
-        format = Either.either throw return
-        renameType' env = renameType (format . replace "variable" env)
+      D.TypeAlias name tvars expanded ->
+          do expanded' <- canonicalize Canonicalize.tipe "type alias" name env expanded
+             return (D.TypeAlias name tvars expanded')
+
+      D.Port port -> do
+          Env.uses "Native.Ports"
+          Env.uses "Native.Json"
+          D.Port <$> case port of
+                       D.In name t ->
+                           do t' <- canonicalize Canonicalize.tipe "port" name env t
+                              return (D.In name t')
+                       D.Out name e t ->
+                           do e' <- expression env e
+                              t' <- canonicalize Canonicalize.tipe "port" name env t
+                              return (D.Out name e' t')
+
+      D.Fixity assoc prec op -> return $ D.Fixity assoc prec op
+
+
+expression :: Environment -> Valid.Expr -> Canonicalizer [Doc] Canonical.Expr
+expression env (A.A ann expr) =
+    let go = expression env
+        tipe' environ = format . Canonicalize.tipe environ
+        throw err = P.vcat [ P.text "Error" <+> pretty ann <> P.colon
+                           , P.text err ]
+        format = Env.onError throw
     in
-    L s <$>
+    A.A ann <$>
     case expr of
-      Literal _ -> return expr
+      Literal lit -> return (Literal lit)
 
-      Range e1 e2 -> Range <$> rnm e1 <*> rnm e2
+      Range e1 e2 -> Range <$> go e1 <*> go e2
 
-      Access e x -> Access <$> rnm e <*> return x
+      Access e x -> Access <$> go e <*> return x
 
-      Remove e x -> flip Remove x <$> rnm e
+      Remove e x -> flip Remove x <$> go e
 
-      Insert e x v -> flip Insert x <$> rnm e <*> rnm v
+      Insert e x v -> flip Insert x <$> go e <*> go v
 
       Modify e fs ->
-          Modify <$> rnm e <*> mapM (\(k,v) -> (,) k <$> rnm v) fs
+          Modify <$> go e <*> mapM (\(k,v) -> (,) k <$> go v) fs
 
-      Record fs -> Record <$> mapM (\(k,v) -> (,) k <$> rnm v) fs
+      Record fs -> Record <$> mapM (\(k,v) -> (,) k <$> go v) fs
 
-      Binop op e1 e2 ->
-          do op' <- format (replace "variable" env op)
-             Binop op' <$> rnm e1 <*> rnm e2
+      Binop (Var.Raw op) e1 e2 ->
+          do op' <- format (Canonicalize.variable env op)
+             Binop op' <$> go e1 <*> go e2
 
-      Lambda pattern e ->
-          let env' = extend env pattern in
-          Lambda <$> format (renamePattern env' pattern) <*> rename env' e
+      Lambda p e ->
+          let env' = update p env in
+          Lambda <$> format (pattern env' p) <*> expression env' e
 
-      App e1 e2 -> App <$> rnm e1 <*> rnm e2
+      App e1 e2 -> App <$> go e1 <*> go e2
 
-      MultiIf ps -> MultiIf <$> mapM grnm ps
-              where grnm (b,e) = (,) <$> rnm b <*> rnm e
+      MultiIf ps -> MultiIf <$> mapM go' ps
+              where go' (b,e) = (,) <$> go b <*> go e
 
-      Let defs e -> Let <$> mapM rename' defs <*> rename env' e
+      Let defs e -> Let <$> mapM rename' defs <*> expression env' e
           where
-            env' = foldl extend env $ map (\(Definition p _ _) -> p) defs
-            rename' (Definition p body mtipe) =
-                Definition <$> format (renamePattern env' p)
-                           <*> rename env' body
-                           <*> T.traverse (renameType' env') mtipe
+            env' = foldr update env $ map (\(Valid.Definition p _ _) -> p) defs
+            rename' (Valid.Definition p body mtipe) =
+                Canonical.Definition
+                    <$> format (pattern env' p)
+                    <*> expression env' body
+                    <*> T.traverse (tipe' env') mtipe
 
-      Var x -> Var <$> format (replace "variable" env x)
+      Var (Var.Raw x) -> Var <$> format (Canonicalize.variable env x)
 
-      Data name es -> Data name <$> mapM rnm es
+      Data name es -> Data name <$> mapM go es
 
-      ExplicitList es -> ExplicitList <$> mapM rnm es
+      ExplicitList es -> ExplicitList <$> mapM go es
 
-      Case e cases -> Case <$> rnm e <*> mapM branch cases
+      Case e cases -> Case <$> go e <*> mapM branch cases
           where
-            branch (pattern,b) = (,) <$> format (renamePattern env pattern)
-                                     <*> rename (extend env pattern) b
+            branch (p,b) = (,) <$> format (pattern env p)
+                               <*> expression (update p env) b
 
-      Markdown uid md es -> Markdown uid md <$> mapM rnm es
+      Markdown uid md es ->
+          do Env.uses "Text"
+             Markdown uid md <$> mapM go es
 
-      PortIn name st -> PortIn name <$> renameType' env st
+      PortIn name st -> PortIn name <$> tipe' env st
 
-      PortOut name st signal -> PortOut name <$> renameType' env st <*> rnm signal
+      PortOut name st signal -> PortOut name <$> tipe' env st <*> go signal
 
+      GLShader uid src tipe -> return (GLShader uid src tipe)
 
-renamePattern :: Env -> P.Pattern -> Either String P.Pattern
-renamePattern env pattern =
-    case pattern of
-      P.PVar _ -> return pattern
-      P.PLiteral _ -> return pattern
-      P.PRecord _ -> return pattern
-      P.PAnything -> return pattern
-      P.PAlias x p -> P.PAlias x <$> renamePattern env p
-      P.PData name ps -> P.PData <$> replace "pattern" env name
-                                 <*> mapM (renamePattern env) ps
+pattern :: Environment -> P.RawPattern -> Canonicalizer String P.CanonicalPattern
+pattern env ptrn =
+    case ptrn of
+      P.Var x       -> return $ P.Var x
+      P.Literal lit -> return $ P.Literal lit
+      P.Record fs   -> return $ P.Record fs
+      P.Anything    -> return P.Anything
+      P.Alias x p   -> P.Alias x <$> pattern env p
+      P.Data (Var.Raw name) ps ->
+          P.Data <$> Canonicalize.pvar env name
+                 <*> mapM (pattern env) ps
diff --git a/compiler/Transform/Canonicalize/Environment.hs b/compiler/Transform/Canonicalize/Environment.hs
new file mode 100644
--- /dev/null
+++ b/compiler/Transform/Canonicalize/Environment.hs
@@ -0,0 +1,84 @@
+{-# OPTIONS_GHC -Wall #-}
+module Transform.Canonicalize.Environment where
+
+import Control.Arrow (second)
+import qualified Control.Monad.Error as Error
+import qualified Control.Monad.State as State
+import qualified Data.Map as Map
+import qualified Data.Set as Set
+
+import AST.Expression.General (saveEnvName)
+import qualified AST.Pattern as P
+import qualified AST.Type as Type
+import qualified AST.Variable as Var
+
+import Text.PrettyPrint (Doc)
+
+type Dict a = Map.Map String [a]
+
+dict :: [(String,a)] -> Dict a
+dict pairs = Map.fromList $ map (second (:[])) pairs
+
+insert :: String -> a -> Dict a -> Dict a
+insert key value = Map.insertWith (++) key [value]
+
+type Canonicalizer err a = Error.ErrorT err (State.State (Set.Set String)) a
+
+uses :: (Error.Error e) => String -> Canonicalizer e ()
+uses home =
+    Error.lift (State.modify (Set.insert home))
+
+using :: Var.Canonical -> Canonicalizer String Var.Canonical
+using var@(Var.Canonical home _) =
+  do case home of
+       Var.BuiltIn     -> return ()
+       Var.Module path -> uses path
+       Var.Local       -> return ()
+     return var
+
+onError :: (String -> Doc) -> Canonicalizer String a -> Canonicalizer [Doc] a
+onError handler canonicalizer =
+  do usedModules <- Error.lift State.get
+     let (result, usedModules') =
+             State.runState (Error.runErrorT canonicalizer) usedModules
+     Error.lift (State.put usedModules')
+     case result of
+       Left err -> Error.throwError [handler err]
+       Right x  -> return x
+
+data Environment = Env
+    { _home     :: String
+    , _values   :: Dict Var.Canonical
+    , _adts     :: Dict Var.Canonical
+    , _aliases  :: Dict (Var.Canonical, [String], Type.CanonicalType)
+    , _patterns :: Dict Var.Canonical
+    }
+
+builtIns :: String -> Environment
+builtIns home =
+    Env { _home     = home
+        , _values   = builtIn (tuples ++ [saveEnvName])
+        , _adts     = builtIn (tuples ++ ["_List","Int","Float","Char","Bool","String"])
+        , _aliases  = dict []
+        , _patterns = builtIn (tuples ++ ["::","[]"])
+        }
+    where
+      builtIn xs = dict $ map (\x -> (x, Var.Canonical Var.BuiltIn x)) xs
+      tuples = map (\n -> "_Tuple" ++ show (n :: Int)) [0..9]
+
+update :: P.Pattern var -> Environment -> Environment
+update ptrn env =
+    env { _values = foldr put (_values env) (P.boundVarList ptrn) }
+    where
+      put x = Map.insert x [Var.local x]
+
+merge :: Environment -> Environment -> Environment
+merge (Env n1 v1 t1 a1 p1) (Env n2 v2 t2 a2 p2)
+    | n1 /= n2 = error "trying to merge incompatable environments"
+    | otherwise =
+        Env { _home     = n1
+            , _values   = Map.unionWith (++) v1 v2
+            , _adts     = Map.unionWith (++) t1 t2
+            , _aliases  = Map.unionWith (++) a1 a2
+            , _patterns = Map.unionWith (++) p1 p2
+            }
diff --git a/compiler/Transform/Canonicalize/Setup.hs b/compiler/Transform/Canonicalize/Setup.hs
new file mode 100644
--- /dev/null
+++ b/compiler/Transform/Canonicalize/Setup.hs
@@ -0,0 +1,230 @@
+{-# OPTIONS_GHC -Wall #-}
+module Transform.Canonicalize.Setup (environment) where
+
+import Control.Arrow (first)
+import Control.Monad (foldM)
+import Control.Monad.Error (throwError)
+import qualified Data.Graph as Graph
+import qualified Data.List as List
+import qualified Data.Map as Map
+
+import qualified AST.Expression.Valid as Valid
+
+import AST.Module (Interface(iAdts, iTypes, iAliases))
+import qualified AST.Module as Module
+import qualified AST.Type as Type
+import qualified AST.Variable as Var
+import qualified AST.Declaration as D
+import AST.PrettyPrint (pretty, eightyCharLines)
+import qualified AST.Pattern as P
+import Text.PrettyPrint as P
+
+import Transform.Canonicalize.Environment as Env
+import qualified Transform.Canonicalize.Type as Canonicalize
+import qualified Transform.Interface as Interface
+
+environment :: Module.Interfaces -> Module.ValidModule -> Canonicalizer [Doc] Environment
+environment interfaces modul@(Module.Module _ _ _ imports decls) =
+  do () <- allImportsAvailable
+     let moduleName = Module.getName modul
+     nonLocalEnv <- foldM (addImports moduleName interfaces) (builtIns moduleName) imports
+     let (aliases, env) = List.foldl' (addDecl moduleName) ([], nonLocalEnv) decls
+     addTypeAliases moduleName aliases env
+  where
+    allImportsAvailable :: Canonicalizer [Doc] ()
+    allImportsAvailable =
+        case filter (not . found) modules of
+          [] -> return ()
+          missings -> throwError [ P.text (missingModuleError missings) ]
+        where
+          modules = map fst imports
+
+          found m = Map.member m interfaces || List.isPrefixOf "Native." m
+
+          missingModuleError missings =
+              concat [ "The following imports were not found: "
+                     , List.intercalate ", " missings
+                     , "\n    You may need to compile with the --make "
+                     , "flag to detect modules you have written." ]
+
+addImports :: String -> Module.Interfaces -> Environment -> (String, Module.ImportMethod)
+           -> Canonicalizer [Doc] Environment
+addImports moduleName interfaces environ (name, method)
+    | List.isPrefixOf "Native." name = return environ
+    | otherwise =
+        case method of
+          Module.As name' ->
+              return (updateEnviron (name' ++ "."))
+
+          Module.Open (Var.Listing vs open)
+              | open -> return (updateEnviron "")
+              | otherwise -> foldM (addValue name interface) environ vs
+    where
+      interface = Interface.filterExports ((Map.!) interfaces name)
+
+      updateEnviron prefix =
+          let dict' = dict . map (first (prefix++)) in
+          merge environ $
+          Env { _home     = moduleName
+              , _values   = dict' $ map pair (Map.keys (iTypes interface)) ++ ctors
+              , _adts     = dict' $ map pair (Map.keys (iAdts interface))
+              , _aliases  = dict' $ map alias (Map.toList (iAliases interface))
+              , _patterns = dict' $ ctors
+              }
+
+      canonical :: String -> Var.Canonical
+      canonical = Var.Canonical (Var.Module name)
+
+      pair :: String -> (String, Var.Canonical)
+      pair key = (key, canonical key)
+
+      alias (x,(tvars,tipe)) = (x, (canonical x, tvars, tipe))
+
+      ctors = concatMap (map (pair . fst) . snd . snd) (Map.toList (iAdts interface))
+
+addValue :: String -> Module.Interface -> Environment -> Var.Value
+         -> Canonicalizer [Doc] Environment
+addValue name interface env value =
+    let insert' x = insert x (Var.Canonical (Var.Module name) x)
+        msg x = "Import Error: Could not import value '" ++ name ++ "." ++ x ++
+                "'.\n    It is not exported by module " ++ name ++ "."
+        notFound x = throwError [ P.text (msg x) ]
+    in
+    case value of
+      Var.Value x
+          | Map.notMember x (iTypes interface) -> notFound x
+          | otherwise ->
+              return $ env { _values = insert' x (_values env) }
+
+      Var.Alias x ->
+          case Map.lookup x (iAliases interface) of
+            Just (tvars, t) ->
+                return $ env
+                    { _aliases = insert x v (_aliases env)
+                    , _values = updatedValues
+                    }
+              where
+                v = (Var.Canonical (Var.Module name) x, tvars, t)
+                updatedValues =
+                    if Map.member x (iTypes interface)
+                      then insert' x (_values env)
+                      else _values env
+
+            Nothing ->
+                case Map.lookup x (iAdts interface) of
+                  Nothing -> notFound x
+                  Just (_,_) ->
+                      return $ env { _adts = insert' x (_adts env) }
+
+      Var.ADT x (Var.Listing xs open) ->
+          case Map.lookup x (iAdts interface) of
+            Nothing -> notFound x
+            Just (_tvars, ctors) ->
+                do ctors' <- filterNames (map fst ctors)
+                   return $ env { _adts = insert' x (_adts env)
+                                , _values = foldr insert' (_values env) ctors'
+                                , _patterns = foldr insert' (_patterns env) ctors'
+                                }
+                where
+                  filterNames names
+                      | open = return names
+                      | otherwise =
+                          case filter (`notElem` names) xs of
+                            [] -> return names
+                            c:_ -> notFound c
+
+type Node = ((String, [String], Type.RawType), String, [String])
+
+node :: String -> [String] -> Type.RawType -> Node
+node name tvars alias = ((name, tvars, alias), name, edges alias)
+    where
+      edges tipe =
+          case tipe of
+            Type.Lambda t1 t2 -> edges t1 ++ edges t2
+            Type.Var _ -> []
+            Type.Type (Var.Raw x) -> [x]
+            Type.App t ts -> edges t ++ concatMap edges ts
+            Type.Record fs ext -> maybe [] edges ext ++ concatMap (edges . snd) fs
+            Type.Aliased _ t -> edges t
+
+addTypeAliases :: String -> [Node] -> Environment -> Canonicalizer [Doc] Environment
+addTypeAliases moduleName nodes environ =
+    foldM addTypeAlias environ (Graph.stronglyConnComp nodes)
+  where
+    addTypeAlias :: Environment -> Graph.SCC (String, [String], Type.RawType)
+                 -> Canonicalizer [Doc] Environment
+    addTypeAlias env scc =
+      case Graph.flattenSCC scc of
+        [(name, tvars, alias)] ->
+            do alias' <- Env.onError throw (Canonicalize.tipe env alias)
+               let value = (Var.Canonical (Var.Module moduleName) name, tvars, alias')
+               return $ env { _aliases = insert name value (_aliases env) }
+            where
+              throw err =
+                  let msg = "Problem with type alias '" ++ name ++ "':"
+                  in  P.vcat [ P.text msg, P.text err ]
+
+        aliases ->
+            throwError [ P.vcat [ P.text (eightyCharLines 0 msg1)
+                                , indented (map typeAlias aliases)
+                                , P.text (eightyCharLines 0 msg2)
+                                , indented (map datatype aliases)
+                                , P.text (eightyCharLines 0 msg3)
+                                ]
+                       ]
+
+    typeAlias (n,ts,t) = D.TypeAlias n ts t
+    datatype (n,ts,t) = D.Datatype n ts [(n,[t])]
+
+    indented :: [D.ValidDecl] -> Doc
+    indented decls = P.vcat (map prty decls) <> P.text "\n"
+        where
+          prty decl = P.text "\n    " <> pretty decl
+
+    msg1 = "The following type aliases are mutually recursive, forming an \
+           \infinite type. When you expand them, they just keep getting bigger:"
+    msg2 = "Instead, you can try something like this:"
+    msg3 = "It looks very similar, but an algebraic data type (ADT) \
+           \actually creates a new type. Unlike with a type alias, this \
+           \freshly created type is meaningful on its own, so an ADT \
+           \does not need to be expanded."
+
+
+-- When canonicalizing, all _values should be Local, but all _adts and _patterns
+-- should be fully namespaced. With _adts, they may appear in types that can
+-- escape the module.
+addDecl :: String -> ([Node], Environment) -> D.ValidDecl -> ([Node], Environment)
+addDecl moduleName info@(nodes,env) decl =
+    let namespacedVar     = Var.Canonical (Var.Module moduleName)
+        addLocal      x e = insert x (Var.local     x) e
+        addNamespaced x e = insert x (namespacedVar x) e
+    in
+    case decl of
+      D.Definition (Valid.Definition pattern _ _) ->
+          (,) nodes $ env
+           { _values = foldr addLocal (_values env) (P.boundVarList pattern) }
+
+      D.Datatype name _ ctors ->
+          (,) nodes $ env
+           { _values   = addCtors addLocal (_values env)
+           , _adts     = addNamespaced name (_adts env)
+           , _patterns = addCtors addNamespaced (_patterns env)
+           }
+        where
+          addCtors how e = foldr how e (map fst ctors)
+
+      D.TypeAlias name tvars alias ->
+          (,) (node name tvars alias : nodes) $ env
+           { _values = case alias of
+                         Type.Record _ _ -> addLocal name (_values env)
+                         _               -> _values env
+           }
+
+      D.Port port ->
+          let portName = case port of
+                           D.Out name _ _ -> name
+                           D.In name _    -> name
+          in
+              (,) nodes $ env { _values = addLocal portName (_values env) }
+
+      D.Fixity _ _ _ -> info
diff --git a/compiler/Transform/Canonicalize/Type.hs b/compiler/Transform/Canonicalize/Type.hs
new file mode 100644
--- /dev/null
+++ b/compiler/Transform/Canonicalize/Type.hs
@@ -0,0 +1,71 @@
+{-# OPTIONS_GHC -Wall #-}
+module Transform.Canonicalize.Type (tipe) where
+
+import Control.Arrow (second)
+import Control.Applicative ((<$>),(<*>))
+import Control.Monad.Error
+import qualified Data.Map as Map
+import Data.Traversable (traverse)
+
+import qualified AST.Type as T
+import qualified AST.Variable as Var
+
+import Transform.Canonicalize.Environment
+import qualified Transform.Canonicalize.Variable as Canonicalize
+
+tipe :: Environment -> T.RawType -> Canonicalizer String T.CanonicalType
+tipe env typ =
+    let go = tipe env in
+    case typ of
+      T.Var x    -> return (T.Var x)
+      T.Type _   -> canonicalizeApp env typ []
+      T.App t ts -> canonicalizeApp env t ts
+
+      T.Lambda a b     -> T.Lambda <$> go a <*> go b
+      T.Aliased name t -> T.Aliased name <$> go t
+
+      T.Record fields ext ->
+          let go' (f,t) = (,) f <$> go t
+          in  T.Record <$> mapM go' fields <*> traverse go ext
+
+canonicalizeApp :: Environment -> T.RawType -> [T.RawType]
+                -> Canonicalizer String T.CanonicalType
+canonicalizeApp env f args =
+  case f of
+    T.Type (Var.Raw rawName) ->
+        do answer <- Canonicalize.tvar env rawName
+           case answer of
+             Right alias -> canonicalizeAlias env alias args
+             Left name -> case args of
+                            []  -> return (T.Type name)
+                            _:_ -> T.App (T.Type name) <$> mapM (tipe env) args
+
+    _ -> T.App <$> tipe env f <*> mapM (tipe env) args
+
+canonicalizeAlias :: Environment -> (Var.Canonical, [String], T.CanonicalType)
+                  -> [T.RawType]
+                  -> Canonicalizer String T.CanonicalType
+canonicalizeAlias env (name, tvars, dealiasedTipe) tipes =
+  do when (tipesLen /= tvarsLen) (throwError msg)
+     tipes' <- mapM (tipe env) tipes
+     let tipe' = replace (Map.fromList (zip tvars tipes')) dealiasedTipe
+     return $ T.Aliased name tipe'
+  where
+    tipesLen = length tipes
+    tvarsLen = length tvars
+
+    msg :: String
+    msg = "Type alias '" ++ Var.toString name ++ "' expects " ++ show tvarsLen ++
+          " type argument" ++ (if tvarsLen == 1 then "" else "s") ++
+          " but was given " ++ show tipesLen
+
+    replace :: Map.Map String T.CanonicalType -> T.CanonicalType -> T.CanonicalType
+    replace typeTable t =
+        let go = replace typeTable in
+        case t of
+          T.Lambda a b          -> T.Lambda (go a) (go b)
+          T.Var x               -> Map.findWithDefault t x typeTable
+          T.Record fields ext   -> T.Record (map (second go) fields) (fmap go ext)
+          T.Aliased original t' -> T.Aliased original (go t')
+          T.Type _              -> t
+          T.App f args          -> T.App (go f) (map go args)
diff --git a/compiler/Transform/Canonicalize/Variable.hs b/compiler/Transform/Canonicalize/Variable.hs
new file mode 100644
--- /dev/null
+++ b/compiler/Transform/Canonicalize/Variable.hs
@@ -0,0 +1,94 @@
+{-# OPTIONS_GHC -Wall #-}
+module Transform.Canonicalize.Variable where
+
+import Control.Monad.Error
+import qualified Data.List as List
+import qualified Data.Map as Map
+import Data.Maybe (fromMaybe)
+
+import AST.Helpers as Help
+import qualified AST.Type as Type
+import qualified AST.Variable as Var
+import Transform.Canonicalize.Environment as Env
+
+variable :: Environment -> String -> Canonicalizer String Var.Canonical
+variable env var =
+  case modul of
+    Just ms@(m:_)
+        | m == "Native" -> Env.using (Var.Canonical home name)
+            where
+              home = Var.Module (List.intercalate "." ms)
+
+    _ ->
+        case Map.lookup var (_values env) of
+          Just [v] -> Env.using v
+          Just vs  -> preferLocals env "variable" vs var
+          Nothing  -> notFound "variable" (Map.keys (_values env)) var
+  where
+    (modul, name) =
+      case Help.splitDots var of
+        [x] -> (Nothing, x)
+        xs  -> (Just (init xs), last xs)
+
+tvar :: Environment -> String
+     -> Canonicalizer String (Either Var.Canonical (Var.Canonical, [String], Type.CanonicalType))
+tvar env var =
+  case adts ++ aliases of
+    []  -> notFound "type" (Map.keys (_adts env) ++ Map.keys (_aliases env)) var
+    [v] -> found extract v
+    vs  -> preferLocals' env extract "type" vs var
+  where
+    adts    = map Left .  fromMaybe [] $ Map.lookup var (_adts env)
+    aliases = map Right . fromMaybe [] $ Map.lookup var (_aliases env)
+
+    extract value =
+        case value of
+          Left v -> v
+          Right (v,_,_) -> v
+
+pvar :: Environment -> String -> Canonicalizer String Var.Canonical
+pvar env var =
+    case Map.lookup var (_patterns env) of
+      Just [v] -> Env.using v
+      Just vs  -> preferLocals env "pattern" vs var
+      Nothing  -> notFound "pattern" (Map.keys (_patterns env)) var
+
+found :: (a -> Var.Canonical) -> a -> Canonicalizer String a
+found extract v = do
+  _ <- Env.using (extract v)
+  return v
+
+notFound :: String -> [String] -> String -> Canonicalizer String a
+notFound kind possibilities var =
+    throwError $ "Could not find " ++ kind ++ " '" ++ var ++ "'." ++ msg
+  where
+    matches = filter (List.isInfixOf var) possibilities
+    msg = if null matches then "" else
+              "\nClose matches include: " ++ List.intercalate ", " matches
+
+preferLocals :: Environment -> String -> [Var.Canonical] -> String
+             -> Canonicalizer String Var.Canonical
+preferLocals env = preferLocals' env id
+
+preferLocals' :: Environment -> (a -> Var.Canonical) -> String -> [a] -> String
+              -> Canonicalizer String a
+preferLocals' env extract kind possibilities var =
+    case filter (isLocal . extract) possibilities of
+      []     -> ambiguous possibilities
+      [v]    -> found extract v
+      locals -> ambiguous locals
+    where
+      isLocal :: Var.Canonical -> Bool
+      isLocal (Var.Canonical home _) =
+          case home of
+            Var.Local -> True
+            Var.BuiltIn -> False
+            Var.Module name -> name == Env._home env
+
+      ambiguous possibleVars =
+          throwError msg
+        where
+          vars = map (Var.toString . extract) possibleVars
+          msg = "Ambiguous usage of " ++ kind ++ " '" ++ var ++ "'.\n" ++
+                "    Disambiguate between: " ++ List.intercalate ", " vars
+
diff --git a/compiler/Transform/Check.hs b/compiler/Transform/Check.hs
--- a/compiler/Transform/Check.hs
+++ b/compiler/Transform/Check.hs
@@ -6,17 +6,18 @@
 import qualified Data.Maybe as Maybe
 import qualified Data.Set as Set
 
-import qualified SourceSyntax.Expression as E
-import qualified SourceSyntax.Declaration as D
-import qualified SourceSyntax.Pattern as Pattern
-import qualified SourceSyntax.Type as T
+import qualified AST.Expression.Valid as Valid
+import qualified AST.Declaration as D
+import qualified AST.Pattern as Pattern
+import qualified AST.Type as T
+import qualified AST.Variable as Var
 import qualified Transform.Expression as Expr
 
-import SourceSyntax.PrettyPrint
+import AST.PrettyPrint
 import Text.PrettyPrint as P
 
 
-mistakes :: [D.Declaration] -> [Doc]
+mistakes :: [D.ValidDecl] -> [Doc]
 mistakes decls =
     concat [ infiniteTypeAliases decls
            , illFormedTypes decls
@@ -30,9 +31,9 @@
 dupErr err x = 
   "Syntax Error: There can only be one " ++ err ++ " '" ++ x ++ "'."
 
-duplicates :: [D.Declaration] -> [String]
+duplicates :: [D.ValidDecl] -> [String]
 duplicates decls =
-    map msg (dups (portNames ++ concatMap getNames defPatterns)) ++
+    map msg (dups (portNames ++ concatMap Pattern.boundVarList defPatterns)) ++
     case mapM exprDups (portExprs ++ defExprs) of
       Left name -> [msg name]
       Right _   -> []
@@ -41,7 +42,7 @@
     msg = dupErr "definition of"
 
     (defPatterns, defExprs) =
-        unzip [ (pat,expr) | D.Definition (E.Definition pat expr _) <- decls ]
+        unzip [ (pat,expr) | D.Definition (Valid.Definition pat expr _) <- decls ]
 
     (portNames, portExprs) =
         Arrow.second concat $ unzip $ 
@@ -50,18 +51,17 @@
               D.Out name expr _ -> (name, [expr])
               D.In name _ -> (name, [])
 
-    getNames = Set.toList . Pattern.boundVars
-
-    exprDups :: E.LExpr -> Either String E.LExpr
+    exprDups :: Valid.Expr -> Either String Valid.Expr
     exprDups expr = Expr.crawlLet defsDups expr
 
-    defsDups :: [E.Def] -> Either String [E.Def]
+    defsDups :: [Valid.Def] -> Either String [Valid.Def]
     defsDups defs =
-        case dups $ concatMap (\(E.Definition name _ _) -> getNames name) defs of
+        let varsIn (Valid.Definition pattern _ _) = Pattern.boundVarList pattern in
+        case dups $ concatMap varsIn defs of
           []     -> Right defs
           name:_ -> Left name
 
-duplicateConstructors :: [D.Declaration] -> [String]
+duplicateConstructors :: [D.ValidDecl] -> [String]
 duplicateConstructors decls = 
     map (dupErr "definition of type constructor") (dups typeCtors) ++
     map (dupErr "definition of data constructor") (dups dataCtors)
@@ -69,7 +69,7 @@
     typeCtors = [ name | D.Datatype name _ _ <- decls ]
     dataCtors = concat [ map fst patterns | D.Datatype _ _ patterns <- decls ]
 
-illFormedTypes :: [D.Declaration] -> [Doc]
+illFormedTypes :: [D.ValidDecl] -> [Doc]
 illFormedTypes decls = map report (Maybe.mapMaybe isIllFormed (aliases ++ adts))
     where
       aliases = [ (decl, tvars, [tipe]) | decl@(D.TypeAlias _ tvars tipe) <- decls ]
@@ -79,9 +79,11 @@
           case tipe of
             T.Lambda t1 t2 -> Set.union (freeVars t1) (freeVars t2)
             T.Var x -> Set.singleton x
-            T.Data _ ts -> Set.unions (map freeVars ts)
+            T.Type _ -> Set.empty
+            T.App t ts -> Set.unions (map freeVars (t:ts))
             T.Record fields ext -> Set.unions (ext' : map (freeVars . snd) fields)
-                where ext' = maybe Set.empty Set.singleton ext
+                where ext' = maybe Set.empty freeVars ext
+            T.Aliased _ t -> freeVars t
 
       undeclared tvars tipes = Set.difference used declared
           where
@@ -114,20 +116,23 @@
             quote tvar = "'" ++ tvar ++ "'"
 
 
-infiniteTypeAliases :: [D.Declaration] -> [Doc]
+infiniteTypeAliases :: [D.ValidDecl] -> [Doc]
 infiniteTypeAliases decls =
     [ report name tvars tipe | D.TypeAlias name tvars tipe <- decls
                              , infiniteType name tipe ]
     where
+      infiniteType :: String -> T.Type Var.Raw -> Bool
       infiniteType name tipe =
           let infinite = infiniteType name in
           case tipe of
             T.Lambda a b -> infinite a || infinite b
             T.Var _ -> False
-            T.Data name' ts -> name == name' || any infinite ts
+            T.Type (Var.Raw name') -> name == name'
+            T.App t ts -> any infinite (t:ts)
             T.Record fields _ -> any (infinite . snd) fields
+            T.Aliased _ t -> infinite t
 
-      indented :: D.Declaration -> Doc
+      indented :: D.ValidDecl -> Doc
       indented decl = P.text "\n    " <> pretty decl <> P.text "\n"
 
       report name args tipe =
diff --git a/compiler/Transform/Declaration.hs b/compiler/Transform/Declaration.hs
--- a/compiler/Transform/Declaration.hs
+++ b/compiler/Transform/Declaration.hs
@@ -1,16 +1,23 @@
 {-# OPTIONS_GHC -Wall #-}
-module Transform.Declaration where
+module Transform.Declaration (combineAnnotations, toExpr) where
 
 import Control.Applicative ((<$>))
-import qualified SourceSyntax.Pattern as P
-import SourceSyntax.Expression as E
-import SourceSyntax.Declaration as D
 
+import qualified AST.Annotation as A
+import qualified AST.Declaration as D
+import qualified AST.Expression.General as E
+import qualified AST.Expression.Source as Source
+import qualified AST.Expression.Valid as Valid
+import qualified AST.Expression.Canonical as Canonical
+import qualified AST.Pattern as P
+import qualified AST.Type as T
+import qualified AST.Variable as Var
+
 import qualified Transform.Expression as Expr
 import qualified Transform.Definition as Def
 
 
-combineAnnotations :: [ParseDeclaration] -> Either String [Declaration]
+combineAnnotations :: [D.SourceDecl] -> Either String [D.ValidDecl]
 combineAnnotations = go
     where
       msg x = "Syntax Error: The type annotation for '" ++ x ++
@@ -23,41 +30,99 @@
             -- simple cases, pass them through with no changes
             [] -> return []
 
-            Datatype name tvars ctors : rest ->
-                (:) (Datatype name tvars ctors) <$> go rest
+            D.Datatype name tvars ctors : rest ->
+                (:) (D.Datatype name tvars ctors) <$> go rest
 
-            TypeAlias name tvars alias : rest ->
-                (:) (TypeAlias name tvars alias) <$> go rest
+            D.TypeAlias name tvars alias : rest ->
+                (:) (D.TypeAlias name tvars alias) <$> go rest
 
-            Fixity assoc prec op : rest ->
-                (:) (Fixity assoc prec op) <$> go rest
+            D.Fixity assoc prec op : rest ->
+                (:) (D.Fixity assoc prec op) <$> go rest
 
             -- combine definitions
             D.Definition def : defRest ->
                 case def of
-                  Def pat expr ->
+                  Source.Definition pat expr ->
                       do expr' <- exprCombineAnnotations expr
-                         let def' = E.Definition pat expr' Nothing
+                         let def' = Valid.Definition pat expr' Nothing
                          (:) (D.Definition def') <$> go defRest
 
-                  TypeAnnotation name tipe ->
+                  Source.TypeAnnotation name tipe ->
                       case defRest of
-                        D.Definition (Def pat@(P.PVar name') expr) : rest | name == name' ->
-                            do expr' <- exprCombineAnnotations expr
-                               let def' = E.Definition pat expr' (Just tipe)
-                               (:) (D.Definition def') <$> go rest
+                        D.Definition (Source.Definition pat@(P.Var name') expr) : rest
+                            | name == name' ->
+                                do expr' <- exprCombineAnnotations expr
+                                   let def' = Valid.Definition pat expr' (Just tipe)
+                                   (:) (D.Definition def') <$> go rest
 
                         _ -> Left (msg name)
 
             -- combine ports
-            Port port : portRest ->
+            D.Port port : portRest ->
                 case port of
-                  PPDef name _ -> Left (msg name)
-                  PPAnnotation name tipe ->
+                  D.PPDef name _ -> Left (msg name)
+                  D.PPAnnotation name tipe ->
                       case portRest of
-                        Port (PPDef name' expr) : rest | name == name' ->
+                        D.Port (D.PPDef name' expr) : rest | name == name' ->
                             do expr' <- exprCombineAnnotations expr
-                               (:) (Port (Out name expr' tipe)) <$> go rest
+                               (:) (D.Port (D.Out name expr' tipe)) <$> go rest
 
-                        _ -> (:) (Port (In name tipe)) <$> go portRest
+                        _ -> (:) (D.Port (D.In name tipe)) <$> go portRest
 
+
+toExpr :: String -> [D.CanonicalDecl] -> [Canonical.Def]
+toExpr moduleName = concatMap (toDefs moduleName)
+
+toDefs :: String -> D.CanonicalDecl -> [Canonical.Def]
+toDefs moduleName decl =
+  let typeVar = Var.Canonical (Var.Module moduleName) in
+  case decl of
+    D.Definition def -> [def]
+
+    D.Datatype name tvars constructors -> concatMap toDefs' constructors
+      where
+        toDefs' (ctor, tipes) =
+            let vars = take (length tipes) arguments
+                tbody = T.App (T.Type (typeVar name)) (map T.Var tvars)
+                body = A.none . E.Data ctor $ map (A.none . E.localVar) vars
+            in  [ definition ctor (buildFunction body vars) (foldr T.Lambda tbody tipes) ]
+
+    D.TypeAlias name _ tipe@(T.Record fields ext) ->
+        [ definition name (buildFunction record vars) (foldr T.Lambda result args) ]
+      where
+        result = T.Aliased (typeVar name) tipe
+
+        args = map snd fields ++ maybe [] (:[]) ext
+
+        var = A.none . E.localVar
+        vars = take (length args) arguments
+
+        efields = zip (map fst fields) (map var vars)
+        record = case ext of
+                   Nothing -> A.none $ E.Record efields
+                   Just _ -> foldl (\r (f,v) -> A.none $ E.Insert r f v) (var $ last vars) efields
+
+    -- Type aliases must be added to an extended equality dictionary,
+    -- but they do not require any basic constraints.
+    D.TypeAlias _ _ _ -> []
+
+    D.Port port ->
+        case port of
+          D.Out name expr@(A.A s _) tipe ->
+              [ definition name (A.A s $ E.PortOut name tipe expr) tipe ]
+          D.In name tipe ->
+              [ definition name (A.none $ E.PortIn name tipe) tipe ]
+
+    -- no constraints are needed for fixity declarations
+    D.Fixity _ _ _ -> []
+
+
+arguments :: [String]
+arguments = map (:[]) ['a'..'z'] ++ map (\n -> "_" ++ show (n :: Int)) [1..]
+
+buildFunction :: Canonical.Expr -> [String] -> Canonical.Expr
+buildFunction body@(A.A s _) vars =
+    foldr (\p e -> A.A s (E.Lambda p e)) body (map P.Var vars)
+
+definition :: String -> Canonical.Expr -> T.CanonicalType -> Canonical.Def
+definition name expr tipe = Canonical.Definition (P.Var name) expr (Just tipe)
diff --git a/compiler/Transform/Definition.hs b/compiler/Transform/Definition.hs
--- a/compiler/Transform/Definition.hs
+++ b/compiler/Transform/Definition.hs
@@ -2,11 +2,12 @@
 module Transform.Definition where
 
 import Control.Applicative ((<$>))
-import qualified SourceSyntax.Pattern as P
-import SourceSyntax.Expression
+import qualified AST.Pattern as P
+import qualified AST.Expression.Source as Source
+import qualified AST.Expression.Valid as Valid
 import qualified Transform.Expression as Expr
 
-combineAnnotations :: [ParseDef] -> Either String [Def]
+combineAnnotations :: [Source.Def] -> Either String [Valid.Def]
 combineAnnotations = go
     where
       msg x = "Syntax Error: The type annotation for '" ++ x ++
@@ -16,16 +17,19 @@
 
       go defs =
           case defs of
-            TypeAnnotation name tipe : Def pat@(P.PVar name') expr : rest | name == name' ->
-                do expr' <- exprCombineAnnotations expr
-                   let def = Definition pat expr' (Just tipe)
-                   (:) def <$> go rest
+            Source.TypeAnnotation name tipe : rest ->
+                case rest of
+                  Source.Definition pat@(P.Var name') expr : rest'
+                      | name == name' ->
+                          do expr' <- exprCombineAnnotations expr
+                             let def = Valid.Definition pat expr' (Just tipe)
+                             (:) def <$> go rest'
 
-            TypeAnnotation name _  : _ -> Left (msg name)
+                  _ -> Left (msg name)
 
-            Def pat expr : rest ->
+            Source.Definition pat expr : rest ->
                 do expr' <- exprCombineAnnotations expr
-                   let def = Definition pat expr' Nothing
+                   let def = Valid.Definition pat expr' Nothing
                    (:) def <$> go rest
 
             [] -> return []
diff --git a/compiler/Transform/Expression.hs b/compiler/Transform/Expression.hs
--- a/compiler/Transform/Expression.hs
+++ b/compiler/Transform/Expression.hs
@@ -2,33 +2,36 @@
 module Transform.Expression (crawlLet, checkPorts) where
 
 import Control.Applicative ((<$>),(<*>))
-import SourceSyntax.Expression
-import SourceSyntax.Location
-import qualified SourceSyntax.Type as ST
+import AST.Annotation ( Annotated(A) )
+import AST.Expression.General
+import qualified AST.Expression.Canonical as Canonical
+import AST.Type (Type, CanonicalType)
 
-crawlLet :: ([def] -> Either a [def']) -> LExpr' def -> Either a (LExpr' def')
+crawlLet :: ([def] -> Either a [def'])
+         -> Expr ann def var
+         -> Either a (Expr ann def' var)
 crawlLet = crawl (\_ _ -> return ()) (\_ _ -> return ())
 
-checkPorts :: (String -> ST.Type -> Either a ())
-           -> (String -> ST.Type -> Either a ())
-           -> LExpr
-           -> Either a LExpr
+checkPorts :: (String -> CanonicalType -> Either a ())
+           -> (String -> CanonicalType -> Either a ())
+           -> Canonical.Expr
+           -> Either a Canonical.Expr
 checkPorts inCheck outCheck expr =
     crawl inCheck outCheck (mapM checkDef) expr
     where
-      checkDef def@(Definition _ body _) =
+      checkDef def@(Canonical.Definition _ body _) =
           do _ <- checkPorts inCheck outCheck body
              return def
 
-crawl :: (String -> ST.Type -> Either a ())
-      -> (String -> ST.Type -> Either a ())
+crawl :: (String -> Type var -> Either a ())
+      -> (String -> Type var -> Either a ())
       -> ([def] -> Either a [def'])
-      -> LExpr' def
-      -> Either a (LExpr' def')
+      -> Expr ann def var
+      -> Either a (Expr ann def' var)
 crawl portInCheck portOutCheck defsTransform = go
     where
-      go (L srcSpan expr) =
-          L srcSpan <$>
+      go (A srcSpan expr) =
+          A srcSpan <$>
           case expr of
             Var x -> return (Var x)
             Lambda p e -> Lambda p <$> go e
@@ -47,6 +50,7 @@
             Record fields -> Record <$> mapM (\(k,v) -> (,) k <$> go v) fields
             Markdown uid md es -> Markdown uid md <$> mapM go es
             Let defs body -> Let <$> defsTransform defs <*> go body
+            GLShader uid src gltipe -> return $ GLShader uid src gltipe
             PortIn name st ->
                 do portInCheck name st
                    return $ PortIn name st
diff --git a/compiler/Transform/Interface.hs b/compiler/Transform/Interface.hs
new file mode 100644
--- /dev/null
+++ b/compiler/Transform/Interface.hs
@@ -0,0 +1,58 @@
+{-# OPTIONS_GHC -W #-}
+module Transform.Interface (filterExports) where
+
+import qualified Data.Map as Map
+import qualified AST.Module as Module
+import qualified AST.Type as Type
+import qualified AST.Variable as Var
+
+filterExports :: Module.Interface -> Module.Interface
+filterExports interface =
+    interface
+    { Module.iTypes =
+        Map.fromList (concatMap getTypes exportedValues)
+    , Module.iAliases =
+        Map.fromList (concatMap getAliases exportedValues)
+    , Module.iAdts =
+        Map.fromList (concatMap getAdts exportedValues)
+    }
+  where
+    exportedValues :: [Var.Value]
+    exportedValues = Module.iExports interface
+
+    get :: Map.Map String a -> String -> [(String, a)]
+    get dict x =
+        case Map.lookup x dict of
+          Just t  -> [(x,t)]
+          Nothing -> []
+
+    getTypes :: Var.Value -> [(String, Type.CanonicalType)]
+    getTypes value =
+        case value of
+          Var.Value x -> getType x
+          Var.Alias _ -> []
+          Var.ADT _ (Var.Listing ctors _) -> concatMap getType ctors
+
+    getType :: String -> [(String, Type.CanonicalType)]
+    getType name =
+        get (Module.iTypes interface) name
+
+    getAliases :: Var.Value -> [(String, ([String], Type.CanonicalType))]
+    getAliases value =
+        case value of
+          Var.Value _ -> []
+          Var.Alias name -> get (Module.iAliases interface) name
+          Var.ADT _ _ -> []
+
+    getAdts :: Var.Value -> [(String, Module.AdtInfo String)]
+    getAdts value =
+        case value of
+          Var.Value _ -> []
+          Var.Alias _ -> []
+          Var.ADT name (Var.Listing exportedCtors _) ->
+              case Map.lookup name (Module.iAdts interface) of
+                Nothing -> []
+                Just (tvars, ctors) ->
+                    [(name, (tvars, filter isExported ctors))]
+                  where
+                    isExported (ctor, _) = ctor `elem` exportedCtors
diff --git a/compiler/Transform/SafeNames.hs b/compiler/Transform/SafeNames.hs
deleted file mode 100644
--- a/compiler/Transform/SafeNames.hs
+++ /dev/null
@@ -1,72 +0,0 @@
-{-# OPTIONS_GHC -Wall #-}
-module Transform.SafeNames (metadataModule) where
-
-import Control.Arrow (first, (***))
-import SourceSyntax.Expression
-import SourceSyntax.Location
-import SourceSyntax.Module
-import SourceSyntax.Pattern
-import qualified Data.Set as Set
-import qualified Parse.Helpers as PHelp
-
-var :: String -> String
-var = dereserve . deprime
-  where
-    deprime = map (\c -> if c == '\'' then '$' else c)
-    dereserve x = case Set.member x PHelp.jsReserveds of
-                    False -> x
-                    True  -> "$" ++ x
-
-pattern :: Pattern -> Pattern
-pattern pat =
-    case pat of
-      PVar x -> PVar (var x)
-      PLiteral _ -> pat
-      PRecord fs -> PRecord (map var fs)
-      PAnything -> pat
-      PAlias x p -> PAlias (var x) (pattern p)
-      PData name ps -> PData name (map pattern ps)
-
-expression :: LExpr -> LExpr
-expression (L loc expr) =
-    let f = expression in
-    L loc $
-    case expr of
-      Literal _ -> expr
-      Var x -> Var (var x)
-      Range e1 e2 -> Range (f e1) (f e2)
-      ExplicitList es -> ExplicitList (map f es)
-      Binop op e1 e2 -> Binop op (f e1) (f e2)
-      Lambda p e -> Lambda (pattern p) (f e)
-      App e1 e2 -> App (f e1) (f e2)
-      MultiIf ps -> MultiIf (map (f *** f) ps)
-      Let defs body -> Let (map definition defs) (f body)
-      Case e cases -> Case (f e) $ map (pattern *** f) cases
-      Data name es -> Data name (map f es)
-      Access e x -> Access (f e) (var x)
-      Remove e x -> Remove (f e) (var x)
-      Insert e x v -> Insert (f e) (var x) (f v)
-      Modify r fs -> Modify (f r) (map (var *** f) fs)
-      Record fs -> Record (map (var *** f) fs)
-      Markdown uid md es -> Markdown uid md (map f es)
-      PortIn name st -> PortIn name st
-      PortOut name st signal -> PortOut name st (f signal)
-
-definition :: Def -> Def
-definition (Definition p e t) =
-    Definition (pattern p) (expression e) t
-
-metadataModule :: MetadataModule -> MetadataModule
-metadataModule modul =
-    modul
-    { names = map var (names modul)
-    , exports = map var (exports modul)
-    , imports = map (first var) (imports modul)
-    , program = expression (program modul)
-    , aliases =
-        let makeSafe (name,tvars,tipe) = (var name, tvars, tipe)
-        in  map makeSafe (aliases modul)
-    , datatypes =
-        let makeSafe (name,tvars,ctors) = (var name, tvars, map (first var) ctors)
-        in  map makeSafe (datatypes modul)
-    }
diff --git a/compiler/Transform/SortDefinitions.hs b/compiler/Transform/SortDefinitions.hs
--- a/compiler/Transform/SortDefinitions.hs
+++ b/compiler/Transform/SortDefinitions.hs
@@ -3,45 +3,61 @@
 
 import Control.Monad.State
 import Control.Applicative ((<$>),(<*>))
-import qualified Data.Map as Map
-import SourceSyntax.Expression
-import SourceSyntax.Location
-import qualified SourceSyntax.Pattern as P
 import qualified Data.Graph as Graph
-import qualified Data.Set as Set
+import qualified Data.Map as Map
 import qualified Data.Maybe as Maybe
+import qualified Data.Set as Set
 
-ctors :: P.Pattern -> [String]
+import AST.Annotation
+import AST.Expression.General (Expr'(..))
+import qualified AST.Expression.Canonical as Canonical
+import qualified AST.Pattern as P
+import qualified AST.Variable as V
+
+ctors :: P.CanonicalPattern -> [String]
 ctors pattern =
     case pattern of
-      P.PVar _ -> []
-      P.PAlias _ p -> ctors p
-      P.PData ctor ps -> ctor : concatMap ctors ps
-      P.PRecord _ -> []
-      P.PAnything -> []
-      P.PLiteral _ -> []
+      P.Var _ -> []
+      P.Alias _ p -> ctors p
+      P.Record _ -> []
+      P.Anything -> []
+      P.Literal _ -> []
+      P.Data (V.Canonical home name) ps ->
+          case home of
+            V.Local -> name : rest
+            V.BuiltIn -> rest
+            V.Module _ -> rest
+          where
+            rest = concatMap ctors ps
 
 free :: String -> State (Set.Set String) ()
 free x = modify (Set.insert x)
 
+freeIfLocal :: V.Canonical -> State (Set.Set String) ()
+freeIfLocal (V.Canonical home name) =
+    do case home of
+         V.Local -> free name
+         V.BuiltIn -> return ()
+         V.Module _ -> return ()
+
 bound :: Set.Set String -> State (Set.Set String) ()
 bound boundVars = modify (\freeVars -> Set.difference freeVars boundVars)
 
-sortDefs :: LExpr -> LExpr
+sortDefs :: Canonical.Expr -> Canonical.Expr
 sortDefs expr = evalState (reorder expr) Set.empty
 
-reorder :: LExpr -> State (Set.Set String) LExpr
-reorder (L s expr) =
-    L s <$>
+reorder :: Canonical.Expr -> State (Set.Set String) Canonical.Expr
+reorder (A ann expr) =
+    A ann <$>
     case expr of
       -- Be careful adding and restricting freeVars
-      Var x -> free x >> return expr
+      Var var -> freeIfLocal var >> return expr
 
       Lambda p e ->
           uncurry Lambda <$> bindingReorder (p,e)
 
       Binop op e1 e2 ->
-          do free op
+          do freeIfLocal op
              Binop op <$> reorder e1 <*> reorder e2
 
       Case e cases ->
@@ -83,6 +99,8 @@
 
       Markdown uid md es -> Markdown uid md <$> mapM reorder es
 
+      GLShader _ _ _ -> return expr
+
       PortOut name st signal -> PortOut name st <$> reorder signal
 
       PortIn name st -> return $ PortIn name st
@@ -99,15 +117,16 @@
              let defss = map Graph.flattenSCC sccs
              
              -- remove let-bound variables from the context
-             forM_ defs $ \(Definition pattern _ _) -> do
+             forM_ defs $ \(Canonical.Definition pattern _ _) -> do
                 bound (P.boundVars pattern)
                 mapM free (ctors pattern)
 
-             let L _ let' = foldr (\ds bod -> L s (Let ds bod)) body' defss
+             let A _ let' = foldr (\ds bod -> A ann (Let ds bod)) body' defss
 
              return let'
 
-bindingReorder :: (P.Pattern, LExpr) -> State (Set.Set String) (P.Pattern, LExpr)
+bindingReorder :: (P.CanonicalPattern, Canonical.Expr)
+               -> State (Set.Set String) (P.CanonicalPattern, Canonical.Expr)
 bindingReorder (pattern,expr) =
     do expr' <- reorder expr
        bound (P.boundVars pattern)
@@ -115,8 +134,8 @@
        return (pattern, expr')
 
 
-reorderAndGetDependencies :: Def -> State (Set.Set String) (Def, [String])
-reorderAndGetDependencies (Definition pattern expr mType) =
+reorderAndGetDependencies :: Canonical.Def -> State (Set.Set String) (Canonical.Def, [String])
+reorderAndGetDependencies (Canonical.Definition pattern expr mType) =
     do globalFrees <- get
        -- work in a fresh environment
        put Set.empty
@@ -124,28 +143,28 @@
        localFrees <- get
        -- merge with global frees
        modify (Set.union globalFrees)
-       return (Definition pattern expr' mType, Set.toList localFrees)
+       return (Canonical.Definition pattern expr' mType, Set.toList localFrees)
 
 
 -- This also reorders the all of the sub-expressions in the Def list.
-buildDefDict :: [Def] -> State (Set.Set String) [(Def, Int, [Int])]
+buildDefDict :: [Canonical.Def] -> State (Set.Set String) [(Canonical.Def, Int, [Int])]
 buildDefDict defs =
   do pdefsDeps <- mapM reorderAndGetDependencies defs
      return $ realDeps (addKey pdefsDeps)
 
   where
-    addKey :: [(Def, [String])] -> [(Def, Int, [String])]
+    addKey :: [(Canonical.Def, [String])] -> [(Canonical.Def, Int, [String])]
     addKey = zipWith (\n (pdef,deps) -> (pdef,n,deps)) [0..]
 
-    variableToKey :: (Def, Int, [String]) -> [(String, Int)]
-    variableToKey (Definition pattern _ _, key, _) =
+    variableToKey :: (Canonical.Def, Int, [String]) -> [(String, Int)]
+    variableToKey (Canonical.Definition pattern _ _, key, _) =
         [ (var, key) | var <- Set.toList (P.boundVars pattern) ]
 
-    variableToKeyMap :: [(Def, Int, [String])] -> Map.Map String Int
+    variableToKeyMap :: [(Canonical.Def, Int, [String])] -> Map.Map String Int
     variableToKeyMap pdefsDeps =
         Map.fromList (concatMap variableToKey pdefsDeps)
 
-    realDeps :: [(Def, Int, [String])] -> [(Def, Int, [Int])]
+    realDeps :: [(Canonical.Def, Int, [String])] -> [(Canonical.Def, Int, [Int])]
     realDeps pdefsDeps = map convert pdefsDeps
         where
           varDict = variableToKeyMap pdefsDeps
diff --git a/compiler/Transform/Substitute.hs b/compiler/Transform/Substitute.hs
--- a/compiler/Transform/Substitute.hs
+++ b/compiler/Transform/Substitute.hs
@@ -2,41 +2,90 @@
 module Transform.Substitute (subst) where
 
 import Control.Arrow (second, (***))
-import SourceSyntax.Expression
-import SourceSyntax.Location
-import qualified SourceSyntax.Pattern as Pattern
 import qualified Data.Set as Set
 
-subst :: String -> Expr -> Expr -> Expr
-subst old new expr =
-    let f (L s e) = L s (subst old new e) in
-    case expr of
-      Range e1 e2 -> Range (f e1) (f e2)
-      ExplicitList es -> ExplicitList (map f es)
-      Binop op e1 e2 -> Binop op (f e1) (f e2)
-      Lambda p e
-          | Set.member old (Pattern.boundVars p) -> expr
-          | otherwise -> Lambda p (f e)
-      App e1 e2 -> App (f e1) (f e2)
-      MultiIf ps -> MultiIf (map (f *** f) ps)
+import AST.Annotation
+import AST.Expression.General (Expr'(..))
+import qualified AST.Expression.Canonical as Canonical
+import qualified AST.Pattern as Pattern
+import qualified AST.Variable as V
 
+
+subst :: String -> Canonical.Expr' -> Canonical.Expr' -> Canonical.Expr'
+subst old new expression =
+    let f (A a e) = A a (subst old new e) in
+    case expression of
+      Range e1 e2 ->
+          Range (f e1) (f e2)
+
+      ExplicitList exprs ->
+          ExplicitList (map f exprs)
+
+      Binop op e1 e2 ->
+          Binop op (f e1) (f e2)
+
+      Lambda pattern body
+          | Set.member old (Pattern.boundVars pattern) -> expression
+          | otherwise -> Lambda pattern (f body)
+
+      App e1 e2 ->
+          App (f e1) (f e2)
+
+      MultiIf branches ->
+          MultiIf (map (f *** f) branches)
+
       Let defs body
-          | anyShadow -> expr
+          | anyShadow -> expression
           | otherwise -> Let (map substDef defs) (f body)
         where
-          substDef (Definition p e t) = Definition p (f e) t
+          substDef (Canonical.Definition p e t) =
+              Canonical.Definition p (f e) t
+
           anyShadow =
-              any (Set.member old . Pattern.boundVars) [ p | Definition p _ _ <- defs ]
+              any (Set.member old . Pattern.boundVars)
+                  [ pattern | Canonical.Definition pattern _ _ <- defs ]
 
-      Var x -> if x == old then new else expr
-      Case e cases -> Case (f e) $ map (second f) cases
-      Data name es -> Data name (map f es)
-      Access e x -> Access (f e) x
-      Remove e x -> Remove (f e) x
-      Insert e x v -> Insert (f e) x (f v)
-      Modify r fs -> Modify (f r) (map (second f) fs)
-      Record fs -> Record (map (second f) fs)
-      Literal _ -> expr
-      Markdown uid md es -> Markdown uid md (map f es)
-      PortIn name st -> PortIn name st
-      PortOut name st signal -> PortOut name st (f signal)
+      Var (V.Canonical home x) ->
+          case home of
+            V.Module _ -> expression
+            V.BuiltIn -> expression
+            V.Local -> if x == old then new else expression
+
+      Case e cases ->
+          Case (f e) (map substCase cases)
+        where
+          substCase (pattern, expr) =
+              if Set.member old (Pattern.boundVars pattern)
+                then (pattern, expr)
+                else (pattern, f expr)
+
+      Data tag values ->
+          Data tag (map f values)
+
+      Access record field ->
+          Access (f record) field
+
+      Remove record field ->
+          Remove (f record) field
+
+      Insert record field value ->
+          Insert (f record) field (f value)
+
+      Modify record fields ->
+          Modify (f record) (map (second f) fields)
+
+      Record fields ->
+          Record (map (second f) fields)
+
+      Literal _ -> expression
+
+      Markdown uid md exprs ->
+          Markdown uid md (map f exprs)
+
+      GLShader _ _ _ -> expression
+
+      PortIn name st ->
+          PortIn name st
+
+      PortOut name st signal ->
+          PortOut name st (f signal)
diff --git a/compiler/Type/Alias.hs b/compiler/Type/Alias.hs
deleted file mode 100644
--- a/compiler/Type/Alias.hs
+++ /dev/null
@@ -1,139 +0,0 @@
-{-# OPTIONS_GHC -W #-}
-module Type.Alias (realias, rules, canonicalRealias, Rules) where
-
-import Control.Applicative ((<$>),(<*>))
-import Control.Monad
-import Control.Arrow (second)
-import Data.Map ((!))
-import qualified Data.Map as Map
-import qualified Data.List as List
-import SourceSyntax.Type
-import SourceSyntax.Module
-
-type Rules = ([Alias], Type -> Type)
-
-rules interfaces moduleAliases moduleImports =
-    (collect interfaces moduleAliases, localizer moduleImports)
-
-collect interfaces moduleAliases =
-    filter (not . isPrimitive) rawAliases
-    where
-      rawAliases =
-          moduleAliases ++ concatMap iAliases (Map.elems interfaces)
-
-      isPrimitive (_,_,tipe) =
-          case tipe of
-          Data _ [] -> True
-          _ -> False
-
-localizer moduleImports = go
-  where
-    go tipe =
-        case tipe of
-          Var _ -> tipe
-          Lambda t1 t2 -> Lambda (go t1) (go t2)
-          Data name ts -> Data (localize name) (map go ts)
-          Record fs ext -> Record (map (second go) fs) ext
-
-    byMethod = foldr (\(n,m) d -> Map.insertWith (++) n [m] d)
-               Map.empty moduleImports
-
-    separate name =
-        case List.elemIndices '.' name of
-          [] -> ("",name)
-          is -> let i = last is in
-                (take i name, drop (i+1) name)
-
-    shortest = List.minimumBy (\a b -> compare (length a) (length b))
-
-    localize name = shortest (name : concatMap (localize' value) methods)
-        where (modul, value) = separate name
-              methods = Map.findWithDefault [] modul byMethod
-
-    localize' name method =
-        case method of
-          As modul -> [modul ++ "." ++ name]
-          Hiding xs | name `notElem` xs -> [name]
-          Importing xs | name `elem` xs -> [name]
-          _ -> []
-
-realias :: Rules -> Type -> Type
-realias (aliases,localize) tipe = localize (canonicalRealias aliases tipe)
-
--- Realias using canonical aliases, so results will have aliases
--- that are fully qualified and possible to compare.
-canonicalRealias :: [Alias] -> Type -> Type
-canonicalRealias aliases tipe =
-    case concatMap tryRealias aliases of
-      [] -> if tipe == tipe' then tipe else f tipe'
-      tipes -> f (bestType tipes)
-  where
-    tryRealias (name, args, aliasTipe) =
-        case diff aliasTipe tipe of
-          Nothing -> []
-          Just kvs ->
-              let holes = collectFields kvs
-                  hasArgs = List.sort args == Map.keys holes
-                  isConsistent = all allEqual (Map.elems holes)
-              in  case hasArgs && isConsistent of
-                    False -> []
-                    True -> [Data name $ map (\arg -> head (holes ! arg)) args]
-
-    f = canonicalRealias aliases
-    tipe' =
-        case tipe of
-          Var _ -> tipe
-          Lambda t1 t2 -> Lambda (f t1) (f t2)
-          Data name ts -> Data name (map f ts)
-          Record fs ext -> Record (map (second f) fs) ext
-
-allEqual [] = True
-allEqual (x:xs) = all (==x) xs
-
-bestType tipes = fst $ List.minimumBy (\a b -> compare (snd a) (snd b)) pairs
-    where
-      pairs :: [(Type,Int)]
-      pairs = zip tipes (map numFields tipes)
-
-      numFields :: Type -> Int
-      numFields tipe =
-          case tipe of
-            Lambda t1 t2 -> numFields t1 + numFields t2
-            Var _ -> 0
-            Data _ ts -> sum (map numFields ts)
-            Record fields _ -> length fields + sum (map (numFields . snd) fields)
-
-diff :: Type -> Type -> Maybe [(String,Type)]
-diff general specific =
-    case (general, specific) of
-      (Lambda g1 g2, Lambda s1 s2) -> (++) <$> diff g1 s1 <*> diff g2 s2
-      (Var x, t) -> Just [(x,t)]
-      (Data gname gts, Data sname sts)
-          | gname == sname && length gts == length sts ->
-              concat <$> zipWithM diff gts sts
-      (Record [] Nothing, Record [] Nothing) -> Just []
-      (Record _ _, Record [] Nothing) -> Nothing
-      (Record [] Nothing, Record _ _) -> Nothing
-      (Record gfs gext, Record sfs sext) ->
-          let gfields = collectFields gfs
-              sfields = collectFields sfs
-
-              overlap = Map.intersectionWith (\gs ss -> length gs == length ss) sfields gfields
-              isAligned = Map.size gfields == Map.size overlap && and (Map.elems overlap)
-          in
-              case isAligned of
-                False -> Nothing
-                True -> let remaining = Map.difference sfields gfields
-                            sext' = case sext of
-                                      Just x | Map.null remaining -> Var x
-                                      _ -> Record (flattenFields remaining) sext
-                            gext' = maybe (Record [] Nothing) Var gext
-                            matchMap = Map.intersectionWith (zipWith diff) gfields sfields
-                        in  concat <$> sequence (diff gext' sext' : concat (Map.elems matchMap))
-      (_,_) -> Nothing
-
-collectFields fields =
-    foldr (\(f,t) fs -> Map.insertWith (++) f [t] fs) Map.empty fields
-
-flattenFields fields =
-    concatMap (\(f,ts) -> map ((,) f) ts) (Map.toList fields)
diff --git a/compiler/Type/Constrain/Declaration.hs b/compiler/Type/Constrain/Declaration.hs
deleted file mode 100644
--- a/compiler/Type/Constrain/Declaration.hs
+++ /dev/null
@@ -1,62 +0,0 @@
-{-# OPTIONS_GHC -Wall #-}
-module Type.Constrain.Declaration where
-
-import SourceSyntax.Declaration
-import qualified SourceSyntax.Expression as E
-import qualified SourceSyntax.Location as L
-import qualified SourceSyntax.Pattern as P
-import qualified SourceSyntax.Type as T
-
-toExpr :: [Declaration] -> [E.Def]
-toExpr = concatMap toDefs
-
-toDefs :: Declaration -> [E.Def]
-toDefs decl =
-  case decl of
-    Definition def -> [def]
-
-    Datatype name tvars constructors -> concatMap toDefs' constructors
-      where
-        toDefs' (ctor, tipes) =
-            let vars = take (length tipes) arguments
-                tbody = T.Data name $ map T.Var tvars
-                body = L.none . E.Data ctor $ map (L.none . E.Var) vars
-            in  [ definition ctor (buildFunction body vars) (foldr T.Lambda tbody tipes) ]
-
-    TypeAlias name _ tipe@(T.Record fields ext) ->
-        [ definition name (buildFunction record vars) (foldr T.Lambda tipe args) ]
-      where
-        args = map snd fields ++ maybe [] (\x -> [T.Var x]) ext
-
-        var = L.none . E.Var
-        vars = take (length args) arguments
-
-        efields = zip (map fst fields) (map var vars)
-        record = case ext of
-                   Nothing -> L.none $ E.Record efields
-                   Just _ -> foldl (\r (f,v) -> L.none $ E.Insert r f v) (var $ last vars) efields
-
-    -- Type aliases must be added to an extended equality dictionary,
-    -- but they do not require any basic constraints.
-    TypeAlias _ _ _ -> []
-
-    Port port ->
-        case port of
-          Out name expr@(L.L s _) tipe ->
-              [ definition name (L.L s $ E.PortOut name tipe expr) tipe ]
-          In name tipe ->
-              [ definition name (L.none $ E.PortIn name tipe) tipe ]
-
-    -- no constraints are needed for fixity declarations
-    Fixity _ _ _ -> []
-
-
-arguments :: [String]
-arguments = map (:[]) ['a'..'z'] ++ map (\n -> "_" ++ show (n :: Int)) [1..]
-
-buildFunction :: E.LExpr -> [String] -> E.LExpr
-buildFunction body@(L.L s _) vars =
-    foldr (\p e -> L.L s (E.Lambda p e)) body (map P.PVar vars)
-
-definition :: String -> E.LExpr -> T.Type -> E.Def
-definition name expr tipe = E.Definition (P.PVar name) expr (Just tipe)
diff --git a/compiler/Type/Constrain/Expression.hs b/compiler/Type/Constrain/Expression.hs
--- a/compiler/Type/Constrain/Expression.hs
+++ b/compiler/Type/Constrain/Expression.hs
@@ -1,44 +1,66 @@
 {-# OPTIONS_GHC -W #-}
 module Type.Constrain.Expression where
 
-import qualified Data.List as List
-import qualified Data.Map as Map
-import qualified Data.Set as Set
 import Control.Applicative ((<$>))
 import qualified Control.Monad as Monad
 import Control.Monad.Error
+import qualified Data.List as List
+import qualified Data.Map as Map
 import qualified Text.PrettyPrint as PP
 
-import SourceSyntax.Location as Loc
-import SourceSyntax.Pattern (Pattern(PVar), boundVars)
-import SourceSyntax.Expression
-import qualified SourceSyntax.Type as SrcT
+import AST.Literal as Lit
+import AST.Annotation as Ann
+import AST.Expression.General
+import qualified AST.Expression.Canonical as Canonical
+import qualified AST.Pattern as P
+import qualified AST.Type as ST
+import qualified AST.Variable as V
 import Type.Type hiding (Descriptor(..))
 import Type.Fragment
 import qualified Type.Environment as Env
 import qualified Type.Constrain.Literal as Literal
 import qualified Type.Constrain.Pattern as Pattern
 
-constrain :: Env.Environment -> LExpr -> Type -> ErrorT [PP.Doc] IO TypeConstraint
-constrain env (L span expr) tipe =
+constrain :: Env.Environment -> Canonical.Expr -> Type
+          -> ErrorT [PP.Doc] IO TypeConstraint
+constrain env (A region expr) tipe =
     let list t = Env.get env Env.types "_List" <| t
-        and = L span . CAnd
-        true = L span CTrue
-        t1 === t2 = L span (CEqual t1 t2)
-        x <? t = L span (CInstance x t)
-        clet schemes c = L span (CLet schemes c)
+        and = A region . CAnd
+        true = A region CTrue
+        t1 === t2 = A region (CEqual t1 t2)
+        x <? t = A region (CInstance x t)
+        clet schemes c = A region (CLet schemes c)
     in
     case expr of
-      Literal lit -> liftIO $ Literal.constrain env span lit tipe
+      Literal lit -> liftIO $ Literal.constrain env region lit tipe
 
-      Var name | name == saveEnvName -> return (L span CSaveEnv)
-               | otherwise           -> return (name <? tipe)
+      GLShader _uid _src gltipe -> 
+          exists $ \attr -> 
+          exists $ \unif -> 
+            let 
+              shaderTipe a u v = Env.get env Env.types "Graphics.WebGL.Shader" <| a <| u <| v
+              glTipe = Env.get env Env.types . Lit.glTipeName
+              makeRec accessor baseRec = 
+                let decls = accessor gltipe
+                in if Map.size decls == 0
+                   then baseRec
+                   else record (Map.map (\t -> [glTipe t]) decls) baseRec
+              attribute = makeRec Lit.attribute attr
+              uniform = makeRec Lit.uniform unif
+              varying = makeRec Lit.varying (termN EmptyRecord1)
+            in return . A region $ CEqual tipe (shaderTipe attribute uniform varying)
 
+      Var var
+          | name == saveEnvName -> return (A region CSaveEnv)
+          | otherwise           -> return (name <? tipe)
+          where
+            name = V.toString var
+
       Range lo hi ->
-          exists $ \x -> do
-            clo <- constrain env lo x
-            chi <- constrain env hi x
-            return $ and [clo, chi, list x === tipe]
+          existsNumber $ \n -> do
+            clo <- constrain env lo n
+            chi <- constrain env hi n
+            return $ and [clo, chi, list n === tipe]
 
       ExplicitList exprs ->
           exists $ \x -> do
@@ -50,12 +72,12 @@
           exists $ \t2 -> do
             c1 <- constrain env e1 t1
             c2 <- constrain env e2 t2
-            return $ and [ c1, c2, op <? (t1 ==> t2 ==> tipe) ]
+            return $ and [ c1, c2, V.toString op <? (t1 ==> t2 ==> tipe) ]
 
       Lambda p e ->
           exists $ \t1 ->
           exists $ \t2 -> do
-            fragment <- try span $ Pattern.constrain env p t1
+            fragment <- try region $ Pattern.constrain env p t1
             c2 <- constrain env e t2
             let c = ex (vars fragment) (clet [monoscheme (typeEnv fragment)]
                                              (typeConstraint fragment /\ c2 ))
@@ -79,13 +101,13 @@
           exists $ \t -> do
             ce <- constrain env exp t
             let branch (p,e) = do
-                  fragment <- try span $ Pattern.constrain env p t
+                  fragment <- try region $ Pattern.constrain env p t
                   clet [toScheme fragment] <$> constrain env e tipe
             and . (:) ce <$> mapM branch branches
 
       Data name exprs ->
-          do vars <- forM exprs $ \_ -> liftIO (var Flexible)
-             let pairs = zip exprs (map VarN vars)
+          do vars <- forM exprs $ \_ -> liftIO (variable Flexible)
+             let pairs = zip exprs (map varN vars)
              (ctipe, cs) <- Monad.foldM step (tipe,true) (reverse pairs)
              return $ ex vars (cs /\ name <? ctipe)
           where
@@ -111,28 +133,28 @@
 
       Modify e fields ->
           exists $ \t -> do
-              oldVars <- forM fields $ \_ -> liftIO (var Flexible)
-              let oldFields = SrcT.fieldMap (zip (map fst fields) (map VarN oldVars))
+              oldVars <- forM fields $ \_ -> liftIO (variable Flexible)
+              let oldFields = ST.fieldMap (zip (map fst fields) (map varN oldVars))
               cOld <- ex oldVars <$> constrain env e (record oldFields t)
 
-              newVars <- forM fields $ \_ -> liftIO (var Flexible)
-              let newFields = SrcT.fieldMap (zip (map fst fields) (map VarN newVars))
+              newVars <- forM fields $ \_ -> liftIO (variable Flexible)
+              let newFields = ST.fieldMap (zip (map fst fields) (map varN newVars))
               let cNew = tipe === record newFields t
 
-              cs <- zipWithM (constrain env) (map snd fields) (map VarN newVars)
+              cs <- zipWithM (constrain env) (map snd fields) (map varN newVars)
 
               return $ cOld /\ ex newVars (and (cNew : cs))
 
       Record fields ->
-          do vars <- forM fields $ \_ -> liftIO (var Flexible)
-             cs <- zipWithM (constrain env) (map snd fields) (map VarN vars)
-             let fields' = SrcT.fieldMap (zip (map fst fields) (map VarN vars))
-                 recordType = record fields' (TermN EmptyRecord1)
+          do vars <- forM fields $ \_ -> liftIO (variable Flexible)
+             cs <- zipWithM (constrain env) (map snd fields) (map varN vars)
+             let fields' = ST.fieldMap (zip (map fst fields) (map varN vars))
+                 recordType = record fields' (termN EmptyRecord1)
              return . ex vars . and $ tipe === recordType : cs
 
       Markdown _ _ es ->
-          do vars <- forM es $ \_ -> liftIO (var Flexible)
-             let tvars = map VarN vars
+          do vars <- forM es $ \_ -> liftIO (variable Flexible)
+             let tvars = map varN vars
              cs <- zipWithM (constrain env) es tvars
              return . ex vars $ and ("Text.markdown" <? tipe : cs)
 
@@ -151,21 +173,21 @@
       PortOut _ _ signal ->
           constrain env signal tipe
 
-constrainDef env info (Definition pattern expr maybeTipe) =
+constrainDef env info (Canonical.Definition pattern expr maybeTipe) =
     let qs = [] -- should come from the def, but I'm not sure what would live there...
         (schemes, rigidQuantifiers, flexibleQuantifiers, headers, c2, c1) = info
     in
-    do rigidVars <- forM qs (\_ -> liftIO $ var Rigid) -- Some mistake may be happening here.
+    do rigidVars <- forM qs (\_ -> liftIO $ variable Rigid) -- Some mistake may be happening here.
                                                        -- Currently, qs is always [].
        case (pattern, maybeTipe) of
-         (PVar name, Just tipe) -> do
-             flexiVars <- forM qs (\_ -> liftIO $ var Flexible)
-             let inserts = zipWith (\arg typ -> Map.insert arg (VarN typ)) qs flexiVars
+         (P.Var name, Just tipe) -> do
+             flexiVars <- forM qs (\_ -> liftIO $ variable Flexible)
+             let inserts = zipWith (\arg typ -> Map.insert arg (varN typ)) qs flexiVars
                  env' = env { Env.value = List.foldl' (\x f -> f x) (Env.value env) inserts }
              (vars, typ) <- Env.instantiateType env tipe Map.empty
              let scheme = Scheme { rigidQuantifiers = [],
                                    flexibleQuantifiers = flexiVars ++ vars,
-                                   constraint = Loc.noneNoDocs CTrue,
+                                   constraint = Ann.noneNoDocs CTrue,
                                    header = Map.singleton name typ }
              c <- constrain env' expr typ
              return ( scheme : schemes
@@ -175,10 +197,10 @@
                     , c2
                     , fl rigidVars c /\ c1 )
 
-         (PVar name, Nothing) -> do
-             v <- liftIO $ var Flexible
-             let tipe = VarN v
-                 inserts = zipWith (\arg typ -> Map.insert arg (VarN typ)) qs rigidVars
+         (P.Var name, Nothing) -> do
+             v <- liftIO $ variable Flexible
+             let tipe = varN v
+                 inserts = zipWith (\arg typ -> Map.insert arg (varN typ)) qs rigidVars
                  env' = env { Env.value = List.foldl' (\x f -> f x) (Env.value env) inserts }
              c <- constrain env' expr tipe
              return ( schemes
@@ -188,22 +210,22 @@
                     , c /\ c2
                     , c1 )
 
-         _ -> error (show pattern)
+         _ -> error ("problem in constrainDef with " ++ show pattern)
 
-expandPattern :: Def -> [Def]
-expandPattern def@(Definition pattern lexpr@(L s _) maybeType) =
+expandPattern :: Canonical.Def -> [Canonical.Def]
+expandPattern def@(Canonical.Definition pattern lexpr@(A r _) maybeType) =
     case pattern of
-      PVar _ -> [def]
-      _ -> Definition (PVar x) lexpr maybeType : map toDef vars
+      P.Var _ -> [def]
+      _ -> Canonical.Definition (P.Var x) lexpr maybeType : map toDef vars
           where
-            vars = Set.toList $ boundVars pattern
+            vars = P.boundVarList pattern
             x = "$" ++ concat vars
-            mkVar = L s . Var
-            toDef y = Definition (PVar y) (L s $ Case (mkVar x) [(pattern, mkVar y)]) Nothing
+            mkVar = A r . localVar
+            toDef y = Canonical.Definition (P.Var y) (A r $ Case (mkVar x) [(pattern, mkVar y)]) Nothing
 
-try :: SrcSpan -> ErrorT (SrcSpan -> PP.Doc) IO a -> ErrorT [PP.Doc] IO a
-try span computation = do
+try :: Region -> ErrorT (Region -> PP.Doc) IO a -> ErrorT [PP.Doc] IO a
+try region computation = do
   result <- liftIO $ runErrorT computation
   case result of
-    Left err -> throwError [err span]
+    Left err -> throwError [err region]
     Right value -> return value
diff --git a/compiler/Type/Constrain/Literal.hs b/compiler/Type/Constrain/Literal.hs
--- a/compiler/Type/Constrain/Literal.hs
+++ b/compiler/Type/Constrain/Literal.hs
@@ -1,20 +1,21 @@
+{-# OPTIONS_GHC -W #-}
 module Type.Constrain.Literal where
 
-import SourceSyntax.Literal
-import SourceSyntax.Location
+import AST.Annotation
+import AST.Literal
 import Type.Type
 import Type.Environment as Env
 
-constrain :: Environment -> SrcSpan -> Literal -> Type -> IO TypeConstraint
-constrain env span literal tipe =
+constrain :: Environment -> Region -> Literal -> Type -> IO TypeConstraint
+constrain env region literal tipe =
     do tipe' <- litType
-       return . L span $ CEqual tipe tipe'
+       return . A region $ CEqual tipe tipe'
     where
       prim name = return (Env.get env Env.types name)
 
       litType =
           case literal of
-            IntNum _   -> VarN `fmap` var (Is Number)
+            IntNum _   -> varN `fmap` variable (Is Number)
             FloatNum _ -> prim "Float"
             Chr _      -> prim "Char"
             Str _      -> prim "String"
diff --git a/compiler/Type/Constrain/Pattern.hs b/compiler/Type/Constrain/Pattern.hs
--- a/compiler/Type/Constrain/Pattern.hs
+++ b/compiler/Type/Constrain/Pattern.hs
@@ -1,3 +1,4 @@
+{-# OPTIONS_GHC -W #-}
 {-# LANGUAGE FlexibleInstances #-}
 module Type.Constrain.Pattern where
 
@@ -8,48 +9,49 @@
 import qualified Data.Map as Map
 import qualified Text.PrettyPrint as PP
 
-import SourceSyntax.Pattern
-import SourceSyntax.Location
-import SourceSyntax.PrettyPrint
-import Text.PrettyPrint (render)
-import qualified SourceSyntax.Location as Loc
+import qualified AST.Annotation as A
+import qualified AST.Pattern as P
+import qualified AST.Variable as V
+import AST.PrettyPrint (pretty)
 import Type.Type
 import Type.Fragment
 import Type.Environment as Env
 import qualified Type.Constrain.Literal as Literal
 
 
-constrain :: Environment -> Pattern -> Type -> ErrorT (SrcSpan -> PP.Doc) IO Fragment
+constrain :: Environment -> P.CanonicalPattern -> Type
+          -> ErrorT (A.Region -> PP.Doc) IO Fragment
 constrain env pattern tipe =
-    let span = Loc.NoSpan (render $ pretty pattern)
-        t1 === t2 = Loc.L span (CEqual t1 t2)
-        x <? t = Loc.L span (CInstance x t)
+    let region = A.None (pretty pattern)
+        t1 === t2 = A.A region (CEqual t1 t2)
     in
     case pattern of
-      PAnything -> return emptyFragment
+      P.Anything -> return emptyFragment
 
-      PLiteral lit -> do
-          c <- liftIO $ Literal.constrain env span lit tipe
+      P.Literal lit -> do
+          c <- liftIO $ Literal.constrain env region lit tipe
           return $ emptyFragment { typeConstraint = c }
 
-      PVar name -> do
-          v <- liftIO $ var Flexible
+      P.Var name -> do
+          v <- liftIO $ variable Flexible
           return $ Fragment {
-              typeEnv    = Map.singleton name (VarN v),
+              typeEnv    = Map.singleton name (varN v),
               vars       = [v],
-              typeConstraint = VarN v === tipe
+              typeConstraint = varN v === tipe
           }
 
-      PAlias name p -> do
+      P.Alias name p -> do
+          v <- liftIO $ variable Flexible
           fragment <- constrain env p tipe
-          return $ fragment {
-              typeEnv = Map.insert name tipe (typeEnv fragment),
-              typeConstraint = name <? tipe /\ typeConstraint fragment
+          return $ fragment
+            { typeEnv = Map.insert name (varN v) (typeEnv fragment)
+            , vars    = v : vars fragment
+            , typeConstraint = varN v === tipe /\ typeConstraint fragment
             }
 
-      PData name patterns -> do
-          (kind, cvars, args, result) <- liftIO $ freshDataScheme env name
-          let msg = concat [ "Constructor '", name, "' expects ", show kind
+      P.Data name patterns -> do
+          (kind, cvars, args, result) <- liftIO $ freshDataScheme env (V.toString name)
+          let msg = concat [ "Constructor '", V.toString name, "' expects ", show kind
                            , " argument", if kind == 1 then "" else "s"
                            , " but was given ", show (length patterns), "." ]
               err span = PP.vcat [ PP.text $ "Type error " ++ show span
@@ -63,9 +65,9 @@
                 vars = cvars ++ vars fragment
               }
 
-      PRecord fields -> do
-          pairs <- liftIO $ mapM (\name -> (,) name <$> var Flexible) fields
-          let tenv = Map.fromList (map (second VarN) pairs)
+      P.Record fields -> do
+          pairs <- liftIO $ mapM (\name -> (,) name <$> variable Flexible) fields
+          let tenv = Map.fromList (map (second varN) pairs)
           c <- exists $ \t -> return (tipe === record (Map.map (:[]) tenv) t)
           return $ Fragment {
               typeEnv        = tenv,
@@ -73,7 +75,7 @@
               typeConstraint = c
           }
 
-instance Error (SrcSpan -> PP.Doc) where
+instance Error (A.Region -> PP.Doc) where
   noMsg _ = PP.empty
   strMsg str span =
       PP.vcat [ PP.text $ "Type error " ++ show span
diff --git a/compiler/Type/Environment.hs b/compiler/Type/Environment.hs
--- a/compiler/Type/Environment.hs
+++ b/compiler/Type/Environment.hs
@@ -4,7 +4,6 @@
 import Control.Applicative ((<$>), (<*>))
 import Control.Exception (try, SomeException)
 import Control.Monad
-import Control.Monad.Trans.Error (ErrorList(..))
 import Control.Monad.Error (ErrorT, throwError, liftIO)
 import qualified Control.Monad.State as State
 import qualified Data.Traversable as Traverse
@@ -12,55 +11,59 @@
 import Data.List (isPrefixOf)
 import qualified Text.PrettyPrint as PP
 
-import qualified SourceSyntax.Type as Src
-import SourceSyntax.Module (ADT, Alias)
+import qualified AST.Type as T
+import qualified AST.Variable as V
+import AST.Module (CanonicalAdt, AdtInfo)
 import Type.Type
 
 type TypeDict = Map.Map String Type
 type VarDict = Map.Map String Variable
 
-data Environment = Environment {
-  constructor :: Map.Map String (IO (Int, [Variable], [Type], Type)),
-  aliases :: Map.Map String ([String], Src.Type),
-  types :: TypeDict,
-  value :: TypeDict
-}
+data Environment = Environment
+    { constructor :: Map.Map String (IO (Int, [Variable], [Type], Type))
+    , types :: TypeDict
+    , value :: TypeDict
+    }
 
-initialEnvironment :: [ADT] -> [Alias] -> IO Environment
-initialEnvironment datatypes aliases = do
+initialEnvironment :: [CanonicalAdt] -> IO Environment
+initialEnvironment datatypes = do
     types <- makeTypes datatypes
-    let aliases' = Map.fromList $ map (\(a,b,c) -> (a,(b,c))) aliases
-        env = Environment {
-                constructor = Map.empty,
-                value = Map.empty,
-                types = types,
-                aliases = aliases' }
-
+    let env = Environment
+              { constructor = Map.empty
+              , value = Map.empty
+              , types = types
+              }
     return $ env { constructor = makeConstructors env datatypes }
 
-makeTypes :: [ADT] -> IO TypeDict
-makeTypes datatypes = 
-    Map.fromList <$> mapM makeCtor (builtins ++ map nameAndKind datatypes)
+makeTypes :: [CanonicalAdt] -> IO TypeDict
+makeTypes datatypes =
+  do adts <- mapM makeImported datatypes
+     bs   <- mapM makeBuiltin builtins
+     return (Map.fromList (adts ++ bs))
   where
-    nameAndKind (name, tvars, _) = (name, length tvars)
-
-    makeCtor (name, _) = do
-      ctor <- VarN <$> namedVar Constant name
-      return (name, ctor)
-
-    tuple n = ("_Tuple" ++ show n, n)
+    makeImported :: (V.Canonical, AdtInfo V.Canonical) -> IO (String, Type)
+    makeImported (var, _) = do
+      tvar <- namedVar Constant var
+      return (V.toString var, varN tvar)
 
-    kind n names = map (\name -> (name, n)) names
+    makeBuiltin :: (String, Int) -> IO (String, Type)
+    makeBuiltin (name, _) = do
+      name' <- namedVar Constant (V.builtin name)
+      return (name, varN name')
 
-    builtins :: [(String,Int)]
+    builtins :: [(String, Int)]
     builtins = concat [ map tuple [0..9]
                       , kind 1 ["_List"]
                       , kind 0 ["Int","Float","Char","String","Bool"]
                       ]
+      where
+        tuple n = ("_Tuple" ++ show n, n)
+        kind n names = map (\name -> (name, n)) names
 
 
+
 makeConstructors :: Environment
-                 -> [ADT]
+                 -> [CanonicalAdt]
                  -> Map.Map String (IO (Int, [Variable], [Type], Type))
 makeConstructors env datatypes = Map.fromList builtins
   where
@@ -68,8 +71,8 @@
 
     inst :: Int -> ([Type] -> ([Type], Type)) -> IO (Int, [Variable], [Type], Type)
     inst numTVars tipe = do
-      vars <- forM [1..numTVars] $ \_ -> var Flexible
-      let (args, result) = tipe (map VarN vars)
+      vars <- forM [1..numTVars] $ \_ -> variable Flexible
+      let (args, result) = tipe (map (varN) vars)
       return (length args, vars, args, result)
 
     tupleCtor n =
@@ -83,88 +86,83 @@
                  ++ concatMap (ctorToType env) datatypes
 
 
-ctorToType :: Environment -> ADT -> [ (String, IO (Int, [Variable], [Type], Type)) ]
-ctorToType env (name, tvars, ctors) =
-    zip (map fst ctors) (map inst ctors)
+ctorToType :: Environment
+           -> (V.Canonical, AdtInfo V.Canonical)
+           -> [(String, IO (Int, [Variable], [Type], Type))]
+ctorToType env (name, (tvars, ctors)) =
+    zip (map (V.toString . fst) ctors) (map inst ctors)
   where
-    inst :: (String, [Src.Type]) -> IO (Int, [Variable], [Type], Type)
+    inst :: (V.Canonical, [T.CanonicalType]) -> IO (Int, [Variable], [Type], Type)
     inst ctor = do
-      ((args, tipe), (dict,_)) <- State.runStateT (go ctor) (Map.empty, Map.empty)
+      ((args, tipe), dict) <- State.runStateT (go ctor) Map.empty
       return (length args, Map.elems dict, args, tipe)
       
 
-    go :: (String, [Src.Type]) -> State.StateT (VarDict, TypeDict) IO ([Type], Type)
+    go :: (V.Canonical, [T.CanonicalType]) -> State.StateT VarDict IO ([Type], Type)
     go (_, args) = do
       types <- mapM (instantiator env) args
-      returnType <- instantiator env (Src.Data name (map Src.Var tvars))
+      returnType <- instantiator env (T.App (T.Type name) (map T.Var tvars))
       return (types, returnType)
 
 
 get :: Environment -> (Environment -> Map.Map String a) -> String -> a
-get env subDict key = Map.findWithDefault err key (subDict env)
+get env subDict key = Map.findWithDefault (error msg) key (subDict env)
   where
-    err = error $ "\nCould not find type constructor '" ++ key ++ "' while checking types."
+    msg = "Could not find type constructor '" ++ key ++ "' while checking types."
 
 
 freshDataScheme :: Environment -> String -> IO (Int, [Variable], [Type], Type)
 freshDataScheme env name = get env constructor name
 
-instance ErrorList PP.Doc where
-  listMsg str = [PP.text str]
-
-instantiateType :: Environment -> Src.Type -> VarDict -> ErrorT [PP.Doc] IO ([Variable], Type)
+instantiateType :: Environment -> T.CanonicalType -> VarDict -> ErrorT [PP.Doc] IO ([Variable], Type)
 instantiateType env sourceType dict =
-  do result <- liftIO $ try (State.runStateT (instantiator env sourceType) (dict, Map.empty))
-     case result :: Either SomeException (Type, (VarDict, TypeDict)) of
+  do result <- liftIO $ try (State.runStateT (instantiator env sourceType) dict)
+     case result :: Either SomeException (Type, VarDict) of
        Left someError -> throwError [ PP.text $ show someError ]
-       Right (tipe, (dict',_)) -> return (Map.elems dict', tipe)
+       Right (tipe, dict') -> return (Map.elems dict', tipe)
 
-instantiator :: Environment -> Src.Type
-             -> State.StateT (VarDict, TypeDict) IO Type
+instantiator :: Environment -> T.CanonicalType -> State.StateT VarDict IO Type
 instantiator env sourceType = go sourceType
   where
-    go :: Src.Type -> State.StateT (VarDict, TypeDict) IO Type
+    go :: T.CanonicalType -> State.StateT VarDict IO Type
     go sourceType =
       case sourceType of
-        Src.Lambda t1 t2 -> (==>) <$> go t1 <*> go t2
+        T.Lambda t1 t2 -> (==>) <$> go t1 <*> go t2
 
-        Src.Var x -> do
-          (dict, aliases) <- State.get
-          case (Map.lookup x dict, Map.lookup x aliases) of
-            (_, Just t) -> return t
-            (Just v, _) -> return (VarN v)
-            _ ->
-                do var <- State.liftIO $ namedVar flex x
-                   State.put (Map.insert x var dict, aliases)
-                   return (VarN var)
+        T.Var x -> do
+          dict <- State.get
+          case Map.lookup x dict of
+            Just v -> return (varN v)
+            Nothing ->
+                do v <- State.liftIO $ namedVar flex (V.local x)
+                   State.put (Map.insert x v dict)
+                   return (varN v)
                 where
                   flex | "number"     `isPrefixOf` x = Is Number
                        | "comparable" `isPrefixOf` x = Is Comparable
                        | "appendable" `isPrefixOf` x = Is Appendable
                        | otherwise = Flexible
 
-        Src.Data name ts -> do
+        T.Aliased name t -> do
+          t' <- go t
+          case t' of
+            VarN _ v     -> return (VarN (Just name) v)
+            TermN _ term -> return (TermN (Just name) term)
+
+        T.Type name ->
+          case Map.lookup (V.toString name) (types env) of
+            Just t  -> return t
+            Nothing -> error $ "Could not find type constructor '" ++
+                               V.toString name ++ "' while checking types."
+
+        T.App t ts -> do
+          t'  <- go t
           ts' <- mapM go ts
-          case (Map.lookup name (types env), Map.lookup name (aliases env)) of
-            (Just t, _) -> return $ foldl (<|) t ts'
-            (_, Just (tvars, t)) ->
-                let tvarLen = length tvars
-                    msg = "\nType alias '" ++ name ++ "' expects " ++ show tvarLen ++
-                          " type argument" ++ (if tvarLen == 1 then "" else "s") ++
-                          " but was given " ++ show (length ts')
-                in  if length ts' /= length tvars then error msg else
-                        do (dict, aliases) <- State.get
-                           let aliases' = Map.union (Map.fromList $ zip tvars ts') aliases
-                           State.put (dict, aliases')
-                           t' <- go t
-                           State.put (dict, aliases)
-                           return t'
-            _ -> error $ "\nCould not find type constructor '" ++
-                         name ++ "' while checking types."
+          return $ foldl (<|) t' ts'
 
-        Src.Record fields ext -> do
-          fields' <- Traverse.traverse (mapM go) (Src.fieldMap fields)
+        T.Record fields ext -> do
+          fields' <- Traverse.traverse (mapM go) (T.fieldMap fields)
           ext' <- case ext of
-                    Nothing -> return $ TermN EmptyRecord1
-                    Just x -> go (Src.Var x)
-          return $ TermN (Record1 fields' ext')
+                    Nothing -> return $ termN EmptyRecord1
+                    Just x -> go x
+          return $ termN (Record1 fields' ext')
diff --git a/compiler/Type/ExtraChecks.hs b/compiler/Type/ExtraChecks.hs
--- a/compiler/Type/ExtraChecks.hs
+++ b/compiler/Type/ExtraChecks.hs
@@ -1,148 +1,156 @@
-{-# OPTIONS_GHC -W #-}
+{-# OPTIONS_GHC -Wall #-}
+
+{-| This module contains checks to be run *after* type inference has completed
+successfully. At that point we still need to do occurs checks and ensure that
+`main` has an acceptable type.
+-}
 module Type.ExtraChecks (mainType, occurs, portTypes) where
--- This module contains checks to be run *after* type inference has
--- completed successfully. At that point we still need to do occurs
--- checks and ensure that `main` has an acceptable type.
 
 import Control.Applicative ((<$>),(<*>))
+import Control.Monad.Error
 import Control.Monad.State
-import qualified Data.List as List
 import qualified Data.Map as Map
+import qualified Data.Traversable as Traverse
 import qualified Data.UnionFind.IO as UF
-import Type.Type ( Variable, structure, Term1(..), toSrcType )
-import qualified Type.State as TS
-import qualified Type.Alias as Alias
 import Text.PrettyPrint as P
-import SourceSyntax.PrettyPrint (pretty)
-import qualified SourceSyntax.Helpers as Help
-import qualified SourceSyntax.Type as T
-import qualified SourceSyntax.Expression as E
-import qualified SourceSyntax.Location as L
+
+import qualified AST.Annotation as A
+import qualified AST.Expression.Canonical as Canonical
+import qualified AST.PrettyPrint as PP
+import qualified AST.Type as ST
+import qualified AST.Variable as V
 import qualified Transform.Expression as Expr
-import qualified Data.Traversable as Traverse
+import qualified Type.Type as TT
+import qualified Type.State as TS
 
+throw :: [Doc] -> Either [Doc] a
 throw err = Left [ P.vcat err ]
 
-mainType :: Alias.Rules -> TS.Env -> IO (Either [P.Doc] (Map.Map String T.Type))
-mainType rules env = mainCheck rules <$> Traverse.traverse toSrcType env
+mainType :: TS.Env -> ErrorT [P.Doc] IO (Map.Map String ST.CanonicalType)
+mainType environment =
+  do environment' <- liftIO $ Traverse.traverse TT.toSrcType environment
+     mainCheck environment'
   where
-    mainCheck :: Alias.Rules -> Map.Map String T.Type -> Either [P.Doc] (Map.Map String T.Type)
-    mainCheck rules env =
+    mainCheck :: (Monad m) => Map.Map String ST.CanonicalType
+              -> ErrorT [P.Doc] m (Map.Map String ST.CanonicalType)
+    mainCheck env =
       case Map.lookup "main" env of
-        Nothing -> Right env
-        Just mainType
-            | tipe `elem` acceptable -> Right env
-            | otherwise              -> throw err
+        Nothing -> return env
+        Just typeOfMain
+            | tipe `elem` acceptable -> return env
+            | otherwise              -> throwError err
             where
               acceptable = [ "Graphics.Element.Element"
                            , "Signal.Signal Graphics.Element.Element" ]
 
-              tipe = P.render . pretty $ Alias.canonicalRealias (fst rules) mainType
+              tipe = PP.renderPretty typeOfMain
               err = [ P.text "Type Error: 'main' must have type Element or (Signal Element)."
                     , P.text "Instead 'main' has type:\n"
-                    , P.nest 4 . pretty $ Alias.realias rules mainType
+                    , P.nest 4 (PP.pretty typeOfMain)
                     , P.text " " ]
 
 data Direction = In | Out
 
-portTypes :: Alias.Rules -> E.LExpr -> Either [P.Doc] ()
-portTypes rules expr =
-  const () <$> Expr.checkPorts (check In) (check Out) expr
+portTypes :: (Monad m) => Canonical.Expr -> ErrorT [P.Doc] m ()
+portTypes expr =
+  case Expr.checkPorts (check In) (check Out) expr of
+    Left err -> throwError err
+    Right _  -> return ()
   where
     check = isValid True False False
     isValid isTopLevel seenFunc seenSignal direction name tipe =
         case tipe of
-          T.Data ctor ts
-              | isJs ctor || isElm ctor -> mapM_ valid ts
-              | ctor == "Signal.Signal" -> handleSignal ts
-              | otherwise               -> err' True "an unsupported type"
+          ST.Aliased _ t -> valid t
 
-          T.Var _ -> err "free type variables"
+          ST.Type v
+              | V.isJson v      -> return ()
+              | V.isPrimitive v -> return ()
+              | V.isTuple v     -> return ()
+              | otherwise       -> err "an unsupported type"
 
-          T.Lambda _ _ ->
+          ST.App t [] -> valid t
+
+          ST.App (ST.Type v) [t]
+              | V.isSignal v -> handleSignal t
+              | V.isMaybe  v -> valid t
+              | V.isArray  v -> valid t
+              | V.isList   v -> valid t
+
+          ST.App (ST.Type v) ts
+              | V.isTuple v -> mapM_ valid ts
+                    
+          ST.App _ _ -> err "an unsupported type"
+
+          ST.Var _ -> err "free type variables"
+
+          ST.Lambda _ _ ->
               case direction of
                 In -> err "functions"
                 Out | seenFunc   -> err "higher-order functions"
                     | seenSignal -> err "signals that contain functions"
                     | otherwise  ->
-                        forM_ (T.collectLambdas tipe)
+                        forM_ (ST.collectLambdas tipe)
                               (isValid' True seenSignal direction name)
 
-          T.Record _ (Just _) -> err "extended records with free type variables"
+          ST.Record _ (Just _) -> err "extended records with free type variables"
 
-          T.Record fields Nothing ->
+          ST.Record fields Nothing ->
               mapM_ (\(k,v) -> (,) k <$> valid v) fields
 
         where
           isValid' = isValid False
           valid = isValid' seenFunc seenSignal direction name
 
-          isJs ctor =
-              List.isPrefixOf "JavaScript." ctor
-              && length (filter (=='.') ctor) == 1
-
-          isElm ctor =
-              ctor `elem` ["Int","Float","String","Bool","Maybe.Maybe","_List"]
-              || Help.isTuple ctor
-
-          handleSignal ts
+          handleSignal t
               | seenFunc   = err "functions that involve signals"
               | seenSignal = err "signals-of-signals"
-              | isTopLevel = mapM_ (isValid' seenFunc True direction name) ts
+              | isTopLevel = isValid' seenFunc True direction name t
               | otherwise  = err "a signal within a data stucture"
 
           dir inMsg outMsg = case direction of { In -> inMsg ; Out -> outMsg }
           txt = P.text . concat
 
-          err = err' False
-          err' couldBeAlias kind =
+          err kind =
               throw $
               [ txt [ "Type Error: the value ", dir "coming in" "sent out"
                     , " through port '", name, "' is invalid." ]
               , txt [ "It contains ", kind, ":\n" ]
-              , (P.nest 4 . pretty $ Alias.realias rules tipe) <> P.text "\n"
-              , txt [ "Acceptable values for ", dir "incoming" "outgoing"
-                    , " ports include JavaScript values and" ]
-              , txt [ "the following Elm values: Ints, Floats, Bools, Strings, Maybes," ]
-              , txt [ "Lists, Tuples, ", dir "" "first-order functions, ", "and concrete records." ]
-              ] ++ if couldBeAlias then aliasWarning else []
-
-          aliasWarning =
-              [ txt [ "\nType aliases are not expanded for this check (yet) so you need to do that" ]
-              , txt [ "manually for now (e.g. {x:Int,y:Int} instead of a type alias of that type)." ]
+              , P.nest 4 (PP.pretty tipe) <> P.text "\n"
+              , txt [ "Acceptable values for ", dir "incoming" "outgoing", " ports include:" ]
+              , txt [ "    Ints, Floats, Bools, Strings, Maybes, Lists, Arrays, Tuples, unit values," ]
+              , txt [ "    Json.Values, ", dir "" "first-order functions, ", "and concrete records." ]
               ]
 
-occurs :: (String, Variable) -> StateT TS.SolverState IO ()
+occurs :: (String, TT.Variable) -> StateT TS.SolverState IO ()
 occurs (name, variable) =
   do vars <- liftIO $ infiniteVars [] variable
      case vars of
        [] -> return ()
        var:_ -> do
          desc <- liftIO $ UF.descriptor var
-         case structure desc of
+         case TT.structure desc of
            Nothing ->
-               modify $ \state -> state { TS.sErrors = fallback : TS.sErrors state }
+               modify $ \s -> s { TS.sErrors = P.text msg : TS.sErrors s }
            Just _ ->
-               do liftIO $ UF.setDescriptor var (desc { structure = Nothing })
+               do liftIO $ UF.setDescriptor var (desc { TT.structure = Nothing })
                   var' <- liftIO $ UF.fresh desc
-                  TS.addError (L.NoSpan name) (Just msg) var var'
+                  TS.addError (A.None (P.text name)) (Just msg) var var'
   where
     msg = "Infinite types are not allowed"
-    fallback _ = return $ P.text msg
 
-    infiniteVars :: [Variable] -> Variable -> IO [Variable]
+    infiniteVars :: [TT.Variable] -> TT.Variable -> IO [TT.Variable]
     infiniteVars seen var =
         let go = infiniteVars (var:seen) in
         if var `elem` seen
         then return [var]
         else do
           desc <- UF.descriptor var
-          case structure desc of
+          case TT.structure desc of
             Nothing -> return []
             Just struct ->
                 case struct of
-                  App1 a b -> (++) <$> go a <*> go b
-                  Fun1 a b -> (++) <$> go a <*> go b
-                  Var1 a   -> go a
-                  EmptyRecord1 -> return []
-                  Record1 fields ext -> concat <$> mapM go (ext : concat (Map.elems fields))
+                  TT.App1 a b -> (++) <$> go a <*> go b
+                  TT.Fun1 a b -> (++) <$> go a <*> go b
+                  TT.Var1 a   -> go a
+                  TT.EmptyRecord1 -> return []
+                  TT.Record1 fields ext -> concat <$> mapM go (ext : concat (Map.elems fields))
diff --git a/compiler/Type/Fragment.hs b/compiler/Type/Fragment.hs
--- a/compiler/Type/Fragment.hs
+++ b/compiler/Type/Fragment.hs
@@ -4,25 +4,24 @@
 import qualified Data.Map as Map
 
 import Type.Type
-import SourceSyntax.Pattern
-import SourceSyntax.Location (noneNoDocs)
+import AST.Pattern
+import AST.Annotation (noneNoDocs)
 
-data Fragment = Fragment {
-    typeEnv        :: Map.Map String Type,
-    vars           :: [Variable],
-    typeConstraint :: TypeConstraint
-} deriving Show
+data Fragment = Fragment
+    { typeEnv        :: Map.Map String Type
+    , vars           :: [Variable]
+    , typeConstraint :: TypeConstraint
+    } deriving Show
 
 emptyFragment = Fragment Map.empty [] (noneNoDocs CTrue)
 
-joinFragment f1 f2 = Fragment {
-    typeEnv = Map.union (typeEnv f1) (typeEnv f2),
-    vars    = vars f1 ++ vars f2,
-    typeConstraint = typeConstraint f1 /\ typeConstraint f2
-}
+joinFragment f1 f2 = Fragment
+    { typeEnv        = Map.union (typeEnv f1) (typeEnv f2)
+    , vars           = vars f1 ++ vars f2
+    , typeConstraint = typeConstraint f1 /\ typeConstraint f2
+    }
 
 joinFragments = List.foldl' (flip joinFragment) emptyFragment
-
 
 toScheme fragment =
     Scheme [] (vars fragment) (typeConstraint fragment) (typeEnv fragment)
diff --git a/compiler/Type/Inference.hs b/compiler/Type/Inference.hs
--- a/compiler/Type/Inference.hs
+++ b/compiler/Type/Inference.hs
@@ -8,50 +8,86 @@
 import qualified Type.Constrain.Expression as TcExpr
 import qualified Type.Solve as Solve
 
-import SourceSyntax.Module as Module
-import SourceSyntax.Location (noneNoDocs)
-import SourceSyntax.Type (Type)
+import qualified AST.Annotation as A
+import AST.Module as Module
+import AST.Type (CanonicalType)
+import qualified AST.Variable as Var
 import Text.PrettyPrint
 import qualified Type.State as TS
 import qualified Type.ExtraChecks as Check
+import Control.Arrow (first, second)
 import Control.Monad.State (execStateT, forM)
-import Control.Monad.Error (runErrorT, liftIO)
-import qualified Type.Alias as Alias
+import Control.Monad.Error (ErrorT, runErrorT, liftIO, throwError)
 
 import System.IO.Unsafe  -- Possible to switch over to the ST monad instead of
                          -- the IO monad. I don't think that'd be worthwhile.
 
 
-infer :: Interfaces -> MetadataModule -> Either [Doc] (Map.Map String Type)
-infer interfaces modul = unsafePerformIO $ do
-  env <- Env.initialEnvironment
-             (datatypes modul ++ concatMap iAdts (Map.elems interfaces))
-             (aliases modul ++ concatMap iAliases (Map.elems interfaces))
-  ctors <- forM (Map.keys (Env.constructor env)) $ \name ->
-               do (_, vars, args, result) <- Env.freshDataScheme env name
-                  return (name, (vars, foldr (T.==>) result args))
+infer :: Interfaces -> CanonicalModule -> Either [Doc] (Map.Map String CanonicalType)
+infer interfaces modul = unsafePerformIO $ runErrorT $ do
+  (header, constraint) <- genConstraints interfaces modul
 
-  attemptConstraint <- runErrorT $ do
-    importedVars <-
-        forM (concatMap (Map.toList . iTypes) $ Map.elems interfaces) $ \(name,tipe) ->
-            (,) name `fmap` Env.instantiateType env tipe Map.empty
+  state <- liftIO $ execStateT (Solve.solve constraint) TS.initialState
 
-    let allTypes = ctors ++ importedVars
-        vars = concatMap (fst . snd) allTypes
-        header = Map.map snd (Map.fromList allTypes)
-        environ = noneNoDocs . T.CLet [ T.Scheme vars [] (noneNoDocs T.CTrue) header ]
+  () <- case TS.sErrors state of
+          errors@(_:_) -> throwError errors
+          []           -> return ()
 
-    fvar <- liftIO $ T.var T.Flexible
-    c <- TcExpr.constrain env (program modul) (T.VarN fvar)
-    return (header, environ c)
+  () <- Check.portTypes (program (body modul))
 
-  case attemptConstraint of
-    Left err -> return $ Left err
-    Right (header, constraint) -> do
-      state <- execStateT (Solve.solve constraint) TS.initialState
-      let rules = Alias.rules interfaces (aliases modul) (imports modul)
-      case TS.sErrors state of
-        errors@(_:_) -> Left `fmap` sequence (map ($ rules) (reverse errors))
-        [] -> case Check.portTypes rules (program modul) of
-                Right () -> Check.mainType rules (Map.difference (TS.sSavedEnv state) header)
-                Left err -> return (Left err)
+  let header' = Map.delete "::" header
+      types = Map.difference (TS.sSavedEnv state) header'
+
+  Check.mainType types
+
+
+genConstraints :: Interfaces -> CanonicalModule
+               -> ErrorT [Doc] IO (Env.TypeDict, T.TypeConstraint)
+genConstraints interfaces modul = do
+  env <- liftIO $ Env.initialEnvironment (canonicalizeAdts interfaces modul)
+
+  ctors <- forM (Map.keys (Env.constructor env)) $ \name -> do
+             (_, vars, args, result) <- liftIO $ Env.freshDataScheme env name
+             return (name, (vars, foldr (T.==>) result args))
+
+  importedVars <- mapM (canonicalizeValues env) (Map.toList interfaces)
+
+  let allTypes = concat (ctors : importedVars)
+      vars = concatMap (fst . snd) allTypes
+      header = Map.map snd (Map.fromList allTypes)
+      environ = A.noneNoDocs . T.CLet [ T.Scheme vars [] (A.noneNoDocs T.CTrue) header ]
+
+  fvar <- liftIO $ T.variable T.Flexible
+  c <- TcExpr.constrain env (program (body modul)) (T.varN fvar)
+  return (header, environ c)
+
+
+canonicalizeValues :: Env.Environment -> (String, Interface)
+                   -> ErrorT [Doc] IO [(String, ([T.Variable], T.Type))]
+canonicalizeValues env (moduleName, iface) =
+    forM (Map.toList (iTypes iface)) $ \(name,tipe) -> do
+      tipe' <- Env.instantiateType env tipe Map.empty
+      return (moduleName ++ "." ++ name, tipe')
+
+canonicalizeAdts :: Interfaces -> CanonicalModule -> [CanonicalAdt]
+canonicalizeAdts interfaces modul =
+    localAdts ++ importedAdts
+  where
+    localAdts :: [CanonicalAdt]
+    localAdts = format (Module.getName modul, datatypes (body modul))
+
+    importedAdts :: [CanonicalAdt]
+    importedAdts = concatMap (format . second iAdts) (Map.toList interfaces)
+
+    format :: (String, Module.ADTs) -> [CanonicalAdt]
+    format (home, adts) =
+        map canonical (Map.toList adts)
+      where
+        canonical :: (String, AdtInfo String) -> CanonicalAdt
+        canonical (name, (tvars, ctors)) =
+            ( toVar name
+            , (tvars, map (first toVar) ctors)
+            )
+
+        toVar :: String -> Var.Canonical
+        toVar = Var.Canonical (Var.Module home)
diff --git a/compiler/Type/PrettyPrint.hs b/compiler/Type/PrettyPrint.hs
--- a/compiler/Type/PrettyPrint.hs
+++ b/compiler/Type/PrettyPrint.hs
@@ -2,15 +2,15 @@
 module Type.PrettyPrint where
 
 import Text.PrettyPrint
-import qualified SourceSyntax.PrettyPrint as Src
+import qualified AST.PrettyPrint as Src
 
 data ParensWhen = Fn | App | Never
 
 class PrettyType a where
   pretty :: ParensWhen -> a -> Doc
 
+commaSep :: [Doc] -> Doc
 commaSep docs = sep (punctuate comma docs)
 
+parensIf :: Bool -> Doc -> Doc
 parensIf bool doc = if bool then parens doc else doc
-
-reprime = Src.reprime
diff --git a/compiler/Type/Solve.hs b/compiler/Type/Solve.hs
--- a/compiler/Type/Solve.hs
+++ b/compiler/Type/Solve.hs
@@ -3,15 +3,15 @@
 
 import Control.Monad
 import Control.Monad.State
-import qualified Data.UnionFind.IO as UF
+import qualified Data.List as List
 import qualified Data.Map as Map
 import qualified Data.Traversable as Traversable
-import qualified Data.List as List
+import qualified Data.UnionFind.IO as UF
 import Type.Type
 import Type.Unify
 import qualified Type.ExtraChecks as Check
 import qualified Type.State as TS
-import SourceSyntax.Location (Located(L), SrcSpan)
+import qualified AST.Annotation as A
 
 
 -- | Every variable has rank less than or equal to the maxRank of the pool.
@@ -21,9 +21,9 @@
   youngMark <- TS.uniqueMark 
   let youngRank = TS.maxRank youngPool
       insert dict var = do
-        desc <- liftIO $ UF.descriptor var
+        descriptor <- liftIO $ UF.descriptor var
         liftIO $ UF.modifyDescriptor var (\desc -> desc { mark = youngMark })
-        return $ Map.insertWith (++) (rank desc) [var] dict
+        return $ Map.insertWith (++) (rank descriptor) [var] dict
 
   -- Sort the youngPool variables by rank.
   rankDict <- foldM insert Map.empty (TS.inhabitants youngPool)
@@ -32,7 +32,8 @@
   -- start at low ranks so that we only have to pass
   -- over the information once.
   visitedMark <- TS.uniqueMark
-  mapM (\(poolRank, vars) -> mapM (adjustRank youngMark visitedMark poolRank) vars) (Map.toList rankDict)
+  forM (Map.toList rankDict) $ \(poolRank, vars) ->
+      mapM (adjustRank youngMark visitedMark poolRank) vars
 
   -- For variables that have rank lowerer than youngRank, register them in
   -- the old pool if they are not redundant.
@@ -64,39 +65,42 @@
 -- adjust the ranks of variables such that ranks never increase as you
 -- move deeper into a variable.
 adjustRank :: Int -> Int -> Int -> Variable -> StateT TS.SolverState IO Int
-adjustRank youngMark visitedMark groupRank variable =
-    let adjust = adjustRank youngMark visitedMark groupRank in
-    do desc <- liftIO $ UF.descriptor variable
+adjustRank youngMark visitedMark groupRank var =
+    do descriptor <- liftIO $ UF.descriptor var
        case () of
-         () | mark desc == youngMark ->
+         () | mark descriptor == youngMark ->
                 do -- Set the variable as marked first because it may be cyclic.
-                   liftIO $ UF.modifyDescriptor variable $ \desc -> desc { mark = visitedMark }
-                   rank' <- case structure desc of
-                              Nothing -> return groupRank
-                              Just term ->
-                                  case term of
-                                    App1 a b -> max `liftM` adjust a `ap` adjust b
-                                    Fun1 a b -> max `liftM` adjust a `ap` adjust b
-                                    Var1 x -> adjust x
-                                    EmptyRecord1 -> return outermostRank
-                                    Record1 fields extension ->
-                                        do ranks <- mapM adjust (concat (Map.elems fields))
-                                           rnk <- adjust extension
-                                           return . maximum $ rnk : ranks
-                   liftIO $ UF.modifyDescriptor variable $ \desc -> desc { rank = rank' }
+                   liftIO $ UF.modifyDescriptor var $ \desc ->
+                       desc { mark = visitedMark }
+                   rank' <- maybe (return groupRank) adjustTerm (structure descriptor)
+                   liftIO $ UF.modifyDescriptor var $ \desc ->
+                       desc { rank = rank' }
                    return rank'
 
-            | mark desc /= visitedMark ->
-                do let rank' = min groupRank (rank desc)
-                   liftIO $ UF.setDescriptor variable (desc { mark = visitedMark, rank = rank' })
+            | mark descriptor /= visitedMark ->
+                do let rank' = min groupRank (rank descriptor)
+                   liftIO $ UF.setDescriptor var (descriptor { mark = visitedMark, rank = rank' })
                    return rank'
 
-            | otherwise -> return (rank desc)
+            | otherwise -> return (rank descriptor)
 
+    where
+      adjust = adjustRank youngMark visitedMark groupRank
 
+      adjustTerm term =
+          case term of
+            App1 a b -> max `liftM` adjust a `ap` adjust b
+            Fun1 a b -> max `liftM` adjust a `ap` adjust b
+            Var1 x -> adjust x
+            EmptyRecord1 -> return outermostRank
+            Record1 fields extension ->
+                do ranks <- mapM adjust (concat (Map.elems fields))
+                   rnk <- adjust extension
+                   return . maximum $ rnk : ranks
 
+
 solve :: TypeConstraint -> StateT TS.SolverState IO ()
-solve (L span constraint) =
+solve (A.A region constraint) =
   case constraint of
     CTrue -> return ()
 
@@ -105,11 +109,11 @@
     CEqual term1 term2 -> do
         t1 <- TS.flatten term1
         t2 <- TS.flatten term2
-        unify span t1 t2
+        unify region t1 t2
 
     CAnd cs -> mapM_ solve cs
 
-    CLet [Scheme [] fqs constraint' _] (L _ CTrue) -> do
+    CLet [Scheme [] fqs constraint' _] (A.A _ CTrue) -> do
         oldEnv <- TS.getEnv
         mapM TS.introduce fqs
         solve constraint'
@@ -117,7 +121,7 @@
 
     CLet schemes constraint' -> do
         oldEnv <- TS.getEnv
-        headers <- Map.unions `fmap` mapM (solveScheme span) schemes
+        headers <- Map.unions `fmap` mapM (solveScheme region) schemes
         TS.modifyEnv $ \env -> Map.union headers env
         solve constraint'
         mapM Check.occurs $ Map.toList headers
@@ -129,15 +133,15 @@
             case Map.lookup name env of
               Just tipe -> TS.makeInstance tipe
               Nothing
-                | List.isPrefixOf "Native." name -> liftIO (var Flexible)
+                | List.isPrefixOf "Native." name -> liftIO (variable Flexible)
                 | otherwise ->
                     error ("Could not find '" ++ name ++ "' when solving type constraints.")
 
         t <- TS.flatten term
-        unify span freshCopy t
+        unify region freshCopy t
 
-solveScheme :: SrcSpan -> TypeScheme -> StateT TS.SolverState IO (Map.Map String Variable)
-solveScheme span scheme =
+solveScheme :: A.Region -> TypeScheme -> StateT TS.SolverState IO (Map.Map String Variable)
+solveScheme region scheme =
     case scheme of
       Scheme [] [] constraint header -> do
           solve constraint
@@ -154,39 +158,39 @@
           header' <- Traversable.traverse TS.flatten header
           solve constraint
 
-          allDistinct span rigidQuantifiers
+          allDistinct region rigidQuantifiers
           youngPool <- TS.getPool
           TS.switchToPool oldPool
           generalize youngPool
-          mapM (isGeneric span) rigidQuantifiers
+          mapM (isGeneric region) rigidQuantifiers
           return header'
 
 
 -- Checks that all of the given variables belong to distinct equivalence classes.
 -- Also checks that their structure is Nothing, so they represent a variable, not
 -- a more complex term.
-allDistinct :: SrcSpan -> [Variable] -> StateT TS.SolverState IO ()
-allDistinct span vars = do
+allDistinct :: A.Region -> [Variable] -> StateT TS.SolverState IO ()
+allDistinct region vars = do
   seen <- TS.uniqueMark
   let check var = do
         desc <- liftIO $ UF.descriptor var
         case structure desc of
-          Just _ -> TS.addError span (Just msg) var var
+          Just _ -> TS.addError region (Just msg) var var
               where msg = "Cannot generalize something that is not a type variable."
 
           Nothing -> do
             if mark desc == seen
               then let msg = "Duplicate variable during generalization."
-                   in  TS.addError span (Just msg) var var
+                   in  TS.addError region (Just msg) var var
               else return ()
             liftIO $ UF.setDescriptor var (desc { mark = seen })
   mapM_ check vars
 
 -- Check that a variable has rank == noRank, meaning that it can be generalized.
-isGeneric :: SrcSpan -> Variable -> StateT TS.SolverState IO ()
-isGeneric span var = do
+isGeneric :: A.Region -> Variable -> StateT TS.SolverState IO ()
+isGeneric region var = do
   desc <- liftIO $ UF.descriptor var
   if rank desc == noRank
     then return ()
     else let msg = "Unable to generalize a type variable. It is not unranked."
-         in  TS.addError span (Just msg) var var
+         in  TS.addError region (Just msg) var var
diff --git a/compiler/Type/State.hs b/compiler/Type/State.hs
--- a/compiler/Type/State.hs
+++ b/compiler/Type/State.hs
@@ -1,26 +1,26 @@
 {-# OPTIONS_GHC -W #-}
 module Type.State where
 
-import Type.Type
-import qualified Data.Map as Map
-import qualified Data.UnionFind.IO as UF
+import Control.Applicative ( (<$>), (<*>), Applicative, (<|>) )
 import Control.Monad.State
-import Control.Applicative ((<$>),(<*>), Applicative)
+import qualified Data.Map as Map
 import qualified Data.Traversable as Traversable
+import qualified Data.UnionFind.IO as UF
+
+import qualified AST.Annotation as A
+import AST.PrettyPrint
 import Text.PrettyPrint as P
-import SourceSyntax.PrettyPrint
-import SourceSyntax.Location
-import qualified Type.Alias as Alias
+import Type.Type
 
 -- Pool
 -- Holds a bunch of variables
 -- The rank of each variable is less than or equal to the pool's "maxRank"
 -- The young pool exists to make it possible to identify these vars in constant time.
 
-data Pool = Pool {
-  maxRank :: Int,
-  inhabitants :: [Variable]
-} deriving Show
+data Pool = Pool
+    { maxRank :: Int
+    , inhabitants :: [Variable]
+    } deriving Show
 
 emptyPool = Pool { maxRank = outermostRank, inhabitants = [] }
 
@@ -32,7 +32,7 @@
     sSavedEnv :: Env,
     sPool :: Pool,
     sMark :: Int,
-    sErrors :: [Alias.Rules -> IO P.Doc]
+    sErrors :: [P.Doc]
 }
 
 initialState = SS {
@@ -46,32 +46,25 @@
 modifyEnv  f = modify $ \state -> state { sEnv = f (sEnv state) }
 modifyPool f = modify $ \state -> state { sPool = f (sPool state) }
 
-addError span hint t1 t2 =
-    modify $ \state -> state { sErrors = makeError : sErrors state }
+addError :: A.Region -> Maybe String -> UF.Point Descriptor -> UF.Point Descriptor
+         -> StateT SolverState IO ()
+addError region hint t1 t2 =
+  do err <- liftIO makeError
+     modify $ \state -> state { sErrors = err : sErrors state }
   where
-    makeError rules = do
-      let prettiest = pretty . Alias.realias rules
-      t1' <- prettiest <$> toSrcType t1
-      t2' <- prettiest <$> toSrcType t2
+    makeError = do
+      t1' <- pretty <$> toSrcType t1
+      t2' <- pretty <$> toSrcType t2
       return . P.vcat $
-         [ P.text $ "Type error" ++ location ++ ":"
+         [ P.text "Type error" <+> pretty region <> P.colon
          , maybe P.empty P.text hint
-         , display $ case span of { NoSpan msg -> msg ; Span _ _ msg -> msg }
+         , P.text ""
+         , P.nest 8 $ A.getRegionDocs region
+         , P.text ""
          , P.text "   Expected Type:" <+> t1'
          , P.text "     Actual Type:" <+> t2'
          ]
 
-    location = case span of
-                 NoSpan _ -> ""
-                 Span p1 p2 _ ->
-                     if line p1 == line p2 then " on line " ++ show (line p1)
-                     else " between lines " ++ show (line p1) ++ " and " ++ show (line p2)
-
-    display msg =
-        P.vcat [ P.text $ concatMap ("\n        "++) (lines msg)
-               , P.text " " ]
-
-
 switchToPool pool = modifyPool (\_ -> pool)
 
 getPool :: StateT SolverState IO Pool
@@ -111,17 +104,20 @@
 flatten :: Type -> StateT SolverState IO Variable
 flatten term =
   case term of
-    VarN v -> return v
-    TermN t -> do
+    VarN maybeAlias v -> do
+      liftIO $ UF.modifyDescriptor v $ \desc -> desc { alias = maybeAlias <|> alias desc }
+      return v
+    TermN maybeAlias t -> do
       flatStructure <- traverseTerm flatten t
       pool <- getPool
-      var <- liftIO . UF.fresh $ Descriptor {
-               structure = Just flatStructure,
-               rank = maxRank pool,
-               flex = Flexible,
-               name = Nothing,
-               copy = Nothing,
-               mark = noMark
+      var <- liftIO . UF.fresh $ Descriptor
+             { structure = Just flatStructure
+             , rank = maxRank pool
+             , flex = Flexible
+             , name = Nothing
+             , copy = Nothing
+             , mark = noMark
+             , alias = maybeAlias
              }
       register var
 
@@ -147,18 +143,19 @@
 
        | otherwise -> do
            pool <- getPool
-           newVar <- liftIO $ UF.fresh $ Descriptor {
-                                   structure = Nothing,
-                                   rank = maxRank pool,
-                                   mark = noMark,
-                                   flex = case flex desc of
-                                            Is s -> Is s
-                                            _ -> Flexible,
-                                   copy = Nothing,
-                                   name = case flex desc of
-                                            Rigid -> Nothing
-                                            _ -> name desc
-                                 }
+           newVar <- liftIO $ UF.fresh $ Descriptor
+                     { structure = Nothing
+                     , rank = maxRank pool
+                     , mark = noMark
+                     , flex = case flex desc of
+                                Is s -> Is s
+                                _ -> Flexible
+                     , copy = Nothing
+                     , name = case flex desc of
+                                Rigid -> Nothing
+                                _ -> name desc
+                     , alias = Nothing
+                     }
            register newVar
 
            -- Link the original variable to the new variable. This lets us
diff --git a/compiler/Type/Type.hs b/compiler/Type/Type.hs
--- a/compiler/Type/Type.hs
+++ b/compiler/Type/Type.hs
@@ -1,3 +1,4 @@
+{-# OPTIONS_GHC -W #-}
 module Type.Type where
 
 import qualified Data.Char as Char
@@ -8,12 +9,13 @@
 import Text.PrettyPrint as P
 import System.IO.Unsafe
 import Control.Applicative ((<$>),(<*>))
-import Control.Monad.State
-import Control.Monad.Error
+import Control.Monad.State (StateT, get, put, execStateT, runStateT)
+import Control.Monad.Error (ErrorT, Error, liftIO)
 import Data.Traversable (traverse)
-import SourceSyntax.Location
-import SourceSyntax.Helpers (isTuple)
-import qualified SourceSyntax.Type as Src
+import AST.Annotation
+import qualified AST.PrettyPrint as PP
+import qualified AST.Type as T
+import qualified AST.Variable as Var
 
 data Term1 a
     = App1 a a
@@ -24,18 +26,24 @@
     deriving Show
 
 data TermN a
-    = VarN a
-    | TermN (Term1 (TermN a))
+    = VarN  (Maybe Var.Canonical) a
+    | TermN (Maybe Var.Canonical) (Term1 (TermN a))
     deriving Show
 
+varN :: a -> TermN a
+varN = VarN Nothing
+
+termN :: (Term1 (TermN a)) -> TermN a
+termN = TermN Nothing
+
 record :: Map.Map String [TermN a] -> TermN a -> TermN a
-record fs rec = TermN (Record1 fs rec)
+record fs rec = termN (Record1 fs rec)
 
 type Type = TermN Variable
 type Variable = UF.Point Descriptor
 
 type SchemeName = String
-type TypeName = String
+type TypeName = Var.Canonical
 
 type Constraint a b = Located (BasicConstraint a b)
 data BasicConstraint a b
@@ -57,12 +65,13 @@
 type TypeConstraint = Constraint Type Variable
 type TypeScheme = Scheme Type Variable
 
+monoscheme :: Map.Map String a -> Scheme a b
 monoscheme headers = Scheme [] [] (noneNoDocs CTrue) headers
 
 infixl 8 /\
 
 (/\) :: Constraint a b -> Constraint a b -> Constraint a b
-a@(L _ c1) /\ b@(L _ c2) =
+a@(A _ c1) /\ b@(A _ c2) =
     case (c1, c2) of
       (CTrue, _) -> b
       (_, CTrue) -> a
@@ -70,23 +79,31 @@
 
 infixr 9 ==>
 (==>) :: Type -> Type -> Type
-a ==> b = TermN (Fun1 a b)
+a ==> b = termN (Fun1 a b)
 
-f <| a = TermN (App1 f a)
+(<|) :: TermN a -> TermN a -> TermN a
+f <| a = termN (App1 f a)
 
-data Descriptor = Descriptor {
-    structure :: Maybe (Term1 Variable),
-    rank :: Int,
-    flex :: Flex,
-    name :: Maybe TypeName,
-    copy :: Maybe Variable,
-    mark :: Int
-} deriving Show
+data Descriptor = Descriptor
+    { structure :: Maybe (Term1 Variable)
+    , rank :: Int
+    , flex :: Flex
+    , name :: Maybe TypeName
+    , copy :: Maybe Variable
+    , mark :: Int
+    , alias :: Maybe Var.Canonical
+    } deriving Show
 
+noRank :: Int
 noRank = -1
-outermostRank = 0 :: Int
 
+outermostRank :: Int
+outermostRank = 0
+
+noMark :: Int
 noMark = 0
+
+initialMark :: Int
 initialMark = 1
 
 data Flex = Rigid | Flexible | Constant | Is SuperType
@@ -95,51 +112,50 @@
 data SuperType = Number | Comparable | Appendable
      deriving (Show, Eq)
 
-namedVar :: Flex -> String -> IO Variable
-namedVar flex name = UF.fresh $ Descriptor {
-    structure = Nothing,
-    rank = noRank,
-    flex = flex,
-    name = Just name,
-    copy = Nothing,
-    mark = noMark
-  }
-
-var :: Flex -> IO Variable
-var flex = UF.fresh $ Descriptor {
-    structure = Nothing,
-    rank = noRank,
-    flex = flex,
-    name = Nothing,
-    copy = Nothing,
-    mark = noMark
+namedVar :: Flex -> Var.Canonical -> IO Variable
+namedVar flex name = UF.fresh $ Descriptor
+  { structure = Nothing
+  , rank = noRank
+  , flex = flex
+  , name = Just name
+  , copy = Nothing
+  , mark = noMark
+  , alias = Nothing
   }
 
-structuredVar :: Term1 Variable -> IO Variable
-structuredVar structure = UF.fresh $ Descriptor {
-    structure = Just structure,
-    rank = noRank,
-    flex = Flexible,
-    name = Nothing,
-    copy = Nothing,
-    mark = noMark
+variable :: Flex -> IO Variable
+variable flex = UF.fresh $ Descriptor
+  { structure = Nothing
+  , rank = noRank
+  , flex = flex
+  , name = Nothing
+  , copy = Nothing
+  , mark = noMark
+  , alias = Nothing
   }
 
 
 -- ex qs constraint == exists qs. constraint
 ex :: [Variable] -> TypeConstraint -> TypeConstraint
-ex fqs constraint@(L s _) = L s $ CLet [Scheme [] fqs constraint Map.empty] (L s CTrue)
+ex fqs constraint@(A ann _) =
+    A ann $ CLet [Scheme [] fqs constraint Map.empty] (A ann CTrue)
 
 -- fl qs constraint == forall qs. constraint
 fl :: [Variable] -> TypeConstraint -> TypeConstraint
-fl rqs constraint@(L s _) = L s $ CLet [Scheme rqs [] constraint Map.empty] (L s CTrue)
+fl rqs constraint@(A ann _) =
+    A ann $ CLet [Scheme rqs [] constraint Map.empty] (A ann CTrue)
 
 exists :: Error e => (Type -> ErrorT e IO TypeConstraint) -> ErrorT e IO TypeConstraint
 exists f = do
-  v <- liftIO $ var Flexible
-  ex [v] <$> f (VarN v)
+  v <- liftIO $ variable Flexible
+  ex [v] <$> f (varN v)
 
+existsNumber :: Error e => (Type -> ErrorT e IO TypeConstraint) -> ErrorT e IO TypeConstraint
+existsNumber f = do
+  v <- liftIO $ variable (Is Number)
+  ex [v] <$> f (varN v)
 
+
 instance Show a => Show (UF.Point a) where
   show point = unsafePerformIO $ fmap show (UF.descriptor point)
 
@@ -148,8 +164,8 @@
   pretty when point = unsafePerformIO $ fmap (pretty when) (UF.descriptor point)
 
 
-instance PrettyType a => PrettyType (Located a) where
-  pretty when (L _ e) = pretty when e
+instance PrettyType t => PrettyType (Annotated a t) where
+  pretty when (A _ e) = pretty when e
 
 
 instance PrettyType a => PrettyType (Term1 a) where
@@ -180,23 +196,32 @@
           prettyExt = prty ext
           extend | P.render prettyExt == "{}" = P.empty
                  | otherwise = prettyExt <+> P.text "|"
-          mkPretty f t = P.text (reprime f) <+> P.text ":" <+> prty t
+          mkPretty f t = P.text f <+> P.text ":" <+> prty t
           prettyFields = concatMap (\(f,ts) -> map (mkPretty f) ts) (Map.toList fields)
 
 
 instance PrettyType a => PrettyType (TermN a) where
   pretty when term =
     case term of
-      VarN x -> pretty when x
-      TermN t1 -> pretty when t1
-
+      VarN alias x -> either alias (pretty when x)
+      TermN alias t1 -> either alias (pretty when t1)
+    where
+      either maybeAlias doc =
+          case maybeAlias of
+            Just alias -> PP.pretty alias
+            Nothing -> doc
 
 instance PrettyType Descriptor where
-  pretty when desc =
-    case (structure desc, name desc) of
-      (Just term, _) -> pretty when term
-      (_, Just name) -> if not (isTuple name) then P.text (reprime name) else
-                            P.parens . P.text $ replicate (read (drop 6 name) - 1) ','
+  pretty when desc = do
+    case (alias desc, structure desc, name desc) of
+      (Just name, _, _) -> PP.pretty name
+      (_, Just term, _) -> pretty when term
+      (_, _, Just name)
+          | Var.isTuple name ->
+              P.parens . P.text $ replicate (read (drop 6 (Var.toString name)) - 1) ','
+          | otherwise ->
+              P.text (Var.toString name)
+                            
       _ -> P.text "?"
 
 
@@ -212,12 +237,12 @@
       CAnd cs ->
         P.parens . P.sep $ P.punctuate (P.text " and") (map (pretty Never) cs)
 
-      CLet [Scheme [] fqs constraint header] (L _ CTrue) | Map.null header ->
+      CLet [Scheme [] fqs constraint header] (A _ CTrue) | Map.null header ->
           P.sep [ binder, pretty Never c ]
         where
-          mergeExists vs (L _ c) =
+          mergeExists vs (A _ c) =
             case c of
-              CLet [Scheme [] fqs' c' _] (L _ CTrue) -> mergeExists (vs ++ fqs') c'
+              CLet [Scheme [] fqs' c' _] (A _ CTrue) -> mergeExists (vs ++ fqs') c'
               _ -> (vs, c)
 
           (fqs', c) = mergeExists fqs constraint
@@ -233,7 +258,7 @@
         P.text name <+> P.text "<" <+> prty tipe
 
 instance (PrettyType a, PrettyType b) => PrettyType (Scheme a b) where
-  pretty _ (Scheme rqs fqs (L _ constraint) headers) =
+  pretty _ (Scheme rqs fqs (A _ constraint) headers) =
       P.sep [ forall, cs, headers' ]
     where
       prty = pretty Never
@@ -262,7 +287,7 @@
     (rawVars, _, _, _) <- execStateT (crawl getNames value) ([], 0, 0, 0)
     let vars = map head . List.group $ List.sort rawVars
         suffix s = map (++s) (map (:[]) ['a'..'z'])
-        allVars = concatMap suffix $ ["","'","_"] ++ map show [0..]
+        allVars = concatMap suffix $ ["","'","_"] ++ map show [ (0 :: Int) .. ]
         okayVars = filter (`notElem` vars) allVars
     runStateT (crawl rename value) (okayVars, 0, 0, 0)
     return value
@@ -270,23 +295,20 @@
     getNames desc state@(vars, a, b, c) =
         let name' = name desc in
         case name' of
-          Just var -> (name', (var:vars, a, b, c))
-          Nothing -> (name', state)
+          Just (Var.Canonical _ var) -> (name', (var:vars, a, b, c))
+          _ -> (name', state)
 
     rename desc state@(vars, a, b, c) =
       case name desc of
         Just var -> (Just var, state)
         Nothing ->
             case flex desc of
-              Is Number     -> (Just $ "number"     ++ replicate a '\'', (vars, a+1, b, c))
-              Is Comparable -> (Just $ "comparable" ++ replicate b '\'', (vars, a, b+1, c))
-              Is Appendable -> (Just $ "appendable" ++ replicate c '\'', (vars, a, b, c+1))
-              other         -> (Just $ head vars, (tail vars, a, b, c))
-                  where mark = case other of
-                                 Flexible -> ""
-                                 Rigid    -> "!"
-                                 Constant -> "#"
-
+              Is Number     -> (local $ "number"     ++ replicate a '\'', (vars, a+1, b, c))
+              Is Comparable -> (local $ "comparable" ++ replicate b '\'', (vars, a, b+1, c))
+              Is Appendable -> (local $ "appendable" ++ replicate c '\'', (vars, a, b, c+1))
+              _             -> (local $ head vars, (tail vars, a, b, c))
+            where
+              local v = Just (Var.local v)
 
 type CrawlState = ([String], Int, Int, Int)
 
@@ -297,8 +319,8 @@
         -> t
         -> StateT CrawlState IO t
 
-instance Crawl a => Crawl (Located a) where
-  crawl nextState (L s e) = L s <$> crawl nextState e
+instance Crawl e => Crawl (Annotated a e) where
+  crawl nextState (A ann e) = A ann <$> crawl nextState e
 
 instance (Crawl t, Crawl v) => Crawl (BasicConstraint t v) where
   crawl nextState constraint = 
@@ -322,8 +344,8 @@
 instance Crawl t => Crawl (TermN t) where
   crawl nextState tipe =
     case tipe of
-      VarN x -> VarN <$> crawl nextState x
-      TermN term -> TermN <$> crawl nextState term
+      VarN a x -> VarN a <$> crawl nextState x
+      TermN a term -> TermN a <$> crawl nextState term
 
 instance Crawl t => Crawl (Term1 t) where
   crawl nextState term =
@@ -352,50 +374,71 @@
     return $ desc { name = name', structure = structure' }
 
                
-toSrcType :: Variable -> IO Src.Type
-toSrcType variable = do
-  desc <- UF.descriptor =<< addNames variable
-  case structure desc of
-    Just term ->
+toSrcType :: Variable -> IO T.CanonicalType
+toSrcType var =
+    go =<< addNames var
+  where
+    go v = do
+      desc <- UF.descriptor v
+      srcType <- maybe (backupSrcType desc) termToSrcType (structure desc)
+      return $ maybe srcType (\name -> T.Aliased name srcType) (alias desc)
+
+    backupSrcType desc = 
+        case name desc of
+          Just v@(Var.Canonical _ x@(c:_))
+              | Char.isLower c -> return (T.Var x)
+              | otherwise -> return $ T.Type v
+
+          _ -> error $ concat
+                        [ "Problem converting the following type "
+                        , "from a type-checker type to a source-syntax type:"
+                        , P.render (pretty Never var) ]
+
+    termToSrcType term =
         case term of
           App1 a b -> do
-            Src.Data name ts <- toSrcType a
-            b' <- toSrcType b
-            return (Src.Data name (ts ++ [b']))
-          Fun1 a b -> Src.Lambda <$> toSrcType a <*> toSrcType b
-          Var1 a -> toSrcType a
-          EmptyRecord1 -> return $ Src.Record [] Nothing
+            a' <- go a
+            b' <- go b
+            case a' of
+              T.App f args -> return $ T.App f (args ++ [b'])
+              _            -> return $ T.App a' [b']
+
+          Fun1 a b -> T.Lambda <$> go a <*> go b
+
+          Var1 a -> go a
+
+          EmptyRecord1 -> return $ T.Record [] Nothing
+
           Record1 tfields extension -> do
-            fields' <- traverse (mapM toSrcType) tfields
+            fields' <- traverse (mapM go) tfields
             let fields = concat [ map ((,) name) ts | (name,ts) <- Map.toList fields' ]
-            ext' <- toSrcType extension
+            ext' <- dealias <$> go extension
             return $ case ext' of
-                       Src.Record fs ext -> Src.Record (fs ++ fields) ext
-                       Src.Var x -> Src.Record fields (Just x)
+                       T.Record fs ext -> T.Record (fs ++ fields) ext
+                       T.Var _ -> T.Record fields (Just ext')
                        _ -> error "Used toSrcType on a type that is not well-formed"
-    Nothing ->
-        case name desc of
-          Just x@(c:_) | Char.isLower c -> return (Src.Var x)
-                       | otherwise      -> return (Src.Data x [])
-          _ -> error $ concat
-                        [ "Problem converting the following type "
-                        , "from a type-checker type to a source-syntax type:"
-                        , P.render (pretty Never variable) ]
 
+    dealias :: T.CanonicalType -> T.CanonicalType
+    dealias t =
+        case t of
+          T.Aliased _ t' -> t'
+          _ -> t
+
+
 data AppStructure = List Variable | Tuple [Variable] | Other
 
 collectApps :: Variable -> IO AppStructure
-collectApps variable = go [] variable
+collectApps var = go [] var
   where
-    go vars variable = do
-      desc <- UF.descriptor variable
+    go vars var = do
+      desc <- UF.descriptor var
       case (structure desc, vars) of
         (Nothing, [v]) -> case name desc of
-                             Just "_List" -> return (List v)
-                             _ -> return Other
+                            Just n | Var.isList n -> return (List v)
+                            _ -> return Other
         (Nothing,  vs) -> case name desc of
-                             Just ctor | isTuple ctor -> return (Tuple vs)
-                             _ -> return Other
+                            Just n | Var.isTuple n -> return (Tuple vs)
+                            _ -> return Other
         (Just term, _) -> case term of
                             App1 a b -> go (vars ++ [b]) a
                             _ -> return Other
diff --git a/compiler/Type/Unify.hs b/compiler/Type/Unify.hs
--- a/compiler/Type/Unify.hs
+++ b/compiler/Type/Unify.hs
@@ -1,119 +1,119 @@
 {-# OPTIONS_GHC -W #-}
 module Type.Unify (unify) where
 
-import Type.Type
-import qualified Data.UnionFind.IO as UF
+import Control.Applicative ((<|>))
+import Control.Monad.State
+import qualified Data.List as List
 import qualified Data.Map as Map
 import qualified Data.Maybe as Maybe
+import qualified Data.UnionFind.IO as UF
+import qualified AST.Annotation as A
+import qualified AST.Variable as Var
 import qualified Type.State as TS
-import Control.Monad.State
-import SourceSyntax.Location
+import Type.Type
 import Type.PrettyPrint
 import Text.PrettyPrint (render)
 
-unify :: SrcSpan -> Variable -> Variable -> StateT TS.SolverState IO ()
-unify span variable1 variable2 = do
+unify :: A.Region -> Variable -> Variable -> StateT TS.SolverState IO ()
+unify region variable1 variable2 = do
   equivalent <- liftIO $ UF.equivalent variable1 variable2
   if equivalent then return ()
-                else actuallyUnify span variable1 variable2
+                else actuallyUnify region variable1 variable2
 
-actuallyUnify :: SrcSpan -> Variable -> Variable -> StateT TS.SolverState IO ()
-actuallyUnify span variable1 variable2 = do
+actuallyUnify :: A.Region -> Variable -> Variable -> StateT TS.SolverState IO ()
+actuallyUnify region variable1 variable2 = do
   desc1 <- liftIO $ UF.descriptor variable1
   desc2 <- liftIO $ UF.descriptor variable2
-  let unify' = unify span
-
-      name' :: Maybe String
-      name' = case (name desc1, name desc2) of
-                (Just name1, Just name2) ->
-                    case (flex desc1, flex desc2) of
-                      (_, Flexible) -> Just name1
-                      (Flexible, _) -> Just name2
-                      (Is Number, Is _) -> Just name1
-                      (Is _, Is Number) -> Just name2
-                      (Is _, Is _) -> Just name1
-                      (_, _) -> Nothing
-                (Just name1, _) -> Just name1
-                (_, Just name2) -> Just name2
-                _ -> Nothing
-
-      flex' :: Flex
-      flex' = case (flex desc1, flex desc2) of
-                (f, Flexible) -> f
-                (Flexible, f) -> f
-                (Is Number, Is _) -> Is Number
-                (Is _, Is Number) -> Is Number
-                (Is super, Is _) -> Is super
-                (_, _) -> Flexible
+  let unify' = unify region
 
-      rank' :: Int
-      rank' = min (rank desc1) (rank desc2)
+      (name', flex', rank', alias') = combinedDescriptors desc1 desc2
 
       merge1 :: StateT TS.SolverState IO ()
       merge1 = liftIO $ do
         if rank desc1 < rank desc2 then UF.union variable2 variable1
                                    else UF.union variable1 variable2
         UF.modifyDescriptor variable1 $ \desc ->
-            desc { structure = structure desc1, flex = flex', name = name' }
+            desc { structure = structure desc1
+                 , flex = flex'
+                 , name = name'
+                 , alias = alias'
+                 }
 
       merge2 :: StateT TS.SolverState IO ()
       merge2 = liftIO $ do
         if rank desc1 < rank desc2 then UF.union variable2 variable1
                                    else UF.union variable1 variable2
         UF.modifyDescriptor variable2 $ \desc ->
-            desc { structure = structure desc2, flex = flex', name = name' }
+            desc { structure = structure desc2
+                 , flex = flex'
+                 , name = name'
+                 , alias = alias'
+                 }
 
       merge = if rank desc1 < rank desc2 then merge1 else merge2
 
       fresh :: Maybe (Term1 Variable) -> StateT TS.SolverState IO Variable
       fresh structure = do
-        var <- liftIO . UF.fresh $ Descriptor {
-                 structure = structure, rank = rank', flex = flex',
-                 name = name', copy = Nothing, mark = noMark
-               }
-        TS.register var
+        v <- liftIO . UF.fresh $ Descriptor
+             { structure = structure
+             , rank = rank'
+             , flex = flex'
+             , name = name'
+             , copy = Nothing
+             , mark = noMark
+             , alias = alias'
+             }
+        TS.register v
 
-      flexAndUnify var = do
-        liftIO $ UF.modifyDescriptor var $ \desc -> desc { flex = Flexible }
+      flexAndUnify v = do
+        liftIO $ UF.modifyDescriptor v $ \desc -> desc { flex = Flexible }
         unify' variable1 variable2
 
-      unifyNumber svar name
-          | name `elem` ["Int","Float","number"] = flexAndUnify svar
-          | otherwise = TS.addError span (Just hint) variable1 variable2
-          where hint = "A number must be an Int or Float."
+      unifyNumber svar (Var.Canonical home name) =
+          case home of
+            Var.BuiltIn | name `elem` ["Int","Float"]   -> flexAndUnify svar
+            Var.Local   | List.isPrefixOf "number" name -> flexAndUnify svar
+            _ -> let hint = "A number must be an Int or Float."
+                 in  TS.addError region (Just hint) variable1 variable2
 
       comparableError maybe =
-          TS.addError span (Just $ Maybe.fromMaybe msg maybe) variable1 variable2
+          TS.addError region (Just $ Maybe.fromMaybe msg maybe) variable1 variable2
           where msg = "A comparable must be an Int, Float, Char, String, list, or tuple."
 
-      unifyComparable var name
-          | name `elem` ["Int","Float","Char","String","comparable"] = flexAndUnify var
-          | otherwise = comparableError Nothing
+      appendableError maybe =
+          TS.addError region (Just $ Maybe.fromMaybe msg maybe) variable1 variable2
+          where msg = "An appendable must be of type String, List, or Text."
 
+      unifyComparable v (Var.Canonical home name) =
+          case home of
+            Var.BuiltIn | name `elem` ["Int","Float","Char","String"] -> flexAndUnify v
+            Var.Local   | List.isPrefixOf "comparable" name           -> flexAndUnify v
+            _ -> comparableError Nothing
+
       unifyComparableStructure varSuper varFlex =
           do struct <- liftIO $ collectApps varFlex
              case struct of
                Other -> comparableError Nothing
                List v -> do flexAndUnify varSuper
-                            unify' v =<< liftIO (var $ Is Comparable)
+                            unify' v =<< liftIO (variable $ Is Comparable)
                Tuple vs
                    | length vs > 6 ->
                        comparableError $ Just "Cannot compare a tuple with more than 6 elements."
                    | otherwise -> 
                        do flexAndUnify varSuper
-                          cmpVars <- liftIO $ forM [1..length vs] $ \_ -> var (Is Comparable)
+                          cmpVars <- liftIO $ forM [1..length vs] $ \_ -> variable (Is Comparable)
                           zipWithM_ unify' vs cmpVars
 
       unifyAppendable varSuper varFlex =
           do struct <- liftIO $ collectApps varFlex
              case struct of
                List _ -> flexAndUnify varSuper
-               _ -> comparableError Nothing
+               _      -> appendableError Nothing
 
-      rigidError variable = TS.addError span (Just hint) variable1 variable2
+      rigidError var = TS.addError region (Just hint) variable1 variable2
           where
-            var = "'" ++ render (pretty Never variable) ++ "'"
-            hint = "Cannot unify rigid type variable " ++ var ++
+            var' = "'" ++ render (pretty Never var) ++ "'"
+            hint = "Cannot unify rigid type variable " ++ var' ++
                    ".\nThe problem probably relates to a type annotation. Note that rigid type\n\
                    \variables are not shared between a top-level and let-bound type annotations."
 
@@ -132,16 +132,16 @@
             (Is Comparable, _, _, _) -> unifyComparableStructure variable1 variable2
             (_, Is Comparable, _, _) -> unifyComparableStructure variable2 variable1
 
-            (Is Appendable, _, _, Just ctor)
-                | ctor `elem` ["Text.Text","String"] -> flexAndUnify variable1
-            (_, Is Appendable, Just ctor, _)
-                | ctor `elem` ["Text.Text","String"] -> flexAndUnify variable2
+            (Is Appendable, _, _, Just name)
+                | Var.isText name || Var.isPrim "String" name -> flexAndUnify variable1
+            (_, Is Appendable, Just name, _)
+                | Var.isText name || Var.isPrim "String" name -> flexAndUnify variable2
             (Is Appendable, _, _, _) -> unifyAppendable variable1 variable2
             (_, Is Appendable, _, _) -> unifyAppendable variable2 variable1
 
             (Rigid, _, _, _) -> rigidError variable1
             (_, Rigid, _, _) -> rigidError variable2
-            _ -> TS.addError span Nothing variable1 variable2
+            _ -> TS.addError region Nothing variable1 variable2
 
   case (structure desc1, structure desc2) of
     (Nothing, Nothing) | flex desc1 == Flexible && flex desc1 == Flexible -> merge
@@ -196,5 +196,38 @@
                 eat (_:xs) (_:ys) = eat xs ys
                 eat xs _ = xs
 
-          _ -> TS.addError span Nothing variable1 variable2
+          _ -> TS.addError region Nothing variable1 variable2
 
+combinedDescriptors :: Descriptor -> Descriptor
+                    -> (Maybe Var.Canonical, Flex, Int, Maybe Var.Canonical)
+combinedDescriptors desc1 desc2 =
+    (name', flex', rank', alias')
+  where
+    rank' :: Int
+    rank' = min (rank desc1) (rank desc2)
+
+    alias' :: Maybe Var.Canonical
+    alias' = alias desc1 <|> alias desc2
+
+    name' :: Maybe Var.Canonical
+    name' = case (name desc1, name desc2) of
+              (Just name1, Just name2) ->
+                  case (flex desc1, flex desc2) of
+                    (_, Flexible)     -> Just name1
+                    (Flexible, _)     -> Just name2
+                    (Is Number, Is _) -> Just name1
+                    (Is _, Is Number) -> Just name2
+                    (Is _, Is _)      -> Just name1
+                    (_, _)            -> Nothing
+              (Just name1, _) -> Just name1
+              (_, Just name2) -> Just name2
+              _ -> Nothing
+
+    flex' :: Flex
+    flex' = case (flex desc1, flex desc2) of
+              (f, Flexible)     -> f
+              (Flexible, f)     -> f
+              (Is Number, Is _) -> Is Number
+              (Is _, Is Number) -> Is Number
+              (Is super, Is _)  -> Is super
+              (_, _)            -> Flexible
diff --git a/data/docs.json b/data/docs.json
--- a/data/docs.json
+++ b/data/docs.json
@@ -1,10367 +1,18178 @@
 [
 {
-  "name": "Basics",
-  "document": "Tons of useful functions that get imported by default.\n\nThe following libraries also get imported by default: List, Signal,\nText, Maybe, Time, Graphics.Element, Color, Graphics.Collage.\n\n# Equality\n@docs (==), (/=)\n\n# Comparison\n\nThese functions only work on `comparable` types. This includes numbers,\ncharacters, strings, lists of comparable things, and tuples of comparable\nthings. Note that tuples with 7 or more elements are not comparable; why\nare your tuples so big?\n\n@docs (\u003c), (\u003e), (\u003c=), (\u003e=), max, min, Order, compare\n\n# Booleans\n@docs not, (&&), (||), xor, otherwise\n\n# Mathematics\n@docs (+), (-), (*), (/), (^), div, rem, mod, abs, sqrt, clamp, logBase, e\n\n# Trigonometry\n@docs pi, cos, sin, tan, acos, asin, atan, atan2\n\n# Number Conversions\n@docs round, floor, ceiling, truncate, toFloat\n\n# Angle Conversions\nAll angle conversions result in &ldquo;standard Elm angles&rdquo;\nwhich happen to be radians.\n\n@docs degrees, radians, turns\n\n# Polar Coordinates\n@docs toPolar, fromPolar\n\n# Tuples\n@docs fst, snd\n\n# Higher-Order Helpers\n@docs id, (\u003c|), (|\u003e), (.), always, flip, curry, uncurry",
-  "aliases": [],
-  "datatypes": [
-    {
-      "name": "Order",
-      "comment": "Represents the relative ordering of two things.\nThe relations are less than, equal to, and greater than.",
-      "raw": "data Order = LT | EQ | GT",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "LT",
-          "type": [
-            "Order"
-          ]
-        },
-        {
-          "name": "EQ",
-          "type": [
-            "Order"
-          ]
-        },
-        {
-          "name": "GT",
-          "type": [
-            "Order"
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "&&",
-      "comment": "The and operator. True if both inputs are True.\nThis operator short-circuits if the first argument is False.",
-      "raw": "(&&) : Bool -\u003e Bool -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Bool"
-        ],
-        [
-          "-\u003e",
-          [
-            "Bool"
-          ],
-          [
-            "Bool"
-          ]
-        ]
-      ],
-      "associativity": "right",
-      "precedence": 3
-    },
-    {
-      "name": "*",
-      "comment": "",
-      "raw": "(*) : number -\u003e number -\u003e number",
-      "type": [
-        "-\u003e",
-        "number",
-        [
-          "-\u003e",
-          "number",
-          "number"
-        ]
-      ],
-      "associativity": "left",
-      "precedence": 7
-    },
-    {
-      "name": "+",
-      "comment": "",
-      "raw": "(+) : number -\u003e number -\u003e number",
-      "type": [
-        "-\u003e",
-        "number",
-        [
-          "-\u003e",
-          "number",
-          "number"
-        ]
-      ],
-      "associativity": "left",
-      "precedence": 6
-    },
-    {
-      "name": "-",
-      "comment": "",
-      "raw": "(-) : number -\u003e number -\u003e number",
-      "type": [
-        "-\u003e",
-        "number",
-        [
-          "-\u003e",
-          "number",
-          "number"
-        ]
-      ],
-      "associativity": "left",
-      "precedence": 6
-    },
-    {
-      "name": ".",
-      "comment": "Function composition: `(f . g == (\\\\x -\u003e f (g x)))`",
-      "raw": "(.) : (b -\u003e c) -\u003e (a -\u003e b) -\u003e (a -\u003e c)",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "b",
-          "c"
-        ],
-        [
-          "-\u003e",
-          [
-            "-\u003e",
-            "a",
-            "b"
-          ],
-          [
-            "-\u003e",
-            "a",
-            "c"
-          ]
-        ]
-      ],
-      "associativity": "right",
-      "precedence": 9
-    },
-    {
-      "name": "/",
-      "comment": "Floating point division.",
-      "raw": "(/) : Float -\u003e Float -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Float"
-          ],
-          [
-            "Float"
-          ]
-        ]
-      ],
-      "associativity": "left",
-      "precedence": 7
-    },
-    {
-      "name": "/=",
-      "comment": "",
-      "raw": "(/=) : a -\u003e a -\u003e Bool",
-      "type": [
-        "-\u003e",
-        "a",
-        [
-          "-\u003e",
-          "a",
-          [
-            "Bool"
-          ]
-        ]
-      ],
-      "associativity": "non",
-      "precedence": 4
-    },
-    {
-      "name": "\u003c",
-      "comment": "",
-      "raw": "(\u003c)  : comparable -\u003e comparable -\u003e Bool",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          "comparable",
-          [
-            "Bool"
-          ]
-        ]
-      ],
-      "associativity": "non",
-      "precedence": 4
-    },
-    {
-      "name": "\u003c=",
-      "comment": "",
-      "raw": "(\u003c=) : comparable -\u003e comparable -\u003e Bool",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          "comparable",
-          [
-            "Bool"
-          ]
-        ]
-      ],
-      "associativity": "non",
-      "precedence": 4
-    },
-    {
-      "name": "\u003c|",
-      "comment": "Function application `f \u003c| x == f x`. This function is useful for avoiding\nparenthesis. Consider the following code to create a text element:\n\n        text (monospace (toText \"code\"))\n\nThis can also be written as:\n\n        text . monospace \u003c| toText \"code\"",
-      "raw": "(\u003c|) : (a -\u003e b) -\u003e a -\u003e b",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          "b"
-        ],
-        [
-          "-\u003e",
-          "a",
-          "b"
-        ]
-      ],
-      "associativity": "right",
-      "precedence": 0
-    },
-    {
-      "name": "==",
-      "comment": "",
-      "raw": "(==) : a -\u003e a -\u003e Bool",
-      "type": [
-        "-\u003e",
-        "a",
-        [
-          "-\u003e",
-          "a",
-          [
-            "Bool"
-          ]
-        ]
-      ],
-      "associativity": "non",
-      "precedence": 4
-    },
-    {
-      "name": "\u003e",
-      "comment": "",
-      "raw": "(\u003e)  : comparable -\u003e comparable -\u003e Bool",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          "comparable",
-          [
-            "Bool"
-          ]
-        ]
-      ],
-      "associativity": "non",
-      "precedence": 4
-    },
-    {
-      "name": "\u003e=",
-      "comment": "",
-      "raw": "(\u003e=) : comparable -\u003e comparable -\u003e Bool",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          "comparable",
-          [
-            "Bool"
-          ]
-        ]
-      ],
-      "associativity": "non",
-      "precedence": 4
-    },
-    {
-      "name": "^",
-      "comment": "Exponentiation: `3^2 == 9`",
-      "raw": "(^) : number -\u003e number -\u003e number",
-      "type": [
-        "-\u003e",
-        "number",
-        [
-          "-\u003e",
-          "number",
-          "number"
-        ]
-      ],
-      "associativity": "left",
-      "precedence": 8
-    },
-    {
-      "name": "abs",
-      "comment": "Take the absolute value of a number.",
-      "raw": "abs : number -\u003e number",
-      "type": [
-        "-\u003e",
-        "number",
-        "number"
-      ]
-    },
-    {
-      "name": "acos",
-      "comment": "",
-      "raw": "acos : Float -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "always",
-      "comment": "Creates a [constant function](http://en.wikipedia.org/wiki/Constant_function),\na function that *always* returns the same value regardless of what input you give.\nIt is defined as:\n\n        always a b = a\n\nIt totally ignores the second argument, so `always 42` is a function that always\nreturns in 42. When you are dealing with higher-order functions, this comes in\nhandy more often than you might expect. For example, creating a zeroed out list\nof length ten would be:\n\n        map (always 0) [0..9]",
-      "raw": "always : a -\u003e b -\u003e a",
-      "type": [
-        "-\u003e",
-        "a",
-        [
-          "-\u003e",
-          "b",
-          "a"
-        ]
-      ]
-    },
-    {
-      "name": "asin",
-      "comment": "",
-      "raw": "asin : Float -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "atan",
-      "comment": "You probably do not want to use this. It takes `(y/x)` as the\nargument, so there is no way to know whether the negative signs comes from\nthe `y` or `x`. Thus, the resulting angle is always between &pi;/2 and -&pi;/2\n(in quadrants I and IV). You probably want to use `atan2` instead.",
-      "raw": "atan : Float -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "atan2",
-      "comment": "This helps you find the angle of a cartesian coordinate.\nYou will almost certainly want to use this instead of `atan`.\nSo `atan2 y x` computes *atan(y/x)* but also keeps track of which\nquadrant the angle should really be in. The result will be between\n&pi; and -&pi;, giving you the full range of angles.",
-      "raw": "atan2 : Float -\u003e Float -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Float"
-          ],
-          [
-            "Float"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "ceiling",
-      "comment": "Ceiling function, rounding up.",
-      "raw": "ceiling : Float -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "clamp",
-      "comment": "Clamps a number within a given range. With the expression\n`clamp 100 200 x` the results are as follows:\n\n      100     if x \u003c 100\n       x      if 100 \u003c= x \u003c 200\n      200     if 200 \u003c= x",
-      "raw": "clamp : number -\u003e number -\u003e number -\u003e number",
-      "type": [
-        "-\u003e",
-        "number",
-        [
-          "-\u003e",
-          "number",
-          [
-            "-\u003e",
-            "number",
-            "number"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "compare",
-      "comment": "Compare any two comparable values. Comparable values include `String`, `Char`,\n`Int`, `Float`, `Time`, or a list or tuple containing comparable values.\nThese are also the only values that work as `Dict` keys or `Set` members.",
-      "raw": "compare : comparable -\u003e comparable -\u003e Order",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          "comparable",
-          [
-            "Order"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "cos",
-      "comment": "",
-      "raw": "cos : Float -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "curry",
-      "comment": "Change how arguments are passed to a function.\nThis splits paired arguments into two separate arguments.",
-      "raw": "curry : ((a,b) -\u003e c) -\u003e a -\u003e b -\u003e c",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          [
-            "_Tuple2",
-            "a",
-            "b"
-          ],
-          "c"
-        ],
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            "c"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "degrees",
-      "comment": "Convert degrees to standard Elm angles (radians).",
-      "raw": "degrees : Float -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "div",
-      "comment": "Integer division, remainder is discarded.",
-      "raw": "div : Int -\u003e Int -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "Int"
-          ]
-        ]
-      ],
-      "associativity": "left",
-      "precedence": 7
-    },
-    {
-      "name": "e",
-      "comment": "An approximation of e.",
-      "raw": "e : Float",
-      "type": [
-        "Float"
-      ]
-    },
-    {
-      "name": "flip",
-      "comment": "Flips the order of the first two arguments to a function.",
-      "raw": "flip : (a -\u003e b -\u003e c) -\u003e (b -\u003e a -\u003e c)",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            "c"
-          ]
-        ],
-        [
-          "-\u003e",
-          "b",
-          [
-            "-\u003e",
-            "a",
-            "c"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "floor",
-      "comment": "Floor function, rounding down.",
-      "raw": "floor : Float -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "fromPolar",
-      "comment": "Start with polar coordinates (r,&theta;)\nand get out cartesian coordinates (x,y).",
-      "raw": "fromPolar : (Float,Float) -\u003e (Float,Float)",
-      "type": [
-        "-\u003e",
-        [
-          "_Tuple2",
-          [
-            "Float"
-          ],
-          [
-            "Float"
-          ]
-        ],
-        [
-          "_Tuple2",
-          [
-            "Float"
-          ],
-          [
-            "Float"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "fst",
-      "comment": "Given a 2-tuple, returns the first value.",
-      "raw": "fst : (a,b) -\u003e a",
-      "type": [
-        "-\u003e",
-        [
-          "_Tuple2",
-          "a",
-          "b"
-        ],
-        "a"
-      ]
-    },
-    {
-      "name": "id",
-      "comment": "Given a value, returns exactly the same value.",
-      "raw": "id : a -\u003e a",
-      "type": [
-        "-\u003e",
-        "a",
-        "a"
-      ]
-    },
-    {
-      "name": "logBase",
-      "comment": "Calculate the logarithm of a number with a given base: `logBase 10 100 == 2`",
-      "raw": "logBase : number -\u003e number -\u003e number",
-      "type": [
-        "-\u003e",
-        "number",
-        [
-          "-\u003e",
-          "number",
-          "number"
-        ]
-      ]
-    },
-    {
-      "name": "max",
-      "comment": "Given two comparables, returns the larger one.",
-      "raw": "max : comparable -\u003e comparable -\u003e comparable",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          "comparable",
-          "comparable"
-        ]
-      ]
-    },
-    {
-      "name": "min",
-      "comment": "Given two comparables, returns the smaller one.",
-      "raw": "min : comparable -\u003e comparable -\u003e comparable",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          "comparable",
-          "comparable"
-        ]
-      ]
-    },
-    {
-      "name": "mod",
-      "comment": "Perform modular arithmetic: ``7 `mod` 2 == 1``",
-      "raw": "mod : Int -\u003e Int -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "Int"
-          ]
-        ]
-      ],
-      "associativity": "left",
-      "precedence": 7
-    },
-    {
-      "name": "not",
-      "comment": "Negate a boolean value: `(not True == False)` and `(not False == True)`",
-      "raw": "not : Bool -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Bool"
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "otherwise",
-      "comment": "Equal to true. Useful as the last case of a multi-way-if.",
-      "raw": "otherwise : Bool",
-      "type": [
-        "Bool"
-      ]
-    },
-    {
-      "name": "pi",
-      "comment": "An approximation of pi.",
-      "raw": "pi : Float",
-      "type": [
-        "Float"
-      ]
-    },
-    {
-      "name": "radians",
-      "comment": "Convert radians to standard Elm angles (radians).",
-      "raw": "radians : Float -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "rem",
-      "comment": "Finds the remainder after dividing one number by another: ``4 `rem` 3 == 1``",
-      "raw": "rem : Int -\u003e Int -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "Int"
-          ]
-        ]
-      ],
-      "associativity": "left",
-      "precedence": 7
-    },
-    {
-      "name": "round",
-      "comment": "Round a number to the nearest integer.",
-      "raw": "round : Float -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "sin",
-      "comment": "",
-      "raw": "sin : Float -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "snd",
-      "comment": "Given a 2-tuple, returns the second value.",
-      "raw": "snd : (a,b) -\u003e b",
-      "type": [
-        "-\u003e",
-        [
-          "_Tuple2",
-          "a",
-          "b"
-        ],
-        "b"
-      ]
-    },
-    {
-      "name": "sqrt",
-      "comment": "Take the square root of a number.",
-      "raw": "sqrt : number -\u003e number",
-      "type": [
-        "-\u003e",
-        "number",
-        "number"
-      ]
-    },
-    {
-      "name": "tan",
-      "comment": "",
-      "raw": "tan : Float -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "toFloat",
-      "comment": "Convert an integer into a float.",
-      "raw": "toFloat : Int -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "toPolar",
-      "comment": "Start with cartesian coordinates (x,y)\nand get out polar coordinates (r,&theta;).",
-      "raw": "toPolar : (Float,Float) -\u003e (Float,Float)",
-      "type": [
-        "-\u003e",
-        [
-          "_Tuple2",
-          [
-            "Float"
-          ],
-          [
-            "Float"
-          ]
-        ],
-        [
-          "_Tuple2",
-          [
-            "Float"
-          ],
-          [
-            "Float"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "truncate",
-      "comment": "Truncate a decimal number, rounding towards zero.",
-      "raw": "truncate : Float -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "turns",
-      "comment": "Convert turns to standard Elm angles (radians).\nOne turn is equal to 360&deg;.",
-      "raw": "turns : Float -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "uncurry",
-      "comment": "Change how arguments are passed to a function.\nThis combines two arguments into a single pair.",
-      "raw": "uncurry : (a -\u003e b -\u003e c) -\u003e (a,b) -\u003e c",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            "c"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "_Tuple2",
-            "a",
-            "b"
-          ],
-          "c"
-        ]
-      ]
-    },
-    {
-      "name": "xor",
-      "comment": "The exclusive-or operator. True if exactly one input is True.",
-      "raw": "xor : Bool -\u003e Bool -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Bool"
-        ],
-        [
-          "-\u003e",
-          [
-            "Bool"
-          ],
-          [
-            "Bool"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "|\u003e",
-      "comment": "Forward function application `x |\u003e f == f x`. This function is useful\nfor avoiding parenthesis and writing code in a more natural way.\nConsider the following code to create a pentagon:\n\n        scale 2 (move (10,10) (filled blue (ngon 5 30)))\n\nThis can also be written as:\n\n        ngon 5 30 |\u003e filled blue\n                  |\u003e move (10,10)\n                  |\u003e scale 2",
-      "raw": "(|\u003e) : a -\u003e (a -\u003e b) -\u003e b",
-      "type": [
-        "-\u003e",
-        "a",
-        [
-          "-\u003e",
-          [
-            "-\u003e",
-            "a",
-            "b"
-          ],
-          "b"
-        ]
-      ],
-      "associativity": "left",
-      "precedence": 0
-    },
-    {
-      "name": "||",
-      "comment": "The or operator. True if one or both inputs are True.\nThis operator short-circuits if the first argument is True.",
-      "raw": "(||) : Bool -\u003e Bool -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Bool"
-        ],
-        [
-          "-\u003e",
-          [
-            "Bool"
-          ],
-          [
-            "Bool"
-          ]
-        ]
-      ],
-      "associativity": "right",
-      "precedence": 2
-    }
-  ]
-},
-{
-  "name": "Bitwise",
-  "document": "Library for [bitwise operations](http://en.wikipedia.org/wiki/Bitwise_operation).\n\n# Basic Operations\n\n@docs and, or, xor, complement\n\n# Bit Shifts\n\n@docs shiftLeft, shiftRight, shiftRightLogical",
-  "aliases": [],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "and",
-      "comment": "Bitwise AND",
-      "raw": "and : Int -\u003e Int -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "Int"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "complement",
-      "comment": "Flip each bit individually, often called bitwise NOT",
-      "raw": "complement : Int -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "or",
-      "comment": "Bitwise OR",
-      "raw": "or : Int -\u003e Int -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "Int"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "shiftLeft",
-      "comment": "Shift bits to the left by a given offset, filling new bits with zeros.\nThis can be used to multiply numbers by powers of two.\n\n    8 `shiftLeft` 1 == 16\n    8 `shiftLeft` 2 == 32",
-      "raw": "shiftLeft : Int -\u003e Int -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "Int"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "shiftRight",
-      "comment": "Shift bits to the right by a given offset, filling new bits with\nwhatever is the topmost bit. This can be used to divide numbers by powers of two.\n\n     32 `shiftRight` 1 == 16\n     32 `shiftRight` 2 == 8\n    -32 `shiftRight` 1 == -16\n\nThis is called an [arithmatic right\nshift](http://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift),\noften written (\u003e\u003e), and sometimes called a sign-propagating\nright shift because it fills empty spots with copies of the highest bit.",
-      "raw": "shiftRight : Int -\u003e Int -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "Int"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "shiftRightLogical",
-      "comment": "Shift bits to the right by a given offset, filling new bits with\nzeros.\n\n     32 `shiftRightLogical` 1 == 16\n     32 `shiftRightLogical` 2 == 8\n    -32 `shiftRightLogical` 1 == 2147483632\n\nThis is called an [logical right\nshift](http://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift), often written (\u003e\u003e\u003e),\nand sometimes called a zero-fill right shift because it fills empty spots\nwith zeros.",
-      "raw": "shiftRightLogical : Int -\u003e Int -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "Int"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "xor",
-      "comment": "Bitwise XOR",
-      "raw": "xor : Int -\u003e Int -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "Int"
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Char",
-  "document": "Functions for working with characters. Character literals are enclosed in\n`'a'` pair of single quotes.\n\n# Classification\n@docs isUpper, isLower, isDigit, isOctDigit, isHexDigit\n\n# Conversion\n@docs toUpper, toLower, toLocaleUpper, toLocaleLower, toCode, fromCode",
-  "aliases": [
-    {
-      "name": "KeyCode",
-      "comment": "",
-      "raw": "type KeyCode = Int",
-      "typeVariables": [],
-      "type": [
-        "Int"
-      ]
-    }
-  ],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "fromCode",
-      "comment": "Convert from unicode.",
-      "raw": "fromCode : KeyCode -\u003e Char",
-      "type": [
-        "-\u003e",
-        [
-          "KeyCode"
-        ],
-        [
-          "Char"
-        ]
-      ]
-    },
-    {
-      "name": "isDigit",
-      "comment": "True for ASCII digits `[0-9]`.",
-      "raw": "isDigit : Char -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Char"
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "isHexDigit",
-      "comment": "True for ASCII hexadecimal digits `[0-9a-fA-F]`.",
-      "raw": "isHexDigit : Char -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Char"
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "isLower",
-      "comment": "True for lower case letters.",
-      "raw": "isLower : Char -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Char"
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "isOctDigit",
-      "comment": "True for ASCII octal digits `[0-7]`.",
-      "raw": "isOctDigit : Char -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Char"
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "isUpper",
-      "comment": "True for upper case letters.",
-      "raw": "isUpper : Char -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Char"
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "toCode",
-      "comment": "Convert to unicode. Used with the [`Keyboard`](/docs/Keyboard.elm)\nlibrary, which expects the input to be uppercase.",
-      "raw": "toCode : Char -\u003e KeyCode",
-      "type": [
-        "-\u003e",
-        [
-          "Char"
-        ],
-        [
-          "KeyCode"
-        ]
-      ]
-    },
-    {
-      "name": "toLocaleLower",
-      "comment": "Convert to lower case, according to any locale-specific case mappings.",
-      "raw": "toLocaleLower : Char -\u003e Char",
-      "type": [
-        "-\u003e",
-        [
-          "Char"
-        ],
-        [
-          "Char"
-        ]
-      ]
-    },
-    {
-      "name": "toLocaleUpper",
-      "comment": "Convert to upper case, according to any locale-specific case mappings.",
-      "raw": "toLocaleUpper : Char -\u003e Char",
-      "type": [
-        "-\u003e",
-        [
-          "Char"
-        ],
-        [
-          "Char"
-        ]
-      ]
-    },
-    {
-      "name": "toLower",
-      "comment": "Convert to lower case.",
-      "raw": "toLower : Char -\u003e Char",
-      "type": [
-        "-\u003e",
-        [
-          "Char"
-        ],
-        [
-          "Char"
-        ]
-      ]
-    },
-    {
-      "name": "toUpper",
-      "comment": "Convert to upper case.",
-      "raw": "toUpper : Char -\u003e Char",
-      "type": [
-        "-\u003e",
-        [
-          "Char"
-        ],
-        [
-          "Char"
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Color",
-  "document": "Library for working with colors. Includes\n[RGB](https://en.wikipedia.org/wiki/RGB_color_model) and\n[HSV](http://en.wikipedia.org/wiki/HSL_and_HSV) creation, gradients, and\nbuilt-in names.\n\n# Creation\n@docs rgb, rgba, hsv, hsva, greyscale, grayscale\n\n# From Other Colors\n@docs complement\n\n# Gradients\n@docs linear, radial\n\n# Built-in Colors\nThese colors come from the [Tango\npalette](http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines)\nwhich provides aesthetically reasonable defaults for colors. Each color also\ncomes with a light and dark version.\n\n### Standard\n@docs red, orange, yellow, green, blue, purple, brown\n\n### Light\n@docs lightRed, lightOrange, lightYellow, lightGreen, lightBlue, lightPurple,\n    lightBrown\n\n### Dark\n@docs darkRed, darkOrange, darkYellow, darkGreen, darkBlue, darkPurple,\n    darkBrown\n\n### Eight Shades of Grey\nThese colors are a compatible series of shades of grey, fitting nicely\nwith the Tango palette.\n@docs white, lightGrey, grey, darkGrey, lightCharcoal, charcoal, darkCharcoal, black\n\nThese are identical to the *grey* versions. It seems the spelling is regional, but\nthat has never helped me remember which one I should be writing.\n@docs lightGray, gray, darkGray",
-  "aliases": [],
-  "datatypes": [
-    {
-      "name": "Color",
-      "comment": "",
-      "raw": "data Color = Color Int Int Int Float",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Color",
-          "type": [
-            "-\u003e",
-            [
-              "Int"
-            ],
-            [
-              "-\u003e",
-              [
-                "Int"
-              ],
-              [
-                "-\u003e",
-                [
-                  "Int"
-                ],
-                [
-                  "-\u003e",
-                  [
-                    "Float"
-                  ],
-                  [
-                    "Color"
-                  ]
-                ]
-              ]
-            ]
-          ]
-        }
-      ]
-    },
-    {
-      "name": "Gradient",
-      "comment": "",
-      "raw": "data Gradient\n  = Linear (Float,Float) (Float,Float) [(Float,Color)]\n  | Radial (Float,Float) Float (Float,Float) Float [(Float,Color)]",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Linear",
-          "type": [
-            "-\u003e",
-            [
-              "_Tuple2",
-              [
-                "Float"
-              ],
-              [
-                "Float"
-              ]
-            ],
-            [
-              "-\u003e",
-              [
-                "_Tuple2",
-                [
-                  "Float"
-                ],
-                [
-                  "Float"
-                ]
-              ],
-              [
-                "-\u003e",
-                [
-                  "_List",
-                  [
-                    "_Tuple2",
-                    [
-                      "Float"
-                    ],
-                    [
-                      "Color"
-                    ]
-                  ]
-                ],
-                [
-                  "Gradient"
-                ]
-              ]
-            ]
-          ]
-        },
-        {
-          "name": "Radial",
-          "type": [
-            "-\u003e",
-            [
-              "_Tuple2",
-              [
-                "Float"
-              ],
-              [
-                "Float"
-              ]
-            ],
-            [
-              "-\u003e",
-              [
-                "Float"
-              ],
-              [
-                "-\u003e",
-                [
-                  "_Tuple2",
-                  [
-                    "Float"
-                  ],
-                  [
-                    "Float"
-                  ]
-                ],
-                [
-                  "-\u003e",
-                  [
-                    "Float"
-                  ],
-                  [
-                    "-\u003e",
-                    [
-                      "_List",
-                      [
-                        "_Tuple2",
-                        [
-                          "Float"
-                        ],
-                        [
-                          "Color"
-                        ]
-                      ]
-                    ],
-                    [
-                      "Gradient"
-                    ]
-                  ]
-                ]
-              ]
-            ]
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "black",
-      "comment": "",
-      "raw": "black         : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "blue",
-      "comment": "",
-      "raw": "blue   : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "brown",
-      "comment": "",
-      "raw": "brown  : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "charcoal",
-      "comment": "",
-      "raw": "charcoal      : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "complement",
-      "comment": "Produce a &ldquo;complementary color&rdquo;.\nThe two colors will accent each other.",
-      "raw": "complement : Color -\u003e Color",
-      "type": [
-        "-\u003e",
-        [
-          "Color"
-        ],
-        [
-          "Color"
-        ]
-      ]
-    },
-    {
-      "name": "darkBlue",
-      "comment": "",
-      "raw": "darkBlue   : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "darkBrown",
-      "comment": "",
-      "raw": "darkBrown  : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "darkCharcoal",
-      "comment": "",
-      "raw": "darkCharcoal  : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "darkGray",
-      "comment": "",
-      "raw": "darkGray  : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "darkGreen",
-      "comment": "",
-      "raw": "darkGreen  : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "darkGrey",
-      "comment": "",
-      "raw": "darkGrey      : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "darkOrange",
-      "comment": "",
-      "raw": "darkOrange : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "darkPurple",
-      "comment": "",
-      "raw": "darkPurple : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "darkRed",
-      "comment": "",
-      "raw": "darkRed    : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "darkYellow",
-      "comment": "",
-      "raw": "darkYellow : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "gray",
-      "comment": "",
-      "raw": "gray      : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "grayscale",
-      "comment": "Produce a gray based on the input. 0 is white, 1 is black.",
-      "raw": "grayscale : Float -\u003e Color",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Color"
-        ]
-      ]
-    },
-    {
-      "name": "green",
-      "comment": "",
-      "raw": "green  : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "grey",
-      "comment": "",
-      "raw": "grey          : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "greyscale",
-      "comment": "",
-      "raw": "greyscale : Float -\u003e Color",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Color"
-        ]
-      ]
-    },
-    {
-      "name": "hsv",
-      "comment": "Create [HSV colors](http://en.wikipedia.org/wiki/HSL_and_HSV).  This is very\nconvenient for creating colors that cycle and shift.  Hue is an angle and should\nbe given in standard Elm angles (radians).",
-      "raw": "hsv : Float -\u003e Float -\u003e Float -\u003e Color",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Float"
-          ],
-          [
-            "-\u003e",
-            [
-              "Float"
-            ],
-            [
-              "Color"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "hsva",
-      "comment": "Create [HSV colors](http://en.wikipedia.org/wiki/HSL_and_HSV)\nwith an alpha component for transparency.",
-      "raw": "hsva : Float -\u003e Float -\u003e Float -\u003e Float -\u003e Color",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Float"
-          ],
-          [
-            "-\u003e",
-            [
-              "Float"
-            ],
-            [
-              "-\u003e",
-              [
-                "Float"
-              ],
-              [
-                "Color"
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "lightBlue",
-      "comment": "",
-      "raw": "lightBlue   : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "lightBrown",
-      "comment": "",
-      "raw": "lightBrown  : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "lightCharcoal",
-      "comment": "",
-      "raw": "lightCharcoal : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "lightGray",
-      "comment": "",
-      "raw": "lightGray : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "lightGreen",
-      "comment": "",
-      "raw": "lightGreen  : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "lightGrey",
-      "comment": "",
-      "raw": "lightGrey     : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "lightOrange",
-      "comment": "",
-      "raw": "lightOrange : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "lightPurple",
-      "comment": "",
-      "raw": "lightPurple : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "lightRed",
-      "comment": "",
-      "raw": "lightRed    : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "lightYellow",
-      "comment": "",
-      "raw": "lightYellow : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "linear",
-      "comment": "Create a linear gradient. Takes a start and end point and then a series of\n&ldquo;color stops&rdquo; that indicate how to interpolate between the start and\nend points. See [this example](/edit/examples/Elements/LinearGradient.elm) for a\nmore visual explanation.",
-      "raw": "linear : (number, number) -\u003e (number, number) -\u003e [(Float,Color)] -\u003e Gradient",
-      "type": [
-        "-\u003e",
-        [
-          "_Tuple2",
-          "number",
-          "number"
-        ],
-        [
-          "-\u003e",
-          [
-            "_Tuple2",
-            "number",
-            "number"
-          ],
-          [
-            "-\u003e",
-            [
-              "_List",
-              [
-                "_Tuple2",
-                [
-                  "Float"
-                ],
-                [
-                  "Color"
-                ]
-              ]
-            ],
-            [
-              "Gradient"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "orange",
-      "comment": "",
-      "raw": "orange : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "purple",
-      "comment": "",
-      "raw": "purple : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "radial",
-      "comment": "Create a radial gradient. First takes a start point and inner radius.  Then\ntakes an end point and outer radius. It then takes a series of &ldquo;color\nstops&rdquo; that indicate how to interpolate between the inner and outer\ncircles. See [this example](/edit/examples/Elements/RadialGradient.elm) for a\nmore visual explanation.",
-      "raw": "radial : (number,number) -\u003e number -\u003e (number,number) -\u003e number -\u003e [(Float,Color)] -\u003e Gradient",
-      "type": [
-        "-\u003e",
-        [
-          "_Tuple2",
-          "number",
-          "number"
-        ],
-        [
-          "-\u003e",
-          "number",
-          [
-            "-\u003e",
-            [
-              "_Tuple2",
-              "number",
-              "number"
-            ],
-            [
-              "-\u003e",
-              "number",
-              [
-                "-\u003e",
-                [
-                  "_List",
-                  [
-                    "_Tuple2",
-                    [
-                      "Float"
-                    ],
-                    [
-                      "Color"
-                    ]
-                  ]
-                ],
-                [
-                  "Gradient"
-                ]
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "red",
-      "comment": "",
-      "raw": "red    : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "rgb",
-      "comment": "Create RGB colors from numbers between 0 and 255 inclusive.",
-      "raw": "rgb : Int -\u003e Int -\u003e Int -\u003e Color",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "-\u003e",
-            [
-              "Int"
-            ],
-            [
-              "Color"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "rgba",
-      "comment": "Create RGB colors with an alpha component for transparency.\nThe alpha component is specified with numbers between 0 and 1.",
-      "raw": "rgba : Int -\u003e Int -\u003e Int -\u003e Float -\u003e Color",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "-\u003e",
-            [
-              "Int"
-            ],
-            [
-              "-\u003e",
-              [
-                "Float"
-              ],
-              [
-                "Color"
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "white",
-      "comment": "",
-      "raw": "white         : Color",
-      "type": [
-        "Color"
-      ]
-    },
-    {
-      "name": "yellow",
-      "comment": "",
-      "raw": "yellow : Color",
-      "type": [
-        "Color"
-      ]
-    }
-  ]
-},
-{
-  "name": "Date",
-  "document": "Library for working with dates. Email the mailing list if you encounter\nissues with internationalization or locale formatting.\n\n# Conversions\n@docs read, toTime\n\n# Extractions\n@docs year, month, Month, day, dayOfWeek, Day, hour, minute, second",
-  "aliases": [],
-  "datatypes": [
-    {
-      "name": "Date",
-      "comment": "",
-      "raw": "data Date = Date",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Date",
-          "type": [
-            "Date"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "Day",
-      "comment": "Represents the days of the week.",
-      "raw": "data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Mon",
-          "type": [
-            "Day"
-          ]
-        },
-        {
-          "name": "Tue",
-          "type": [
-            "Day"
-          ]
-        },
-        {
-          "name": "Wed",
-          "type": [
-            "Day"
-          ]
-        },
-        {
-          "name": "Thu",
-          "type": [
-            "Day"
-          ]
-        },
-        {
-          "name": "Fri",
-          "type": [
-            "Day"
-          ]
-        },
-        {
-          "name": "Sat",
-          "type": [
-            "Day"
-          ]
-        },
-        {
-          "name": "Sun",
-          "type": [
-            "Day"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "Month",
-      "comment": "Represents the month of the year.",
-      "raw": "data Month = Jan | Feb | Mar | Apr\n           | May | Jun | Jul | Aug\n           | Sep | Oct | Nov | Dec",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Jan",
-          "type": [
-            "Month"
-          ]
-        },
-        {
-          "name": "Feb",
-          "type": [
-            "Month"
-          ]
-        },
-        {
-          "name": "Mar",
-          "type": [
-            "Month"
-          ]
-        },
-        {
-          "name": "Apr",
-          "type": [
-            "Month"
-          ]
-        },
-        {
-          "name": "May",
-          "type": [
-            "Month"
-          ]
-        },
-        {
-          "name": "Jun",
-          "type": [
-            "Month"
-          ]
-        },
-        {
-          "name": "Jul",
-          "type": [
-            "Month"
-          ]
-        },
-        {
-          "name": "Aug",
-          "type": [
-            "Month"
-          ]
-        },
-        {
-          "name": "Sep",
-          "type": [
-            "Month"
-          ]
-        },
-        {
-          "name": "Oct",
-          "type": [
-            "Month"
-          ]
-        },
-        {
-          "name": "Nov",
-          "type": [
-            "Month"
-          ]
-        },
-        {
-          "name": "Dec",
-          "type": [
-            "Month"
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "day",
-      "comment": "Extract the day of a given date. Given the date 23 June 1990 at 11:45AM\nthis returns the integer `23`.",
-      "raw": "day : Date -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Date"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "dayOfWeek",
-      "comment": "Extract the day of the week for a given date. Given the date 23 June\n1990 at 11:45AM this returns the Day `Thu` as defined below.",
-      "raw": "dayOfWeek : Date -\u003e Day",
-      "type": [
-        "-\u003e",
-        [
-          "Date"
-        ],
-        [
-          "Day"
-        ]
-      ]
-    },
-    {
-      "name": "hour",
-      "comment": "Extract the hour of a given date. Given the date 23 June 1990 at 11:45AM\nthis returns the integer `11`.",
-      "raw": "hour : Date -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Date"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "minute",
-      "comment": "Extract the minute of a given date. Given the date 23 June 1990 at 11:45AM\nthis returns the integer `45`.",
-      "raw": "minute : Date -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Date"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "month",
-      "comment": "Extract the month of a given date. Given the date 23 June 1990 at 11:45AM\nthis returns the Month `Jun` as defined below.",
-      "raw": "month : Date -\u003e Month",
-      "type": [
-        "-\u003e",
-        [
-          "Date"
-        ],
-        [
-          "Month"
-        ]
-      ]
-    },
-    {
-      "name": "read",
-      "comment": "Attempt to read a date from a string.",
-      "raw": "read : String -\u003e Maybe Date",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "Maybe",
-          [
-            "Date"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "second",
-      "comment": "Extract the second of a given date. Given the date 23 June 1990 at 11:45AM\nthis returns the integer `0`.",
-      "raw": "second : Date -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Date"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "toTime",
-      "comment": "Convert a date into a time since midnight (UTC) of 1 January 1990 (i.e.\n[UNIX time](http://en.wikipedia.org/wiki/Unix_time)). Given the date 23 June\n1990 at 11:45AM this returns the corresponding time.",
-      "raw": "toTime : Date -\u003e Time",
-      "type": [
-        "-\u003e",
-        [
-          "Date"
-        ],
-        [
-          "Time"
-        ]
-      ]
-    },
-    {
-      "name": "year",
-      "comment": "Extract the year of a given date. Given the date 23 June 1990 at 11:45AM\nthis returns the integer `1990`.",
-      "raw": "year : Date -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Date"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Dict",
-  "document": "A dictionary mapping unique keys to values. The keys can be any comparable\ntype. This includes `Int`, `Float`, `Time`, `Char`, `String`, and tuples or\nlists of comparable types.\n\nInsert, remove, and query operations all take *O(log n)* time.\n\n# Build\n@docs empty, singleton, insert, update, remove\n\n# Query\n@docs member, lookup, findWithDefault\n\n# Combine\n@docs union, intersect, diff\n\n# Lists\n@docs keys, values, toList, fromList\n\n# Transform\n@docs map, foldl, foldr",
-  "aliases": [],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "diff",
-      "comment": "Keep a key-value pair when its key does not appear in the second dictionary.\nPreference is given to the first dictionary.",
-      "raw": "diff : Dict comparable v -\u003e Dict comparable v -\u003e Dict comparable v",
-      "type": [
-        "-\u003e",
-        [
-          "Dict",
-          "comparable",
-          "v"
-        ],
-        [
-          "-\u003e",
-          [
-            "Dict",
-            "comparable",
-            "v"
-          ],
-          [
-            "Dict",
-            "comparable",
-            "v"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "empty",
-      "comment": "Create an empty dictionary.",
-      "raw": "empty : Dict comparable v",
-      "type": [
-        "Dict",
-        "comparable",
-        "v"
-      ]
-    },
-    {
-      "name": "findWithDefault",
-      "comment": "Find the value associated with a key. If the key is not found,\nreturn the default value.",
-      "raw": "findWithDefault : v -\u003e comparable -\u003e Dict comparable v -\u003e v",
-      "type": [
-        "-\u003e",
-        "v",
-        [
-          "-\u003e",
-          "comparable",
-          [
-            "-\u003e",
-            [
-              "Dict",
-              "comparable",
-              "v"
-            ],
-            "v"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "foldl",
-      "comment": "Fold over the key-value pairs in a dictionary, in order from lowest\nkey to highest key.",
-      "raw": "foldl : (comparable -\u003e v -\u003e b -\u003e b) -\u003e b -\u003e Dict comparable v -\u003e b",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "comparable",
-          [
-            "-\u003e",
-            "v",
-            [
-              "-\u003e",
-              "b",
-              "b"
-            ]
-          ]
-        ],
-        [
-          "-\u003e",
-          "b",
-          [
-            "-\u003e",
-            [
-              "Dict",
-              "comparable",
-              "v"
-            ],
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "foldr",
-      "comment": "Fold over the key-value pairs in a dictionary, in order from highest\nkey to lowest key.",
-      "raw": "foldr : (comparable -\u003e v -\u003e b -\u003e b) -\u003e b -\u003e Dict comparable v -\u003e b",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "comparable",
-          [
-            "-\u003e",
-            "v",
-            [
-              "-\u003e",
-              "b",
-              "b"
-            ]
-          ]
-        ],
-        [
-          "-\u003e",
-          "b",
-          [
-            "-\u003e",
-            [
-              "Dict",
-              "comparable",
-              "v"
-            ],
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "fromList",
-      "comment": "Convert an association list into a dictionary.",
-      "raw": "fromList : [(comparable,v)] -\u003e Dict comparable v",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "_Tuple2",
-            "comparable",
-            "v"
-          ]
-        ],
-        [
-          "Dict",
-          "comparable",
-          "v"
-        ]
-      ]
-    },
-    {
-      "name": "insert",
-      "comment": "Insert a key-value pair into a dictionary. Replaces value when there is\na collision.",
-      "raw": "insert : comparable -\u003e v -\u003e Dict comparable v -\u003e Dict comparable v",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          "v",
-          [
-            "-\u003e",
-            [
-              "Dict",
-              "comparable",
-              "v"
-            ],
-            [
-              "Dict",
-              "comparable",
-              "v"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "intersect",
-      "comment": "Keep a key-value pair when its key appears in the second dictionary.\nPreference is given to values in the first dictionary.",
-      "raw": "intersect : Dict comparable v -\u003e Dict comparable v -\u003e Dict comparable v",
-      "type": [
-        "-\u003e",
-        [
-          "Dict",
-          "comparable",
-          "v"
-        ],
-        [
-          "-\u003e",
-          [
-            "Dict",
-            "comparable",
-            "v"
-          ],
-          [
-            "Dict",
-            "comparable",
-            "v"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "keys",
-      "comment": "Get all of the keys in a dictionary.",
-      "raw": "keys : Dict comparable v -\u003e [comparable]",
-      "type": [
-        "-\u003e",
-        [
-          "Dict",
-          "comparable",
-          "v"
-        ],
-        [
-          "_List",
-          "comparable"
-        ]
-      ]
-    },
-    {
-      "name": "lookup",
-      "comment": "Lookup the value associated with a key.",
-      "raw": "lookup : comparable -\u003e Dict comparable v -\u003e Maybe v",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          [
-            "Dict",
-            "comparable",
-            "v"
-          ],
-          [
-            "Maybe",
-            "v"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "map",
-      "comment": "Apply a function to all values in a dictionary.",
-      "raw": "map : (a -\u003e b) -\u003e Dict comparable a -\u003e Dict comparable b",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          "b"
-        ],
-        [
-          "-\u003e",
-          [
-            "Dict",
-            "comparable",
-            "a"
-          ],
-          [
-            "Dict",
-            "comparable",
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "member",
-      "comment": "Determine if a key is in a dictionary.",
-      "raw": "member : comparable -\u003e Dict comparable v -\u003e Bool",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          [
-            "Dict",
-            "comparable",
-            "v"
-          ],
-          [
-            "Bool"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "remove",
-      "comment": "Remove a key-value pair from a dictionary. If the key is not found,\nno changes are made.",
-      "raw": "remove : comparable -\u003e Dict comparable v -\u003e Dict comparable v",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          [
-            "Dict",
-            "comparable",
-            "v"
-          ],
-          [
-            "Dict",
-            "comparable",
-            "v"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "singleton",
-      "comment": "Create a dictionary with one key-value pair.",
-      "raw": "singleton : comparable -\u003e v -\u003e Dict comparable v",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          "v",
-          [
-            "Dict",
-            "comparable",
-            "v"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "toList",
-      "comment": "Convert a dictionary into an association list of key-value pairs.",
-      "raw": "toList : Dict comparable v -\u003e [(comparable,v)]",
-      "type": [
-        "-\u003e",
-        [
-          "Dict",
-          "comparable",
-          "v"
-        ],
-        [
-          "_List",
-          [
-            "_Tuple2",
-            "comparable",
-            "v"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "union",
-      "comment": "Combine two dictionaries. If there is a collision, preference is given\nto the first dictionary.",
-      "raw": "union : Dict comparable v -\u003e Dict comparable v -\u003e Dict comparable v",
-      "type": [
-        "-\u003e",
-        [
-          "Dict",
-          "comparable",
-          "v"
-        ],
-        [
-          "-\u003e",
-          [
-            "Dict",
-            "comparable",
-            "v"
-          ],
-          [
-            "Dict",
-            "comparable",
-            "v"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "update",
-      "comment": "Update the value of a dictionary for a specific key with a given function.",
-      "raw": "update : comparable -\u003e (Maybe v -\u003e Maybe v) -\u003e Dict comparable v -\u003e Dict comparable v",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          [
-            "-\u003e",
-            [
-              "Maybe",
-              "v"
-            ],
-            [
-              "Maybe",
-              "v"
-            ]
-          ],
-          [
-            "-\u003e",
-            [
-              "Dict",
-              "comparable",
-              "v"
-            ],
-            [
-              "Dict",
-              "comparable",
-              "v"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "values",
-      "comment": "Get all of the values in a dictionary.",
-      "raw": "values : Dict comparable v -\u003e [v]",
-      "type": [
-        "-\u003e",
-        [
-          "Dict",
-          "comparable",
-          "v"
-        ],
-        [
-          "_List",
-          "v"
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Either",
-  "document": "Represents any data that can take two different types.\n\n# Type and Constructors\n@docs Either\n\n# Taking Eithers apart\n@docs either, isLeft, isRight\n\n# Eithers and Lists\n@docs lefts, rights, partition",
-  "aliases": [],
-  "datatypes": [
-    {
-      "name": "Either",
-      "comment": "Represents any data may take two forms. For example, a user ID may be\neither an `Int` or a `String`.\n\nThis can also be used for error handling `(Either String a)` where\nerror messages are stored on the left, and the correct values\n(&ldquo;right&rdquo; values) are stored on the right.",
-      "raw": "data Either a b = Left a | Right b",
-      "typeVariables": [
-        "a",
-        "b"
-      ],
-      "constructors": [
-        {
-          "name": "Left",
-          "type": [
-            "-\u003e",
-            "a",
-            [
-              "Either",
-              "a",
-              "b"
-            ]
-          ]
-        },
-        {
-          "name": "Right",
-          "type": [
-            "-\u003e",
-            "b",
-            [
-              "Either",
-              "a",
-              "b"
-            ]
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "either",
-      "comment": "Apply the first function to a `Left` and the second function to a `Right`.\nThis allows the extraction of a value from an `Either`.",
-      "raw": "either : (a -\u003e c) -\u003e (b -\u003e c) -\u003e Either a b -\u003e c",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          "c"
-        ],
-        [
-          "-\u003e",
-          [
-            "-\u003e",
-            "b",
-            "c"
-          ],
-          [
-            "-\u003e",
-            [
-              "Either",
-              "a",
-              "b"
-            ],
-            "c"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "isLeft",
-      "comment": "True if the value is a `Left`.",
-      "raw": "isLeft : Either a b -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Either",
-          "a",
-          "b"
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "isRight",
-      "comment": "True if the value is a `Right`.",
-      "raw": "isRight : Either a b -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Either",
-          "a",
-          "b"
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "lefts",
-      "comment": "Keep only the values held in `Left` values.",
-      "raw": "lefts : [Either a b] -\u003e [a]",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "Either",
-            "a",
-            "b"
-          ]
-        ],
-        [
-          "_List",
-          "a"
-        ]
-      ]
-    },
-    {
-      "name": "partition",
-      "comment": "Split into two lists, lefts on the left and rights on the right. So we\nhave the equivalence: `(partition es == (lefts es, rights es))`",
-      "raw": "partition : [Either a b] -\u003e ([a],[b])",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "Either",
-            "a",
-            "b"
-          ]
-        ],
-        [
-          "_Tuple2",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "_List",
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "rights",
-      "comment": "Keep only the values held in `Right` values.",
-      "raw": "rights : [Either a b] -\u003e [b]",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "Either",
-            "a",
-            "b"
-          ]
-        ],
-        [
-          "_List",
-          "b"
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Http",
-  "document": "A library for asynchronous HTTP requests. See the\n[WebSocket](http://elm-lang.org/docs/WebSocket.elm) library if\nyou have very strict latency requirements.\n\n# Sending Requests\n@docs send, sendGet\n\n# Creating Requests\n@docs get, post, request\n\n# Responses\n@docs Response",
-  "aliases": [
-    {
-      "name": "Request",
-      "comment": "",
-      "raw": "type Request a = {\n  verb : String,\n  url  : String,\n  body : a,\n  headers : [(String,String)]\n }",
-      "typeVariables": [
-        "a"
-      ],
-      "type": {
-        "headers": [
-          "_List",
-          [
-            "_Tuple2",
-            [
-              "String"
-            ],
-            [
-              "String"
-            ]
-          ]
-        ],
-        "body": "a",
-        "url": [
-          "String"
-        ],
-        "verb": [
-          "String"
-        ]
-      }
-    }
-  ],
-  "datatypes": [
-    {
-      "name": "Response",
-      "comment": "The datatype for responses. Success contains only the returned message.\nFailures contain both an error code and an error message.",
-      "raw": "data Response a = Success a | Waiting | Failure Int String",
-      "typeVariables": [
-        "a"
-      ],
-      "constructors": [
-        {
-          "name": "Success",
-          "type": [
-            "-\u003e",
-            "a",
-            [
-              "Response",
-              "a"
-            ]
-          ]
-        },
-        {
-          "name": "Waiting",
-          "type": [
-            "Response",
-            "a"
-          ]
-        },
-        {
-          "name": "Failure",
-          "type": [
-            "-\u003e",
-            [
-              "Int"
-            ],
-            [
-              "-\u003e",
-              [
-                "String"
-              ],
-              [
-                "Response",
-                "a"
-              ]
-            ]
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "get",
-      "comment": "Create a GET request to the given url.",
-      "raw": "get : String -\u003e Request String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "Request",
-          [
-            "String"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "post",
-      "comment": "Create a POST request to the given url, carrying the given data.",
-      "raw": "post : String -\u003e String -\u003e Request String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "Request",
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "request",
-      "comment": "Create a customized request. Arguments are request type (get, post, put,\ndelete, etc.), target url, data, and a list of additional headers.",
-      "raw": "request : String -\u003e String -\u003e String -\u003e [(String,String)] -\u003e Request String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "-\u003e",
-            [
-              "String"
-            ],
-            [
-              "-\u003e",
-              [
-                "_List",
-                [
-                  "_Tuple2",
-                  [
-                    "String"
-                  ],
-                  [
-                    "String"
-                  ]
-                ]
-              ],
-              [
-                "Request",
-                [
-                  "String"
-                ]
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "send",
-      "comment": "Performs an HTTP request with the given requests. Produces a signal\nthat carries the responses.",
-      "raw": "send : Signal (Request a) -\u003e Signal (Response String)",
-      "type": [
-        "-\u003e",
-        [
-          "Signal",
-          [
-            "Request",
-            "a"
-          ]
-        ],
-        [
-          "Signal",
-          [
-            "Response",
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "sendGet",
-      "comment": "Performs an HTTP GET request with the given urls. Produces a signal\nthat carries the responses.",
-      "raw": "sendGet : Signal String -\u003e Signal (Response String)",
-      "type": [
-        "-\u003e",
-        [
-          "Signal",
-          [
-            "String"
-          ]
-        ],
-        [
-          "Signal",
-          [
-            "Response",
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "JavaScript",
-  "document": "This library does basic conversions between Elm and JS values. This allows\nthe internal data structures of Elm to change and improve with no impact on JS\nintegration.\n\nIt is intended to be imported as `import JavaScript as JS`. That way functions\nlike `JS.toInt` convert JavaScript *to* Elm integers and functions like\n`JS.fromString` gets JavaScript *from* Elm strings.\n\n# Javascript to Elm\n@docs toString, toInt, toFloat, toBool, toList\n\n# JavaScript from Elm\n@docs fromString, fromInt, fromFloat, fromBool, fromList",
-  "aliases": [],
-  "datatypes": [
-    {
-      "name": "JSArray",
-      "comment": "",
-      "raw": "data JSArray a = JSArray a",
-      "typeVariables": [
-        "a"
-      ],
-      "constructors": [
-        {
-          "name": "JSArray",
-          "type": [
-            "-\u003e",
-            "a",
-            [
-              "JSArray",
-              "a"
-            ]
-          ]
-        }
-      ]
-    },
-    {
-      "name": "JSBool",
-      "comment": "",
-      "raw": "data JSBool = JSBool",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "JSBool",
-          "type": [
-            "JSBool"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "JSDomNode",
-      "comment": "",
-      "raw": "data JSDomNode = JSDomNode",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "JSDomNode",
-          "type": [
-            "JSDomNode"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "JSNumber",
-      "comment": "",
-      "raw": "data JSNumber = JSNumber",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "JSNumber",
-          "type": [
-            "JSNumber"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "JSObject",
-      "comment": "",
-      "raw": "data JSObject = JSObject",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "JSObject",
-          "type": [
-            "JSObject"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "JSString",
-      "comment": "",
-      "raw": "data JSString = JSString",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "JSString",
-          "type": [
-            "JSString"
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "fromBool",
-      "comment": "",
-      "raw": "fromBool : Bool -\u003e JSBool",
-      "type": [
-        "-\u003e",
-        [
-          "Bool"
-        ],
-        [
-          "JSBool"
-        ]
-      ]
-    },
-    {
-      "name": "fromFloat",
-      "comment": "",
-      "raw": "fromFloat : Float -\u003e JSNumber",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "JSNumber"
-        ]
-      ]
-    },
-    {
-      "name": "fromInt",
-      "comment": "",
-      "raw": "fromInt : Int -\u003e JSNumber",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "JSNumber"
-        ]
-      ]
-    },
-    {
-      "name": "fromList",
-      "comment": "Produces a uniform JavaScript array with all members of the same type.",
-      "raw": "fromList : [a] -\u003e JSArray a",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "a"
-        ],
-        [
-          "JSArray",
-          "a"
-        ]
-      ]
-    },
-    {
-      "name": "fromString",
-      "comment": "",
-      "raw": "fromString : String -\u003e JSString",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "JSString"
-        ]
-      ]
-    },
-    {
-      "name": "toBool",
-      "comment": "",
-      "raw": "toBool : JSBool -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "JSBool"
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "toFloat",
-      "comment": "",
-      "raw": "toFloat : JSNumber -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "JSNumber"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "toInt",
-      "comment": "",
-      "raw": "toInt : JSNumber -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "JSNumber"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "toList",
-      "comment": "Requires that the input array be uniform (all members have the same type)",
-      "raw": "toList : JSArray a -\u003e [a]",
-      "type": [
-        "-\u003e",
-        [
-          "JSArray",
-          "a"
-        ],
-        [
-          "_List",
-          "a"
-        ]
-      ]
-    },
-    {
-      "name": "toString",
-      "comment": "",
-      "raw": "toString : JSString -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "JSString"
-        ],
-        [
-          "String"
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Json",
-  "document": "Library for working with [JSON](https://en.wikipedia.org/wiki/JSON) values.\n\n# Json Values\n@docs JsonValue\n\n# Strings\n@docs fromString, toString\n\n# JS Strings\n@docs fromJSString, toJSString\n\n# JS Objects\n@docs fromJSObject, toJSObject",
-  "aliases": [],
-  "datatypes": [
-    {
-      "name": "JsonValue",
-      "comment": "This datatype can represent all valid values that can be held in a JSON\nobject. In Elm, a proper JSON object is represented as a (Dict String JsonValue)\nwhich is a mapping from strings to Json Values.",
-      "raw": "data JsonValue\n    = String String\n    | Number Float\n    | Boolean Bool\n    | Null\n    | Array [JsonValue]\n    | Object (Dict.Dict String JsonValue)",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "String",
-          "type": [
-            "-\u003e",
-            [
-              "String"
-            ],
-            [
-              "JsonValue"
-            ]
-          ]
-        },
-        {
-          "name": "Number",
-          "type": [
-            "-\u003e",
-            [
-              "Float"
-            ],
-            [
-              "JsonValue"
-            ]
-          ]
-        },
-        {
-          "name": "Boolean",
-          "type": [
-            "-\u003e",
-            [
-              "Bool"
-            ],
-            [
-              "JsonValue"
-            ]
-          ]
-        },
-        {
-          "name": "Null",
-          "type": [
-            "JsonValue"
-          ]
-        },
-        {
-          "name": "Array",
-          "type": [
-            "-\u003e",
-            [
-              "_List",
-              [
-                "JsonValue"
-              ]
-            ],
-            [
-              "JsonValue"
-            ]
-          ]
-        },
-        {
-          "name": "Object",
-          "type": [
-            "-\u003e",
-            [
-              "Dict.Dict",
-              [
-                "String"
-              ],
-              [
-                "JsonValue"
-              ]
-            ],
-            [
-              "JsonValue"
-            ]
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "fromJSObject",
-      "comment": "Convert a JS object into a `JsonValue`.",
-      "raw": "fromJSObject : JSObject -\u003e JsonValue",
-      "type": [
-        "-\u003e",
-        [
-          "JSObject"
-        ],
-        [
-          "JsonValue"
-        ]
-      ]
-    },
-    {
-      "name": "fromJSString",
-      "comment": "Parse a JavaScript string representation of a proper JSON object into\nits Elm representation.",
-      "raw": "fromJSString : JSString -\u003e Maybe JsonValue",
-      "type": [
-        "-\u003e",
-        [
-          "JSString"
-        ],
-        [
-          "Maybe",
-          [
-            "JsonValue"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "fromString",
-      "comment": "Parse a string representation of a proper JSON object into\nits Elm representation.",
-      "raw": "fromString : String -\u003e Maybe JsonValue",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "Maybe",
-          [
-            "JsonValue"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "toJSObject",
-      "comment": "Convert a `JsonValue` into a `JSObject`. Paired with the\n[`JavaScript.Experimental` library](/docs/JavaScript/Experimental.elm),\nThis lets you convert strings into Elm records:\n\n       import JavaScript.Experimental as JS\n\n       stringToRecord str =\n           case fromString str of\n             Just jsonValue -\u003e Just (JS.toRecord (toJSObject jsonValue))\n             Nothing -\u003e Nothing",
-      "raw": "toJSObject : JsonValue -\u003e JSObject",
-      "type": [
-        "-\u003e",
-        [
-          "JsonValue"
-        ],
-        [
-          "JSObject"
-        ]
-      ]
-    },
-    {
-      "name": "toJSString",
-      "comment": "Convert a proper JSON object into a JavaScript string.\nNote that the type JSString seen here is not the same as the type constructor\nJsonString used elsewhere in this module.",
-      "raw": "toJSString : String -\u003e JsonValue -\u003e JSString",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "JsonValue"
-          ],
-          [
-            "JSString"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "toString",
-      "comment": "Convert a `JsonValue` into a prettified string.\nThe first argument is a separator token (e.g. \\\" \\\", \\\"\\\\n\\\", etc.) that will\nbe used for indentation in the prettified string version of the JSON.",
-      "raw": "toString : String -\u003e JsonValue -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "JsonValue"
-          ],
-          [
-            "String"
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Keyboard",
-  "document": "Library for working with keyboard input.\n\n# Representing Keys\n@docs KeyCode\n\n# Directions\n@docs arrows, wasd, directions\n\n# Specific Keys\n@docs shift, enter, space, ctrl\n\n# General Keypresses\n@docs isDown, keysDown, lastPressed",
-  "aliases": [
-    {
-      "name": "KeyCode",
-      "comment": "Type alias to make it clearer what integers are supposed to represent\nin this library. Use [`Char.toCode`](docs/Char.elm#toCode) and\n[`Char.fromCode`](/docs/Char.elm#fromCode) to convert key codes to characters.\nUse the uppercase character with `toCode`.",
-      "raw": "type KeyCode = Int",
-      "typeVariables": [],
-      "type": [
-        "Int"
-      ]
-    }
-  ],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "arrows",
-      "comment": "A signal of records indicating which arrow keys are pressed.\n\n`{ x = 0, y = 0 }` when pressing no arrows.\u003cbr\u003e\n`{ x =-1, y = 0 }` when pressing the left arrow.\u003cbr\u003e\n`{ x = 1, y = 1 }` when pressing the up and right arrows.\u003cbr\u003e\n`{ x = 0, y =-1 }` when pressing the down, left, and right arrows.",
-      "raw": "arrows : Signal { x:Int, y:Int }",
-      "type": [
-        "Signal",
-        {
-          "y": [
-            "Int"
-          ],
-          "x": [
-            "Int"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "ctrl",
-      "comment": "Whether the control key is pressed.",
-      "raw": "ctrl : Signal Bool",
-      "type": [
-        "Signal",
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "directions",
-      "comment": "Custom key directions to support different locales. The order is up, down,\nleft, right.",
-      "raw": "directions : KeyCode -\u003e KeyCode -\u003e KeyCode -\u003e KeyCode -\u003e Signal { x:Int, y:Int }",
-      "type": [
-        "-\u003e",
-        [
-          "KeyCode"
-        ],
-        [
-          "-\u003e",
-          [
-            "KeyCode"
-          ],
-          [
-            "-\u003e",
-            [
-              "KeyCode"
-            ],
-            [
-              "-\u003e",
-              [
-                "KeyCode"
-              ],
-              [
-                "Signal",
-                {
-                  "y": [
-                    "Int"
-                  ],
-                  "x": [
-                    "Int"
-                  ]
-                }
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "enter",
-      "comment": "Whether the enter key is pressed.",
-      "raw": "enter : Signal Bool",
-      "type": [
-        "Signal",
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "isDown",
-      "comment": "Whether an arbitrary key is pressed.",
-      "raw": "isDown : KeyCode -\u003e Signal Bool",
-      "type": [
-        "-\u003e",
-        [
-          "KeyCode"
-        ],
-        [
-          "Signal",
-          [
-            "Bool"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "keysDown",
-      "comment": "List of keys that are currently down.",
-      "raw": "keysDown : Signal [KeyCode]",
-      "type": [
-        "Signal",
-        [
-          "_List",
-          [
-            "KeyCode"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "lastPressed",
-      "comment": "The latest key that has been pressed.",
-      "raw": "lastPressed : Signal KeyCode",
-      "type": [
-        "Signal",
-        [
-          "KeyCode"
-        ]
-      ]
-    },
-    {
-      "name": "shift",
-      "comment": "Whether the shift key is pressed.",
-      "raw": "shift : Signal Bool",
-      "type": [
-        "Signal",
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "space",
-      "comment": "Whether the space key is pressed.",
-      "raw": "space : Signal Bool",
-      "type": [
-        "Signal",
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "wasd",
-      "comment": "Just like the arrows signal, but this uses keys w, a, s, and d,\nwhich are common controls for many computer games.",
-      "raw": "wasd : Signal { x:Int, y:Int }",
-      "type": [
-        "Signal",
-        {
-          "y": [
-            "Int"
-          ],
-          "x": [
-            "Int"
-          ]
-        }
-      ]
-    }
-  ]
-},
-{
-  "name": "List",
-  "document": "A library for manipulating lists of values. Every value in a\nlist must have the same type.\n\n# Basics\n@docs (::), (++), isEmpty, length, reverse, map\n\n# Sub-lists\n@docs head, tail, last, filter, take, drop\n\n# Putting Lists Together\n@docs concat, concatMap, join, intersperse, zip, zipWith\n\n# Taking Lists Apart\n@docs partition, unzip\n\n# Folds\n@docs foldr, foldl, foldr1, foldl1, scanl, scanl1\n\n# Special Folds\n@docs sum, product, maximum, minimum, all, any, and, or\n\n# Sorting\n@docs sort, sortBy, sortWith",
-  "aliases": [],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "++",
-      "comment": "Puts two appendable things together:\n\n      [1,1] ++ [2,3] == [1,1,2,3]\n      \"abc\" ++ \"123\" == \"abc123\"",
-      "raw": "(++) : appendable -\u003e appendable -\u003e appendable",
-      "type": [
-        "-\u003e",
-        "appendable",
-        [
-          "-\u003e",
-          "appendable",
-          "appendable"
-        ]
-      ],
-      "associativity": "right",
-      "precedence": 5
-    },
-    {
-      "name": "::",
-      "comment": "Add an element to the front of a list `(1 :: [2,3] == [1,2,3])`",
-      "raw": "(::) : a -\u003e [a] -\u003e [a]",
-      "type": [
-        "-\u003e",
-        "a",
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "_List",
-            "a"
-          ]
-        ]
-      ],
-      "associativity": "right",
-      "precedence": 5
-    },
-    {
-      "name": "all",
-      "comment": "Check to see if all elements satisfy the predicate.",
-      "raw": "all : (a -\u003e Bool) -\u003e [a] -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "Bool"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "and",
-      "comment": "Check to see if all elements are True.",
-      "raw": "and : [Bool] -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "any",
-      "comment": "Check to see if any elements satisfy the predicate.",
-      "raw": "any : (a -\u003e Bool) -\u003e [a] -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "Bool"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "concat",
-      "comment": "Concatenate a list of appendable things:\n\n      concat [[1,2],[3],[4,5]] == [1,2,3,4,5]\n      concat [\"tree\",\"house\"]  == \"treehouse\"",
-      "raw": "concat : [appendable] -\u003e appendable",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "appendable"
-        ],
-        "appendable"
-      ]
-    },
-    {
-      "name": "concatMap",
-      "comment": "Map a given function onto a list and flatten the resulting lists.\n\n      concatMap f xs == concat (map f xs)",
-      "raw": "concatMap : (a -\u003e appendable) -\u003e [a] -\u003e appendable",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          "appendable"
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          "appendable"
-        ]
-      ]
-    },
-    {
-      "name": "drop",
-      "comment": "Drop the first n members of a list: `(drop 2 [1,2,3,4] == [3,4])`",
-      "raw": "drop : Int -\u003e [a] -\u003e [a]",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "_List",
-            "a"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "filter",
-      "comment": "Keep only elements that satisfy the predicate:\n`(filter isEven [1..6] == [2,4,6])`",
-      "raw": "filter : (a -\u003e Bool) -\u003e [a] -\u003e [a]",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "_List",
-            "a"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "foldl",
-      "comment": "Reduce a list from the left: `(foldl (::) [] [1,2,3] == [3,2,1])`",
-      "raw": "foldl : (a -\u003e b -\u003e b) -\u003e b -\u003e [a] -\u003e b",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            "b"
-          ]
-        ],
-        [
-          "-\u003e",
-          "b",
-          [
-            "-\u003e",
-            [
-              "_List",
-              "a"
-            ],
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "foldl1",
-      "comment": "Reduce a list from the left without a base case. List must be non-empty.",
-      "raw": "foldl1 : (a -\u003e a -\u003e a) -\u003e [a] -\u003e a",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "a",
-            "a"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          "a"
-        ]
-      ]
-    },
-    {
-      "name": "foldr",
-      "comment": "Reduce a list from the right: `(foldr (+) 0 [1,2,3] == 6)`",
-      "raw": "foldr : (a -\u003e b -\u003e b) -\u003e b -\u003e [a] -\u003e b",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            "b"
-          ]
-        ],
-        [
-          "-\u003e",
-          "b",
-          [
-            "-\u003e",
-            [
-              "_List",
-              "a"
-            ],
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "foldr1",
-      "comment": "Reduce a list from the right without a base case. List must be non-empty.",
-      "raw": "foldr1 : (a -\u003e a -\u003e a) -\u003e [a] -\u003e a",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "a",
-            "a"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          "a"
-        ]
-      ]
-    },
-    {
-      "name": "head",
-      "comment": "Extract the first element of a list. List must be non-empty.\n`(head [1,2,3] == 1)`",
-      "raw": "head : [a] -\u003e a",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "a"
-        ],
-        "a"
-      ]
-    },
-    {
-      "name": "intersperse",
-      "comment": "Places the given value between all members of the given list.\n\n      intersperse \"on\" [\"turtles\",\"turtles\",\"turtles\"] == [\"turtles\",\"on\",\"turtles\",\"on\",\"turtles\"]",
-      "raw": "intersperse : a -\u003e [a] -\u003e [a]",
-      "type": [
-        "-\u003e",
-        "a",
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "_List",
-            "a"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "isEmpty",
-      "comment": "Check if a list is empty `(isEmpty [] == True)`",
-      "raw": "isEmpty : [a] -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "a"
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "join",
-      "comment": "Places the given value between all of the lists in the second\nargument and concatenates the result.\n\n      join \"a\" [\"H\",\"w\",\"ii\",\"n\"] == \"Hawaiian\"",
-      "raw": "join : appendable -\u003e [appendable] -\u003e appendable",
-      "type": [
-        "-\u003e",
-        "appendable",
-        [
-          "-\u003e",
-          [
-            "_List",
-            "appendable"
-          ],
-          "appendable"
-        ]
-      ]
-    },
-    {
-      "name": "last",
-      "comment": "Extract the last element of a list. List must be non-empty.\n`(last [1,2,3] == 3)`",
-      "raw": "last : [a] -\u003e a",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "a"
-        ],
-        "a"
-      ]
-    },
-    {
-      "name": "length",
-      "comment": "Determine the length of a list: `(length [1,2,3] == 3)`",
-      "raw": "length : [a] -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "a"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "map",
-      "comment": "Apply a function to every element of a list: `(map sqrt [1,4,9] == [1,2,3])`",
-      "raw": "map : (a -\u003e b) -\u003e [a] -\u003e [b]",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          "b"
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "_List",
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "maximum",
-      "comment": "Find the maximum element in a non-empty list: `maximum [1,4,2] == 4`",
-      "raw": "maximum : [comparable] -\u003e comparable",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "comparable"
-        ],
-        "comparable"
-      ]
-    },
-    {
-      "name": "minimum",
-      "comment": "Find the minimum element in a non-empty list: `minimum [3,2,1] == 1`",
-      "raw": "minimum : [comparable] -\u003e comparable",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "comparable"
-        ],
-        "comparable"
-      ]
-    },
-    {
-      "name": "or",
-      "comment": "Check to see if any elements are True.",
-      "raw": "or : [Bool] -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "partition",
-      "comment": "Split a list based on the predicate.",
-      "raw": "partition : (a -\u003e Bool) -\u003e [a] -\u003e ([a],[a])",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "_Tuple2",
-            [
-              "_List",
-              "a"
-            ],
-            [
-              "_List",
-              "a"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "product",
-      "comment": "Get the product of the list elements. `(product [1..4] == 24)`",
-      "raw": "product : [number] -\u003e number",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "number"
-        ],
-        "number"
-      ]
-    },
-    {
-      "name": "repeat",
-      "comment": "Creates a list with *n* copies of a value:\n`(repeat 3 (0,0) == [(0,0),(0,0),(0,0)]`",
-      "raw": "repeat : Int -\u003e a -\u003e [a]",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          "a",
-          [
-            "_List",
-            "a"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "reverse",
-      "comment": "Reverse a list. `(reverse [1..4] == [4,3,2,1])`",
-      "raw": "reverse : [a] -\u003e [a]",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "a"
-        ],
-        [
-          "_List",
-          "a"
-        ]
-      ]
-    },
-    {
-      "name": "scanl",
-      "comment": "Reduce a list from the left, building up all of the intermediate results into a list.\n\n      scanl (+) 0 [1,2,3,4] == [0,1,3,6,10]",
-      "raw": "scanl : (a -\u003e b -\u003e b) -\u003e b -\u003e [a] -\u003e [b]",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            "b"
-          ]
-        ],
-        [
-          "-\u003e",
-          "b",
-          [
-            "-\u003e",
-            [
-              "_List",
-              "a"
-            ],
-            [
-              "_List",
-              "b"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "scanl1",
-      "comment": "Same as scanl but it doesn't require a base case. List must be non-empty.\n\n      scanl1 (+) [1,2,3,4] == [1,3,6,10]",
-      "raw": "scanl1 : (a -\u003e a -\u003e a) -\u003e [a] -\u003e [a]",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "a",
-            "a"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "_List",
-            "a"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "sort",
-      "comment": "Sort values from lowest to highest: `sort [3,1,5] == [1,3,5]`",
-      "raw": "sort : [comparable] -\u003e [comparable]",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "comparable"
-        ],
-        [
-          "_List",
-          "comparable"
-        ]
-      ]
-    },
-    {
-      "name": "sortBy",
-      "comment": "Sort values by a derived property.\n\n```haskell\nalice = { name=\"Alice\", height=1.62 }\nbob   = { name=\"Bob\"  , height=1.85 }\nchuck = { name=\"Chuck\", height=1.76 }\n\nsortBy .name   [chuck,alice,bob] == [alice,bob,chuck]\nsortBy .height [chuck,alice,bob] == [alice,chuck,bob]\n\nsortBy String.length [\"mouse\",\"cat\"] == [\"cat\",\"mouse\"]\n```",
-      "raw": "sortBy : (a -\u003e comparable) -\u003e  [a] -\u003e [a]",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          "comparable"
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "_List",
-            "a"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "sortWith",
-      "comment": "Sort values with a custom comparison function.\n\n```haskell\nsortWith flippedComparison [1..5] == [5,4,3,2,1]\n\nflippedComparison a b =\n     case compare a b of\n       LT -\u003e GT\n       EQ -\u003e EQ\n       GT -\u003e LT\n```\n\nThis is also the most general sort function, allowing you\nto define any other: `sort == sortWith compare`",
-      "raw": "sortWith : (a -\u003e a -\u003e Order) -\u003e  [a] -\u003e [a]",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "a",
-            [
-              "Order"
-            ]
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "_List",
-            "a"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "sum",
-      "comment": "Get the sum of the list elements. `(sum [1..4] == 10)`",
-      "raw": "sum : [number] -\u003e number",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "number"
-        ],
-        "number"
-      ]
-    },
-    {
-      "name": "tail",
-      "comment": "Extract the elements after the head of the list. List must be non-empty.\n`(tail [1,2,3] == [2,3])`",
-      "raw": "tail : [a] -\u003e [a]",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "a"
-        ],
-        [
-          "_List",
-          "a"
-        ]
-      ]
-    },
-    {
-      "name": "take",
-      "comment": "Take the first n members of a list: `(take 2 [1,2,3,4] == [1,2])`",
-      "raw": "take : Int -\u003e [a] -\u003e [a]",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "_List",
-            "a"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "unzip",
-      "comment": "Decompose a list of tuples.",
-      "raw": "unzip : [(a,b)] -\u003e ([a],[b])",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "_Tuple2",
-            "a",
-            "b"
-          ]
-        ],
-        [
-          "_Tuple2",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "_List",
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "zip",
-      "comment": "Combine two lists, combining them into tuples pairwise.\nIf one list is longer, the extra elements are dropped.\n\n      zip [1,2,3] [6,7] == [(1,6),(2,7)]\n      zip == zipWith (,)",
-      "raw": "zip : [a] -\u003e [b] -\u003e [(a,b)]",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "a"
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "b"
-          ],
-          [
-            "_List",
-            [
-              "_Tuple2",
-              "a",
-              "b"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "zipWith",
-      "comment": "Combine two lists, combining them with the given function.\nIf one list is longer, the extra elements are dropped.\n\n      zipWith (+) [1,2,3] [1,2,3,4] == [2,4,6]",
-      "raw": "zipWith : (a -\u003e b -\u003e c) -\u003e [a] -\u003e [b] -\u003e [c]",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            "c"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            "a"
-          ],
-          [
-            "-\u003e",
-            [
-              "_List",
-              "b"
-            ],
-            [
-              "_List",
-              "c"
-            ]
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Maybe",
-  "document": "Represents an optional value. Maybe it is there, maybe it is not.\n\n# Type and Constructors\n@docs Maybe\n\n# Taking Maybes apart\n@docs maybe, isJust, isNothing\n\n# Maybes and Lists\n@docs justs",
-  "aliases": [],
-  "datatypes": [
-    {
-      "name": "Maybe",
-      "comment": "The Maybe datatype. Useful when a computation may or may not\nresult in a value (e.g. logarithm is defined only for positive\nnumbers).",
-      "raw": "data Maybe a = Just a | Nothing",
-      "typeVariables": [
-        "a"
-      ],
-      "constructors": [
-        {
-          "name": "Just",
-          "type": [
-            "-\u003e",
-            "a",
-            [
-              "Maybe",
-              "a"
-            ]
-          ]
-        },
-        {
-          "name": "Nothing",
-          "type": [
-            "Maybe",
-            "a"
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "isJust",
-      "comment": "Check if constructed with `Just`.",
-      "raw": "isJust : Maybe a -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Maybe",
-          "a"
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "isNothing",
-      "comment": "Check if constructed with `Nothing`.",
-      "raw": "isNothing : Maybe a -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Maybe",
-          "a"
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "justs",
-      "comment": "Filters out Nothings and extracts the remaining values.",
-      "raw": "justs : [Maybe a] -\u003e [a]",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "Maybe",
-            "a"
-          ]
-        ],
-        [
-          "_List",
-          "a"
-        ]
-      ]
-    },
-    {
-      "name": "maybe",
-      "comment": "Apply a function to the contents of a `Maybe`.\nReturn default when given `Nothing`.",
-      "raw": "maybe : b -\u003e (a -\u003e b) -\u003e Maybe a -\u003e b",
-      "type": [
-        "-\u003e",
-        "b",
-        [
-          "-\u003e",
-          [
-            "-\u003e",
-            "a",
-            "b"
-          ],
-          [
-            "-\u003e",
-            [
-              "Maybe",
-              "a"
-            ],
-            "b"
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Mouse",
-  "document": "Library for working with mouse input.\n\n# Position\n@docs position, x, y\n\n# Button Status\n@docs isDown, clicks, isClicked",
-  "aliases": [],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "clicks",
-      "comment": "Always equal to unit. Event triggers on every mouse click.",
-      "raw": "clicks : Signal ()",
-      "type": [
-        "Signal",
-        [
-          "_Tuple0"
-        ]
-      ]
-    },
-    {
-      "name": "isClicked",
-      "comment": "True immediately after the left mouse-button has been clicked,\nand false otherwise.",
-      "raw": "isClicked : Signal Bool",
-      "type": [
-        "Signal",
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "isDown",
-      "comment": "The current state of the left mouse-button.\nTrue when the button is down, and false otherwise.",
-      "raw": "isDown : Signal Bool",
-      "type": [
-        "Signal",
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "position",
-      "comment": "The current mouse position.",
-      "raw": "position : Signal (Int,Int)",
-      "type": [
-        "Signal",
-        [
-          "_Tuple2",
-          [
-            "Int"
-          ],
-          [
-            "Int"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "x",
-      "comment": "The current x-coordinate of the mouse.",
-      "raw": "x : Signal Int",
-      "type": [
-        "Signal",
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "y",
-      "comment": "The current y-coordinate of the mouse.",
-      "raw": "y : Signal Int",
-      "type": [
-        "Signal",
-        [
-          "Int"
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Prelude",
-  "document": "Everything that is automatically imported",
-  "aliases": [],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "show",
-      "comment": "",
-      "raw": "show : a -\u003e String",
-      "type": [
-        "-\u003e",
-        "a",
-        [
-          "String"
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Random",
-  "document": "Since the core of Elm is pure, randomness must be handled via signals.\n\n# Random Numbers\n@docs range, float, floatList",
-  "aliases": [],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "float",
-      "comment": "Produces a new signal that changes whenever the input signal changes.\nThe new values are random numbers in [0..1).",
-      "raw": "float : Signal a -\u003e Signal Float",
-      "type": [
-        "-\u003e",
-        [
-          "Signal",
-          "a"
-        ],
-        [
-          "Signal",
-          [
-            "Float"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "floatList",
-      "comment": "Produces a new signal of lists that changes whenever the input signal\nchanges. The input signal specifies the length of the random list. Each value is\na random number in [0..1).",
-      "raw": "floatList : Signal Int -\u003e Signal [Float]",
-      "type": [
-        "-\u003e",
-        [
-          "Signal",
-          [
-            "Int"
-          ]
-        ],
-        [
-          "Signal",
-          [
-            "_List",
-            [
-              "Float"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "range",
-      "comment": "Given a range from low to high and a signal of values, this produces\na new signal that changes whenever the input signal changes. The new\nvalues are random number between 'low' and 'high' inclusive.",
-      "raw": "range : Int -\u003e Int -\u003e Signal a -\u003e Signal Int",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "-\u003e",
-            [
-              "Signal",
-              "a"
-            ],
-            [
-              "Signal",
-              [
-                "Int"
-              ]
-            ]
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Regex",
-  "document": "A library for working with regular expressions. It uses [the\nsame kind of regular expressions accepted by JavaScript](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions).\n\n# Create\n@docs pattern, caseInsensitive, escape\n\n# Match\n@docs Match\n\n# Find and Replace\n@docs contains, find, findAll, replace, replaceAll\n\n# Split\n@docs split, splitN",
-  "aliases": [
-    {
-      "name": "Match",
-      "comment": "A `Match` represents all of the details about a particular match in a string.\nHere are details on each field:\n\n  * `match` &mdash; the full string of the match.\n  * `submatches` &mdash; a pattern might have [subpatterns, surrounded by\n    parentheses](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Using_Parenthesized_Substring_Matches).\n    If there are N subpatterns, there will be N elements in the `submatches` list.\n    Each submatch in this list is a `Maybe` because not all subpatterns may trigger.\n    For example, `(pattern \"(a+)|(b+)\")` will either match many `a`&rsquo;s or\n    many `b`&rsquo;s, but never both.\n  * `index` &mdash; the index of the match in the original string.\n  * `number` &mdash; if you find many matches, you can think of each one\n    as being labeled with a `number` starting at one. So the first time you\n    find a match, that is match `number` one. Second time is match `number` two.\n    This is useful when paired with `replaceAll` if replacement is dependent on how\n    many times a pattern has appeared before.",
-      "raw": "type Match = { match : String, submatches : [Maybe String], index : Int, number : Int }",
-      "typeVariables": [],
-      "type": {
-        "submatches": [
-          "_List",
-          [
-            "Maybe",
-            [
-              "String"
-            ]
-          ]
-        ],
-        "match": [
-          "String"
-        ],
-        "index": [
-          "Int"
-        ],
-        "number": [
-          "Int"
-        ]
-      }
-    }
-  ],
-  "datatypes": [
-    {
-      "name": "Regex",
-      "comment": "",
-      "raw": "data Regex = Regex",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Regex",
-          "type": [
-            "Regex"
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "caseInsensitive",
-      "comment": "Make a pattern case insensitive",
-      "raw": "caseInsensitive : Regex -\u003e Regex",
-      "type": [
-        "-\u003e",
-        [
-          "Regex"
-        ],
-        [
-          "Regex"
-        ]
-      ]
-    },
-    {
-      "name": "contains",
-      "comment": "Check to see if a Regex is contained in a string.\n\n```haskell\n  contains (pattern \"123\") \"12345\" == True\n  contains (pattern \"b+\") \"aabbcc\" == True\n\n  contains (pattern \"789\") \"12345\" == False\n  contains (pattern \"z+\") \"aabbcc\" == False\n```",
-      "raw": "contains : Regex -\u003e String -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Regex"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "Bool"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "escape",
-      "comment": "Escape all special characters. So `pattern (escape \"$$$\")`\nwill match exactly `\"$$$\"` even though `$` is a special character.",
-      "raw": "escape : String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "String"
-        ]
-      ]
-    },
-    {
-      "name": "find",
-      "comment": "Same as `findAll`, but `find` will quit searching after the *n\u003csup\u003eth\u003c/sup\u003e* match.\nThat means the resulting list has maximum length N, but *it can be shorter*\nif there are not that many matches in the given string.",
-      "raw": "find : Int -\u003e Regex -\u003e String -\u003e [Match]",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Regex"
-          ],
-          [
-            "-\u003e",
-            [
-              "String"
-            ],
-            [
-              "_List",
-              [
-                "Match"
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "findAll",
-      "comment": "Find all of the matches in a string:\n\n```haskell\n  words = findAll (pattern \"\\\\w+\") \"hello world\"\n\n    map .match words == [\"hello\",\"world\"]\n    map .index words == [0,6]\n\n  places = findAll (pattern \"[oi]n a (\\\\w+)\") \"I am on a boat in a lake.\"\n\n    map .match places== [\"on a boat\", \"in a lake\"]\n    map .submatches places == [ [Just \"boat\"], [Just \"lake\"] ]\n```",
-      "raw": "findAll : Regex -\u003e String -\u003e [Match]",
-      "type": [
-        "-\u003e",
-        [
-          "Regex"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "_List",
-            [
-              "Match"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "pattern",
-      "comment": "Create a Regex that matches patterns [as specified in JavaScript](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Writing_a_Regular_Expression_Pattern).\nBe careful to escape backslashes properly!",
-      "raw": "pattern : String -\u003e Regex",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "Regex"
-        ]
-      ]
-    },
-    {
-      "name": "replace",
-      "comment": "Same as `replaceAll`, but `replace` will quit after the *n\u003csup\u003eth\u003c/sup\u003e* match.",
-      "raw": "replace : Int -\u003e Regex -\u003e (Match -\u003e String) -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Regex"
-          ],
-          [
-            "-\u003e",
-            [
-              "-\u003e",
-              [
-                "Match"
-              ],
-              [
-                "String"
-              ]
-            ],
-            [
-              "-\u003e",
-              [
-                "String"
-              ],
-              [
-                "String"
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "replaceAll",
-      "comment": "Replace all matches. The function from `Match` to `String` lets\nyou use the details of a specific match when making replacements.\n\n```haskell\n  devowel = replaceAll (pattern \"[aeiou]\") (\\_ -\u003e \"\")\n\n    devowel \"The quick brown fox\" == \"Th qck brwn fx\"\n\n  reverseWords = replaceAll (pattern \"\\\\w+\") (\\{match} -\u003e String.reverse match)\n\n    reverseWords \"deliver mined parts\" == \"reviled denim strap\"\n```",
-      "raw": "replaceAll : Regex -\u003e (Match -\u003e String) -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "Regex"
-        ],
-        [
-          "-\u003e",
-          [
-            "-\u003e",
-            [
-              "Match"
-            ],
-            [
-              "String"
-            ]
-          ],
-          [
-            "-\u003e",
-            [
-              "String"
-            ],
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "split",
-      "comment": "Split a string, using the regex as the separator.\n\n```haskell\n  split (pattern \" *, *\") \"a ,b, c,d\" == [\"a\",\"b\",\"c\",\"d\"]\n```",
-      "raw": "split : Regex -\u003e String -\u003e [String]",
-      "type": [
-        "-\u003e",
-        [
-          "Regex"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "_List",
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "splitN",
-      "comment": "Same as `split` but stops after the *n\u003csup\u003eth\u003c/sup\u003e* match.\n\n```haskell\n  splitN 1 (pattern \": *\") \"tom: 99,90,85\" == [\"tom\",\"99,90,85\"]\n```",
-      "raw": "splitN : Int -\u003e Regex -\u003e String -\u003e [String]",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Regex"
-          ],
-          [
-            "-\u003e",
-            [
-              "String"
-            ],
-            [
-              "_List",
-              [
-                "String"
-              ]
-            ]
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Set",
-  "document": "A set of unique values. The values can be any comparable type. This\nincludes `Int`, `Float`, `Time`, `Char`, `String`, and tuples or lists\nof comparable types.\n\nInsert, remove, and query operations all take *O(log n)* time.\n\n# Build\n@docs empty, singleton, insert, remove\n\n# Query\n@docs member\n\n# Combine\n@docs union, intersect, diff\n\n# Lists\n@docs toList, fromList\n\n# Transform\n@docs map, foldl, foldr",
-  "aliases": [],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "diff",
-      "comment": "Get the difference between the first set and the second. Keeps values\nthat do not appear in the second set.",
-      "raw": "diff : Set comparable -\u003e Set comparable -\u003e Set comparable",
-      "type": [
-        "-\u003e",
-        [
-          "Set",
-          "comparable"
-        ],
-        [
-          "-\u003e",
-          [
-            "Set",
-            "comparable"
-          ],
-          [
-            "Set",
-            "comparable"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "empty",
-      "comment": "Create an empty set.",
-      "raw": "empty : Set comparable",
-      "type": [
-        "Set",
-        "comparable"
-      ]
-    },
-    {
-      "name": "foldl",
-      "comment": "Fold over the values in a set, in order from lowest to highest.",
-      "raw": "foldl : (comparable -\u003e b -\u003e b) -\u003e b -\u003e Set comparable -\u003e b",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "comparable",
-          [
-            "-\u003e",
-            "b",
-            "b"
-          ]
-        ],
-        [
-          "-\u003e",
-          "b",
-          [
-            "-\u003e",
-            [
-              "Set",
-              "comparable"
-            ],
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "foldr",
-      "comment": "Fold over the values in a set, in order from highest to lowest.",
-      "raw": "foldr : (comparable -\u003e b -\u003e b) -\u003e b -\u003e Set comparable -\u003e b",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "comparable",
-          [
-            "-\u003e",
-            "b",
-            "b"
-          ]
-        ],
-        [
-          "-\u003e",
-          "b",
-          [
-            "-\u003e",
-            [
-              "Set",
-              "comparable"
-            ],
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "fromList",
-      "comment": "Convert a list into a set, removing any duplicates.",
-      "raw": "fromList : [comparable] -\u003e Set comparable",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          "comparable"
-        ],
-        [
-          "Set",
-          "comparable"
-        ]
-      ]
-    },
-    {
-      "name": "insert",
-      "comment": "Insert a value into a set.",
-      "raw": "insert : comparable -\u003e Set comparable -\u003e Set comparable",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          [
-            "Set",
-            "comparable"
-          ],
-          [
-            "Set",
-            "comparable"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "intersect",
-      "comment": "Get the intersection of two sets. Keeps values that appear in both sets.",
-      "raw": "intersect : Set comparable -\u003e Set comparable -\u003e Set comparable",
-      "type": [
-        "-\u003e",
-        [
-          "Set",
-          "comparable"
-        ],
-        [
-          "-\u003e",
-          [
-            "Set",
-            "comparable"
-          ],
-          [
-            "Set",
-            "comparable"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "map",
-      "comment": "Map a function onto a set, creating a new set with no duplicates.",
-      "raw": "map : (comparable -\u003e comparable') -\u003e Set comparable -\u003e Set comparable'",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "comparable",
-          "comparable'"
-        ],
-        [
-          "-\u003e",
-          [
-            "Set",
-            "comparable"
-          ],
-          [
-            "Set",
-            "comparable'"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "member",
-      "comment": "Determine if a value is in a set.",
-      "raw": "member : comparable -\u003e Set comparable -\u003e Bool",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          [
-            "Set",
-            "comparable"
-          ],
-          [
-            "Bool"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "remove",
-      "comment": "Remove a value from a set. If the value is not found, no changes are made.",
-      "raw": "remove : comparable -\u003e Set comparable -\u003e Set comparable",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "-\u003e",
-          [
-            "Set",
-            "comparable"
-          ],
-          [
-            "Set",
-            "comparable"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "singleton",
-      "comment": "Create a set with one value.",
-      "raw": "singleton : comparable -\u003e Set comparable",
-      "type": [
-        "-\u003e",
-        "comparable",
-        [
-          "Set",
-          "comparable"
-        ]
-      ]
-    },
-    {
-      "name": "toList",
-      "comment": "Convert a set into a list.",
-      "raw": "toList : Set comparable -\u003e [comparable]",
-      "type": [
-        "-\u003e",
-        [
-          "Set",
-          "comparable"
-        ],
-        [
-          "_List",
-          "comparable"
-        ]
-      ]
-    },
-    {
-      "name": "union",
-      "comment": "Get the union of two sets. Keep all values.",
-      "raw": "union : Set comparable -\u003e Set comparable -\u003e Set comparable",
-      "type": [
-        "-\u003e",
-        [
-          "Set",
-          "comparable"
-        ],
-        [
-          "-\u003e",
-          [
-            "Set",
-            "comparable"
-          ],
-          [
-            "Set",
-            "comparable"
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Signal",
-  "document": "The library for general signal manipulation. Includes lift functions up to\n`lift8` and infix lift operators `\u003c~` and `~`, combinations, filters, and\npast-dependence.\n\nSignals are time-varying values. Lifted functions are reevaluated whenever any of\ntheir input signals has an event. Signal events may be of the same value as the\nprevious value of the signal. Such signals are useful for timing and\npast-dependence.\n\nSome useful functions for working with time (e.g. setting FPS) and combining\nsignals and time (e.g.  delaying updates, getting timestamps) can be found in\nthe [`Time`](/docs/Signal/Time.elm) library.\n\n# Combine\n@docs constant, lift, lift2, merge, merges, combine\n\n# Past-Dependence\n@docs foldp, count, countIf\n\n#Filters\n@docs keepIf, dropIf, keepWhen, dropWhen, dropRepeats, sampleOn\n\n# Pretty Lift\n@docs (\u003c~), (~)\n\n# Do you even lift?\n@docs lift3, lift4, lift5, lift6, lift7, lift8",
-  "aliases": [],
-  "datatypes": [
-    {
-      "name": "Signal",
-      "comment": "",
-      "raw": "data Signal a = Signal",
-      "typeVariables": [
-        "a"
-      ],
-      "constructors": [
-        {
-          "name": "Signal",
-          "type": [
-            "Signal",
-            "a"
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "\u003c~",
-      "comment": "An alias for `lift`. A prettier way to apply a function to the current value\nof a signal.",
-      "raw": "(\u003c~) : (a -\u003e b) -\u003e Signal a -\u003e Signal b",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          "b"
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "Signal",
-            "b"
-          ]
-        ]
-      ],
-      "associativity": "left",
-      "precedence": 4
-    },
-    {
-      "name": "combine",
-      "comment": "Combine a list of signals into a signal of lists.",
-      "raw": "combine : [Signal a] -\u003e Signal [a]",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "Signal",
-            "a"
-          ]
-        ],
-        [
-          "Signal",
-          [
-            "_List",
-            "a"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "constant",
-      "comment": "Create a constant signal that never changes.",
-      "raw": "constant : a -\u003e Signal a",
-      "type": [
-        "-\u003e",
-        "a",
-        [
-          "Signal",
-          "a"
-        ]
-      ]
-    },
-    {
-      "name": "count",
-      "comment": "Count the number of events that have occurred.",
-      "raw": "count : Signal a -\u003e Signal Int",
-      "type": [
-        "-\u003e",
-        [
-          "Signal",
-          "a"
-        ],
-        [
-          "Signal",
-          [
-            "Int"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "countIf",
-      "comment": "Count the number of events that have occurred that satisfy a given predicate.",
-      "raw": "countIf : (a -\u003e Bool) -\u003e Signal a -\u003e Signal Int",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "Signal",
-            [
-              "Int"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "dropIf",
-      "comment": "Drop events that satisfy the given predicate. Elm does not allow undefined\nsignals, so a base case must be provided in case the predicate is satisfied\ninitially.",
-      "raw": "dropIf : (a -\u003e Bool) -\u003e a -\u003e Signal a -\u003e Signal a",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            [
-              "Signal",
-              "a"
-            ],
-            [
-              "Signal",
-              "a"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "dropRepeats",
-      "comment": "Drop updates that repeat the current value of the signal.\n\nImagine a signal `numbers` has initial value\n0 and then updates with values 0, 0, 1, 1, and 2. `dropRepeats numbers`\nis a signal that has initial value 0 and updates as follows: ignore 0,\nignore 0, update to 1, ignore 1, update to 2.",
-      "raw": "dropRepeats : Signal a -\u003e Signal a",
-      "type": [
-        "-\u003e",
-        [
-          "Signal",
-          "a"
-        ],
-        [
-          "Signal",
-          "a"
-        ]
-      ]
-    },
-    {
-      "name": "dropWhen",
-      "comment": "Drop events when the first signal is true. When the first signal becomes\nfalse, the most recent value of the second signal will be propagated. Until the\nfirst signal becomes true again, all events will be propagated. Elm does not\nallow undefined signals, s oa base case must be provided in case the first\nsignal is true initially.",
-      "raw": "dropWhen : Signal Bool -\u003e a -\u003e Signal a -\u003e Signal a",
-      "type": [
-        "-\u003e",
-        [
-          "Signal",
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            [
-              "Signal",
-              "a"
-            ],
-            [
-              "Signal",
-              "a"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "foldp",
-      "comment": "Create a past-dependent signal. Each value given on the input signal will\nbe accumulated, producing a new output value.\n\nFor instance, `foldp (+) 0 (fps 40)` is the time the program has been running,\nupdated 40 times a second.",
-      "raw": "foldp : (a -\u003e b -\u003e b) -\u003e b -\u003e Signal a -\u003e Signal b",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            "b"
-          ]
-        ],
-        [
-          "-\u003e",
-          "b",
-          [
-            "-\u003e",
-            [
-              "Signal",
-              "a"
-            ],
-            [
-              "Signal",
-              "b"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "keepIf",
-      "comment": "Keep only events that satisfy the given predicate. Elm does not allow\nundefined signals, so a base case must be provided in case the predicate is\nnot satisfied initially.",
-      "raw": "keepIf : (a -\u003e Bool) -\u003e a -\u003e Signal a -\u003e Signal a",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            [
-              "Signal",
-              "a"
-            ],
-            [
-              "Signal",
-              "a"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "keepWhen",
-      "comment": "Keep events only when the first signal is true. When the first signal\nbecomes true, the most recent value of the second signal will be propagated.\nUntil the first signal becomes false again, all events will be propagated. Elm\ndoes not allow undefined signals, so a base case must be provided in case the\nfirst signal is not true initially.",
-      "raw": "keepWhen : Signal Bool -\u003e a -\u003e Signal a -\u003e Signal a",
-      "type": [
-        "-\u003e",
-        [
-          "Signal",
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            [
-              "Signal",
-              "a"
-            ],
-            [
-              "Signal",
-              "a"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "lift",
-      "comment": "Transform a signal with a given function.",
-      "raw": "lift  : (a -\u003e b) -\u003e Signal a -\u003e Signal b",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          "b"
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "Signal",
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "lift2",
-      "comment": "Combine two signals with a given function.",
-      "raw": "lift2 : (a -\u003e b -\u003e c) -\u003e Signal a -\u003e Signal b -\u003e Signal c",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            "c"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "-\u003e",
-            [
-              "Signal",
-              "b"
-            ],
-            [
-              "Signal",
-              "c"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "lift3",
-      "comment": "",
-      "raw": "lift3 : (a -\u003e b -\u003e c -\u003e d) -\u003e Signal a -\u003e Signal b -\u003e Signal c -\u003e Signal d",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            [
-              "-\u003e",
-              "c",
-              "d"
-            ]
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "-\u003e",
-            [
-              "Signal",
-              "b"
-            ],
-            [
-              "-\u003e",
-              [
-                "Signal",
-                "c"
-              ],
-              [
-                "Signal",
-                "d"
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "lift4",
-      "comment": "",
-      "raw": "lift4 : (a -\u003e b -\u003e c -\u003e d -\u003e e) -\u003e Signal a -\u003e Signal b -\u003e Signal c -\u003e Signal d -\u003e Signal e",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            [
-              "-\u003e",
-              "c",
-              [
-                "-\u003e",
-                "d",
-                "e"
-              ]
-            ]
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "-\u003e",
-            [
-              "Signal",
-              "b"
-            ],
-            [
-              "-\u003e",
-              [
-                "Signal",
-                "c"
-              ],
-              [
-                "-\u003e",
-                [
-                  "Signal",
-                  "d"
-                ],
-                [
-                  "Signal",
-                  "e"
-                ]
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "lift5",
-      "comment": "",
-      "raw": "lift5 : (a -\u003e b -\u003e c -\u003e d -\u003e e -\u003e f) -\u003e Signal a -\u003e Signal b -\u003e Signal c -\u003e Signal d -\u003e Signal e -\u003e Signal f",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            [
-              "-\u003e",
-              "c",
-              [
-                "-\u003e",
-                "d",
-                [
-                  "-\u003e",
-                  "e",
-                  "f"
-                ]
-              ]
-            ]
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "-\u003e",
-            [
-              "Signal",
-              "b"
-            ],
-            [
-              "-\u003e",
-              [
-                "Signal",
-                "c"
-              ],
-              [
-                "-\u003e",
-                [
-                  "Signal",
-                  "d"
-                ],
-                [
-                  "-\u003e",
-                  [
-                    "Signal",
-                    "e"
-                  ],
-                  [
-                    "Signal",
-                    "f"
-                  ]
-                ]
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "lift6",
-      "comment": "",
-      "raw": "lift6 : (a -\u003e b -\u003e c -\u003e d -\u003e e -\u003e f -\u003e g)\n      -\u003e Signal a -\u003e Signal b -\u003e Signal c -\u003e Signal d -\u003e Signal e -\u003e Signal f -\u003e Signal g",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            [
-              "-\u003e",
-              "c",
-              [
-                "-\u003e",
-                "d",
-                [
-                  "-\u003e",
-                  "e",
-                  [
-                    "-\u003e",
-                    "f",
-                    "g"
-                  ]
-                ]
-              ]
-            ]
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "-\u003e",
-            [
-              "Signal",
-              "b"
-            ],
-            [
-              "-\u003e",
-              [
-                "Signal",
-                "c"
-              ],
-              [
-                "-\u003e",
-                [
-                  "Signal",
-                  "d"
-                ],
-                [
-                  "-\u003e",
-                  [
-                    "Signal",
-                    "e"
-                  ],
-                  [
-                    "-\u003e",
-                    [
-                      "Signal",
-                      "f"
-                    ],
-                    [
-                      "Signal",
-                      "g"
-                    ]
-                  ]
-                ]
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "lift7",
-      "comment": "",
-      "raw": "lift7 : (a -\u003e b -\u003e c -\u003e d -\u003e e -\u003e f -\u003e g -\u003e h)\n      -\u003e Signal a -\u003e Signal b -\u003e Signal c -\u003e Signal d -\u003e Signal e -\u003e Signal f -\u003e Signal g -\u003e Signal h",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            [
-              "-\u003e",
-              "c",
-              [
-                "-\u003e",
-                "d",
-                [
-                  "-\u003e",
-                  "e",
-                  [
-                    "-\u003e",
-                    "f",
-                    [
-                      "-\u003e",
-                      "g",
-                      "h"
-                    ]
-                  ]
-                ]
-              ]
-            ]
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "-\u003e",
-            [
-              "Signal",
-              "b"
-            ],
-            [
-              "-\u003e",
-              [
-                "Signal",
-                "c"
-              ],
-              [
-                "-\u003e",
-                [
-                  "Signal",
-                  "d"
-                ],
-                [
-                  "-\u003e",
-                  [
-                    "Signal",
-                    "e"
-                  ],
-                  [
-                    "-\u003e",
-                    [
-                      "Signal",
-                      "f"
-                    ],
-                    [
-                      "-\u003e",
-                      [
-                        "Signal",
-                        "g"
-                      ],
-                      [
-                        "Signal",
-                        "h"
-                      ]
-                    ]
-                  ]
-                ]
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "lift8",
-      "comment": "",
-      "raw": "lift8 : (a -\u003e b -\u003e c -\u003e d -\u003e e -\u003e f -\u003e g -\u003e h -\u003e i)\n      -\u003e Signal a -\u003e Signal b -\u003e Signal c -\u003e Signal d -\u003e Signal e -\u003e Signal f -\u003e Signal g -\u003e Signal h -\u003e Signal i",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          "a",
-          [
-            "-\u003e",
-            "b",
-            [
-              "-\u003e",
-              "c",
-              [
-                "-\u003e",
-                "d",
-                [
-                  "-\u003e",
-                  "e",
-                  [
-                    "-\u003e",
-                    "f",
-                    [
-                      "-\u003e",
-                      "g",
-                      [
-                        "-\u003e",
-                        "h",
-                        "i"
-                      ]
-                    ]
-                  ]
-                ]
-              ]
-            ]
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "-\u003e",
-            [
-              "Signal",
-              "b"
-            ],
-            [
-              "-\u003e",
-              [
-                "Signal",
-                "c"
-              ],
-              [
-                "-\u003e",
-                [
-                  "Signal",
-                  "d"
-                ],
-                [
-                  "-\u003e",
-                  [
-                    "Signal",
-                    "e"
-                  ],
-                  [
-                    "-\u003e",
-                    [
-                      "Signal",
-                      "f"
-                    ],
-                    [
-                      "-\u003e",
-                      [
-                        "Signal",
-                        "g"
-                      ],
-                      [
-                        "-\u003e",
-                        [
-                          "Signal",
-                          "h"
-                        ],
-                        [
-                          "Signal",
-                          "i"
-                        ]
-                      ]
-                    ]
-                  ]
-                ]
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "merge",
-      "comment": "Merge two signals into one, biased towards the first signal if both signals\nupdate at the same time.",
-      "raw": "merge : Signal a -\u003e Signal a -\u003e Signal a",
-      "type": [
-        "-\u003e",
-        [
-          "Signal",
-          "a"
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "Signal",
-            "a"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "merges",
-      "comment": "Merge many signals into one, biased towards the left-most signal if multiple\nsignals update simultaneously.",
-      "raw": "merges : [Signal a] -\u003e Signal a",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "Signal",
-            "a"
-          ]
-        ],
-        [
-          "Signal",
-          "a"
-        ]
-      ]
-    },
-    {
-      "name": "sampleOn",
-      "comment": "Sample from the second input every time an event occurs on the first input.\nFor example, `(sampleOn clicks (every second))` will give the approximate time\nof the latest click.",
-      "raw": "sampleOn : Signal a -\u003e Signal b -\u003e Signal b",
-      "type": [
-        "-\u003e",
-        [
-          "Signal",
-          "a"
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "b"
-          ],
-          [
-            "Signal",
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "~",
-      "comment": "Informally, an alias for `liftN`. Intersperse it between additional signal\narguments of the lifted function.\n\nFormally, signal application. This takes two signals, holding a function and\na value. It applies the current function to the current value.\n\nThe following expressions are equivalent:\n\n         scene \u003c~ Window.dimensions ~ Mouse.position\n         lift2 scene Window.dimensions Mouse.position",
-      "raw": "(~) : Signal (a -\u003e b) -\u003e Signal a -\u003e Signal b",
-      "type": [
-        "-\u003e",
-        [
-          "Signal",
-          [
-            "-\u003e",
-            "a",
-            "b"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "Signal",
-            "b"
-          ]
-        ]
-      ],
-      "associativity": "left",
-      "precedence": 4
-    }
-  ]
-},
-{
-  "name": "String",
-  "document": "A built-in representation for efficient string manipulation. String literals\nare enclosed in `\"double quotes\"`. Strings are *not* lists of characters.\n\n# Basics\n@docs isEmpty, length, reverse, repeat\n\n# Building and Splitting\n@docs  cons, uncons, append, concat, split, join, words, lines\n\n# Get Substrings\n@docs sub, left, right, dropLeft, dropRight\n\n# Check for Substrings\n@docs contains, startsWith, endsWith, indexes, indices\n\n# Conversions\n@docs toInt, toFloat, toList, fromList\n\n# Formatting\nCosmetic operations such as padding with extra characters or trimming whitespace.\n\n@docs toUpper, toLower,\n      pad, padLeft, padRight,\n      trim, trimLeft, trimRight\n\n# Higher-Order Functions\n@docs map, filter, foldl, foldr, any, all",
-  "aliases": [],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "all",
-      "comment": "Check to see if *all* characters satisfy a predicate.\n\n      all isDigit \"90210\" == True\n      all isDigit \"R2-D2\" == False\n      any isDigit \"heart\" == False",
-      "raw": "all : (Char -\u003e Bool) -\u003e String -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          [
-            "Char"
-          ],
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "Bool"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "any",
-      "comment": "Check to see if *any* characters satisfy a predicate.\n\n      any isDigit \"90210\" == True\n      any isDigit \"R2-D2\" == True\n      any isDigit \"heart\" == False",
-      "raw": "any : (Char -\u003e Bool) -\u003e String -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          [
-            "Char"
-          ],
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "Bool"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "append",
-      "comment": "Append two strings. You can also use [the `(++)` operator](/library/List.elm#++)\nto do this.\n\n      append \"butter\" \"fly\" == \"butterfly\"",
-      "raw": "append : String -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "String"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "concat",
-      "comment": "Concatenate many strings into one.\n\n      concat [\"never\",\"the\",\"less\"] == \"nevertheless\"",
-      "raw": "concat : [String] -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "String"
-          ]
-        ],
-        [
-          "String"
-        ]
-      ]
-    },
-    {
-      "name": "cons",
-      "comment": "Add a character to the beginning of a string",
-      "raw": "cons : Char -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "Char"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "String"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "contains",
-      "comment": "See if a string contains another one.\n\n      contains \"the\" \"theory\" == True\n      contains \"hat\" \"theory\" == False\n      contains \"THE\" \"theory\" == False",
-      "raw": "contains : String -\u003e String -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "Bool"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "dropLeft",
-      "comment": "Drop N characters from the left side of a string.",
-      "raw": "dropLeft : Int -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "String"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "dropRight",
-      "comment": "Drop N characters from the right side of a string.",
-      "raw": "dropRight : Int -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "String"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "endsWith",
-      "comment": "See if a string ends with another one.\n\n      endsWith \"the\" \"theory\" == False\n      endsWith \"ory\" \"theory\" == True",
-      "raw": "endsWith : String -\u003e String -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "Bool"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "filter",
-      "comment": "Keep only the characters that satisfy the predicate:\n\n      filter isDigit \"R2-D2\" == \"22\"",
-      "raw": "filter : (Char -\u003e Bool) -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          [
-            "Char"
-          ],
-          [
-            "Bool"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "String"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "foldl",
-      "comment": "Reduce a string from the left:\n\n      foldl cons \"\" \"time\" == \"emit\"",
-      "raw": "foldl : (Char -\u003e b -\u003e b) -\u003e b -\u003e String -\u003e b",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          [
-            "Char"
-          ],
-          [
-            "-\u003e",
-            "b",
-            "b"
-          ]
-        ],
-        [
-          "-\u003e",
-          "b",
-          [
-            "-\u003e",
-            [
-              "String"
-            ],
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "foldr",
-      "comment": "Reduce a string from the right:\n\n      foldr cons \"\" \"time\" == \"time\"",
-      "raw": "foldr : (Char -\u003e b -\u003e b) -\u003e b -\u003e String -\u003e b",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          [
-            "Char"
-          ],
-          [
-            "-\u003e",
-            "b",
-            "b"
-          ]
-        ],
-        [
-          "-\u003e",
-          "b",
-          [
-            "-\u003e",
-            [
-              "String"
-            ],
-            "b"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "fromList",
-      "comment": "Convert a list of characters into a String. Can be useful if you\nwant to create a string primarly by consing, perhaps for decoding\nsomething.\n\n      fromList ['a','b','c'] == \"abc\"",
-      "raw": "fromList : [Char] -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "Char"
-          ]
-        ],
-        [
-          "String"
-        ]
-      ]
-    },
-    {
-      "name": "indexes",
-      "comment": "Get all of the indexes for a substring.\n\n      indexes \"i\" \"Mississippi\"   == [1,4,7,10]\n      indexes \"ss\" \"Mississippi\"  == [2,5]\n      indexes \"needle\" \"haystack\" == []",
-      "raw": "indexes : String -\u003e String -\u003e [Int]",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "_List",
-            [
-              "Int"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "indices",
-      "comment": "Alias for `indexes`",
-      "raw": "indices : String -\u003e String -\u003e [Int]",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "_List",
-            [
-              "Int"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "isEmpty",
-      "comment": "Check if a string is empty `(isEmpty \"\" == True)`",
-      "raw": "isEmpty : String -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "Bool"
-        ]
-      ]
-    },
-    {
-      "name": "join",
-      "comment": "Put many strings together with a given separator.\n\n      join \" \" [\"cat\",\"dog\",\"cow\"]       == \"cat dog cow\"\n      join \"/\" [\"home\",\"evan\",\"Desktop\"] == \"home/evan/Desktop\"",
-      "raw": "join : String -\u003e [String] -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            [
-              "String"
-            ]
-          ],
-          [
-            "String"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "left",
-      "comment": "Take N characters from the left side of a string.",
-      "raw": "left : Int -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "String"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "length",
-      "comment": "Get the length of a string `(length \"innumerable\" == 11)`",
-      "raw": "length : String -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "lines",
-      "comment": "Break a string into lines, splitting on newlines.\n\n      lines \"How are you?\\nGood? == [\"How are you?\", \"Good?\"]",
-      "raw": "lines : String -\u003e [String]",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "_List",
-          [
-            "String"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "map",
-      "comment": "Transform every character in a string\n\n      map (\\c -\u003e if c == '/' then '.' else c) \"a/b/c\" == \"a.b.c\"",
-      "raw": "map : (Char -\u003e Char) -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "-\u003e",
-          [
-            "Char"
-          ],
-          [
-            "Char"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "String"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "pad",
-      "comment": "Pad a string on both sides until it has a given length.\n\n      pad 5 ' ' \"1\"   == \"  1  \"\n      pad 5 ' ' \"11\"  == \"  11 \"\n      pad 5 ' ' \"121\" == \" 121 \"",
-      "raw": "pad : Int -\u003e Char -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Char"
-          ],
-          [
-            "-\u003e",
-            [
-              "String"
-            ],
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "padLeft",
-      "comment": "Pad a string on the left until it has a given length.\n\n      pad 5 '.' \"1\"   == \"....1\"\n      pad 5 '.' \"11\"  == \"...11\"\n      pad 5 '.' \"121\" == \"..121\"",
-      "raw": "padLeft : Int -\u003e Char -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Char"
-          ],
-          [
-            "-\u003e",
-            [
-              "String"
-            ],
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "padRight",
-      "comment": "Pad a string on the right until it has a given length.\n\n      pad 5 '.' \"1\"   == \"1....\"\n      pad 5 '.' \"11\"  == \"11...\"\n      pad 5 '.' \"121\" == \"121..\"",
-      "raw": "padRight : Int -\u003e Char -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Char"
-          ],
-          [
-            "-\u003e",
-            [
-              "String"
-            ],
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "repeat",
-      "comment": "Repeat a string N times `(repeat 3 \"ha\" == \"hahaha\")`",
-      "raw": "repeat : Int -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "String"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "reverse",
-      "comment": "Reverse a string. `(reverse \"stressed\" == \"desserts\")`",
-      "raw": "reverse : String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "String"
-        ]
-      ]
-    },
-    {
-      "name": "right",
-      "comment": "Take N characters from the right side of a string.",
-      "raw": "right : Int -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "String"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "split",
-      "comment": "Split a string using a given separator.\n\n      split \",\" \"cat,dog,cow\"        == [\"cat\",\"dog\",\"cow\"]\n      split \"/\" \"home/evan/Desktop/\" == [\"home\",\"evan\",\"Desktop\"]",
-      "raw": "split : String -\u003e String -\u003e [String]",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "_List",
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "startsWith",
-      "comment": "See if a string starts with another one.\n\n      startsWith \"the\" \"theory\" == True\n      startsWith \"ory\" \"theory\" == False",
-      "raw": "startsWith : String -\u003e String -\u003e Bool",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "String"
-          ],
-          [
-            "Bool"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "sub",
-      "comment": "Take a substring given a start and end index. Negative indexes\nare taken starting from the *end* of the list.\n\n      sub  7  9 \"snakes on a plane!\" == \"on\"\n      sub  0  6 \"snakes on a plane!\" == \"snakes\"\n      sub  0 -7 \"snakes on a plane!\" == \"snakes on a\"\n      sub -6 -1 \"snakes on a plane!\" == \"plane\"",
-      "raw": "sub : Int -\u003e Int -\u003e String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "-\u003e",
-            [
-              "String"
-            ],
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "toFloat",
-      "comment": "Try to convert a string into a float, failing on improperly formatted strings.\n\n      toFloat \"123\" == Just 123.0\n      toFloat \"-42\" == Just -42.0\n      toFloat \"3.1\" == Just 3.1\n      toFloat \"31a\" == Nothing",
-      "raw": "toFloat : String -\u003e Maybe Float",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "Maybe",
-          [
-            "Float"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "toInt",
-      "comment": "Try to convert a string into an int, failing on improperly formatted strings.\n\n      toInt \"123\" == Just 123\n      toInt \"-42\" == Just -42\n      toInt \"3.1\" == Nothing\n      toInt \"31a\" == Nothing",
-      "raw": "toInt : String -\u003e Maybe Int",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "Maybe",
-          [
-            "Int"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "toList",
-      "comment": "Convert a string to a list of characters.\n\n      toList \"abc\" == ['a','b','c']",
-      "raw": "toList : String -\u003e [Char]",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "_List",
-          [
-            "Char"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "toLower",
-      "comment": "Convert a string to all lower case. Useful for case insensitive comparisons.",
-      "raw": "toLower : String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "String"
-        ]
-      ]
-    },
-    {
-      "name": "toUpper",
-      "comment": "Convert a string to all upper case. Useful for case insensitive comparisons\nand VIRTUAL YELLING.",
-      "raw": "toUpper : String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "String"
-        ]
-      ]
-    },
-    {
-      "name": "trim",
-      "comment": "Get rid of whitespace on both sides of a string.\n\n      trim \"  hats  \\n\" == \"hats\"",
-      "raw": "trim : String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "String"
-        ]
-      ]
-    },
-    {
-      "name": "trimLeft",
-      "comment": "Get rid of whitespace on the left of a string.\n\n      trimLeft \"  hats  \\n\" == \"hats  \\n\"",
-      "raw": "trimLeft : String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "String"
-        ]
-      ]
-    },
-    {
-      "name": "trimRight",
-      "comment": "Get rid of whitespace on the left of a string.\n\n      trimRight \"  hats  \\n\" == \"  hats\"",
-      "raw": "trimRight : String -\u003e String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "String"
-        ]
-      ]
-    },
-    {
-      "name": "uncons",
-      "comment": "Split a non-empty string into its head and tail. This lets you\npattern match on strings exactly as you would with lists.\n\n      uncons \"abc\" == Just ('a',\"bc\")\n      uncons \"\"    == Nothing",
-      "raw": "uncons : String -\u003e Maybe (Char, String)",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "Maybe",
-          [
-            "_Tuple2",
-            [
-              "Char"
-            ],
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "words",
-      "comment": "Break a string into words, splitting on chunks of whitespace.\n\n      words \"How are \\t you? \\n Good?\" == [\"How\",\"are\",\"you?\",\"Good?\"]",
-      "raw": "words : String -\u003e [String]",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "_List",
-          [
-            "String"
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Text",
-  "document": "Functions for displaying text\n\n# Creating Text\n@docs toText\n\n# Creating Elements\n@docs plainText, asText, text, centered, justified, righted\n\n# Formatting\n@docs color, typeface, height, link\n\n# Simple Formatting\n@docs monospace, bold, italic, underline, overline, strikeThrough",
-  "aliases": [],
-  "datatypes": [
-    {
-      "name": "Text",
-      "comment": "",
-      "raw": "data Text = Text",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Text",
-          "type": [
-            "Text"
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "asText",
-      "comment": "Convert anything to its textual representation and make it displayable in\nthe browser:\n\n        asText == text . monospace . show\n\nExcellent for debugging.",
-      "raw": "asText : a -\u003e Element",
-      "type": [
-        "-\u003e",
-        "a",
-        [
-          "Element"
-        ]
-      ]
-    },
-    {
-      "name": "bold",
-      "comment": "Make a string bold.",
-      "raw": "bold : Text -\u003e Text",
-      "type": [
-        "-\u003e",
-        [
-          "Text"
-        ],
-        [
-          "Text"
-        ]
-      ]
-    },
-    {
-      "name": "centered",
-      "comment": "Display centered, styled text.",
-      "raw": "centered : Text -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Text"
-        ],
-        [
-          "Element"
-        ]
-      ]
-    },
-    {
-      "name": "color",
-      "comment": "Set the color of a string.",
-      "raw": "color : Color -\u003e Text -\u003e Text",
-      "type": [
-        "-\u003e",
-        [
-          "Color"
-        ],
-        [
-          "-\u003e",
-          [
-            "Text"
-          ],
-          [
-            "Text"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "height",
-      "comment": "Set the height of text in pixels.",
-      "raw": "height : Float -\u003e Text -\u003e Text",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Text"
-          ],
-          [
-            "Text"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "italic",
-      "comment": "Italicize a string.",
-      "raw": "italic : Text -\u003e Text",
-      "type": [
-        "-\u003e",
-        [
-          "Text"
-        ],
-        [
-          "Text"
-        ]
-      ]
-    },
-    {
-      "name": "justified",
-      "comment": "Display justified, styled text.",
-      "raw": "justified : Text -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Text"
-        ],
-        [
-          "Element"
-        ]
-      ]
-    },
-    {
-      "name": "link",
-      "comment": "Create a link.",
-      "raw": "link : String -\u003e Text -\u003e Text",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "Text"
-          ],
-          [
-            "Text"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "markdown",
-      "comment": "for internal use only",
-      "raw": "markdown : Element",
-      "type": [
-        "Element"
-      ]
-    },
-    {
-      "name": "monospace",
-      "comment": "Switch to a monospace typeface. Good for code snippets.",
-      "raw": "monospace : Text -\u003e Text",
-      "type": [
-        "-\u003e",
-        [
-          "Text"
-        ],
-        [
-          "Text"
-        ]
-      ]
-    },
-    {
-      "name": "overline",
-      "comment": "Draw a line above a string.",
-      "raw": "overline : Text -\u003e Text",
-      "type": [
-        "-\u003e",
-        [
-          "Text"
-        ],
-        [
-          "Text"
-        ]
-      ]
-    },
-    {
-      "name": "plainText",
-      "comment": "Display a plain string.",
-      "raw": "plainText : String -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "Element"
-        ]
-      ]
-    },
-    {
-      "name": "righted",
-      "comment": "Display right justified, styled text.",
-      "raw": "righted : Text -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Text"
-        ],
-        [
-          "Element"
-        ]
-      ]
-    },
-    {
-      "name": "strikeThrough",
-      "comment": "Draw a line through a string.",
-      "raw": "strikeThrough : Text -\u003e Text",
-      "type": [
-        "-\u003e",
-        [
-          "Text"
-        ],
-        [
-          "Text"
-        ]
-      ]
-    },
-    {
-      "name": "text",
-      "comment": "Display styled text.",
-      "raw": "text : Text -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Text"
-        ],
-        [
-          "Element"
-        ]
-      ]
-    },
-    {
-      "name": "toText",
-      "comment": "Convert a string into text which can be styled and displayed.",
-      "raw": "toText : String -\u003e Text",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "Text"
-        ]
-      ]
-    },
-    {
-      "name": "typeface",
-      "comment": "Set the typeface of some text. The first argument should be a comma\nseparated listing of the desired typefaces:\n\n        \"helvetica, arial, sans-serif\"\n\nWorks the same as the CSS font-family property.",
-      "raw": "typeface : String -\u003e Text -\u003e Text",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "Text"
-          ],
-          [
-            "Text"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "underline",
-      "comment": "Underline a string.",
-      "raw": "underline : Text -\u003e Text",
-      "type": [
-        "-\u003e",
-        [
-          "Text"
-        ],
-        [
-          "Text"
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Time",
-  "document": "Library for working with time.\n\n# Units\n@docs Time, millisecond, second, minute, hour,\n      inMilliseconds, inSeconds, inMinutes, inHours\n\n# Tickers\n@docs fps, fpsWhen, every\n\n# Timing\n@docs timestamp, delay, since",
-  "aliases": [
-    {
-      "name": "Time",
-      "comment": "Type alias to make it clearer when you are working with time values.\nUsing the `Time` constants instead of raw numbers is very highly recommended.",
-      "raw": "type Time = Float",
-      "typeVariables": [],
-      "type": [
-        "Float"
-      ]
-    }
-  ],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "delay",
-      "comment": "Delay a signal by a certain amount of time. So `(delay second Mouse.clicks)`\nwill update one second later than any mouse click.",
-      "raw": "delay : Time -\u003e Signal a -\u003e Signal a",
-      "type": [
-        "-\u003e",
-        [
-          "Time"
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "Signal",
-            "a"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "every",
-      "comment": "Takes a time interval t. The resulting signal is the current time, updated\nevery t.",
-      "raw": "every : Time -\u003e Signal Time",
-      "type": [
-        "-\u003e",
-        [
-          "Time"
-        ],
-        [
-          "Signal",
-          [
-            "Time"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "fps",
-      "comment": "Takes desired number of frames per second (fps). The resulting signal\ngives a sequence of time deltas as quickly as possible until it reaches\nthe desired FPS. A time delta is the time between the last frame and the\ncurrent frame.",
-      "raw": "fps : number -\u003e Signal Time",
-      "type": [
-        "-\u003e",
-        "number",
-        [
-          "Signal",
-          [
-            "Time"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "fpsWhen",
-      "comment": "Same as the fps function, but you can turn it on and off. Allows you\nto do brief animations based on user input without major inefficiencies.\nThe first time delta after a pause is always zero, no matter how long\nthe pause was. This way summing the deltas will actually give the amount\nof time that the output signal has been running.",
-      "raw": "fpsWhen : number -\u003e Signal Bool -\u003e Signal Time",
-      "type": [
-        "-\u003e",
-        "number",
-        [
-          "-\u003e",
-          [
-            "Signal",
-            [
-              "Bool"
-            ]
-          ],
-          [
-            "Signal",
-            [
-              "Time"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "hour",
-      "comment": "",
-      "raw": "hour : Time",
-      "type": [
-        "Time"
-      ]
-    },
-    {
-      "name": "inHours",
-      "comment": "",
-      "raw": "inHours : Time -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Time"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "inMilliseconds",
-      "comment": "",
-      "raw": "inMilliseconds : Time -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Time"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "inMinutes",
-      "comment": "",
-      "raw": "inMinutes : Time -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Time"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "inSeconds",
-      "comment": "",
-      "raw": "inSeconds : Time -\u003e Float",
-      "type": [
-        "-\u003e",
-        [
-          "Time"
-        ],
-        [
-          "Float"
-        ]
-      ]
-    },
-    {
-      "name": "millisecond",
-      "comment": "Units of time, making it easier to specify things like a half-second\n`(500 * milliseconds)` without remembering Elm&rsquo;s underlying units of time.",
-      "raw": "millisecond : Time",
-      "type": [
-        "Time"
-      ]
-    },
-    {
-      "name": "minute",
-      "comment": "",
-      "raw": "minute : Time",
-      "type": [
-        "Time"
-      ]
-    },
-    {
-      "name": "second",
-      "comment": "",
-      "raw": "second : Time",
-      "type": [
-        "Time"
-      ]
-    },
-    {
-      "name": "since",
-      "comment": "Takes a time `t` and any signal. The resulting boolean signal is true for\ntime `t` after every event on the input signal. So ``(second `since`\nMouse.clicks)`` would result in a signal that is true for one second after\neach mouse click and false otherwise.",
-      "raw": "since : Time -\u003e Signal a -\u003e Signal Bool",
-      "type": [
-        "-\u003e",
-        [
-          "Time"
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            "a"
-          ],
-          [
-            "Signal",
-            [
-              "Bool"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "timestamp",
-      "comment": "Add a timestamp to any signal. Timestamps increase monotonically. When you\ncreate `(timestamp Mouse.x)`, an initial timestamp is produced. The timestamp\nupdates whenever `Mouse.x` updates.\n\nTimestamp updates are tied to individual events, so\n`(timestamp Mouse.x)` and `(timestamp Mouse.y)` will always have the same\ntimestamp because they rely on the same underlying event (`Mouse.position`).",
-      "raw": "timestamp : Signal a -\u003e Signal (Time, a)",
-      "type": [
-        "-\u003e",
-        [
-          "Signal",
-          "a"
-        ],
-        [
-          "Signal",
-          [
-            "_Tuple2",
-            [
-              "Time"
-            ],
-            "a"
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Touch",
-  "document": "This is an early version of the touch library. It will likely grow to\ninclude gestures that would be useful for both games and web-pages.\n\n# Touches\n@docs Touch, touches\n\n# Gestures\n@docs taps",
-  "aliases": [
-    {
-      "name": "Touch",
-      "comment": "Every `Touch` has `xy` coordinates. It also has an identifier\n`id` to distinguish one touch from another.\n\nA touch also keeps info about the initial point and time of contact:\n`x0`, `y0`, and `t0`. This helps compute more complicated gestures\nlike taps, drags, and swipes which need to know about timing or direction.",
-      "raw": "type Touch = { x:Int, y:Int, id:Int, x0:Int, y0:Int, t0:Time }",
-      "typeVariables": [],
-      "type": {
-        "y0": [
-          "Int"
-        ],
-        "y": [
-          "Int"
-        ],
-        "x": [
-          "Int"
-        ],
-        "id": [
-          "Int"
-        ],
-        "t0": [
-          "Time"
-        ],
-        "x0": [
-          "Int"
-        ]
-      }
-    }
-  ],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "taps",
-      "comment": "The last position that was tapped. Default value is `{x=0,y=0}`.\nUpdates whenever the user taps the screen.",
-      "raw": "taps : Signal { x:Int, y:Int }",
-      "type": [
-        "Signal",
-        {
-          "y": [
-            "Int"
-          ],
-          "x": [
-            "Int"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "touches",
-      "comment": "A list of ongoing touches.",
-      "raw": "touches : Signal [Touch]",
-      "type": [
-        "Signal",
-        [
-          "_List",
-          [
-            "Touch"
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Transform2D",
-  "document": "A library for performing [2D matrix transformations][affine].\nIt is used primarily with the `groupTransform` function from `Graphics.Collage` and\nallows you to do things like rotation, scaling, translation, shearing, and reflection.\n\nNote that all the matrices in this library are 3x3 matrices of homogeneous\ncoordinates, used for [affine transformations][affine]. Since the bottom row as\nalways `0 0 1` in these matrices, it is omitted in the diagrams below.\n\n [affine]: http://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations\n\n# Transforms\n@docs identity, matrix, rotation, translation, scale, scaleX, scaleY\n\n# Multiplication\n@docs multiply",
-  "aliases": [],
-  "datatypes": [
-    {
-      "name": "Transform2D",
-      "comment": "",
-      "raw": "data Transform2D = Transform2D",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Transform2D",
-          "type": [
-            "Transform2D"
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "identity",
-      "comment": "Create an identity transform. Transforming by the identity does\nnot change anything, but it can come in handy as a default or\nbase case.\n\n          / 1 0 0 \\\n          \\ 0 1 0 /",
-      "raw": "identity : Transform2D",
-      "type": [
-        "Transform2D"
-      ]
-    },
-    {
-      "name": "matrix",
-      "comment": "Creates a transformation matrix. This lets you create transforms\nsuch as scales, shears, reflections, and translations.\n\n      matrix a b c d x y\n\n          / a b x \\\n          \\ c d y /\n\nNote that `x` and `y` are the translation values.",
-      "raw": "matrix : Float -\u003e Float -\u003e Float -\u003e Float -\u003e Float -\u003e Float -\u003e Transform2D",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Float"
-          ],
-          [
-            "-\u003e",
-            [
-              "Float"
-            ],
-            [
-              "-\u003e",
-              [
-                "Float"
-              ],
-              [
-                "-\u003e",
-                [
-                  "Float"
-                ],
-                [
-                  "-\u003e",
-                  [
-                    "Float"
-                  ],
-                  [
-                    "Transform2D"
-                  ]
-                ]
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "multiply",
-      "comment": "Multiplies two transforms together:\n\n      multiply m n\n\n          / ma mb mx \\     / na nb nx \\\n          | mc md my |  .  | nc nd ny |\n          \\  0  0  1 /     \\  0  0  1 /",
-      "raw": "multiply : Transform2D -\u003e Transform2D -\u003e Transform2D",
-      "type": [
-        "-\u003e",
-        [
-          "Transform2D"
-        ],
-        [
-          "-\u003e",
-          [
-            "Transform2D"
-          ],
-          [
-            "Transform2D"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "rotation",
-      "comment": "Creates a [rotation matrix](http://en.wikipedia.org/wiki/Rotation_matrix).\nGiven an angle t, it creates a counterclockwise rotation matrix:\n\n          / cos t  -sin t  0 \\\n          \\ sin t   cos t  0 /",
-      "raw": "rotation : Float -\u003e Transform2D",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Transform2D"
-        ]
-      ]
-    },
-    {
-      "name": "scale",
-      "comment": "Creates a transformation matrix for scaling by a all directions:\n\n    scale s\n\n        / s 0 0 \\\n        \\ 0 s 0 /",
-      "raw": "scale : Float -\u003e Transform2D",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Transform2D"
-        ]
-      ]
-    },
-    {
-      "name": "scaleX",
-      "comment": "Creates a transformation for horizontal scaling",
-      "raw": "scaleX : Float -\u003e Transform2D",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Transform2D"
-        ]
-      ]
-    },
-    {
-      "name": "scaleY",
-      "comment": "Creates a transformation for vertical scaling",
-      "raw": "scaleY : Float -\u003e Transform2D",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Transform2D"
-        ]
-      ]
-    },
-    {
-      "name": "translation",
-      "comment": "Creates a transformation matrix for translation:\n\n    translation x y\n\n          / 1 0 x \\\n          \\ 0 1 y /",
-      "raw": "translation : Float -\u003e Float -\u003e Transform2D",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Float"
-          ],
-          [
-            "Transform2D"
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "WebSocket",
-  "document": "A library for low latency HTTP communication. See the HTTP library for\nstandard requests like GET, POST, etc. The API of this library is likely to\nchange to make it more flexible.\n\n# Open a Connection\n@docs connect",
-  "aliases": [],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "connect",
-      "comment": "Create a web-socket. The first argument is the URL of the desired\nweb-socket server. The input signal holds the outgoing messages,\nand the resulting signal contains the incoming ones.",
-      "raw": "connect : String -\u003e Signal String -\u003e Signal String",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "Signal",
-            [
-              "String"
-            ]
-          ],
-          [
-            "Signal",
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Window",
-  "document": "Provides information about the container that your Elm program lives in.\nWhen you embed Elm in a `\u003cdiv\u003e` it gives the dimensions of the container, not\nthe whole window.\n\n# Dimensions\n@docs dimensions, width, height",
-  "aliases": [],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "dimensions",
-      "comment": "The current width and height of the window (i.e. the area viewable to the\nuser, not including scroll bars).",
-      "raw": "dimensions : Signal (Int,Int)",
-      "type": [
-        "Signal",
-        [
-          "_Tuple2",
-          [
-            "Int"
-          ],
-          [
-            "Int"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "height",
-      "comment": "The current height of the window.",
-      "raw": "height : Signal Int",
-      "type": [
-        "Signal",
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "width",
-      "comment": "The current width of the window.",
-      "raw": "width : Signal Int",
-      "type": [
-        "Signal",
-        [
-          "Int"
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Graphics.Collage",
-  "document": "The collage API is for freeform graphics. You can move, rotate, scale, etc.\nall sorts of forms including lines, shapes, images, and elements.\n\n# Unstructured Graphics\n@docs collage\n \n# Creating Forms\n@docs toForm, filled, textured, gradient, outlined, traced\n \n# Transforming Forms\n@docs move, moveX, moveY, scale, rotate, alpha\n \n# Grouping Forms\nGrouping forms makes it easier to write modular graphics code. You can create\na form that is a composite of many subforms. From there it is easy to transform\nit as a single unit.\n\n@docs group, groupTransform\n \n# Shapes\n@docs rect, oval, square, circle, ngon, polygon\n\n# Paths\n@docs segment, path\n \n# Line Styles\n@docs solid, dashed, dotted, LineStyle, LineCap, LineJoin, defaultLine",
-  "aliases": [
-    {
-      "name": "Form",
-      "comment": "",
-      "raw": "type Form = {\n  theta : Float,\n  scale : Float,\n  x : Float,\n  y : Float,\n  alpha : Float,\n  form : BasicForm\n }",
-      "typeVariables": [],
-      "type": {
-        "alpha": [
-          "Float"
-        ],
-        "y": [
-          "Float"
-        ],
-        "form": [
-          "BasicForm"
-        ],
-        "x": [
-          "Float"
-        ],
-        "theta": [
-          "Float"
-        ],
-        "scale": [
-          "Float"
-        ]
-      }
-    },
-    {
-      "name": "LineStyle",
-      "comment": "All of the attributes of a line style. This lets you build up a line style\nhowever you want. You can also update existing line styles with record updates.",
-      "raw": "type LineStyle = {\n  color : Color,\n  width : Float,\n  cap   : LineCap,\n  join  : LineJoin,\n  dashing    : [Int],\n  dashOffset : Int\n }",
-      "typeVariables": [],
-      "type": {
-        "width": [
-          "Float"
-        ],
-        "dashOffset": [
-          "Int"
-        ],
-        "color": [
-          "Color"
-        ],
-        "join": [
-          "LineJoin"
-        ],
-        "dashing": [
-          "_List",
-          [
-            "Int"
-          ]
-        ],
-        "cap": [
-          "LineCap"
-        ]
-      }
-    },
-    {
-      "name": "Path",
-      "comment": "",
-      "raw": "type Path = [(Float,Float)]",
-      "typeVariables": [],
-      "type": [
-        "_List",
-        [
-          "_Tuple2",
-          [
-            "Float"
-          ],
-          [
-            "Float"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "Shape",
-      "comment": "",
-      "raw": "type Shape = [(Float,Float)]",
-      "typeVariables": [],
-      "type": [
-        "_List",
-        [
-          "_Tuple2",
-          [
-            "Float"
-          ],
-          [
-            "Float"
-          ]
-        ]
-      ]
-    }
-  ],
-  "datatypes": [
-    {
-      "name": "BasicForm",
-      "comment": "",
-      "raw": "data BasicForm\n  = FPath LineStyle Path\n  | FShape (Either LineStyle FillStyle) Shape\n  | FImage Int Int (Int,Int) String\n  | FElement Element\n  | FGroup Transform2D [Form]",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "FPath",
-          "type": [
-            "-\u003e",
-            [
-              "LineStyle"
-            ],
-            [
-              "-\u003e",
-              [
-                "Path"
-              ],
-              [
-                "BasicForm"
-              ]
-            ]
-          ]
-        },
-        {
-          "name": "FShape",
-          "type": [
-            "-\u003e",
-            [
-              "Either",
-              [
-                "LineStyle"
-              ],
-              [
-                "FillStyle"
-              ]
-            ],
-            [
-              "-\u003e",
-              [
-                "Shape"
-              ],
-              [
-                "BasicForm"
-              ]
-            ]
-          ]
-        },
-        {
-          "name": "FImage",
-          "type": [
-            "-\u003e",
-            [
-              "Int"
-            ],
-            [
-              "-\u003e",
-              [
-                "Int"
-              ],
-              [
-                "-\u003e",
-                [
-                  "_Tuple2",
-                  [
-                    "Int"
-                  ],
-                  [
-                    "Int"
-                  ]
-                ],
-                [
-                  "-\u003e",
-                  [
-                    "String"
-                  ],
-                  [
-                    "BasicForm"
-                  ]
-                ]
-              ]
-            ]
-          ]
-        },
-        {
-          "name": "FElement",
-          "type": [
-            "-\u003e",
-            [
-              "Element"
-            ],
-            [
-              "BasicForm"
-            ]
-          ]
-        },
-        {
-          "name": "FGroup",
-          "type": [
-            "-\u003e",
-            [
-              "Transform2D"
-            ],
-            [
-              "-\u003e",
-              [
-                "_List",
-                [
-                  "Form"
-                ]
-              ],
-              [
-                "BasicForm"
-              ]
-            ]
-          ]
-        }
-      ]
-    },
-    {
-      "name": "FillStyle",
-      "comment": "",
-      "raw": "data FillStyle\n  = Solid Color\n  | Texture String\n  | Grad Gradient",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Solid",
-          "type": [
-            "-\u003e",
-            [
-              "Color"
-            ],
-            [
-              "FillStyle"
-            ]
-          ]
-        },
-        {
-          "name": "Texture",
-          "type": [
-            "-\u003e",
-            [
-              "String"
-            ],
-            [
-              "FillStyle"
-            ]
-          ]
-        },
-        {
-          "name": "Grad",
-          "type": [
-            "-\u003e",
-            [
-              "Gradient"
-            ],
-            [
-              "FillStyle"
-            ]
-          ]
-        }
-      ]
-    },
-    {
-      "name": "LineCap",
-      "comment": "The shape of the ends of a line.",
-      "raw": "data LineCap = Flat | Round | Padded",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Flat",
-          "type": [
-            "LineCap"
-          ]
-        },
-        {
-          "name": "Round",
-          "type": [
-            "LineCap"
-          ]
-        },
-        {
-          "name": "Padded",
-          "type": [
-            "LineCap"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "LineJoin",
-      "comment": "The shape of the &ldquo;joints&rdquo; of a line, where each line segment\nmeets. `Sharp` takes an argument to limit the length of the joint. This\ndefaults to 10.",
-      "raw": "data LineJoin = Smooth | Sharp Float | Clipped",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Smooth",
-          "type": [
-            "LineJoin"
-          ]
-        },
-        {
-          "name": "Sharp",
-          "type": [
-            "-\u003e",
-            [
-              "Float"
-            ],
-            [
-              "LineJoin"
-            ]
-          ]
-        },
-        {
-          "name": "Clipped",
-          "type": [
-            "LineJoin"
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "alpha",
-      "comment": "Set the alpha of a `Form`. The default is 1, and 0 is totally transparent.",
-      "raw": "alpha : Float -\u003e Form -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Form"
-          ],
-          [
-            "Form"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "circle",
-      "comment": "A circle with a given radius.",
-      "raw": "circle : Float -\u003e Shape",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Shape"
-        ]
-      ]
-    },
-    {
-      "name": "collage",
-      "comment": "A collage is a collection of 2D forms. There are no strict positioning\nrelationships between forms, so you are free to do all kinds of 2D graphics.",
-      "raw": "collage : Int -\u003e Int -\u003e [Form] -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "-\u003e",
-            [
-              "_List",
-              [
-                "Form"
-              ]
-            ],
-            [
-              "Element"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "dashed",
-      "comment": "Create a dashed line style with a given color. Dashing equals `[8,4]`.",
-      "raw": "dashed : Color -\u003e LineStyle",
-      "type": [
-        "-\u003e",
-        [
-          "Color"
-        ],
-        [
-          "LineStyle"
-        ]
-      ]
-    },
-    {
-      "name": "defaultLine",
-      "comment": "The default line style, which is solid black with flat caps and sharp joints.\nYou can use record updates to build the line style you\nwant. For example, to make a thicker line, you could say:\n\n        { defaultLine | width \u003c- 10 }",
-      "raw": "defaultLine : LineStyle",
-      "type": [
-        "LineStyle"
-      ]
-    },
-    {
-      "name": "dotted",
-      "comment": "Create a dotted line style with a given color. Dashing equals `[3,3]`.",
-      "raw": "dotted : Color -\u003e LineStyle",
-      "type": [
-        "-\u003e",
-        [
-          "Color"
-        ],
-        [
-          "LineStyle"
-        ]
-      ]
-    },
-    {
-      "name": "filled",
-      "comment": "Create a filled in shape.",
-      "raw": "filled : Color -\u003e Shape -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "Color"
-        ],
-        [
-          "-\u003e",
-          [
-            "Shape"
-          ],
-          [
-            "Form"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "form",
-      "comment": "",
-      "raw": "form : BasicForm -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "BasicForm"
-        ],
-        [
-          "Form"
-        ]
-      ]
-    },
-    {
-      "name": "gradient",
-      "comment": "Fill a shape with a [gradient](/library/Color.elm#linear).",
-      "raw": "gradient : Gradient -\u003e Shape -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "Gradient"
-        ],
-        [
-          "-\u003e",
-          [
-            "Shape"
-          ],
-          [
-            "Form"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "group",
-      "comment": "Flatten many forms into a single `Form`. This lets you move and rotate them\nas a single unit, making it possible to build small, modular components.",
-      "raw": "group : [Form] -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "Form"
-          ]
-        ],
-        [
-          "Form"
-        ]
-      ]
-    },
-    {
-      "name": "groupTransform",
-      "comment": "Flatten many forms into a single `Form` and then apply a matrix\ntransformation.",
-      "raw": "groupTransform : Transform2D -\u003e [Form] -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "Transform2D"
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            [
-              "Form"
-            ]
-          ],
-          [
-            "Form"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "move",
-      "comment": "Move a form by the given amount. This is a relative translation so\n`(move (10,10) form)` would move `form` ten pixels up and ten pixels to the\nright.",
-      "raw": "move : (Float,Float) -\u003e Form -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "_Tuple2",
-          [
-            "Float"
-          ],
-          [
-            "Float"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "Form"
-          ],
-          [
-            "Form"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "moveX",
-      "comment": "Move a shape in the x direction. This is relative so `(moveX 10 form)` moves\n`form` 10 pixels to the right.",
-      "raw": "moveX : Float -\u003e Form -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Form"
-          ],
-          [
-            "Form"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "moveY",
-      "comment": "Move a shape in the y direction. This is relative so `(moveY 10 form)` moves\n`form` upwards by 10 pixels.",
-      "raw": "moveY : Float -\u003e Form -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Form"
-          ],
-          [
-            "Form"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "ngon",
-      "comment": "A regular polygon with N sides. The first argument specifies the number\nof sides and the second is the radius. So to create a pentagon with radius\n30 you would say:\n\n        ngon 5 30",
-      "raw": "ngon : Int -\u003e Float -\u003e Shape",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Float"
-          ],
-          [
-            "Shape"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "outlined",
-      "comment": "Outline a shape with a given line style.",
-      "raw": "outlined : LineStyle -\u003e Shape -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "LineStyle"
-        ],
-        [
-          "-\u003e",
-          [
-            "Shape"
-          ],
-          [
-            "Form"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "oval",
-      "comment": "An oval with a given width and height.",
-      "raw": "oval : Float -\u003e Float -\u003e Shape",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Float"
-          ],
-          [
-            "Shape"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "path",
-      "comment": "Create a path that follows a sequence of points.",
-      "raw": "path : [(Float,Float)] -\u003e Path",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "_Tuple2",
-            [
-              "Float"
-            ],
-            [
-              "Float"
-            ]
-          ]
-        ],
-        [
-          "Path"
-        ]
-      ]
-    },
-    {
-      "name": "polygon",
-      "comment": "Create an arbitrary polygon by specifying its corners in order.\n`polygon` will automatically close all shapes, so the given list\nof points does not need to start and end with the same position.",
-      "raw": "polygon : [(Float,Float)] -\u003e Shape",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "_Tuple2",
-            [
-              "Float"
-            ],
-            [
-              "Float"
-            ]
-          ]
-        ],
-        [
-          "Shape"
-        ]
-      ]
-    },
-    {
-      "name": "rect",
-      "comment": "A rectangle with a given width and height.",
-      "raw": "rect : Float -\u003e Float -\u003e Shape",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Float"
-          ],
-          [
-            "Shape"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "rotate",
-      "comment": "Rotate a form by a given angle. Rotate takes standard Elm angles (radians)\nand turns things counterclockwise. So to turn `form` 30&deg; to the left\nyou would say, `(rotate (degrees 30) form)`.",
-      "raw": "rotate : Float -\u003e Form -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Form"
-          ],
-          [
-            "Form"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "scale",
-      "comment": "Scale a form by a given factor. Scaling by 2 doubles the size.",
-      "raw": "scale : Float -\u003e Form -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Form"
-          ],
-          [
-            "Form"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "segment",
-      "comment": "Create a path along a given line segment.",
-      "raw": "segment : (Float,Float) -\u003e (Float,Float) -\u003e Path",
-      "type": [
-        "-\u003e",
-        [
-          "_Tuple2",
-          [
-            "Float"
-          ],
-          [
-            "Float"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "_Tuple2",
-            [
-              "Float"
-            ],
-            [
-              "Float"
-            ]
-          ],
-          [
-            "Path"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "solid",
-      "comment": "Create a solid line style with a given color.",
-      "raw": "solid : Color -\u003e LineStyle",
-      "type": [
-        "-\u003e",
-        [
-          "Color"
-        ],
-        [
-          "LineStyle"
-        ]
-      ]
-    },
-    {
-      "name": "sprite",
-      "comment": "Create a sprite from a sprite sheet. It cuts out a rectangle\nat a given position.",
-      "raw": "sprite : Int -\u003e Int -\u003e (Int,Int) -\u003e String -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "-\u003e",
-            [
-              "_Tuple2",
-              [
-                "Int"
-              ],
-              [
-                "Int"
-              ]
-            ],
-            [
-              "-\u003e",
-              [
-                "String"
-              ],
-              [
-                "Form"
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "square",
-      "comment": "A square with a given edge length.",
-      "raw": "square : Float -\u003e Shape",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Shape"
-        ]
-      ]
-    },
-    {
-      "name": "textured",
-      "comment": "Create a textured shape. The texture is described by some url and is\ntiled to fill the entire shape.",
-      "raw": "textured : String -\u003e Shape -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "Shape"
-          ],
-          [
-            "Form"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "toForm",
-      "comment": "Turn any `Element` into a `Form`. This lets you use text, gifs, and video\nin your collage. This means you can move, rotate, and scale\nan `Element` however you want.",
-      "raw": "toForm : Element -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "Element"
-        ],
-        [
-          "Form"
-        ]
-      ]
-    },
-    {
-      "name": "traced",
-      "comment": "Trace a path with a given line style.",
-      "raw": "traced : LineStyle -\u003e Path -\u003e Form",
-      "type": [
-        "-\u003e",
-        [
-          "LineStyle"
-        ],
-        [
-          "-\u003e",
-          [
-            "Path"
-          ],
-          [
-            "Form"
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Graphics.Element",
-  "document": "Graphical elements that snap together to build complex widgets and layouts.\nEach Element is a rectangle with a known width and height, making them easy to\ncombine and position.\n\n# Images\n@docs image, fittedImage, croppedImage, tiledImage\n\n# Styling\n@docs width, height, size, color, opacity, link, tag\n\n# Inspection\n@docs widthOf, heightOf, sizeOf\n\n# Layout\n@docs flow, up, down, left, right, inward, outward\n\n## Layout Aliases\nThere are also some convenience functions for working\nwith `flow` in specific cases:\n\n@docs layers, above, below, beside\n\n# Positioning\n@docs empty, spacer, container\n\n## Specific Positions\n\nTo create a `Position` you can use any of the built-in positions\nwhich cover nine common positions.\n@docs middle, midTop, midBottom, midLeft, midRight, topLeft, topRight,\n      bottomLeft, bottomRight\n\nIf you need more precision, you can create custom positions.\n\n@docs absolute, relative, middleAt, midTopAt, midBottomAt, midLeftAt,\n      midRightAt, topLeftAt, topRightAt, bottomLeftAt, bottomRightAt",
-  "aliases": [
-    {
-      "name": "Element",
-      "comment": "",
-      "raw": "type Element = { props : Properties, element : ElementPrim }",
-      "typeVariables": [],
-      "type": {
-        "props": [
-          "Properties"
-        ],
-        "element": [
-          "ElementPrim"
-        ]
-      }
-    },
-    {
-      "name": "Position",
-      "comment": "",
-      "raw": "type Position = { horizontal : Three, vertical : Three, x : Pos, y : Pos }",
-      "typeVariables": [],
-      "type": {
-        "y": [
-          "Pos"
-        ],
-        "horizontal": [
-          "Three"
-        ],
-        "x": [
-          "Pos"
-        ],
-        "vertical": [
-          "Three"
-        ]
-      }
-    },
-    {
-      "name": "Properties",
-      "comment": "",
-      "raw": "type Properties = {\n  id      : Int,\n  width   : Int,\n  height  : Int,\n  opacity : Float,\n  color   : Maybe Color,\n  href    : JSString,\n  tag     : JSString,\n  hover   : ()\n }",
-      "typeVariables": [],
-      "type": {
-        "height": [
-          "Int"
-        ],
-        "href": [
-          "JSString"
-        ],
-        "width": [
-          "Int"
-        ],
-        "id": [
-          "Int"
-        ],
-        "color": [
-          "Maybe",
-          [
-            "Color"
-          ]
-        ],
-        "opacity": [
-          "Float"
-        ],
-        "hover": [
-          "_Tuple0"
-        ],
-        "tag": [
-          "JSString"
-        ]
-      }
-    }
-  ],
-  "datatypes": [
-    {
-      "name": "Direction",
-      "comment": "",
-      "raw": "data Direction = DUp | DDown | DLeft | DRight | DIn | DOut",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "DUp",
-          "type": [
-            "Direction"
-          ]
-        },
-        {
-          "name": "DDown",
-          "type": [
-            "Direction"
-          ]
-        },
-        {
-          "name": "DLeft",
-          "type": [
-            "Direction"
-          ]
-        },
-        {
-          "name": "DRight",
-          "type": [
-            "Direction"
-          ]
-        },
-        {
-          "name": "DIn",
-          "type": [
-            "Direction"
-          ]
-        },
-        {
-          "name": "DOut",
-          "type": [
-            "Direction"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "ElementPrim",
-      "comment": "",
-      "raw": "data ElementPrim\n  = Image ImageStyle Int Int JSString\n  | Container Position Element\n  | Flow Direction [Element]\n  | Spacer\n  | RawHtml\n  | Custom",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Image",
-          "type": [
-            "-\u003e",
-            [
-              "ImageStyle"
-            ],
-            [
-              "-\u003e",
-              [
-                "Int"
-              ],
-              [
-                "-\u003e",
-                [
-                  "Int"
-                ],
-                [
-                  "-\u003e",
-                  [
-                    "JSString"
-                  ],
-                  [
-                    "ElementPrim"
-                  ]
-                ]
-              ]
-            ]
-          ]
-        },
-        {
-          "name": "Container",
-          "type": [
-            "-\u003e",
-            [
-              "Position"
-            ],
-            [
-              "-\u003e",
-              [
-                "Element"
-              ],
-              [
-                "ElementPrim"
-              ]
-            ]
-          ]
-        },
-        {
-          "name": "Flow",
-          "type": [
-            "-\u003e",
-            [
-              "Direction"
-            ],
-            [
-              "-\u003e",
-              [
-                "_List",
-                [
-                  "Element"
-                ]
-              ],
-              [
-                "ElementPrim"
-              ]
-            ]
-          ]
-        },
-        {
-          "name": "Spacer",
-          "type": [
-            "ElementPrim"
-          ]
-        },
-        {
-          "name": "RawHtml",
-          "type": [
-            "ElementPrim"
-          ]
-        },
-        {
-          "name": "Custom",
-          "type": [
-            "ElementPrim"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "ImageStyle",
-      "comment": "",
-      "raw": "data ImageStyle = Plain | Fitted | Cropped (Int,Int) | Tiled",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Plain",
-          "type": [
-            "ImageStyle"
-          ]
-        },
-        {
-          "name": "Fitted",
-          "type": [
-            "ImageStyle"
-          ]
-        },
-        {
-          "name": "Cropped",
-          "type": [
-            "-\u003e",
-            [
-              "_Tuple2",
-              [
-                "Int"
-              ],
-              [
-                "Int"
-              ]
-            ],
-            [
-              "ImageStyle"
-            ]
-          ]
-        },
-        {
-          "name": "Tiled",
-          "type": [
-            "ImageStyle"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "Pos",
-      "comment": "",
-      "raw": "data Pos = Absolute Int | Relative Float",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "Absolute",
-          "type": [
-            "-\u003e",
-            [
-              "Int"
-            ],
-            [
-              "Pos"
-            ]
-          ]
-        },
-        {
-          "name": "Relative",
-          "type": [
-            "-\u003e",
-            [
-              "Float"
-            ],
-            [
-              "Pos"
-            ]
-          ]
-        }
-      ]
-    },
-    {
-      "name": "Three",
-      "comment": "",
-      "raw": "data Three = P | Z | N",
-      "typeVariables": [],
-      "constructors": [
-        {
-          "name": "P",
-          "type": [
-            "Three"
-          ]
-        },
-        {
-          "name": "Z",
-          "type": [
-            "Three"
-          ]
-        },
-        {
-          "name": "N",
-          "type": [
-            "Three"
-          ]
-        }
-      ]
-    }
-  ],
-  "values": [
-    {
-      "name": "above",
-      "comment": "Stack elements vertically.\nTo put `a` above `b` you would say: ``a `above` b``",
-      "raw": "above : Element -\u003e Element -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Element"
-        ],
-        [
-          "-\u003e",
-          [
-            "Element"
-          ],
-          [
-            "Element"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "absolute",
-      "comment": "",
-      "raw": "absolute : Int -\u003e Pos",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "Pos"
-        ]
-      ]
-    },
-    {
-      "name": "below",
-      "comment": "Stack elements vertically.\nTo put `a` below `b` you would say: ``a `below` b``",
-      "raw": "below : Element -\u003e Element -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Element"
-        ],
-        [
-          "-\u003e",
-          [
-            "Element"
-          ],
-          [
-            "Element"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "beside",
-      "comment": "Put elements beside each other horizontally.\nTo put `a` beside `b` you would say: ``a `beside` b``",
-      "raw": "beside : Element -\u003e Element -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Element"
-        ],
-        [
-          "-\u003e",
-          [
-            "Element"
-          ],
-          [
-            "Element"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "bottomLeft",
-      "comment": "",
-      "raw": "bottomLeft  : Position",
-      "type": [
-        "Position"
-      ]
-    },
-    {
-      "name": "bottomLeftAt",
-      "comment": "",
-      "raw": "bottomLeftAt      : Pos -\u003e Pos -\u003e Position",
-      "type": [
-        "-\u003e",
-        [
-          "Pos"
-        ],
-        [
-          "-\u003e",
-          [
-            "Pos"
-          ],
-          [
-            "Position"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "bottomRight",
-      "comment": "",
-      "raw": "bottomRight : Position",
-      "type": [
-        "Position"
-      ]
-    },
-    {
-      "name": "bottomRightAt",
-      "comment": "",
-      "raw": "bottomRightAt     : Pos -\u003e Pos -\u003e Position",
-      "type": [
-        "-\u003e",
-        [
-          "Pos"
-        ],
-        [
-          "-\u003e",
-          [
-            "Pos"
-          ],
-          [
-            "Position"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "color",
-      "comment": "Create an `Element` with a given background color.",
-      "raw": "color : Color -\u003e Element -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Color"
-        ],
-        [
-          "-\u003e",
-          [
-            "Element"
-          ],
-          [
-            "Element"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "container",
-      "comment": "Put an element in a container. This lets you position the element really\neasily, and there are tons of ways to set the `Position`.\nTo center `element` exactly in a 300-by-300 square you would say:\n\n        container 300 300 middle element\n\nBy setting the color of the container, you can create borders.",
-      "raw": "container : Int -\u003e Int -\u003e Position -\u003e Element -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "-\u003e",
-            [
-              "Position"
-            ],
-            [
-              "-\u003e",
-              [
-                "Element"
-              ],
-              [
-                "Element"
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "croppedImage",
-      "comment": "Create a cropped image. Take a rectangle out of the picture starting\nat the given top left coordinate. If you have a 140-by-140 image,\nthe following will cut a 100-by-100 square out of the middle of it.\n\n        croppedImage (20,20) 100 100 \"yogi.jpg\"",
-      "raw": "croppedImage : (Int,Int) -\u003e Int -\u003e Int -\u003e String -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "_Tuple2",
-          [
-            "Int"
-          ],
-          [
-            "Int"
-          ]
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "-\u003e",
-            [
-              "Int"
-            ],
-            [
-              "-\u003e",
-              [
-                "String"
-              ],
-              [
-                "Element"
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "down",
-      "comment": "",
-      "raw": "down : Direction",
-      "type": [
-        "Direction"
-      ]
-    },
-    {
-      "name": "empty",
-      "comment": "An Element that takes up no space. Good for things that appear conditionally:\n\n    flow down [ img1, if showMore then img2 else empty ]",
-      "raw": "empty : Element",
-      "type": [
-        "Element"
-      ]
-    },
-    {
-      "name": "fittedImage",
-      "comment": "Create a fitted image given a width, height, and image source.\nThis will crop the picture to best fill the given dimensions.",
-      "raw": "fittedImage : Int -\u003e Int -\u003e String -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "-\u003e",
-            [
-              "String"
-            ],
-            [
-              "Element"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "flow",
-      "comment": "Have a list of elements flow in a particular direction.\nThe `Direction` starts from the first element in the list.\n\n        flow right [a,b,c]\n\n          +---+---+---+\n          | a | b | c |\n          +---+---+---+",
-      "raw": "flow : Direction -\u003e [Element] -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Direction"
-        ],
-        [
-          "-\u003e",
-          [
-            "_List",
-            [
-              "Element"
-            ]
-          ],
-          [
-            "Element"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "height",
-      "comment": "Create an `Element` with a given height.",
-      "raw": "height : Int -\u003e Element -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Element"
-          ],
-          [
-            "Element"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "heightOf",
-      "comment": "Get the height of an Element",
-      "raw": "heightOf : Element -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Element"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    },
-    {
-      "name": "image",
-      "comment": "Create an image given a width, height, and image source.",
-      "raw": "image : Int -\u003e Int -\u003e String -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "-\u003e",
-            [
-              "String"
-            ],
-            [
-              "Element"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "inward",
-      "comment": "",
-      "raw": "inward : Direction",
-      "type": [
-        "Direction"
-      ]
-    },
-    {
-      "name": "layers",
-      "comment": "Layer elements on top of each other, starting from the bottom:\n`layers == flow outward`",
-      "raw": "layers : [Element] -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "Element"
-          ]
-        ],
-        [
-          "Element"
-        ]
-      ]
-    },
-    {
-      "name": "left",
-      "comment": "",
-      "raw": "left : Direction",
-      "type": [
-        "Direction"
-      ]
-    },
-    {
-      "name": "link",
-      "comment": "Create an `Element` that is a hyper-link.",
-      "raw": "link : String -\u003e Element -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "Element"
-          ],
-          [
-            "Element"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "midBottom",
-      "comment": "",
-      "raw": "midBottom   : Position",
-      "type": [
-        "Position"
-      ]
-    },
-    {
-      "name": "midBottomAt",
-      "comment": "",
-      "raw": "midBottomAt       : Pos -\u003e Pos -\u003e Position",
-      "type": [
-        "-\u003e",
-        [
-          "Pos"
-        ],
-        [
-          "-\u003e",
-          [
-            "Pos"
-          ],
-          [
-            "Position"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "midLeft",
-      "comment": "",
-      "raw": "midLeft     : Position",
-      "type": [
-        "Position"
-      ]
-    },
-    {
-      "name": "midLeftAt",
-      "comment": "",
-      "raw": "midLeftAt         : Pos -\u003e Pos -\u003e Position",
-      "type": [
-        "-\u003e",
-        [
-          "Pos"
-        ],
-        [
-          "-\u003e",
-          [
-            "Pos"
-          ],
-          [
-            "Position"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "midRight",
-      "comment": "",
-      "raw": "midRight    : Position",
-      "type": [
-        "Position"
-      ]
-    },
-    {
-      "name": "midRightAt",
-      "comment": "",
-      "raw": "midRightAt        : Pos -\u003e Pos -\u003e Position",
-      "type": [
-        "-\u003e",
-        [
-          "Pos"
-        ],
-        [
-          "-\u003e",
-          [
-            "Pos"
-          ],
-          [
-            "Position"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "midTop",
-      "comment": "",
-      "raw": "midTop      : Position",
-      "type": [
-        "Position"
-      ]
-    },
-    {
-      "name": "midTopAt",
-      "comment": "",
-      "raw": "midTopAt          : Pos -\u003e Pos -\u003e Position",
-      "type": [
-        "-\u003e",
-        [
-          "Pos"
-        ],
-        [
-          "-\u003e",
-          [
-            "Pos"
-          ],
-          [
-            "Position"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "middle",
-      "comment": "",
-      "raw": "middle      : Position",
-      "type": [
-        "Position"
-      ]
-    },
-    {
-      "name": "middleAt",
-      "comment": "",
-      "raw": "middleAt          : Pos -\u003e Pos -\u003e Position",
-      "type": [
-        "-\u003e",
-        [
-          "Pos"
-        ],
-        [
-          "-\u003e",
-          [
-            "Pos"
-          ],
-          [
-            "Position"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "opacity",
-      "comment": "Create an `Element` with a given opacity. Opacity is a number between 0 and 1\nwhere 0 means totally clear.",
-      "raw": "opacity : Float -\u003e Element -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "-\u003e",
-          [
-            "Element"
-          ],
-          [
-            "Element"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "outward",
-      "comment": "",
-      "raw": "outward : Direction",
-      "type": [
-        "Direction"
-      ]
-    },
-    {
-      "name": "relative",
-      "comment": "",
-      "raw": "relative : Float -\u003e Pos",
-      "type": [
-        "-\u003e",
-        [
-          "Float"
-        ],
-        [
-          "Pos"
-        ]
-      ]
-    },
-    {
-      "name": "right",
-      "comment": "",
-      "raw": "right : Direction",
-      "type": [
-        "Direction"
-      ]
-    },
-    {
-      "name": "size",
-      "comment": "Create an `Element` with a new width and height.",
-      "raw": "size : Int -\u003e Int -\u003e Element -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "-\u003e",
-            [
-              "Element"
-            ],
-            [
-              "Element"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "sizeOf",
-      "comment": "Get the width and height of an Element",
-      "raw": "sizeOf : Element -\u003e (Int,Int)",
-      "type": [
-        "-\u003e",
-        [
-          "Element"
-        ],
-        [
-          "_Tuple2",
-          [
-            "Int"
-          ],
-          [
-            "Int"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "spacer",
-      "comment": "Create an empty box. This is useful for getting your spacing right and\nfor making borders.",
-      "raw": "spacer : Int -\u003e Int -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "Element"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "tag",
-      "comment": "Create an `Element` with a tag. This lets you link directly to it.\nThe element `(tag \"all-about-badgers\" thirdParagraph)` can be reached\nwith a link like this: `/facts-about-animals.elm#all-about-badgers`",
-      "raw": "tag : String -\u003e Element -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "-\u003e",
-          [
-            "Element"
-          ],
-          [
-            "Element"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "tiledImage",
-      "comment": "",
-      "raw": "tiledImage : Int -\u003e Int -\u003e String -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Int"
-          ],
-          [
-            "-\u003e",
-            [
-              "String"
-            ],
-            [
-              "Element"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "topLeft",
-      "comment": "",
-      "raw": "topLeft     : Position",
-      "type": [
-        "Position"
-      ]
-    },
-    {
-      "name": "topLeftAt",
-      "comment": "",
-      "raw": "topLeftAt         : Pos -\u003e Pos -\u003e Position",
-      "type": [
-        "-\u003e",
-        [
-          "Pos"
-        ],
-        [
-          "-\u003e",
-          [
-            "Pos"
-          ],
-          [
-            "Position"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "topRight",
-      "comment": "",
-      "raw": "topRight    : Position",
-      "type": [
-        "Position"
-      ]
-    },
-    {
-      "name": "topRightAt",
-      "comment": "",
-      "raw": "topRightAt        : Pos -\u003e Pos -\u003e Position",
-      "type": [
-        "-\u003e",
-        [
-          "Pos"
-        ],
-        [
-          "-\u003e",
-          [
-            "Pos"
-          ],
-          [
-            "Position"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "up",
-      "comment": "",
-      "raw": "up : Direction",
-      "type": [
-        "Direction"
-      ]
-    },
-    {
-      "name": "width",
-      "comment": "Create an `Element` with a given width.",
-      "raw": "width : Int -\u003e Element -\u003e Element",
-      "type": [
-        "-\u003e",
-        [
-          "Int"
-        ],
-        [
-          "-\u003e",
-          [
-            "Element"
-          ],
-          [
-            "Element"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "widthOf",
-      "comment": "Get the width of an Element",
-      "raw": "widthOf : Element -\u003e Int",
-      "type": [
-        "-\u003e",
-        [
-          "Element"
-        ],
-        [
-          "Int"
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "Graphics.Input",
-  "document": "This module is for creating standard input widgets such as buttons and\ntext boxes. In general, functions in this library return a signal representing\nevents from the user.\n\nThe simplest inputs are *one-way inputs*, meaning the user can update\nthem, but the programmer cannot. If you need to update an input from\nwithin the program you want the slightly more complex *two-way inputs*.\nThis document will always show the one-way inputs first, *then* the\ntwo-way inputs.\n\n# Buttons\n@docs button, customButton, buttons, customButtons\n\n# Fields\n@docs field, password, email, fields, FieldState, emptyFieldState\n\n# Checkboxes\n@docs checkbox, checkboxes\n\n# Drop Downs\n@docs stringDropDown, dropDown\n\n# Mouse Hover\n@docs hoverable, hoverables",
-  "aliases": [
-    {
-      "name": "FieldState",
-      "comment": "Represents the current state of a text field. The `string` represents the\ncharacters filling the text field. The `selectionStart` and `selectionEnd`\nvalues represent what the user has selected with their mouse or keyboard.\nFor example:\n\n        { string=\"She sells sea shells\", selectionStart=3, selectionEnd=0 }\n\nThis means the user highlighted the substring `\"She\"` backwards.",
-      "raw": "type FieldState = { string:String, selectionStart:Int, selectionEnd:Int }",
-      "typeVariables": [],
-      "type": {
-        "selectionEnd": [
-          "Int"
-        ],
-        "selectionStart": [
-          "Int"
-        ],
-        "string": [
-          "String"
-        ]
-      }
-    }
-  ],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "button",
-      "comment": "Create a button with a given label. The result is an `Element` and\na signal of units. This signal triggers whenever the button is pressed.",
-      "raw": "button : String -\u003e (Element, Signal ())",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "_Tuple2",
-          [
-            "Element"
-          ],
-          [
-            "Signal",
-            [
-              "_Tuple0"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "buttons",
-      "comment": "Create a group of buttons.\n\n * The first argument is the default value of the `events` signal.\n * The `events` signal represents all of the activity in this group\n   of buttons.\n * The `button` function creates a button\n   with the given name, like &ldquo;Submit&rdquo; or &ldquo;Cancel&rdquo;.\n   The `a` value is sent to `events` whenever the button is pressed.",
-      "raw": "buttons : a -\u003e { events : Signal a,\n                 button : a -\u003e String -\u003e Element }",
-      "type": [
-        "-\u003e",
-        "a",
-        {
-          "events": [
-            "Signal",
-            "a"
-          ],
-          "button": [
-            "-\u003e",
-            "a",
-            [
-              "-\u003e",
-              [
-                "String"
-              ],
-              [
-                "Element"
-              ]
-            ]
-          ]
-        }
-      ]
-    },
-    {
-      "name": "checkbox",
-      "comment": "Create a checkbox with a given start state. Unlike `button`, this\nresult is a *signal* of elements. That is because a checkbox has state\nthat updates based on user input. The boolean signal represents the\ncurrent state of the checkbox.",
-      "raw": "checkbox : Bool -\u003e (Signal Element, Signal Bool)",
-      "type": [
-        "-\u003e",
-        [
-          "Bool"
-        ],
-        [
-          "_Tuple2",
-          [
-            "Signal",
-            [
-              "Element"
-            ]
-          ],
-          [
-            "Signal",
-            [
-              "Bool"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "checkboxes",
-      "comment": "Create a group of checkboxes.\n\n * The first argument is the default value of the `events` signal.\n * The `events` signal represents all of the activity in this group\n   of checkboxes.\n * The `checkbox` function creates a\n   checkbox with a given state. The `(Bool -\u003e a)` function is used\n   when the checkbox is modified. It takes the new state and turns\n   it into a value that can be sent to `events`. For example, this\n   lets you add an ID to distinguish between checkboxes.",
-      "raw": "checkboxes : a -\u003e { events : Signal a,\n                    checkbox : (Bool -\u003e a) -\u003e Bool -\u003e Element }",
-      "type": [
-        "-\u003e",
-        "a",
-        {
-          "events": [
-            "Signal",
-            "a"
-          ],
-          "checkbox": [
-            "-\u003e",
-            [
-              "-\u003e",
-              [
-                "Bool"
-              ],
-              "a"
-            ],
-            [
-              "-\u003e",
-              [
-                "Bool"
-              ],
-              [
-                "Element"
-              ]
-            ]
-          ]
-        }
-      ]
-    },
-    {
-      "name": "customButton",
-      "comment": "Create a button with custom states for up, hovering, and down\n(given in that order). The result is an `Element` and  a signal of\nunits. This signal triggers whenever the button is pressed.",
-      "raw": "customButton : Element -\u003e Element -\u003e Element -\u003e (Element, Signal ())",
-      "type": [
-        "-\u003e",
-        [
-          "Element"
-        ],
-        [
-          "-\u003e",
-          [
-            "Element"
-          ],
-          [
-            "-\u003e",
-            [
-              "Element"
-            ],
-            [
-              "_Tuple2",
-              [
-                "Element"
-              ],
-              [
-                "Signal",
-                [
-                  "_Tuple0"
-                ]
-              ]
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "customButtons",
-      "comment": "Create a group of custom buttons.\n\n * The first argument is the default value of the `events` signal.\n * The `events` signal represents all of the activity in this group\n   of custom buttons.\n * The `customButton` function creates a button with three different visual\n   states, one for up, hovering, and down. The resulting button has dimensions\n   large enough to fit all three possible `Elements`.\n   The `a` value is sent to `events` whenever the button is pressed.",
-      "raw": "customButtons : a -\u003e { events : Signal a,\n                       customButton : a -\u003e Element -\u003e Element -\u003e Element -\u003e Element }",
-      "type": [
-        "-\u003e",
-        "a",
-        {
-          "customButton": [
-            "-\u003e",
-            "a",
-            [
-              "-\u003e",
-              [
-                "Element"
-              ],
-              [
-                "-\u003e",
-                [
-                  "Element"
-                ],
-                [
-                  "-\u003e",
-                  [
-                    "Element"
-                  ],
-                  [
-                    "Element"
-                  ]
-                ]
-              ]
-            ]
-          ],
-          "events": [
-            "Signal",
-            "a"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "dropDown",
-      "comment": "Create a drop-down menu. When the user selects a string,\nthe current state of the drop-down is set to the associated\nvalue. This lets you avoid manually mapping the string onto\nfunctions and values.",
-      "raw": "dropDown : [(String,a)] -\u003e (Signal Element, Signal a)",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "_Tuple2",
-            [
-              "String"
-            ],
-            "a"
-          ]
-        ],
-        [
-          "_Tuple2",
-          [
-            "Signal",
-            [
-              "Element"
-            ]
-          ],
-          [
-            "Signal",
-            "a"
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "email",
-      "comment": "Same as `field` but it adds an annotation that this field is for email\naddresses. This is helpful for auto-complete and for mobile users who may\nget a custom keyboard with an `@` and `.com` button.",
-      "raw": "email : String -\u003e (Signal Element, Signal String)",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "_Tuple2",
-          [
-            "Signal",
-            [
-              "Element"
-            ]
-          ],
-          [
-            "Signal",
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "emptyFieldState",
-      "comment": "The empty field state:\n\n        { string=\"\", selectionStart=0, selectionEnd=0 }",
-      "raw": "emptyFieldState : FieldState",
-      "type": [
-        "FieldState"
-      ]
-    },
-    {
-      "name": "field",
-      "comment": "Create a field with the given default text. The output is an element\nthat updates to match the user input and a signal of strings representing\nthe content of the field.",
-      "raw": "field : String -\u003e (Signal Element, Signal String)",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "_Tuple2",
-          [
-            "Signal",
-            [
-              "Element"
-            ]
-          ],
-          [
-            "Signal",
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "fields",
-      "comment": "Create a group of text input fields.\n\n * The first argument is the default value of the `events` signal.\n * The `events` signal represents all of the activity in this group\n   of text fields.\n * The `field` function creates a\n   field with the given ghost text and initial field state.\n   When the field is modified, the `(FieldState -\u003e a)` function\n   takes the new state and turns\n   it into a value that can be sent to `events`. For example, this\n   lets you add an ID to distinguish between input fields.",
-      "raw": "fields : a -\u003e { events : Signal a,\n                field : (FieldState -\u003e a) -\u003e String -\u003e FieldState -\u003e Element }",
-      "type": [
-        "-\u003e",
-        "a",
-        {
-          "events": [
-            "Signal",
-            "a"
-          ],
-          "field": [
-            "-\u003e",
-            [
-              "-\u003e",
-              [
-                "FieldState"
-              ],
-              "a"
-            ],
-            [
-              "-\u003e",
-              [
-                "String"
-              ],
-              [
-                "-\u003e",
-                [
-                  "FieldState"
-                ],
-                [
-                  "Element"
-                ]
-              ]
-            ]
-          ]
-        }
-      ]
-    },
-    {
-      "name": "hoverable",
-      "comment": "Detect when the mouse is hovering over a specific `Element`.",
-      "raw": "hoverable : Element -\u003e (Element, Signal Bool)",
-      "type": [
-        "-\u003e",
-        [
-          "Element"
-        ],
-        [
-          "_Tuple2",
-          [
-            "Element"
-          ],
-          [
-            "Signal",
-            [
-              "Bool"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "hoverables",
-      "comment": "Detect when the mouse is hovering over some elements. This\nallows you to create and destroy elements dynamically and still\ndetect hover information.",
-      "raw": "hoverables : a -\u003e { events : Signal a,\n                    hoverable : (Bool -\u003e a) -\u003e Element -\u003e Element }",
-      "type": [
-        "-\u003e",
-        "a",
-        {
-          "hoverable": [
-            "-\u003e",
-            [
-              "-\u003e",
-              [
-                "Bool"
-              ],
-              "a"
-            ],
-            [
-              "-\u003e",
-              [
-                "Element"
-              ],
-              [
-                "Element"
-              ]
-            ]
-          ],
-          "events": [
-            "Signal",
-            "a"
-          ]
-        }
-      ]
-    },
-    {
-      "name": "password",
-      "comment": "Same as `field` but the UI element blocks out each characters.",
-      "raw": "password : String -\u003e (Signal Element, Signal String)",
-      "type": [
-        "-\u003e",
-        [
-          "String"
-        ],
-        [
-          "_Tuple2",
-          [
-            "Signal",
-            [
-              "Element"
-            ]
-          ],
-          [
-            "Signal",
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    },
-    {
-      "name": "stringDropDown",
-      "comment": "Create a drop-down menu for selecting strings. The resulting\nsignal of strings represents the string that is currently selected.",
-      "raw": "stringDropDown : [String] -\u003e (Signal Element, Signal String)",
-      "type": [
-        "-\u003e",
-        [
-          "_List",
-          [
-            "String"
-          ]
-        ],
-        [
-          "_Tuple2",
-          [
-            "Signal",
-            [
-              "Element"
-            ]
-          ],
-          [
-            "Signal",
-            [
-              "String"
-            ]
-          ]
-        ]
-      ]
-    }
-  ]
-},
-{
-  "name": "JavaScript.Experimental",
-  "document": "A pair of very experimental functions for converting between\nElm records and JavaScript objects. It currently uses a best effort\nconversion that can cause runtime errors. This API should change and\nimprove as we find its key failings.\n\n# Converting between Elm records and JS Objects\n@docs toRecord, fromRecord",
-  "aliases": [],
-  "datatypes": [],
-  "values": [
-    {
-      "name": "fromRecord",
-      "comment": "Turn arbitrary Elm records into JavaScript objects.\nLists become arrays, nested records are allowed. No ADTs.\n\n        -- OK records\n        { student=\"Steve\", scores=[83,94,99,72] }\n        { errorLevel=10, critical=True }\n\n        -- BAD records\n        { answer = Nothing }\n        { result = Left \"An error occurred\" }",
-      "raw": "fromRecord : a -\u003e JSObject",
-      "type": [
-        "-\u003e",
-        "a",
-        [
-          "JSObject"
-        ]
-      ]
-    },
-    {
-      "name": "toRecord",
-      "comment": "Turn arbitrary JavaScript objects into Elm records.\nArrays are converted into lists, nested objects are allowed.\nNo `null` values or non-homogeneous arrays.\n\n        -- OK objects\n        { student:\"Steve\", scores:[83,94,99,72] }\n        { errorLevel:10, critical:true }\n\n        -- BAD objects\n        { answer:null }\n        { info:[true,42,'what'] }",
-      "raw": "toRecord : JSObject -\u003e a",
-      "type": [
-        "-\u003e",
-        [
-          "JSObject"
-        ],
-        "a"
-      ]
+  "name": "Array",
+  "document": "A library for fast immutable arrays. The elements in an array must have the\nsame type. The arrays are implemented in Relaxed Radix Balanced-Trees for fast\nreads, updates, and appends.\n\n# Creating Arrays\n@docs empty, repeat, initialize, fromList\n\n# Basics\n@docs length, push, append\n\n# Get and Set\n@docs get, getOrElse, getOrFail, set\n\n# Taking Arrays Apart\n@docs slice, toList, toIndexedList\n\n# Mapping and Folding\n@docs map, indexedMap, foldl, foldr",
+  "aliases": [],
+  "datatypes": [
+    {
+      "name": "Array",
+      "comment": "",
+      "raw": "data Array a = Array",
+      "typeVariables": [
+        "a"
+      ],
+      "constructors": [
+        {
+          "name": "Array",
+          "type": {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "append",
+      "comment": "Append two arrays to a new one.\n\n      append (array 2 42) (array 3 81) == fromList [42,42,81,81,81]",
+      "raw": "append : Array a -\u003e Array a -\u003e Array a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Array",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "empty",
+      "comment": "Return an empty array.\n\n      length empty == 0",
+      "raw": "empty : Array a",
+      "type": {
+        "tag": "adt",
+        "name": "Array",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ]
+      }
+    },
+    {
+      "name": "filter",
+      "comment": "Keep only elements that satisfy the predicate:\n\n      filter isEven (fromList [1..6]) == (fromList [2,4,6])",
+      "raw": "filter : (a -\u003e Bool) -\u003e Array a -\u003e Array a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Array",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "foldl",
+      "comment": "Reduce an array from the left. Read `foldl` as &ldquo;fold from the left&rdquo;.\n\n      foldl (::) [] (fromList [1,2,3]) == [3,2,1]",
+      "raw": "foldl : (a -\u003e b -\u003e b) -\u003e b -\u003e Array a -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      }
+    },
+    {
+      "name": "foldr",
+      "comment": "Reduce an array from the right. Read `foldr` as &ldquo;fold from the right&rdquo;.\n\n      foldr (+) 0 (repeat 3 5) == 15",
+      "raw": "foldr : (a -\u003e b -\u003e b) -\u003e b -\u003e Array a -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      }
+    },
+    {
+      "name": "fromList",
+      "comment": "Create an array from a list.",
+      "raw": "fromList : [a] -\u003e Array a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Array",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "get",
+      "comment": "Return Just the element at the index or Nothing if the index is out of range.\n\n      get  0 (fromList [0,1,2]) == Just 0\n      get  2 (fromList [0,1,2]) == Just 2\n      get  5 (fromList [0,1,2]) == Nothing\n      get -1 (fromList [0,1,2]) == Nothing",
+      "raw": "get : Int -\u003e Array a -\u003e Maybe a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Maybe",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "getOrElse",
+      "comment": "Get the element at the index. Or if the index is out of range, a default\nvalue is returned.\n\n      getOrElse 0 2 (fromList [0,1,2]) == 2\n      getOrElse 0 5 (fromList [0,1,2]) == 0",
+      "raw": "getOrElse : a -\u003e Int -\u003e Array a -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    },
+    {
+      "name": "getOrFail",
+      "comment": "Get the element at a particular index.\n\n      getOrFail 0 (A.fromList [0,1,2]) == 0\n\nWarning: this function will result in a runtime error if the index is not found,\nso it is best to use `get` or `getOrElse` unless you are sure the index will be\nfound.",
+      "raw": "getOrFail : Int -\u003e Array a -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    },
+    {
+      "name": "indexedMap",
+      "comment": "Apply a function on every element with its index as first argument.\n\n      indexedMap (*) (fromList [5,5,5]) == fromList [0,5,10]",
+      "raw": "indexedMap : (Int -\u003e a -\u003e b) -\u003e Array a -\u003e Array b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Array",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "initialize",
+      "comment": "Initialize an array. `initialize n f` creates an array of length `n` with\nthe element at index `i` initialized to the result of `(f i)`.\n\n      initialize 4 id          == fromList [0,1,2,3]\n      initialize 4 (\\n -\u003e n*n) == fromList [0,1,4,9]\n      initialize 4 (always 0)  == fromList [0,0,0,0]",
+      "raw": "initialize : Int -\u003e (Int -\u003e a) -\u003e Array a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "a"
+            }
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Array",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "length",
+      "comment": "Return the length of an array.\n\n      length (fromList [1,2,3]) == 3",
+      "raw": "length : Array a -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "map",
+      "comment": "Apply a function on every element in an array.\n\n      map sqrt (fromList [1,4,9]) == fromList [1,2,3]",
+      "raw": "map : (a -\u003e b) -\u003e Array a -\u003e Array b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Array",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "push",
+      "comment": "Push an element to the end of an array.\n\n      push 3 (fromList [1,2]) == fromList [1,2,3]",
+      "raw": "push : a -\u003e Array a -\u003e Array a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Array",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "repeat",
+      "comment": "Creates an array with a given length, filled with a default element.\n\n      repeat 5 0     == fromList [0,0,0,0,0]\n      repeat 3 \"cat\" == fromList [\"cat\",\"cat\",\"cat\"]\n\nNotice that `repeat 3 x` is the same as `initialize 3 (always x)`.",
+      "raw": "repeat : Int -\u003e a -\u003e Array a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Array",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "set",
+      "comment": "Set the element at a particular index. Returns an updated array.\nIf the index is out of range, the array is unaltered.\n\n      set 1 7 (fromList [1,2,3]) == fromList [1,7,3]",
+      "raw": "set : Int -\u003e a -\u003e Array a -\u003e Array a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Array",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "slice",
+      "comment": "Get a sub-section of an array: `(slice start end array)`. The `start` is a\nzero-based index where we will start our slice. The `end` is a zero-based index\nthat indicates the end of the slice. The slice extracts up to but not including\n`end`.\n\n      slice  0  3 (fromList [0,1,2,3,4]) == fromList [0,1,2]\n      slice  1  4 (fromList [0,1,2,3,4]) == fromList [1,2,3]\n\nBoth the `start` and `end` indexes can be negative, indicating an offset from\nthe end of the array.\n\n      slice  1 -1 (fromList [0,1,2,3,4]) == fromList [1,2,3]\n      slice -2  5 (fromList [0,1,2,3,4]) == fromList [3,4]\n\nThis makes it pretty easy to `pop` the last element off of an array: `slice 0 -1 array`",
+      "raw": "slice : Int -\u003e Int -\u003e Array a -\u003e Array a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Array",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "toIndexedList",
+      "comment": "Create an indexed list from an array. Each element of the array will be\npaired with its index.\n\n      toIndexedList (fromList [\"cat\",\"dog\"]) == [(0,\"cat\"), (1,\"dog\")]",
+      "raw": "toIndexedList : Array a -\u003e [(Int, a)]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "_Tuple2",
+              "args": [
+                {
+                  "tag": "adt",
+                  "name": "Int",
+                  "args": []
+                },
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "toList",
+      "comment": "Create a list of elements from an array.\n\n      toList (fromList [3,5,8]) == [3,5,8]",
+      "raw": "toList : Array a -\u003e [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Array",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Basics",
+  "document": "Tons of useful functions that get imported by default.\n\nThe following libraries also get imported by default: List, Signal,\nText, Maybe, Time, Graphics.Element, Color, Graphics.Collage.\n\n# Equality\n@docs (==), (/=)\n\n# Comparison\n\nThese functions only work on `comparable` types. This includes numbers,\ncharacters, strings, lists of comparable things, and tuples of comparable\nthings. Note that tuples with 7 or more elements are not comparable; why\nare your tuples so big?\n\n@docs (\u003c), (\u003e), (\u003c=), (\u003e=), max, min, Order, compare\n\n# Booleans\n@docs not, (&&), (||), xor, otherwise\n\n# Mathematics\n@docs (+), (-), (*), (/), (^), (//), rem, (%), negate, abs, sqrt, clamp, logBase, e\n\n# Trigonometry\n@docs pi, cos, sin, tan, acos, asin, atan, atan2\n\n# Number Conversions\n@docs round, floor, ceiling, truncate, toFloat\n\n# Angle Conversions\nAll angle conversions result in &ldquo;standard Elm angles&rdquo;\nwhich happen to be radians.\n\n@docs degrees, radians, turns\n\n# Polar Coordinates\n@docs toPolar, fromPolar\n\n# Floating Point Checks\n@docs isNaN, isInfinite\n\n# Tuples\n@docs fst, snd\n\n# Higher-Order Helpers\n@docs identity, always, (\u003c|), (|\u003e), (\u003c\u003c), (\u003e\u003e), flip, curry, uncurry",
+  "aliases": [],
+  "datatypes": [
+    {
+      "name": "Order",
+      "comment": "Represents the relative ordering of two things.\nThe relations are less than, equal to, and greater than.",
+      "raw": "data Order = LT | EQ | GT",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "LT",
+          "type": {
+            "tag": "adt",
+            "name": "Order",
+            "args": []
+          }
+        },
+        {
+          "name": "EQ",
+          "type": {
+            "tag": "adt",
+            "name": "Order",
+            "args": []
+          }
+        },
+        {
+          "name": "GT",
+          "type": {
+            "tag": "adt",
+            "name": "Order",
+            "args": []
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "%",
+      "comment": "Perform [modular arithmetic](http://en.wikipedia.org/wiki/Modular_arithmetic):\n\n       7 % 2 == 1\n      -1 % 4 == 3",
+      "raw": "(%) : Int -\u003e Int -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      },
+      "associativity": "left",
+      "precedence": 7
+    },
+    {
+      "name": "&&",
+      "comment": "The and operator. True if both inputs are True.\nThis operator short-circuits if the first argument is False.",
+      "raw": "(&&) : Bool -\u003e Bool -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      },
+      "associativity": "right",
+      "precedence": 3
+    },
+    {
+      "name": "*",
+      "comment": "",
+      "raw": "(*) : number -\u003e number -\u003e number",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "number"
+          },
+          {
+            "tag": "var",
+            "name": "number"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "number"
+        }
+      },
+      "associativity": "left",
+      "precedence": 7
+    },
+    {
+      "name": "+",
+      "comment": "",
+      "raw": "(+) : number -\u003e number -\u003e number",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "number"
+          },
+          {
+            "tag": "var",
+            "name": "number"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "number"
+        }
+      },
+      "associativity": "left",
+      "precedence": 6
+    },
+    {
+      "name": "-",
+      "comment": "",
+      "raw": "(-) : number -\u003e number -\u003e number",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "number"
+          },
+          {
+            "tag": "var",
+            "name": "number"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "number"
+        }
+      },
+      "associativity": "left",
+      "precedence": 6
+    },
+    {
+      "name": "/",
+      "comment": "Floating point division.",
+      "raw": "(/) : Float -\u003e Float -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      },
+      "associativity": "left",
+      "precedence": 7
+    },
+    {
+      "name": "//",
+      "comment": "Integer division, remainder is discarded.",
+      "raw": "(//) : Int -\u003e Int -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      },
+      "associativity": "left",
+      "precedence": 7
+    },
+    {
+      "name": "/=",
+      "comment": "",
+      "raw": "(/=) : a -\u003e a -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      },
+      "associativity": "non",
+      "precedence": 4
+    },
+    {
+      "name": "\u003c",
+      "comment": "",
+      "raw": "(\u003c)  : comparable -\u003e comparable -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "var",
+            "name": "comparable"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      },
+      "associativity": "non",
+      "precedence": 4
+    },
+    {
+      "name": "\u003c\u003c",
+      "comment": "Function composition, passing results along in the suggested direction. For\nexample, the following code checks if the square root of a number is odd:\n\n      not \u003c\u003c isEven \u003c\u003c sqrt\n\nYou can think of this operator as equivalent to the following:\n\n      (g \u003c\u003c f)  ==  (\\x -\u003e g (f x))\n\nSo our example expands out to something like this:\n\n      \\n -\u003e not (isEven (sqrt n))",
+      "raw": "(\u003c\u003c) : (b -\u003e c) -\u003e (a -\u003e b) -\u003e (a -\u003e c)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "c"
+            }
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "c"
+        }
+      },
+      "associativity": "right",
+      "precedence": 9
+    },
+    {
+      "name": "\u003c=",
+      "comment": "",
+      "raw": "(\u003c=) : comparable -\u003e comparable -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "var",
+            "name": "comparable"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      },
+      "associativity": "non",
+      "precedence": 4
+    },
+    {
+      "name": "\u003c|",
+      "comment": "Function application `f \u003c| x == f x`. This function is useful for avoiding\nparenthesis. Consider the following code to create a text element:\n\n        text (monospace (toText \"code\"))\n\nThis can also be written as:\n\n        text . monospace \u003c| toText \"code\"",
+      "raw": "(\u003c|) : (a -\u003e b) -\u003e a -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      },
+      "associativity": "right",
+      "precedence": 0
+    },
+    {
+      "name": "==",
+      "comment": "",
+      "raw": "(==) : a -\u003e a -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      },
+      "associativity": "non",
+      "precedence": 4
+    },
+    {
+      "name": "\u003e",
+      "comment": "",
+      "raw": "(\u003e)  : comparable -\u003e comparable -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "var",
+            "name": "comparable"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      },
+      "associativity": "non",
+      "precedence": 4
+    },
+    {
+      "name": "\u003e=",
+      "comment": "",
+      "raw": "(\u003e=) : comparable -\u003e comparable -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "var",
+            "name": "comparable"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      },
+      "associativity": "non",
+      "precedence": 4
+    },
+    {
+      "name": "\u003e\u003e",
+      "comment": "Function composition, passing results along in the suggested direction. For\nexample, the following code checks if the square root of a number is odd:\n\n      sqrt \u003e\u003e isEven \u003e\u003e not\n\nThis direction of function composition seems less pleasant than `(\u003c\u003c)` which\nreads nicely in expressions like: `filter (not \u003c\u003c isRegistered) students`",
+      "raw": "(\u003e\u003e) : (a -\u003e b) -\u003e (b -\u003e c) -\u003e (a -\u003e c)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "c"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "c"
+        }
+      },
+      "associativity": "left",
+      "precedence": 9
+    },
+    {
+      "name": "^",
+      "comment": "Exponentiation: `3^2 == 9`",
+      "raw": "(^) : number -\u003e number -\u003e number",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "number"
+          },
+          {
+            "tag": "var",
+            "name": "number"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "number"
+        }
+      },
+      "associativity": "left",
+      "precedence": 8
+    },
+    {
+      "name": "abs",
+      "comment": "Take the absolute value of a number.",
+      "raw": "abs : number -\u003e number",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "number"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "number"
+        }
+      }
+    },
+    {
+      "name": "acos",
+      "comment": "",
+      "raw": "acos : Float -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "always",
+      "comment": "Creates a [constant function](http://en.wikipedia.org/wiki/Constant_function),\na function that *always* returns the same value regardless of what input you give.\nIt is defined as:\n\n        always a b = a\n\nIt totally ignores the second argument, so `always 42` is a function that always\nreturns 42. When you are dealing with higher-order functions, this comes in\nhandy more often than you might expect. For example, creating a zeroed out list\nof length ten would be:\n\n        map (always 0) [0..9]",
+      "raw": "always : a -\u003e b -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    },
+    {
+      "name": "asin",
+      "comment": "",
+      "raw": "asin : Float -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "atan",
+      "comment": "You probably do not want to use this. It takes `(y/x)` as the\nargument, so there is no way to know whether the negative signs comes from\nthe `y` or `x`. Thus, the resulting angle is always between &pi;/2 and -&pi;/2\n(in quadrants I and IV). You probably want to use `atan2` instead.",
+      "raw": "atan : Float -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "atan2",
+      "comment": "This helps you find the angle of a cartesian coordinate.\nYou will almost certainly want to use this instead of `atan`.\nSo `atan2 y x` computes *atan(y/x)* but also keeps track of which\nquadrant the angle should really be in. The result will be between\n&pi; and -&pi;, giving you the full range of angles.",
+      "raw": "atan2 : Float -\u003e Float -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "ceiling",
+      "comment": "Ceiling function, rounding up.",
+      "raw": "ceiling : Float -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "clamp",
+      "comment": "Clamps a number within a given range. With the expression\n`clamp 100 200 x` the results are as follows:\n\n      100     if x \u003c 100\n       x      if 100 \u003c= x \u003c 200\n      200     if 200 \u003c= x",
+      "raw": "clamp : number -\u003e number -\u003e number -\u003e number",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "number"
+          },
+          {
+            "tag": "var",
+            "name": "number"
+          },
+          {
+            "tag": "var",
+            "name": "number"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "number"
+        }
+      }
+    },
+    {
+      "name": "compare",
+      "comment": "Compare any two comparable values. Comparable values include `String`, `Char`,\n`Int`, `Float`, `Time`, or a list or tuple containing comparable values.\nThese are also the only values that work as `Dict` keys or `Set` members.",
+      "raw": "compare : comparable -\u003e comparable -\u003e Order",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "var",
+            "name": "comparable"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Order",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "cos",
+      "comment": "",
+      "raw": "cos : Float -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "curry",
+      "comment": "Change how arguments are passed to a function.\nThis splits paired arguments into two separate arguments.",
+      "raw": "curry : ((a,b) -\u003e c) -\u003e a -\u003e b -\u003e c",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "var",
+                    "name": "a"
+                  },
+                  {
+                    "tag": "var",
+                    "name": "b"
+                  }
+                ]
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "c"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "c"
+        }
+      }
+    },
+    {
+      "name": "degrees",
+      "comment": "Convert degrees to standard Elm angles (radians).",
+      "raw": "degrees : Float -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "e",
+      "comment": "An approximation of e.",
+      "raw": "e : Float",
+      "type": {
+        "tag": "adt",
+        "name": "Float",
+        "args": []
+      }
+    },
+    {
+      "name": "flip",
+      "comment": "Flips the order of the first two arguments to a function.",
+      "raw": "flip : (a -\u003e b -\u003e c) -\u003e (b -\u003e a -\u003e c)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "c"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "c"
+        }
+      }
+    },
+    {
+      "name": "floor",
+      "comment": "Floor function, rounding down.",
+      "raw": "floor : Float -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "fromPolar",
+      "comment": "Start with polar coordinates (r,&theta;)\nand get out cartesian coordinates (x,y).",
+      "raw": "fromPolar : (Float,Float) -\u003e (Float,Float)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_Tuple2",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            },
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "fst",
+      "comment": "Given a 2-tuple, returns the first value.",
+      "raw": "fst : (a,b) -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    },
+    {
+      "name": "identity",
+      "comment": "Given a value, returns exactly the same value. This is called\n[the identity function](http://en.wikipedia.org/wiki/Identity_function).",
+      "raw": "identity : a -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    },
+    {
+      "name": "isInfinite",
+      "comment": "",
+      "raw": "isInfinite : Float -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "isNaN",
+      "comment": "",
+      "raw": "isNaN : Float -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "logBase",
+      "comment": "Calculate the logarithm of a number with a given base: `logBase 10 100 == 2`",
+      "raw": "logBase : Float -\u003e Float -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "max",
+      "comment": "Given two comparables, returns the larger one.",
+      "raw": "max : comparable -\u003e comparable -\u003e comparable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "var",
+            "name": "comparable"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "comparable"
+        }
+      }
+    },
+    {
+      "name": "min",
+      "comment": "Given two comparables, returns the smaller one.",
+      "raw": "min : comparable -\u003e comparable -\u003e comparable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "var",
+            "name": "comparable"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "comparable"
+        }
+      }
+    },
+    {
+      "name": "negate",
+      "comment": "Negate any number: `negate 42 == -42`",
+      "raw": "negate : number -\u003e number",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "number"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "number"
+        }
+      }
+    },
+    {
+      "name": "not",
+      "comment": "Negate a boolean value: `(not True == False)` and `(not False == True)`",
+      "raw": "not : Bool -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "otherwise",
+      "comment": "Equal to true. Useful as the last case of a multi-way-if.",
+      "raw": "otherwise : Bool",
+      "type": {
+        "tag": "adt",
+        "name": "Bool",
+        "args": []
+      }
+    },
+    {
+      "name": "pi",
+      "comment": "An approximation of pi.",
+      "raw": "pi : Float",
+      "type": {
+        "tag": "adt",
+        "name": "Float",
+        "args": []
+      }
+    },
+    {
+      "name": "radians",
+      "comment": "Convert radians to standard Elm angles (radians).",
+      "raw": "radians : Float -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "rem",
+      "comment": "Finds the remainder after dividing one number by another:\n\n       7 `rem` 2 == 1\n      -1 `rem` 4 == 1",
+      "raw": "rem : Int -\u003e Int -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      },
+      "associativity": "left",
+      "precedence": 7
+    },
+    {
+      "name": "round",
+      "comment": "Round a number to the nearest integer.",
+      "raw": "round : Float -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "sin",
+      "comment": "",
+      "raw": "sin : Float -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "snd",
+      "comment": "Given a 2-tuple, returns the second value.",
+      "raw": "snd : (a,b) -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      }
+    },
+    {
+      "name": "sqrt",
+      "comment": "Take the square root of a number.",
+      "raw": "sqrt : Float -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "tan",
+      "comment": "",
+      "raw": "tan : Float -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toFloat",
+      "comment": "Convert an integer into a float.",
+      "raw": "toFloat : Int -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toPolar",
+      "comment": "Start with cartesian coordinates (x,y)\nand get out polar coordinates (r,&theta;).",
+      "raw": "toPolar : (Float,Float) -\u003e (Float,Float)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_Tuple2",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            },
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "truncate",
+      "comment": "Truncate a decimal number, rounding towards zero.",
+      "raw": "truncate : Float -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "turns",
+      "comment": "Convert turns to standard Elm angles (radians).\nOne turn is equal to 360&deg;.",
+      "raw": "turns : Float -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "uncurry",
+      "comment": "Change how arguments are passed to a function.\nThis combines two arguments into a single pair.",
+      "raw": "uncurry : (a -\u003e b -\u003e c) -\u003e (a,b) -\u003e c",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "c"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "c"
+        }
+      }
+    },
+    {
+      "name": "xor",
+      "comment": "The exclusive-or operator. True if exactly one input is True.",
+      "raw": "xor : Bool -\u003e Bool -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "|\u003e",
+      "comment": "Forward function application `x |\u003e f == f x`. This function is useful\nfor avoiding parenthesis and writing code in a more natural way.\nConsider the following code to create a pentagon:\n\n        scale 2 (move (10,10) (filled blue (ngon 5 30)))\n\nThis can also be written as:\n\n        ngon 5 30 |\u003e filled blue\n                  |\u003e move (10,10)\n                  |\u003e scale 2",
+      "raw": "(|\u003e) : a -\u003e (a -\u003e b) -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      },
+      "associativity": "left",
+      "precedence": 0
+    },
+    {
+      "name": "||",
+      "comment": "The or operator. True if one or both inputs are True.\nThis operator short-circuits if the first argument is True.",
+      "raw": "(||) : Bool -\u003e Bool -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      },
+      "associativity": "right",
+      "precedence": 2
+    }
+  ]
+},
+{
+  "name": "Bitwise",
+  "document": "Library for [bitwise operations](http://en.wikipedia.org/wiki/Bitwise_operation).\n\n# Basic Operations\n\n@docs and, or, xor, complement\n\n# Bit Shifts\n\n@docs shiftLeft, shiftRight, shiftRightLogical",
+  "aliases": [],
+  "datatypes": [],
+  "values": [
+    {
+      "name": "and",
+      "comment": "Bitwise AND",
+      "raw": "and : Int -\u003e Int -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "complement",
+      "comment": "Flip each bit individually, often called bitwise NOT",
+      "raw": "complement : Int -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "or",
+      "comment": "Bitwise OR",
+      "raw": "or : Int -\u003e Int -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "shiftLeft",
+      "comment": "Shift bits to the left by a given offset, filling new bits with zeros.\nThis can be used to multiply numbers by powers of two.\n\n    8 `shiftLeft` 1 == 16\n    8 `shiftLeft` 2 == 32",
+      "raw": "shiftLeft : Int -\u003e Int -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "shiftRight",
+      "comment": "Shift bits to the right by a given offset, filling new bits with\nwhatever is the topmost bit. This can be used to divide numbers by powers of two.\n\n     32 `shiftRight` 1 == 16\n     32 `shiftRight` 2 == 8\n    -32 `shiftRight` 1 == -16\n\nThis is called an [arithmatic right\nshift](http://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift),\noften written (\u003e\u003e), and sometimes called a sign-propagating\nright shift because it fills empty spots with copies of the highest bit.",
+      "raw": "shiftRight : Int -\u003e Int -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "shiftRightLogical",
+      "comment": "Shift bits to the right by a given offset, filling new bits with\nzeros.\n\n     32 `shiftRightLogical` 1 == 16\n     32 `shiftRightLogical` 2 == 8\n    -32 `shiftRightLogical` 1 == 2147483632\n\nThis is called an [logical right\nshift](http://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift), often written (\u003e\u003e\u003e),\nand sometimes called a zero-fill right shift because it fills empty spots\nwith zeros.",
+      "raw": "shiftRightLogical : Int -\u003e Int -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "xor",
+      "comment": "Bitwise XOR",
+      "raw": "xor : Int -\u003e Int -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Char",
+  "document": "Functions for working with characters. Character literals are enclosed in\n`'a'` pair of single quotes.\n\n# Classification\n@docs isUpper, isLower, isDigit, isOctDigit, isHexDigit\n\n# Conversion\n@docs toUpper, toLower, toLocaleUpper, toLocaleLower, toCode, fromCode",
+  "aliases": [
+    {
+      "name": "KeyCode",
+      "comment": "",
+      "raw": "type KeyCode = Int",
+      "typeVariables": [],
+      "type": {
+        "tag": "adt",
+        "name": "Int",
+        "args": []
+      }
+    }
+  ],
+  "datatypes": [],
+  "values": [
+    {
+      "name": "fromCode",
+      "comment": "Convert from unicode.",
+      "raw": "fromCode : KeyCode -\u003e Char",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "KeyCode",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Char",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "isDigit",
+      "comment": "True for ASCII digits `[0-9]`.",
+      "raw": "isDigit : Char -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "isHexDigit",
+      "comment": "True for ASCII hexadecimal digits `[0-9a-fA-F]`.",
+      "raw": "isHexDigit : Char -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "isLower",
+      "comment": "True for lower case letters.",
+      "raw": "isLower : Char -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "isOctDigit",
+      "comment": "True for ASCII octal digits `[0-7]`.",
+      "raw": "isOctDigit : Char -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "isUpper",
+      "comment": "True for upper case letters.",
+      "raw": "isUpper : Char -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toCode",
+      "comment": "Convert to unicode. Used with the `Keyboard` library, which expects the\ninput to be uppercase.",
+      "raw": "toCode : Char -\u003e KeyCode",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "KeyCode",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toLocaleLower",
+      "comment": "Convert to lower case, according to any locale-specific case mappings.",
+      "raw": "toLocaleLower : Char -\u003e Char",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Char",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toLocaleUpper",
+      "comment": "Convert to upper case, according to any locale-specific case mappings.",
+      "raw": "toLocaleUpper : Char -\u003e Char",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Char",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toLower",
+      "comment": "Convert to lower case.",
+      "raw": "toLower : Char -\u003e Char",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Char",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toUpper",
+      "comment": "Convert to upper case.",
+      "raw": "toUpper : Char -\u003e Char",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Char",
+          "args": []
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Color",
+  "document": "Library for working with colors. Includes\n[RGB](https://en.wikipedia.org/wiki/RGB_color_model) and\n[HSL](http://en.wikipedia.org/wiki/HSL_and_HSV) creation, gradients, and\nbuilt-in names.\n\n# Creation\n@docs rgb, rgba, hsl, hsla, greyscale, grayscale, complement\n\n# Gradients\n@docs linear, radial\n\n# Extracting Colors\n@docs toRgb, toHsl\n\n# Built-in Colors\nThese colors come from the [Tango\npalette](http://tango.freedesktop.org/Tango_Icon_Theme_Guidelines)\nwhich provides aesthetically reasonable defaults for colors. Each color also\ncomes with a light and dark version.\n\n### Standard\n@docs red, orange, yellow, green, blue, purple, brown\n\n### Light\n@docs lightRed, lightOrange, lightYellow, lightGreen, lightBlue, lightPurple, lightBrown\n\n### Dark\n@docs darkRed, darkOrange, darkYellow, darkGreen, darkBlue, darkPurple, darkBrown\n\n### Eight Shades of Grey\nThese colors are a compatible series of shades of grey, fitting nicely\nwith the Tango palette.\n@docs white, lightGrey, grey, darkGrey, lightCharcoal, charcoal, darkCharcoal, black\n\nThese are identical to the *grey* versions. It seems the spelling is regional, but\nthat has never helped me remember which one I should be writing.\n@docs lightGray, gray, darkGray",
+  "aliases": [],
+  "datatypes": [
+    {
+      "name": "Color",
+      "comment": "",
+      "raw": "data Color\n    = RGBA Int Int Int Float\n    | HSLA Float Float Float Float",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "RGBA",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Color",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "HSLA",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Color",
+              "args": []
+            }
+          }
+        }
+      ]
+    },
+    {
+      "name": "Gradient",
+      "comment": "",
+      "raw": "data Gradient\n  = Linear (Float,Float) (Float,Float) [(Float,Color)]\n  | Radial (Float,Float) Float (Float,Float) Float [(Float,Color)]",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Linear",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  },
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  }
+                ]
+              },
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  },
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  }
+                ]
+              },
+              {
+                "tag": "adt",
+                "name": "_List",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "_Tuple2",
+                    "args": [
+                      {
+                        "tag": "adt",
+                        "name": "Float",
+                        "args": []
+                      },
+                      {
+                        "tag": "adt",
+                        "name": "Color",
+                        "args": []
+                      }
+                    ]
+                  }
+                ]
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Gradient",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "Radial",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  },
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  }
+                ]
+              },
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  },
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  }
+                ]
+              },
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "_List",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "_Tuple2",
+                    "args": [
+                      {
+                        "tag": "adt",
+                        "name": "Float",
+                        "args": []
+                      },
+                      {
+                        "tag": "adt",
+                        "name": "Color",
+                        "args": []
+                      }
+                    ]
+                  }
+                ]
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Gradient",
+              "args": []
+            }
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "black",
+      "comment": "",
+      "raw": "black         : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "blue",
+      "comment": "",
+      "raw": "blue   : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "brown",
+      "comment": "",
+      "raw": "brown  : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "charcoal",
+      "comment": "",
+      "raw": "charcoal      : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "complement",
+      "comment": "Produce a &ldquo;complementary color&rdquo;. The two colors will\naccent each other. This is the same as rotating the hue by 180&deg;.",
+      "raw": "complement : Color -\u003e Color",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Color",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Color",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "darkBlue",
+      "comment": "",
+      "raw": "darkBlue   : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "darkBrown",
+      "comment": "",
+      "raw": "darkBrown  : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "darkCharcoal",
+      "comment": "",
+      "raw": "darkCharcoal  : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "darkGray",
+      "comment": "",
+      "raw": "darkGray  : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "darkGreen",
+      "comment": "",
+      "raw": "darkGreen  : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "darkGrey",
+      "comment": "",
+      "raw": "darkGrey      : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "darkOrange",
+      "comment": "",
+      "raw": "darkOrange : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "darkPurple",
+      "comment": "",
+      "raw": "darkPurple : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "darkRed",
+      "comment": "",
+      "raw": "darkRed    : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "darkYellow",
+      "comment": "",
+      "raw": "darkYellow : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "fmod",
+      "comment": "",
+      "raw": "fmod : Float -\u003e Int -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "gray",
+      "comment": "",
+      "raw": "gray      : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "grayscale",
+      "comment": "Produce a gray based on the input. 0 is white, 1 is black.",
+      "raw": "grayscale : Float -\u003e Color",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Color",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "green",
+      "comment": "",
+      "raw": "green  : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "grey",
+      "comment": "",
+      "raw": "grey          : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "greyscale",
+      "comment": "",
+      "raw": "greyscale : Float -\u003e Color",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Color",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "hsl",
+      "comment": "Create [HSL colors](http://en.wikipedia.org/wiki/HSL_and_HSV). This gives\nyou access to colors more like a color wheel, where all hues are aranged in a\ncircle that you specify with standard Elm angles (radians).\n\n      red   = hsl (degrees   0) 1 0.5\n      green = hsl (degrees 120) 1 0.5\n      blue  = hsl (degrees 240) 1 0.5\n\n      pastelRed = hsl (degrees 0) 0.7 0.7\n\nTo cycle through all colors, just cycle through degrees. The saturation level\nis how vibrant the color is, like a dial between grey and bright colors. The\nlightness level is a dial between white and black.",
+      "raw": "hsl : Float -\u003e Float -\u003e Float -\u003e Color",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Color",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "hslToRgb",
+      "comment": "",
+      "raw": "hslToRgb : Float -\u003e Float -\u003e Float -\u003e (Float,Float,Float)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_Tuple3",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            },
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            },
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "hsla",
+      "comment": "Create [HSL colors](http://en.wikipedia.org/wiki/HSL_and_HSV)\nwith an alpha component for transparency.",
+      "raw": "hsla : Float -\u003e Float -\u003e Float -\u003e Float -\u003e Color",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Color",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "lightBlue",
+      "comment": "",
+      "raw": "lightBlue   : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "lightBrown",
+      "comment": "",
+      "raw": "lightBrown  : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "lightCharcoal",
+      "comment": "",
+      "raw": "lightCharcoal : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "lightGray",
+      "comment": "",
+      "raw": "lightGray : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "lightGreen",
+      "comment": "",
+      "raw": "lightGreen  : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "lightGrey",
+      "comment": "",
+      "raw": "lightGrey     : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "lightOrange",
+      "comment": "",
+      "raw": "lightOrange : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "lightPurple",
+      "comment": "",
+      "raw": "lightPurple : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "lightRed",
+      "comment": "",
+      "raw": "lightRed    : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "lightYellow",
+      "comment": "",
+      "raw": "lightYellow : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "linear",
+      "comment": "Create a linear gradient. Takes a start and end point and then a series of\n&ldquo;color stops&rdquo; that indicate how to interpolate between the start and\nend points. See [this example](/edit/examples/Elements/LinearGradient.elm) for a\nmore visual explanation.",
+      "raw": "linear : (number, number) -\u003e (number, number) -\u003e [(Float,Color)] -\u003e Gradient",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "var",
+                "name": "number"
+              },
+              {
+                "tag": "var",
+                "name": "number"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "var",
+                "name": "number"
+              },
+              {
+                "tag": "var",
+                "name": "number"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  },
+                  {
+                    "tag": "adt",
+                    "name": "Color",
+                    "args": []
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Gradient",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "orange",
+      "comment": "",
+      "raw": "orange : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "purple",
+      "comment": "",
+      "raw": "purple : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "radial",
+      "comment": "Create a radial gradient. First takes a start point and inner radius.  Then\ntakes an end point and outer radius. It then takes a series of &ldquo;color\nstops&rdquo; that indicate how to interpolate between the inner and outer\ncircles. See [this example](/edit/examples/Elements/RadialGradient.elm) for a\nmore visual explanation.",
+      "raw": "radial : (number,number) -\u003e number -\u003e (number,number) -\u003e number -\u003e [(Float,Color)] -\u003e Gradient",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "var",
+                "name": "number"
+              },
+              {
+                "tag": "var",
+                "name": "number"
+              }
+            ]
+          },
+          {
+            "tag": "var",
+            "name": "number"
+          },
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "var",
+                "name": "number"
+              },
+              {
+                "tag": "var",
+                "name": "number"
+              }
+            ]
+          },
+          {
+            "tag": "var",
+            "name": "number"
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  },
+                  {
+                    "tag": "adt",
+                    "name": "Color",
+                    "args": []
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Gradient",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "red",
+      "comment": "",
+      "raw": "red    : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "rgb",
+      "comment": "Create RGB colors from numbers between 0 and 255 inclusive.",
+      "raw": "rgb : Int -\u003e Int -\u003e Int -\u003e Color",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Color",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "rgbToHsl",
+      "comment": "",
+      "raw": "rgbToHsl : Int -\u003e Int -\u003e Int -\u003e (Float,Float,Float)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_Tuple3",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            },
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            },
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "rgba",
+      "comment": "Create RGB colors with an alpha component for transparency.\nThe alpha component is specified with numbers between 0 and 1.",
+      "raw": "rgba : Int -\u003e Int -\u003e Int -\u003e Float -\u003e Color",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Color",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toHsl",
+      "comment": "Extract the components of a color in the HSL format.",
+      "raw": "toHsl : Color -\u003e { hue:Float, saturation:Float, lightness:Float, alpha:Float }",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Color",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "record",
+          "extension": null,
+          "fields": [
+            [
+              "hue",
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ],
+            [
+              "saturation",
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ],
+            [
+              "lightness",
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ],
+            [
+              "alpha",
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ]
+          ]
+        }
+      }
+    },
+    {
+      "name": "toRgb",
+      "comment": "Extract the components of a color in the RGB format.",
+      "raw": "toRgb : Color -\u003e { red:Int, green:Int, blue:Int, alpha:Float }",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Color",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "record",
+          "extension": null,
+          "fields": [
+            [
+              "red",
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              }
+            ],
+            [
+              "green",
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              }
+            ],
+            [
+              "blue",
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              }
+            ],
+            [
+              "alpha",
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ]
+          ]
+        }
+      }
+    },
+    {
+      "name": "white",
+      "comment": "",
+      "raw": "white         : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    },
+    {
+      "name": "yellow",
+      "comment": "",
+      "raw": "yellow : Color",
+      "type": {
+        "tag": "adt",
+        "name": "Color",
+        "args": []
+      }
+    }
+  ]
+},
+{
+  "name": "Date",
+  "document": "Library for working with dates. Email the mailing list if you encounter\nissues with internationalization or locale formatting.\n\n# Conversions\n@docs read, toTime, fromTime\n\n# Extractions\n@docs year, month, Month, day, dayOfWeek, Day, hour, minute, second",
+  "aliases": [],
+  "datatypes": [
+    {
+      "name": "Date",
+      "comment": "",
+      "raw": "data Date = Date",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Date",
+          "type": {
+            "tag": "adt",
+            "name": "Date",
+            "args": []
+          }
+        }
+      ]
+    },
+    {
+      "name": "Day",
+      "comment": "Represents the days of the week.",
+      "raw": "data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Mon",
+          "type": {
+            "tag": "adt",
+            "name": "Day",
+            "args": []
+          }
+        },
+        {
+          "name": "Tue",
+          "type": {
+            "tag": "adt",
+            "name": "Day",
+            "args": []
+          }
+        },
+        {
+          "name": "Wed",
+          "type": {
+            "tag": "adt",
+            "name": "Day",
+            "args": []
+          }
+        },
+        {
+          "name": "Thu",
+          "type": {
+            "tag": "adt",
+            "name": "Day",
+            "args": []
+          }
+        },
+        {
+          "name": "Fri",
+          "type": {
+            "tag": "adt",
+            "name": "Day",
+            "args": []
+          }
+        },
+        {
+          "name": "Sat",
+          "type": {
+            "tag": "adt",
+            "name": "Day",
+            "args": []
+          }
+        },
+        {
+          "name": "Sun",
+          "type": {
+            "tag": "adt",
+            "name": "Day",
+            "args": []
+          }
+        }
+      ]
+    },
+    {
+      "name": "Month",
+      "comment": "Represents the month of the year.",
+      "raw": "data Month = Jan | Feb | Mar | Apr\n           | May | Jun | Jul | Aug\n           | Sep | Oct | Nov | Dec",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Jan",
+          "type": {
+            "tag": "adt",
+            "name": "Month",
+            "args": []
+          }
+        },
+        {
+          "name": "Feb",
+          "type": {
+            "tag": "adt",
+            "name": "Month",
+            "args": []
+          }
+        },
+        {
+          "name": "Mar",
+          "type": {
+            "tag": "adt",
+            "name": "Month",
+            "args": []
+          }
+        },
+        {
+          "name": "Apr",
+          "type": {
+            "tag": "adt",
+            "name": "Month",
+            "args": []
+          }
+        },
+        {
+          "name": "May",
+          "type": {
+            "tag": "adt",
+            "name": "Month",
+            "args": []
+          }
+        },
+        {
+          "name": "Jun",
+          "type": {
+            "tag": "adt",
+            "name": "Month",
+            "args": []
+          }
+        },
+        {
+          "name": "Jul",
+          "type": {
+            "tag": "adt",
+            "name": "Month",
+            "args": []
+          }
+        },
+        {
+          "name": "Aug",
+          "type": {
+            "tag": "adt",
+            "name": "Month",
+            "args": []
+          }
+        },
+        {
+          "name": "Sep",
+          "type": {
+            "tag": "adt",
+            "name": "Month",
+            "args": []
+          }
+        },
+        {
+          "name": "Oct",
+          "type": {
+            "tag": "adt",
+            "name": "Month",
+            "args": []
+          }
+        },
+        {
+          "name": "Nov",
+          "type": {
+            "tag": "adt",
+            "name": "Month",
+            "args": []
+          }
+        },
+        {
+          "name": "Dec",
+          "type": {
+            "tag": "adt",
+            "name": "Month",
+            "args": []
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "day",
+      "comment": "Extract the day of a given date. Given the date 23 June 1990 at 11:45AM\nthis returns the integer `23`.",
+      "raw": "day : Date -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Date",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "dayOfWeek",
+      "comment": "Extract the day of the week for a given date. Given the date 23 June\n1990 at 11:45AM this returns the Day `Thu` as defined below.",
+      "raw": "dayOfWeek : Date -\u003e Day",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Date",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Day",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "fromTime",
+      "comment": "Take a UNIX time and convert it to a `Date`",
+      "raw": "fromTime : Time -\u003e Date",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Time",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Date",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "hour",
+      "comment": "Extract the hour of a given date. Given the date 23 June 1990 at 11:45AM\nthis returns the integer `11`.",
+      "raw": "hour : Date -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Date",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "minute",
+      "comment": "Extract the minute of a given date. Given the date 23 June 1990 at 11:45AM\nthis returns the integer `45`.",
+      "raw": "minute : Date -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Date",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "month",
+      "comment": "Extract the month of a given date. Given the date 23 June 1990 at 11:45AM\nthis returns the Month `Jun` as defined below.",
+      "raw": "month : Date -\u003e Month",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Date",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Month",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "read",
+      "comment": "Attempt to read a date from a string.",
+      "raw": "read : String -\u003e Maybe Date",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Maybe",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Date",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "second",
+      "comment": "Extract the second of a given date. Given the date 23 June 1990 at 11:45AM\nthis returns the integer `0`.",
+      "raw": "second : Date -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Date",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toTime",
+      "comment": "Convert a date into a time since midnight (UTC) of 1 January 1990 (i.e.\n[UNIX time](http://en.wikipedia.org/wiki/Unix_time)). Given the date 23 June\n1990 at 11:45AM this returns the corresponding time.",
+      "raw": "toTime : Date -\u003e Time",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Date",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Time",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "year",
+      "comment": "Extract the year of a given date. Given the date 23 June 1990 at 11:45AM\nthis returns the integer `1990`.",
+      "raw": "year : Date -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Date",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Debug",
+  "document": "This library is for investigating bugs or performance problems. It should\n*not* be used in production code.\n\n# Console Debugging\n@docs log, crash\n\n# Time-Travel Debugging\n@docs watch, watchSummary, trace",
+  "aliases": [],
+  "datatypes": [],
+  "values": [
+    {
+      "name": "crash",
+      "comment": "Crash the program with an error message. This is an uncatchable error,\nintended for code that is soon-to-be-implemented. For example, if you are\nworking with a large ADT and have partially completed a case expression, it may\nmake sense to do this:\n\n      data Entity = Ship | Fish | Captain | Seagull\n\n      drawEntity entity =\n          case entity of\n            Ship -\u003e ...\n            Fish -\u003e ...\n            _ -\u003e Debug.crash (\"drawEntity not implemented for \" ++ show entity ++ \" yet!\")\n\nNote that incomplete pattern matches are *very* bad practice! They are one of\nthe very few ways to crash an Elm program, and they are completely avoidable.\nProduction code should not have incomplete pattern matches!\n\n**Use this if** you want to do some testing while you are partway through\nwriting a function.\n\n**Do not use this if** you want to do some typical try-catch exception handling.\nUse the `Maybe` or `Either` libraries instead.",
+      "raw": "crash : String -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    },
+    {
+      "name": "log",
+      "comment": "Log a tagged value on the developer console, and then return the value.\n\n      1 + log \"number\" 1        -- equals 2, logs \"number: 1\"\n      length (log \"start\" [])   -- equals 0, logs \"start: []\"\n\nNotice that `log` is not a pure function! It should *only* be used for\ninvestigating bugs or performance problems.",
+      "raw": "log : String -\u003e a -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    },
+    {
+      "name": "trace",
+      "comment": "Trace all past positions of a `Form` in the debugger. Add this to a `Form`\nand you will see a line tracing its entire history.",
+      "raw": "trace : String -\u003e Form -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Form",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "watch",
+      "comment": "Watch a particular value in the debugger. Say we want to know the value of\na variable called `velocity` because it may not be updated correctly. Adding\n`Debug.watch` allows us to name the value and show it with the debugger.\n\n\t  Debug.watch \"velocity\" velocity == velocity\n\nNotice that the result of evaluating this expression is exactly the same as\nnot having the expression at all. That means it's easy to add to any value.",
+      "raw": "watch : String -\u003e a -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    },
+    {
+      "name": "watchSummary",
+      "comment": "Watch a summary of a particular value in the debugger. This function is\npretty much the same as `watch` but it lets you specify a way to summarize\nthe value you are interested in. For example, maybe you only want to see part\nof a record:\n\n\t  Debug.watchSummary \"velocity\" .velocity object\n\nThis is the same as just writing `object`, but it creates a watch that *only*\nlooks at the value of `object.velocity`. You can also show summary statistics\nlike length of a list:\n\n\t  Debug.watchSummary \"Number of clicks\" length clicks\n\nAgain, this evaluates to `clicks` but we get to see how long that list is in\nthe debugger.",
+      "raw": "watchSummary : String -\u003e (a -\u003e b) -\u003e a -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Dict",
+  "document": "A dictionary mapping unique keys to values. The keys can be any comparable\ntype. This includes `Int`, `Float`, `Time`, `Char`, `String`, and tuples or\nlists of comparable types.\n\nInsert, remove, and query operations all take *O(log n)* time.\n\n# Build\n@docs empty, singleton, insert, update, remove\n\n# Query\n@docs member, get, getOrElse, getOrFail\n\n# Combine\n@docs union, intersect, diff\n\n# Lists\n@docs keys, values, toList, fromList\n\n# Transform\n@docs map, foldl, foldr, filter, partition",
+  "aliases": [
+    {
+      "name": "Another",
+      "comment": "",
+      "raw": "type Another = (Int, Int)",
+      "typeVariables": [],
+      "type": {
+        "tag": "adt",
+        "name": "_Tuple2",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ]
+      }
+    },
+    {
+      "name": "Fakeout",
+      "comment": "",
+      "raw": "type Fakeout = (Int, Int)",
+      "typeVariables": [],
+      "type": {
+        "tag": "adt",
+        "name": "_Tuple2",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ]
+      }
+    }
+  ],
+  "datatypes": [
+    {
+      "name": "Dict",
+      "comment": "",
+      "raw": "data Dict k v\n    = RBNode NColor k v (Dict k v) (Dict k v)\n    | RBEmpty LeafColor",
+      "typeVariables": [
+        "k",
+        "v"
+      ],
+      "constructors": [
+        {
+          "name": "RBNode",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "NColor",
+                "args": []
+              },
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              },
+              {
+                "tag": "adt",
+                "name": "Dict",
+                "args": [
+                  {
+                    "tag": "var",
+                    "name": "k"
+                  },
+                  {
+                    "tag": "var",
+                    "name": "v"
+                  }
+                ]
+              },
+              {
+                "tag": "adt",
+                "name": "Dict",
+                "args": [
+                  {
+                    "tag": "var",
+                    "name": "k"
+                  },
+                  {
+                    "tag": "var",
+                    "name": "v"
+                  }
+                ]
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Dict",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "k"
+                },
+                {
+                  "tag": "var",
+                  "name": "v"
+                }
+              ]
+            }
+          }
+        },
+        {
+          "name": "RBEmpty",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "LeafColor",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Dict",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "k"
+                },
+                {
+                  "tag": "var",
+                  "name": "v"
+                }
+              ]
+            }
+          }
+        }
+      ]
+    },
+    {
+      "name": "Flag",
+      "comment": "",
+      "raw": "data Flag = Insert | Remove | Same",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Insert",
+          "type": {
+            "tag": "adt",
+            "name": "Flag",
+            "args": []
+          }
+        },
+        {
+          "name": "Remove",
+          "type": {
+            "tag": "adt",
+            "name": "Flag",
+            "args": []
+          }
+        },
+        {
+          "name": "Same",
+          "type": {
+            "tag": "adt",
+            "name": "Flag",
+            "args": []
+          }
+        }
+      ]
+    },
+    {
+      "name": "LeafColor",
+      "comment": "",
+      "raw": "data LeafColor\n    = LBlack\n    | LBBlack",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "LBlack",
+          "type": {
+            "tag": "adt",
+            "name": "LeafColor",
+            "args": []
+          }
+        },
+        {
+          "name": "LBBlack",
+          "type": {
+            "tag": "adt",
+            "name": "LeafColor",
+            "args": []
+          }
+        }
+      ]
+    },
+    {
+      "name": "NColor",
+      "comment": "",
+      "raw": "data NColor\n    = Red\n    | Black\n    | BBlack  -- Double Black, counts as 2 blacks for the invariant\n    | NBlack",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Red",
+          "type": {
+            "tag": "adt",
+            "name": "NColor",
+            "args": []
+          }
+        },
+        {
+          "name": "Black",
+          "type": {
+            "tag": "adt",
+            "name": "NColor",
+            "args": []
+          }
+        },
+        {
+          "name": "BBlack",
+          "type": {
+            "tag": "adt",
+            "name": "NColor",
+            "args": []
+          }
+        },
+        {
+          "name": "NBlack",
+          "type": {
+            "tag": "adt",
+            "name": "NColor",
+            "args": []
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "balance",
+      "comment": "",
+      "raw": "balance : NColor -\u003e k -\u003e v -\u003e Dict k v -\u003e Dict k v -\u003e Dict k v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "NColor",
+            "args": []
+          },
+          {
+            "tag": "var",
+            "name": "k"
+          },
+          {
+            "tag": "var",
+            "name": "v"
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "k"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "balance_node",
+      "comment": "",
+      "raw": "balance_node : Dict k v -\u003e Dict k v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "k"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "blacken",
+      "comment": "",
+      "raw": "blacken : Dict k v -\u003e Dict k v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "k"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "blackish",
+      "comment": "",
+      "raw": "blackish : Dict k v -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "bubble",
+      "comment": "",
+      "raw": "bubble : NColor -\u003e k -\u003e v -\u003e Dict k v -\u003e Dict k v -\u003e Dict k v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "NColor",
+            "args": []
+          },
+          {
+            "tag": "var",
+            "name": "k"
+          },
+          {
+            "tag": "var",
+            "name": "v"
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "k"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "diff",
+      "comment": "Keep a key-value pair when its key does not appear in the second dictionary.\nPreference is given to the first dictionary.",
+      "raw": "diff : Dict comparable v -\u003e Dict comparable v -\u003e Dict comparable v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "empty",
+      "comment": "Create an empty dictionary.",
+      "raw": "empty : Dict comparable v",
+      "type": {
+        "tag": "adt",
+        "name": "Dict",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "var",
+            "name": "v"
+          }
+        ]
+      }
+    },
+    {
+      "name": "ensureBlackRoot",
+      "comment": "",
+      "raw": "ensureBlackRoot : Dict k v -\u003e Dict k v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "k"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "filter",
+      "comment": "Keep a key-value pair when it satisfies a predicate.",
+      "raw": "filter : (comparable -\u003e v -\u003e Bool) -\u003e Dict comparable v -\u003e Dict comparable v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "foldl",
+      "comment": "Fold over the key-value pairs in a dictionary, in order from lowest\nkey to highest key.",
+      "raw": "foldl : (comparable -\u003e v -\u003e b -\u003e b) -\u003e b -\u003e Dict comparable v -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      }
+    },
+    {
+      "name": "foldr",
+      "comment": "Fold over the key-value pairs in a dictionary, in order from highest\nkey to lowest key.",
+      "raw": "foldr : (comparable -\u003e v -\u003e b -\u003e b) -\u003e b -\u003e Dict comparable v -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      }
+    },
+    {
+      "name": "fromList",
+      "comment": "Convert an association list into a dictionary.",
+      "raw": "fromList : [(comparable,v)] -\u003e Dict comparable v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "var",
+                    "name": "comparable"
+                  },
+                  {
+                    "tag": "var",
+                    "name": "v"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "get",
+      "comment": "Get the value associated with a key. If the key is not found, return\n`Nothing`. This is useful when you are not sure if a key will be in the\ndictionary.\n\n      animals = fromList [ (\"Tom\", Cat), (\"Jerry\", Mouse) ]\n\n      get \"Tom\"   animals == Just Cat\n      get \"Mouse\" animals == Just Mouse\n      get \"Spike\" animals == Nothing\n\nThe `getOrElse` and `getOrFail` are built-in ways to handle common ways of\nusing the resulting `Maybe`.",
+      "raw": "get : comparable -\u003e Dict comparable v -\u003e Maybe v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Maybe",
+          "args": [
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "getOrElse",
+      "comment": "Get the value associated with a key. If the key is not found,\nreturn a default value.\n\n      animals = fromList [ (\"Tom\", Cat), (\"Jerry\", Mouse) ]\n\n      getOrElse Dog \"Tom\"   animals == Cat\n      getOrElse Dog \"Mouse\" animals == Mouse\n      getOrElse Dog \"Spike\" animals == Dog",
+      "raw": "getOrElse : v -\u003e comparable -\u003e Dict comparable v -\u003e v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "v"
+          },
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "v"
+        }
+      }
+    },
+    {
+      "name": "getOrFail",
+      "comment": "Get the value associated with a key.\n\n      animals = fromList [ (\"Tom\", Cat), (\"Jerry\", Mouse) ]\n\n      getOrFail \"Tom\"   animals == Cat\n      getOrFail \"Mouse\" animals == Mouse\n      getOrFail \"Spike\" animals == -- Runtime Error!\n\nWarning: this function will result in a runtime error if the key is not found,\nso it is best to use `get` or `getOrElse` unless you are sure the key will be\nfound.",
+      "raw": "getOrFail : comparable -\u003e Dict comparable v -\u003e v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "v"
+        }
+      }
+    },
+    {
+      "name": "insert",
+      "comment": "Insert a key-value pair into a dictionary. Replaces value when there is\na collision.",
+      "raw": "insert : comparable -\u003e v -\u003e Dict comparable v -\u003e Dict comparable v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "var",
+            "name": "v"
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "intersect",
+      "comment": "Keep a key-value pair when its key appears in the second dictionary.\nPreference is given to values in the first dictionary.",
+      "raw": "intersect : Dict comparable v -\u003e Dict comparable v -\u003e Dict comparable v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "isBBlack",
+      "comment": "",
+      "raw": "isBBlack : Dict k v -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "keys",
+      "comment": "Get all of the keys in a dictionary.",
+      "raw": "keys : Dict comparable v -\u003e [comparable]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "lessBlack",
+      "comment": "",
+      "raw": "lessBlack : NColor -\u003e NColor",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "NColor",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "NColor",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "lessBlackTree",
+      "comment": "",
+      "raw": "lessBlackTree : Dict k v -\u003e Dict k v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "k"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "map",
+      "comment": "Apply a function to all values in a dictionary.",
+      "raw": "map : (a -\u003e b) -\u003e Dict comparable a -\u003e Dict comparable b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            },
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "max",
+      "comment": "",
+      "raw": "max : Dict k v -\u003e (k, v)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_Tuple2",
+          "args": [
+            {
+              "tag": "var",
+              "name": "k"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "member",
+      "comment": "Determine if a key is in a dictionary.",
+      "raw": "member : comparable -\u003e Dict comparable v -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "min",
+      "comment": "",
+      "raw": "min : Dict k v -\u003e (k,v)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_Tuple2",
+          "args": [
+            {
+              "tag": "var",
+              "name": "k"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "moreBlack",
+      "comment": "",
+      "raw": "moreBlack : NColor -\u003e NColor",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "NColor",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "NColor",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "partition",
+      "comment": "Partition a dictionary according to a predicate. The first dictionary\ncontains all key-value pairs which satisfy the predicate, and the second\ncontains the rest.",
+      "raw": "partition : (comparable -\u003e v -\u003e Bool) -\u003e Dict comparable v -\u003e (Dict comparable v, Dict comparable v)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_Tuple2",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Dict",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "comparable"
+                },
+                {
+                  "tag": "var",
+                  "name": "v"
+                }
+              ]
+            },
+            {
+              "tag": "adt",
+              "name": "Dict",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "comparable"
+                },
+                {
+                  "tag": "var",
+                  "name": "v"
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "redden",
+      "comment": "",
+      "raw": "redden : Dict k v -\u003e Dict k v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "k"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "rem",
+      "comment": "",
+      "raw": "rem : NColor -\u003e Dict k v -\u003e Dict k v -\u003e Dict k v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "NColor",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "k"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "remove",
+      "comment": "Remove a key-value pair from a dictionary. If the key is not found,\nno changes are made.",
+      "raw": "remove : comparable -\u003e Dict comparable v -\u003e Dict comparable v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "remove_max",
+      "comment": "",
+      "raw": "remove_max : NColor -\u003e k -\u003e v -\u003e Dict k v -\u003e Dict k v -\u003e Dict k v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "NColor",
+            "args": []
+          },
+          {
+            "tag": "var",
+            "name": "k"
+          },
+          {
+            "tag": "var",
+            "name": "v"
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "k"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "k"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "reportRemBug",
+      "comment": "",
+      "raw": "reportRemBug : String -\u003e NColor -\u003e String -\u003e String -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "NColor",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    },
+    {
+      "name": "showFlag",
+      "comment": "",
+      "raw": "showFlag : Flag -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Flag",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "showLColor",
+      "comment": "",
+      "raw": "showLColor : LeafColor -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "LeafColor",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "showNColor",
+      "comment": "",
+      "raw": "showNColor : NColor -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "NColor",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "singleton",
+      "comment": "Create a dictionary with one key-value pair.",
+      "raw": "singleton : comparable -\u003e v -\u003e Dict comparable v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "var",
+            "name": "v"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "toList",
+      "comment": "Convert a dictionary into an association list of key-value pairs.",
+      "raw": "toList : Dict comparable v -\u003e [(comparable,v)]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "_Tuple2",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "comparable"
+                },
+                {
+                  "tag": "var",
+                  "name": "v"
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "union",
+      "comment": "Combine two dictionaries. If there is a collision, preference is given\nto the first dictionary.",
+      "raw": "union : Dict comparable v -\u003e Dict comparable v -\u003e Dict comparable v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "update",
+      "comment": "Update the value of a dictionary for a specific key with a given function.",
+      "raw": "update : comparable -\u003e (Maybe v -\u003e Maybe v) -\u003e Dict comparable v -\u003e Dict comparable v",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Maybe",
+                "args": [
+                  {
+                    "tag": "var",
+                    "name": "v"
+                  }
+                ]
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Maybe",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "v"
+                }
+              ]
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dict",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            },
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "values",
+      "comment": "Get all of the values in a dictionary.",
+      "raw": "values : Dict comparable v -\u003e [v]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Dict",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "v"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "v"
+            }
+          ]
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Either",
+  "document": "Represents any data that can take two different types.\n\n# Type and Constructors\n@docs Either\n\n# Taking Eithers apart\n@docs either, isLeft, isRight\n\n# Eithers and Lists\n@docs lefts, rights, partition",
+  "aliases": [],
+  "datatypes": [
+    {
+      "name": "Either",
+      "comment": "Represents any data that can take two forms. For example, a user ID may be\neither an `Int` or a `String`.\n\nThis can also be used for error handling `(Either String a)` where\nerror messages are stored on the left, and the correct values\n(&ldquo;right&rdquo; values) are stored on the right.",
+      "raw": "data Either a b = Left a | Right b",
+      "typeVariables": [
+        "a",
+        "b"
+      ],
+      "constructors": [
+        {
+          "name": "Left",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Either",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                },
+                {
+                  "tag": "var",
+                  "name": "b"
+                }
+              ]
+            }
+          }
+        },
+        {
+          "name": "Right",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Either",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                },
+                {
+                  "tag": "var",
+                  "name": "b"
+                }
+              ]
+            }
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "either",
+      "comment": "Apply the first function to a `Left` and the second function to a `Right`.\nThis allows the extraction of a value from an `Either`.\n\n      either (\\n -\u003e n + 1) sqrt (Left  4) == 5\n      either (\\n -\u003e n + 1) sqrt (Right 4) == 2\n\n      map : (a -\u003e b) -\u003e Either err a -\u003e Either err b\n      map f e = either Left (\\x -\u003e Right (f x)) e",
+      "raw": "either : (a -\u003e c) -\u003e (b -\u003e c) -\u003e Either a b -\u003e c",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "c"
+            }
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "c"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Either",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "c"
+        }
+      }
+    },
+    {
+      "name": "isLeft",
+      "comment": "True if the value is a `Left`.\n\n      isLeft (Left \"Cat\") == True\n      isLeft (Right 1123) == False",
+      "raw": "isLeft : Either a b -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Either",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "isRight",
+      "comment": "True if the value is a `Right`.\n\n      isRight (Left \"Cat\") == False\n      isRight (Right 1123) == True",
+      "raw": "isRight : Either a b -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Either",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "lefts",
+      "comment": "Keep only the values held in `Left` values.\n\n      lefts [Left 3, Right 'a', Left 5, Right \"eight\"] == [3,5]",
+      "raw": "lefts : [Either a b] -\u003e [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Either",
+                "args": [
+                  {
+                    "tag": "var",
+                    "name": "a"
+                  },
+                  {
+                    "tag": "var",
+                    "name": "b"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "partition",
+      "comment": "Split into two lists, lefts on the left and rights on the right. So we\nhave the equivalence: `(partition es == (lefts es, rights es))`\n\n      partition [Left 3, Right 'a', Left 5, Right 'b'] == ([3,5],['a','b'])",
+      "raw": "partition : [Either a b] -\u003e ([a],[b])",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Either",
+                "args": [
+                  {
+                    "tag": "var",
+                    "name": "a"
+                  },
+                  {
+                    "tag": "var",
+                    "name": "b"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_Tuple2",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "_List",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            },
+            {
+              "tag": "adt",
+              "name": "_List",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "b"
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "rights",
+      "comment": "Keep only the values held in `Right` values.\n\n      rights [Left 3, Right 'a', Left 5, Right 'b'] == ['a','b']",
+      "raw": "rights : [Either a b] -\u003e [b]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Either",
+                "args": [
+                  {
+                    "tag": "var",
+                    "name": "a"
+                  },
+                  {
+                    "tag": "var",
+                    "name": "b"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Http",
+  "document": "A library for asynchronous HTTP requests. See the `WebSocket`\nlibrary if you have very strict latency requirements.\n\n# Sending Requests\n@docs send, sendGet\n\n# Creating Requests\n@docs get, post, request\n\n# Responses\n@docs Response",
+  "aliases": [
+    {
+      "name": "Request",
+      "comment": "",
+      "raw": "type Request a = {\n  verb : String,\n  url  : String,\n  body : a,\n  headers : [(String,String)]\n }",
+      "typeVariables": [
+        "a"
+      ],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "verb",
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ],
+          [
+            "url",
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ],
+          [
+            "body",
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ],
+          [
+            "headers",
+            {
+              "tag": "adt",
+              "name": "_List",
+              "args": [
+                {
+                  "tag": "adt",
+                  "name": "_Tuple2",
+                  "args": [
+                    {
+                      "tag": "adt",
+                      "name": "String",
+                      "args": []
+                    },
+                    {
+                      "tag": "adt",
+                      "name": "String",
+                      "args": []
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        ]
+      }
+    }
+  ],
+  "datatypes": [
+    {
+      "name": "Response",
+      "comment": "The datatype for responses. Success contains only the returned message.\nFailures contain both an error code and an error message.",
+      "raw": "data Response a = Success a | Waiting | Failure Int String",
+      "typeVariables": [
+        "a"
+      ],
+      "constructors": [
+        {
+          "name": "Success",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Response",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            }
+          }
+        },
+        {
+          "name": "Waiting",
+          "type": {
+            "tag": "adt",
+            "name": "Response",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        },
+        {
+          "name": "Failure",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "String",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Response",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            }
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "get",
+      "comment": "Create a GET request to the given url.",
+      "raw": "get : String -\u003e Request String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Request",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "post",
+      "comment": "Create a POST request to the given url, carrying the given data.",
+      "raw": "post : String -\u003e String -\u003e Request String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Request",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "request",
+      "comment": "Create a customized request. Arguments are request type (get, post, put,\ndelete, etc.), target url, data, and a list of additional headers.",
+      "raw": "request : String -\u003e String -\u003e String -\u003e [(String,String)] -\u003e Request String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "String",
+                    "args": []
+                  },
+                  {
+                    "tag": "adt",
+                    "name": "String",
+                    "args": []
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Request",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "send",
+      "comment": "Performs an HTTP request with the given requests. Produces a signal\nthat carries the responses.",
+      "raw": "send : Signal (Request a) -\u003e Signal (Response String)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Request",
+                "args": [
+                  {
+                    "tag": "var",
+                    "name": "a"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Response",
+              "args": [
+                {
+                  "tag": "adt",
+                  "name": "String",
+                  "args": []
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "sendGet",
+      "comment": "Performs an HTTP GET request with the given urls. Produces a signal\nthat carries the responses.",
+      "raw": "sendGet : Signal String -\u003e Signal (Response String)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "String",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Response",
+              "args": [
+                {
+                  "tag": "adt",
+                  "name": "String",
+                  "args": []
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Json",
+  "document": "Library for working with [JSON](https://en.wikipedia.org/wiki/JSON) values.\n\n@docs Value, fromString, toString",
+  "aliases": [],
+  "datatypes": [
+    {
+      "name": "Value",
+      "comment": "This datatype can represent all valid JSON values. A `Value` can be sent\nthrough ports, and the runtime will do a conversion like this:\n\n      [2,'abc',null] == Array [Number 2, String \"abc\", Null]\n\nJSON is an intentional subset of JavaScript values which excludes functions.\nThis ensures that impure functions cannot sneak into Elm through ports.",
+      "raw": "data Value\n    = String String\n    | Number Float\n    | Boolean Bool\n    | Null\n    | Array [Value]\n    | Object (Dict.Dict String Value)",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "String",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "String",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Value",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "Number",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Value",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "Boolean",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Bool",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Value",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "Null",
+          "type": {
+            "tag": "adt",
+            "name": "Value",
+            "args": []
+          }
+        },
+        {
+          "name": "Array",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "_List",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "Value",
+                    "args": []
+                  }
+                ]
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Value",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "Object",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Dict.Dict",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "String",
+                    "args": []
+                  },
+                  {
+                    "tag": "adt",
+                    "name": "Value",
+                    "args": []
+                  }
+                ]
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Value",
+              "args": []
+            }
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "fromString",
+      "comment": "Parse a string representation of a proper JSON object into\nits Elm representation.\n\n      fromString \"null\"      == Just Null\n      fromString \"[true,3]\"  == Just (Array [Boolean True, Number 3])\n      fromString \"{'abc':4}\" == Just (Object (Dict.fromList [(\"abc\", Number 4)]))",
+      "raw": "fromString : String -\u003e Maybe Value",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Maybe",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Value",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "toString",
+      "comment": "Convert a `Value` into a prettified string.\nThe first argument is a separator token (e.g. \\\" \\\", \\\"\\\\n\\\", etc.) that will\nbe used for indentation in the prettified string version of the JSON.\n\n      toString \"\" Null         == \"null\"\n      toString \"\" (Number 4.0) == \"4.0\"",
+      "raw": "toString : String -\u003e Value -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Value",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Keyboard",
+  "document": "Library for working with keyboard input.\n\n# Representing Keys\n@docs KeyCode\n\n# Directions\n@docs arrows, wasd, directions\n\n# Specific Keys\nThe following signals are `True` when the particular key is pressed and `False`\notherwise.\n\n@docs enter, space, ctrl, shift, alt, meta\n\n# General Keypresses\n@docs isDown, keysDown, lastPressed",
+  "aliases": [
+    {
+      "name": "KeyCode",
+      "comment": "Type alias to make it clearer what integers are supposed to represent\nin this library. Use `Char.toCode` and `Char.fromCode` to convert key codes\nto characters. Use the uppercase character with `toCode`.",
+      "raw": "type KeyCode = Int",
+      "typeVariables": [],
+      "type": {
+        "tag": "adt",
+        "name": "Int",
+        "args": []
+      }
+    }
+  ],
+  "datatypes": [],
+  "values": [
+    {
+      "name": "alt",
+      "comment": "",
+      "raw": "alt   : Signal Bool",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          }
+        ]
+      }
+    },
+    {
+      "name": "arrows",
+      "comment": "A signal of records indicating which arrow keys are pressed.\n\n`{ x = 0, y = 0 }` when pressing no arrows.\u003cbr\u003e\n`{ x =-1, y = 0 }` when pressing the left arrow.\u003cbr\u003e\n`{ x = 1, y = 1 }` when pressing the up and right arrows.\u003cbr\u003e\n`{ x = 0, y =-1 }` when pressing the down, left, and right arrows.",
+      "raw": "arrows : Signal { x:Int, y:Int }",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "record",
+            "extension": null,
+            "fields": [
+              [
+                "x",
+                {
+                  "tag": "adt",
+                  "name": "Int",
+                  "args": []
+                }
+              ],
+              [
+                "y",
+                {
+                  "tag": "adt",
+                  "name": "Int",
+                  "args": []
+                }
+              ]
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "name": "ctrl",
+      "comment": "",
+      "raw": "ctrl  : Signal Bool",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          }
+        ]
+      }
+    },
+    {
+      "name": "directions",
+      "comment": "Custom key directions to support different locales. The order is up, down,\nleft, right.",
+      "raw": "directions : KeyCode -\u003e KeyCode -\u003e KeyCode -\u003e KeyCode -\u003e Signal { x:Int, y:Int }",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "KeyCode",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "KeyCode",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "KeyCode",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "KeyCode",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "record",
+              "extension": null,
+              "fields": [
+                [
+                  "x",
+                  {
+                    "tag": "adt",
+                    "name": "Int",
+                    "args": []
+                  }
+                ],
+                [
+                  "y",
+                  {
+                    "tag": "adt",
+                    "name": "Int",
+                    "args": []
+                  }
+                ]
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "enter",
+      "comment": "",
+      "raw": "enter : Signal Bool",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          }
+        ]
+      }
+    },
+    {
+      "name": "isDown",
+      "comment": "Whether an arbitrary key is pressed.",
+      "raw": "isDown : KeyCode -\u003e Signal Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "KeyCode",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "keysDown",
+      "comment": "List of keys that are currently down.",
+      "raw": "keysDown : Signal [KeyCode]",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "KeyCode",
+                "args": []
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "name": "lastPressed",
+      "comment": "The latest key that has been pressed.",
+      "raw": "lastPressed : Signal KeyCode",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "KeyCode",
+            "args": []
+          }
+        ]
+      }
+    },
+    {
+      "name": "meta",
+      "comment": "The meta key is the Windows key on Windows and the Command key on Mac.",
+      "raw": "meta  : Signal Bool",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          }
+        ]
+      }
+    },
+    {
+      "name": "shift",
+      "comment": "",
+      "raw": "shift : Signal Bool",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          }
+        ]
+      }
+    },
+    {
+      "name": "space",
+      "comment": "",
+      "raw": "space : Signal Bool",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          }
+        ]
+      }
+    },
+    {
+      "name": "wasd",
+      "comment": "Just like the arrows signal, but this uses keys w, a, s, and d,\nwhich are common controls for many computer games.",
+      "raw": "wasd : Signal { x:Int, y:Int }",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "record",
+            "extension": null,
+            "fields": [
+              [
+                "x",
+                {
+                  "tag": "adt",
+                  "name": "Int",
+                  "args": []
+                }
+              ],
+              [
+                "y",
+                {
+                  "tag": "adt",
+                  "name": "Int",
+                  "args": []
+                }
+              ]
+            ]
+          }
+        ]
+      }
+    }
+  ]
+},
+{
+  "name": "List",
+  "document": "A library for manipulating lists of values. Every value in a\nlist must have the same type.\n\n# Basics\n@docs (::), (++), isEmpty, length, reverse, map\n\n# Sub-lists\n@docs head, tail, last, filter, take, drop\n\n# Putting Lists Together\n@docs concat, join, intersperse, zip, zipWith, repeat\n\n# Taking Lists Apart\n@docs partition, unzip\n\n# Folds\n@docs foldr, foldl\n\n# Special Maps\n@docs filterMap, concatMap, indexedMap\n\n# Special Folds\n@docs sum, product, maximum, minimum, all, any, foldr1, foldl1, scanl, scanl1\n\n# Sorting\n@docs sort, sortBy, sortWith\n\n# Additional Zips\n@docs zip3, zip4, zip5, zipWith3, zipWith4, zipWith5\n\nIf you can think of a legitimate use of `zipN` or `zipWithN` where `N` is 6 or\nmore, please let us know on [the\nlist](https://groups.google.com/forum/#!forum/elm-discuss). The current\nsentiment is that it is already quite error prone once you get to 4 and\npossibly should be approached another way.",
+  "aliases": [],
+  "datatypes": [],
+  "values": [
+    {
+      "name": "++",
+      "comment": "Puts two appendable things together:\n\n      [1,1] ++ [2,3] == [1,1,2,3]\n      \"abc\" ++ \"123\" == \"abc123\"",
+      "raw": "(++) : appendable -\u003e appendable -\u003e appendable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "appendable"
+          },
+          {
+            "tag": "var",
+            "name": "appendable"
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "appendable"
+        }
+      },
+      "associativity": "right",
+      "precedence": 5
+    },
+    {
+      "name": "::",
+      "comment": "Add an element to the front of a list `(1 :: [2,3] == [1,2,3])`",
+      "raw": "(::) : a -\u003e [a] -\u003e [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      },
+      "associativity": "right",
+      "precedence": 5
+    },
+    {
+      "name": "all",
+      "comment": "Check to see if all elements satisfy the predicate.",
+      "raw": "all : (a -\u003e Bool) -\u003e [a] -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "any",
+      "comment": "Check to see if any elements satisfy the predicate.",
+      "raw": "any : (a -\u003e Bool) -\u003e [a] -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "concat",
+      "comment": "Concatenate a list of appendable things:\n\n      concat [[1,2],[3],[4,5]] == [1,2,3,4,5]\n      concat [\"tree\",\"house\"]  == \"treehouse\"",
+      "raw": "concat : [appendable] -\u003e appendable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "appendable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "appendable"
+        }
+      }
+    },
+    {
+      "name": "concatMap",
+      "comment": "Map a given function onto a list and flatten the resulting lists.\n\n      concatMap f xs == concat (map f xs)",
+      "raw": "concatMap : (a -\u003e appendable) -\u003e [a] -\u003e appendable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "appendable"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "appendable"
+        }
+      }
+    },
+    {
+      "name": "drop",
+      "comment": "Drop the first n members of a list: `(drop 2 [1,2,3,4] == [3,4])`",
+      "raw": "drop : Int -\u003e [a] -\u003e [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "filter",
+      "comment": "Keep only elements that satisfy the predicate:\n`(filter isEven [1..6] == [2,4,6])`",
+      "raw": "filter : (a -\u003e Bool) -\u003e [a] -\u003e [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "filterMap",
+      "comment": "Apply a function that may succeed to all values in the list, but only keep\nthe successes.\n\n      toInt : String -\u003e Maybe Int\n\n      filterMap toInt [\"3\", \"4.0\", \"5\", \"hats\"] == [3,5]",
+      "raw": "filterMap : (a -\u003e Maybe b) -\u003e [a] -\u003e [b]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Maybe",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "b"
+                }
+              ]
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "foldl",
+      "comment": "Reduce a list from the left: `(foldl (::) [] [1,2,3] == [3,2,1])`",
+      "raw": "foldl : (a -\u003e b -\u003e b) -\u003e b -\u003e [a] -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      }
+    },
+    {
+      "name": "foldl1",
+      "comment": "Reduce a list from the left without a base case. List must be non-empty.",
+      "raw": "foldl1 : (a -\u003e a -\u003e a) -\u003e [a] -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "a"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    },
+    {
+      "name": "foldr",
+      "comment": "Reduce a list from the right: `(foldr (+) 0 [1,2,3] == 6)`",
+      "raw": "foldr : (a -\u003e b -\u003e b) -\u003e b -\u003e [a] -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      }
+    },
+    {
+      "name": "foldr1",
+      "comment": "Reduce a list from the right without a base case. List must be non-empty.",
+      "raw": "foldr1 : (a -\u003e a -\u003e a) -\u003e [a] -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "a"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    },
+    {
+      "name": "head",
+      "comment": "Extract the first element of a list. List must be non-empty.\n`(head [1,2,3] == 1)`",
+      "raw": "head : [a] -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    },
+    {
+      "name": "indexedMap",
+      "comment": "Same as `map` but the function is also applied to the index of each\nelement (starting at zero).\n\n      indexedMap (,) [\"Tom\",\"Sue\",\"Bob\"] == [ (0,\"Tom\"), (1,\"Sue\"), (2,\"Bob\") ]",
+      "raw": "indexedMap : (Int -\u003e a -\u003e b) -\u003e [a] -\u003e [b]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "intersperse",
+      "comment": "Places the given value between all members of the given list.\n\n      intersperse \"on\" [\"turtles\",\"turtles\",\"turtles\"] == [\"turtles\",\"on\",\"turtles\",\"on\",\"turtles\"]",
+      "raw": "intersperse : a -\u003e [a] -\u003e [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "isEmpty",
+      "comment": "Check if a list is empty `(isEmpty [] == True)`",
+      "raw": "isEmpty : [a] -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "join",
+      "comment": "Places the given value between all of the lists in the second\nargument and concatenates the result.\n\n      join \"a\" [\"H\",\"w\",\"ii\",\"n\"] == \"Hawaiian\"",
+      "raw": "join : appendable -\u003e [appendable] -\u003e appendable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "appendable"
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "appendable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "appendable"
+        }
+      }
+    },
+    {
+      "name": "last",
+      "comment": "Extract the last element of a list. List must be non-empty.\n`(last [1,2,3] == 3)`",
+      "raw": "last : [a] -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    },
+    {
+      "name": "length",
+      "comment": "Determine the length of a list: `(length [1,2,3] == 3)`",
+      "raw": "length : [a] -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "map",
+      "comment": "Apply a function to every element of a list: `(map sqrt [1,4,9] == [1,2,3])`",
+      "raw": "map : (a -\u003e b) -\u003e [a] -\u003e [b]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "maximum",
+      "comment": "Find the maximum element in a non-empty list: `maximum [1,4,2] == 4`",
+      "raw": "maximum : [comparable] -\u003e comparable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "comparable"
+        }
+      }
+    },
+    {
+      "name": "maybeCons",
+      "comment": "",
+      "raw": "maybeCons : (a -\u003e Maybe b) -\u003e a -\u003e [b] -\u003e [b]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Maybe",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "b"
+                }
+              ]
+            }
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "minimum",
+      "comment": "Find the minimum element in a non-empty list: `minimum [3,2,1] == 1`",
+      "raw": "minimum : [comparable] -\u003e comparable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "comparable"
+        }
+      }
+    },
+    {
+      "name": "partition",
+      "comment": "Partition a list based on a predicate. The first list contains all values\nthat satisfy the predicate, and the second list contains all the value that do\nnot.\n\n      partition (\\x -\u003e x \u003c 3) [0..5] == ([0,1,2], [3,4,5])\n      partition isEven        [0..5] == ([0,2,4], [1,3,5])",
+      "raw": "partition : (a -\u003e Bool) -\u003e [a] -\u003e ([a],[a])",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_Tuple2",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "_List",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            },
+            {
+              "tag": "adt",
+              "name": "_List",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "product",
+      "comment": "Get the product of the list elements. `(product [1..4] == 24)`",
+      "raw": "product : [number] -\u003e number",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "number"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "number"
+        }
+      }
+    },
+    {
+      "name": "repeat",
+      "comment": "Creates a list with *n* copies of a value:\n`(repeat 3 (0,0) == [(0,0),(0,0),(0,0)]`",
+      "raw": "repeat : Int -\u003e a -\u003e [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "reverse",
+      "comment": "Reverse a list. `(reverse [1..4] == [4,3,2,1])`",
+      "raw": "reverse : [a] -\u003e [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "scanl",
+      "comment": "Reduce a list from the left, building up all of the intermediate results into a list.\n\n      scanl (+) 0 [1,2,3,4] == [0,1,3,6,10]",
+      "raw": "scanl : (a -\u003e b -\u003e b) -\u003e b -\u003e [a] -\u003e [b]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "scanl1",
+      "comment": "Same as scanl but it doesn't require a base case. List must be non-empty.\n\n      scanl1 (+) [1,2,3,4] == [1,3,6,10]",
+      "raw": "scanl1 : (a -\u003e a -\u003e a) -\u003e [a] -\u003e [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "a"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "sort",
+      "comment": "Sort values from lowest to highest: `sort [3,1,5] == [1,3,5]`",
+      "raw": "sort : [comparable] -\u003e [comparable]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "sortBy",
+      "comment": "Sort values by a derived property.\n\n```haskell\nalice = { name=\"Alice\", height=1.62 }\nbob   = { name=\"Bob\"  , height=1.85 }\nchuck = { name=\"Chuck\", height=1.76 }\n\nsortBy .name   [chuck,alice,bob] == [alice,bob,chuck]\nsortBy .height [chuck,alice,bob] == [alice,chuck,bob]\n\nsortBy String.length [\"mouse\",\"cat\"] == [\"cat\",\"mouse\"]\n```",
+      "raw": "sortBy : (a -\u003e comparable) -\u003e  [a] -\u003e [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "comparable"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "sortWith",
+      "comment": "Sort values with a custom comparison function.\n\n```haskell\nsortWith flippedComparison [1..5] == [5,4,3,2,1]\n\nflippedComparison a b =\n     case compare a b of\n       LT -\u003e GT\n       EQ -\u003e EQ\n       GT -\u003e LT\n```\n\nThis is also the most general sort function, allowing you\nto define any other: `sort == sortWith compare`",
+      "raw": "sortWith : (a -\u003e a -\u003e Order) -\u003e  [a] -\u003e [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Order",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "sum",
+      "comment": "Get the sum of the list elements. `(sum [1..4] == 10)`",
+      "raw": "sum : [number] -\u003e number",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "number"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "number"
+        }
+      }
+    },
+    {
+      "name": "tail",
+      "comment": "Extract the elements after the head of the list. List must be non-empty.\n`(tail [1,2,3] == [2,3])`",
+      "raw": "tail : [a] -\u003e [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "take",
+      "comment": "Take the first n members of a list: `(take 2 [1,2,3,4] == [1,2])`",
+      "raw": "take : Int -\u003e [a] -\u003e [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "unzip",
+      "comment": "Decompose a list of tuples. \n\n      unzip [(0, True), (17, False), (1337, True)] == ([0,17,1337], [True,False,True])",
+      "raw": "unzip : [(a,b)] -\u003e ([a],[b])",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "var",
+                    "name": "a"
+                  },
+                  {
+                    "tag": "var",
+                    "name": "b"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_Tuple2",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "_List",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            },
+            {
+              "tag": "adt",
+              "name": "_List",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "b"
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "zip",
+      "comment": "Combine two lists, combining them into tuples pairwise.\nIf one list is longer, the extra elements are dropped.\n\n      zip [1,2,3] [6,7] == [(1,6),(2,7)]\n      zip == zipWith (,)",
+      "raw": "zip : [a] -\u003e [b] -\u003e [(a,b)]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "_Tuple2",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                },
+                {
+                  "tag": "var",
+                  "name": "b"
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "zip3",
+      "comment": "",
+      "raw": "zip3 : [a] -\u003e [b] -\u003e [c] -\u003e [(a,b,c)]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "_Tuple3",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                },
+                {
+                  "tag": "var",
+                  "name": "b"
+                },
+                {
+                  "tag": "var",
+                  "name": "c"
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "zip4",
+      "comment": "",
+      "raw": "zip4 : [a] -\u003e [b] -\u003e [c] -\u003e [d] -\u003e [(a,b,c,d)]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "d"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "_Tuple4",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                },
+                {
+                  "tag": "var",
+                  "name": "b"
+                },
+                {
+                  "tag": "var",
+                  "name": "c"
+                },
+                {
+                  "tag": "var",
+                  "name": "d"
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "zip5",
+      "comment": "",
+      "raw": "zip5 : [a] -\u003e [b] -\u003e [c] -\u003e [d] -\u003e [e] -\u003e [(a,b,c,d,e)]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "d"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "e"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "_Tuple5",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                },
+                {
+                  "tag": "var",
+                  "name": "b"
+                },
+                {
+                  "tag": "var",
+                  "name": "c"
+                },
+                {
+                  "tag": "var",
+                  "name": "d"
+                },
+                {
+                  "tag": "var",
+                  "name": "e"
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "zipWith",
+      "comment": "Combine two lists, combining them with the given function.\nIf one list is longer, the extra elements are dropped.\n\n      zipWith (+) [1,2,3] [1,2,3,4] == [2,4,6]",
+      "raw": "zipWith : (a -\u003e b -\u003e c) -\u003e [a] -\u003e [b] -\u003e [c]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "c"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "c"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "zipWith3",
+      "comment": "",
+      "raw": "zipWith3 : (a -\u003e b -\u003e c -\u003e x) -\u003e [a] -\u003e [b] -\u003e [c] -\u003e [x]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              },
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "x"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "x"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "zipWith4",
+      "comment": "",
+      "raw": "zipWith4 : (a -\u003e b -\u003e c -\u003e d -\u003e x) -\u003e [a] -\u003e [b] -\u003e [c] -\u003e [d] -\u003e [x]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              },
+              {
+                "tag": "var",
+                "name": "c"
+              },
+              {
+                "tag": "var",
+                "name": "d"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "x"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "d"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "x"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "zipWith5",
+      "comment": "",
+      "raw": "zipWith5 : (a -\u003e b -\u003e c -\u003e d -\u003e e -\u003e x) -\u003e [a] -\u003e [b] -\u003e [c] -\u003e [d] -\u003e [e] -\u003e [x]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              },
+              {
+                "tag": "var",
+                "name": "c"
+              },
+              {
+                "tag": "var",
+                "name": "d"
+              },
+              {
+                "tag": "var",
+                "name": "e"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "x"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "d"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "e"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "x"
+            }
+          ]
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Maybe",
+  "document": "Represents an optional value. Maybe it is there, maybe it is not.\n\n# Type and Constructors\n@docs Maybe\n\n# Taking Maybes apart\n@docs maybe, isJust, isNothing\n\n# Map\n@docs map",
+  "aliases": [],
+  "datatypes": [
+    {
+      "name": "Maybe",
+      "comment": "The Maybe datatype. Useful when a computation may or may not\nresult in a value (e.g. logarithm is defined only for positive\nnumbers).",
+      "raw": "data Maybe a = Just a | Nothing",
+      "typeVariables": [
+        "a"
+      ],
+      "constructors": [
+        {
+          "name": "Just",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Maybe",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            }
+          }
+        },
+        {
+          "name": "Nothing",
+          "type": {
+            "tag": "adt",
+            "name": "Maybe",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "isJust",
+      "comment": "Check if a maybe happens to be a `Just`.\n\n      isJust (Just 42) == True\n      isJust (Just []) == True\n      isJust Nothing   == False",
+      "raw": "isJust : Maybe a -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Maybe",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "isNothing",
+      "comment": "Check if constructed with `Nothing`.\n\n      isNothing (Just 42) == False\n      isNothing (Just []) == False\n      isNothing Nothing   == True",
+      "raw": "isNothing : Maybe a -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Maybe",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "map",
+      "comment": "Transform the contents of a `Maybe` with a given function:\n\n      map sqrt (Just 9) == Just 3\n      map sqrt Nothing  == Nothing",
+      "raw": "map : (a -\u003e b) -\u003e Maybe a -\u003e Maybe b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Maybe",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Maybe",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "maybe",
+      "comment": "Provide a default value and a function to extract the contents of a `Maybe`.\nWhen given `Nothing` you get the default, when given a `Just` you apply the\nfunction to the associated value.\n\n      isPositive : Maybe Int -\u003e Bool\n      isPositive maybeInt = maybe False (\\n -\u003e n \u003e 0) maybeInt",
+      "raw": "maybe : b -\u003e (a -\u003e b) -\u003e Maybe a -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Maybe",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Mouse",
+  "document": "Library for working with mouse input.\n\n# Position\n@docs position, x, y\n\n# Button Status\n@docs isDown, clicks",
+  "aliases": [],
+  "datatypes": [],
+  "values": [
+    {
+      "name": "clicks",
+      "comment": "Always equal to unit. Event triggers on every mouse click.",
+      "raw": "clicks : Signal ()",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple0",
+            "args": []
+          }
+        ]
+      }
+    },
+    {
+      "name": "isDown",
+      "comment": "The current state of the left mouse-button.\nTrue when the button is down, and false otherwise.",
+      "raw": "isDown : Signal Bool",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          }
+        ]
+      }
+    },
+    {
+      "name": "position",
+      "comment": "The current mouse position.",
+      "raw": "position : Signal (Int,Int)",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "name": "x",
+      "comment": "The current x-coordinate of the mouse.",
+      "raw": "x : Signal Int",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ]
+      }
+    },
+    {
+      "name": "y",
+      "comment": "The current y-coordinate of the mouse.",
+      "raw": "y : Signal Int",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ]
+      }
+    }
+  ]
+},
+{
+  "name": "Random",
+  "document": "Since the core of Elm is pure, randomness must be handled via signals.\n\n# Random Numbers\n@docs range, float, floatList",
+  "aliases": [],
+  "datatypes": [],
+  "values": [
+    {
+      "name": "float",
+      "comment": "Produces a new signal that changes whenever the input signal changes.\nThe new values are random numbers in [0..1).",
+      "raw": "float : Signal a -\u003e Signal Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "floatList",
+      "comment": "Produces a new signal of lists that changes whenever the input signal\nchanges. The input signal specifies the length of the random list. Each value is\na random number in [0..1).",
+      "raw": "floatList : Signal Int -\u003e Signal [Float]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "_List",
+              "args": [
+                {
+                  "tag": "adt",
+                  "name": "Float",
+                  "args": []
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "range",
+      "comment": "Given a range from low to high and a signal of values, this produces\na new signal that changes whenever the input signal changes. The new\nvalues are random number between 'low' and 'high' inclusive.",
+      "raw": "range : Int -\u003e Int -\u003e Signal a -\u003e Signal Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ]
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Regex",
+  "document": "A library for working with regular expressions. It uses [the\nsame kind of regular expressions accepted by JavaScript](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions).\n\n# Create\n@docs regex, escape, caseInsensitive\n\n# Helpful Data Structures\n\nThese data structures are needed to help define functions like [`find`](#find)\nand [`replace`](#replace).\n\n@docs HowMany, Match\n\n# Use\n@docs contains, find, replace, split",
+  "aliases": [
+    {
+      "name": "Match",
+      "comment": "A `Match` represents all of the details about a particular match in a string.\nHere are details on each field:\n\n  * `match` &mdash; the full string of the match.\n  * `submatches` &mdash; a regex might have [subpatterns, surrounded by\n    parentheses](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Using_Parenthesized_Substring_Matches).\n    If there are N subpatterns, there will be N elements in the `submatches` list.\n    Each submatch in this list is a `Maybe` because not all subpatterns may trigger.\n    For example, `(regex \"(a+)|(b+)\")` will either match many `a`&rsquo;s or\n    many `b`&rsquo;s, but never both.\n  * `index` &mdash; the index of the match in the original string.\n  * `number` &mdash; if you find many matches, you can think of each one\n    as being labeled with a `number` starting at one. So the first time you\n    find a match, that is match `number` one. Second time is match `number` two.\n    This is useful when paired with `replace All` if replacement is dependent on how\n    many times a pattern has appeared before.",
+      "raw": "type Match = { match : String, submatches : [Maybe String], index : Int, number : Int }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "match",
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ],
+          [
+            "submatches",
+            {
+              "tag": "adt",
+              "name": "_List",
+              "args": [
+                {
+                  "tag": "adt",
+                  "name": "Maybe",
+                  "args": [
+                    {
+                      "tag": "adt",
+                      "name": "String",
+                      "args": []
+                    }
+                  ]
+                }
+              ]
+            }
+          ],
+          [
+            "index",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "number",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ]
+        ]
+      }
+    }
+  ],
+  "datatypes": [
+    {
+      "name": "HowMany",
+      "comment": "`HowMany` is used to specify how many matches you want to make. So\n`replace All` would replace every match, but `replace (AtMost 2)` would\nreplace at most two matches (i.e. zero, one, two, but never three or more).",
+      "raw": "data HowMany = All | AtMost Int",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "All",
+          "type": {
+            "tag": "adt",
+            "name": "HowMany",
+            "args": []
+          }
+        },
+        {
+          "name": "AtMost",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "HowMany",
+              "args": []
+            }
+          }
+        }
+      ]
+    },
+    {
+      "name": "Regex",
+      "comment": "",
+      "raw": "data Regex = Regex",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Regex",
+          "type": {
+            "tag": "adt",
+            "name": "Regex",
+            "args": []
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "caseInsensitive",
+      "comment": "Make a regex case insensitive",
+      "raw": "caseInsensitive : Regex -\u003e Regex",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Regex",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Regex",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "contains",
+      "comment": "Check to see if a Regex is contained in a string.\n\n```haskell\n  contains (regex \"123\") \"12345\" == True\n  contains (regex \"b+\") \"aabbcc\" == True\n\n  contains (regex \"789\") \"12345\" == False\n  contains (regex \"z+\") \"aabbcc\" == False\n```",
+      "raw": "contains : Regex -\u003e String -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Regex",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "escape",
+      "comment": "Escape strings to be regular expressions, making all special characters\nsafe. So `regex (escape \"^a+\")` will match exactly `\"^a+\"` instead of a series\nof `a`&rsquo;s that start at the beginning of the line.",
+      "raw": "escape : String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "find",
+      "comment": "Find matches in a string:\n\n```haskell\n  findTwoCommas = find (AtMost 2) (regex \",\")\n\n    -- map .index (findTwoCommas \"a,b,c,d,e\") == [1,3]\n    -- map .index (findTwoCommas \"a b c d e\") == []\n\n  places = find All (regex \"[oi]n a (\\\\w+)\") \"I am on a boat in a lake.\"\n\n    -- map .match places == [\"on a boat\", \"in a lake\"]\n    -- map .submatches places == [ [Just \"boat\"], [Just \"lake\"] ]\n```",
+      "raw": "find : HowMany -\u003e Regex -\u003e String -\u003e [Match]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "HowMany",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Regex",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Match",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "regex",
+      "comment": "Create a Regex that matches patterns [as specified in JavaScript](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Writing_a_Regular_Expression_Pattern).\n\nBe careful to escape backslashes properly! For example, `\"\\w\"` is escaping the\nletter `w` which is probably not what you want. You probably want `\"\\\\w\"`\ninstead, which escapes the backslash.",
+      "raw": "regex : String -\u003e Regex",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Regex",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "replace",
+      "comment": "Replace matches. The function from `Match` to `String` lets\nyou use the details of a specific match when making replacements.\n\n```haskell\n  devowel = replace All (regex \"[aeiou]\") (\\_ -\u003e \"\")\n\n    -- devowel \"The quick brown fox\" == \"Th qck brwn fx\"\n\n  reverseWords = replace All (regex \"\\\\w+\") (\\{match} -\u003e String.reverse match)\n\n    -- reverseWords \"deliver mined parts\" == \"reviled denim strap\"\n```",
+      "raw": "replace : HowMany -\u003e Regex -\u003e (Match -\u003e String) -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "HowMany",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Regex",
+            "args": []
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Match",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "split",
+      "comment": "Split a string, using the regex as the separator.\n\n```haskell\n  split (AtMost 1) (regex \",\") \"tom,99,90,85\" == [\"tom\",\"99,90,85\"]\n\n  split All (regex \",\") \"a,b,c,d\" == [\"a\",\"b\",\"c\",\"d\"]\n```",
+      "raw": "split : HowMany -\u003e Regex -\u003e String -\u003e [String]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "HowMany",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Regex",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ]
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Set",
+  "document": "A set of unique values. The values can be any comparable type. This\nincludes `Int`, `Float`, `Time`, `Char`, `String`, and tuples or lists\nof comparable types.\n\nInsert, remove, and query operations all take *O(log n)* time.\n\n# Build\n@docs empty, singleton, insert, remove\n\n# Query\n@docs member\n\n# Combine\n@docs union, intersect, diff\n\n# Lists\n@docs toList, fromList\n\n# Transform\n@docs map, foldl, foldr, filter, partition",
+  "aliases": [
+    {
+      "name": "Set",
+      "comment": "",
+      "raw": "type Set t = Dict.Dict t ()",
+      "typeVariables": [
+        "t"
+      ],
+      "type": {
+        "tag": "adt",
+        "name": "Dict.Dict",
+        "args": [
+          {
+            "tag": "var",
+            "name": "t"
+          },
+          {
+            "tag": "adt",
+            "name": "_Tuple0",
+            "args": []
+          }
+        ]
+      }
+    }
+  ],
+  "datatypes": [],
+  "values": [
+    {
+      "name": "diff",
+      "comment": "Get the difference between the first set and the second. Keeps values\nthat do not appear in the second set.",
+      "raw": "diff : Set comparable -\u003e Set comparable -\u003e Set comparable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Set",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "empty",
+      "comment": "Create an empty set.",
+      "raw": "empty : Set comparable",
+      "type": {
+        "tag": "adt",
+        "name": "Set",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          }
+        ]
+      }
+    },
+    {
+      "name": "filter",
+      "comment": "Create a new set consisting only of elements which satisfy a predicate.",
+      "raw": "filter : (comparable -\u003e Bool) -\u003e Set comparable -\u003e Set comparable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Set",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "foldl",
+      "comment": "Fold over the values in a set, in order from lowest to highest.",
+      "raw": "foldl : (comparable -\u003e b -\u003e b) -\u003e b -\u003e Set comparable -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      }
+    },
+    {
+      "name": "foldr",
+      "comment": "Fold over the values in a set, in order from highest to lowest.",
+      "raw": "foldr : (comparable -\u003e b -\u003e b) -\u003e b -\u003e Set comparable -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      }
+    },
+    {
+      "name": "fromList",
+      "comment": "Convert a list into a set, removing any duplicates.",
+      "raw": "fromList : [comparable] -\u003e Set comparable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Set",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "insert",
+      "comment": "Insert a value into a set.",
+      "raw": "insert : comparable -\u003e Set comparable -\u003e Set comparable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Set",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "intersect",
+      "comment": "Get the intersection of two sets. Keeps values that appear in both sets.",
+      "raw": "intersect : Set comparable -\u003e Set comparable -\u003e Set comparable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Set",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "map",
+      "comment": "Map a function onto a set, creating a new set with no duplicates.",
+      "raw": "map : (comparable -\u003e comparable') -\u003e Set comparable -\u003e Set comparable'",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "comparable'"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Set",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable'"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "member",
+      "comment": "Determine if a value is in a set.",
+      "raw": "member : comparable -\u003e Set comparable -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "partition",
+      "comment": "Create two new sets; the first consisting of elements which satisfy a\npredicate, the second consisting of elements which do not.",
+      "raw": "partition : (comparable -\u003e Bool) -\u003e Set comparable -\u003e (Set comparable, Set comparable)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_Tuple2",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Set",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "comparable"
+                }
+              ]
+            },
+            {
+              "tag": "adt",
+              "name": "Set",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "comparable"
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "remove",
+      "comment": "Remove a value from a set. If the value is not found, no changes are made.",
+      "raw": "remove : comparable -\u003e Set comparable -\u003e Set comparable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          },
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Set",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "singleton",
+      "comment": "Create a set with one value.",
+      "raw": "singleton : comparable -\u003e Set comparable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "comparable"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Set",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "toList",
+      "comment": "Convert a set into a list.",
+      "raw": "toList : Set comparable -\u003e [comparable]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "union",
+      "comment": "Get the union of two sets. Keep all values.",
+      "raw": "union : Set comparable -\u003e Set comparable -\u003e Set comparable",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Set",
+            "args": [
+              {
+                "tag": "var",
+                "name": "comparable"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Set",
+          "args": [
+            {
+              "tag": "var",
+              "name": "comparable"
+            }
+          ]
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Signal",
+  "document": "The library for general signal manipulation. Includes lift functions up to\n`lift8` and infix lift operators `\u003c~` and `~`, combinations, filters, and\npast-dependence.\n\nSignals are time-varying values. Lifted functions are reevaluated whenever any of\ntheir input signals has an event. Signal events may be of the same value as the\nprevious value of the signal. Such signals are useful for timing and\npast-dependence.\n\nSome useful functions for working with time (e.g. setting FPS) and combining\nsignals and time (e.g.  delaying updates, getting timestamps) can be found in\nthe `Time` library.\n\n# Combine\n@docs constant, lift, lift2, merge, merges, combine\n\n# Past-Dependence\n@docs foldp, count, countIf\n\n#Filters\n@docs keepIf, dropIf, keepWhen, dropWhen, dropRepeats, sampleOn\n\n# Pretty Lift\n@docs (\u003c~), (~)\n\n# Do you even lift?\n@docs lift3, lift4, lift5, lift6, lift7, lift8",
+  "aliases": [],
+  "datatypes": [
+    {
+      "name": "Signal",
+      "comment": "",
+      "raw": "data Signal a = Signal",
+      "typeVariables": [
+        "a"
+      ],
+      "constructors": [
+        {
+          "name": "Signal",
+          "type": {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "\u003c~",
+      "comment": "An alias for `lift`. A prettier way to apply a function to the current value\nof a signal.",
+      "raw": "(\u003c~) : (a -\u003e b) -\u003e Signal a -\u003e Signal b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      },
+      "associativity": "left",
+      "precedence": 4
+    },
+    {
+      "name": "combine",
+      "comment": "Combine a list of signals into a signal of lists.",
+      "raw": "combine : [Signal a] -\u003e Signal [a]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Signal",
+                "args": [
+                  {
+                    "tag": "var",
+                    "name": "a"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "_List",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "constant",
+      "comment": "Create a constant signal that never changes.",
+      "raw": "constant : a -\u003e Signal a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "count",
+      "comment": "Count the number of events that have occurred.",
+      "raw": "count : Signal a -\u003e Signal Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "countIf",
+      "comment": "Count the number of events that have occurred that satisfy a given predicate.",
+      "raw": "countIf : (a -\u003e Bool) -\u003e Signal a -\u003e Signal Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "dropIf",
+      "comment": "Drop events that satisfy the given predicate. Elm does not allow undefined\nsignals, so a base case must be provided in case the predicate is satisfied\ninitially.",
+      "raw": "dropIf : (a -\u003e Bool) -\u003e a -\u003e Signal a -\u003e Signal a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "dropRepeats",
+      "comment": "Drop updates that repeat the current value of the signal.\n\nImagine a signal `numbers` has initial value\n0 and then updates with values 0, 0, 1, 1, and 2. `dropRepeats numbers`\nis a signal that has initial value 0 and updates as follows: ignore 0,\nignore 0, update to 1, ignore 1, update to 2.",
+      "raw": "dropRepeats : Signal a -\u003e Signal a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "dropWhen",
+      "comment": "Drop events when the first signal is true. Elm does not allow undefined\nsignals, so a base case must be provided in case the first signal is true\ninitially.",
+      "raw": "dropWhen : Signal Bool -\u003e a -\u003e Signal a -\u003e Signal a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Bool",
+                "args": []
+              }
+            ]
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "foldp",
+      "comment": "Create a past-dependent signal. Each value given on the input signal will\nbe accumulated, producing a new output value.\n\nFor instance, `foldp (+) 0 (fps 40)` is the time the program has been running,\nupdated 40 times a second.",
+      "raw": "foldp : (a -\u003e b -\u003e b) -\u003e b -\u003e Signal a -\u003e Signal b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "keepIf",
+      "comment": "Keep only events that satisfy the given predicate. Elm does not allow\nundefined signals, so a base case must be provided in case the predicate is\nnot satisfied initially.",
+      "raw": "keepIf : (a -\u003e Bool) -\u003e a -\u003e Signal a -\u003e Signal a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "keepWhen",
+      "comment": "Keep events only when the first signal is true. Elm does not allow undefined\nsignals, so a base case must be provided in case the first signal is not true\ninitially.",
+      "raw": "keepWhen : Signal Bool -\u003e a -\u003e Signal a -\u003e Signal a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Bool",
+                "args": []
+              }
+            ]
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "lift",
+      "comment": "Transform a signal with a given function.",
+      "raw": "lift  : (a -\u003e b) -\u003e Signal a -\u003e Signal b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "lift2",
+      "comment": "Combine two signals with a given function.",
+      "raw": "lift2 : (a -\u003e b -\u003e c) -\u003e Signal a -\u003e Signal b -\u003e Signal c",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "c"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "c"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "lift3",
+      "comment": "",
+      "raw": "lift3 : (a -\u003e b -\u003e c -\u003e d) -\u003e Signal a -\u003e Signal b -\u003e Signal c -\u003e Signal d",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              },
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "d"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "d"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "lift4",
+      "comment": "",
+      "raw": "lift4 : (a -\u003e b -\u003e c -\u003e d -\u003e e) -\u003e Signal a -\u003e Signal b -\u003e Signal c -\u003e Signal d -\u003e Signal e",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              },
+              {
+                "tag": "var",
+                "name": "c"
+              },
+              {
+                "tag": "var",
+                "name": "d"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "e"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "d"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "e"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "lift5",
+      "comment": "",
+      "raw": "lift5 : (a -\u003e b -\u003e c -\u003e d -\u003e e -\u003e f) -\u003e Signal a -\u003e Signal b -\u003e Signal c -\u003e Signal d -\u003e Signal e -\u003e Signal f",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              },
+              {
+                "tag": "var",
+                "name": "c"
+              },
+              {
+                "tag": "var",
+                "name": "d"
+              },
+              {
+                "tag": "var",
+                "name": "e"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "f"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "d"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "e"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "f"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "lift6",
+      "comment": "",
+      "raw": "lift6 : (a -\u003e b -\u003e c -\u003e d -\u003e e -\u003e f -\u003e g)\n      -\u003e Signal a -\u003e Signal b -\u003e Signal c -\u003e Signal d -\u003e Signal e -\u003e Signal f -\u003e Signal g",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              },
+              {
+                "tag": "var",
+                "name": "c"
+              },
+              {
+                "tag": "var",
+                "name": "d"
+              },
+              {
+                "tag": "var",
+                "name": "e"
+              },
+              {
+                "tag": "var",
+                "name": "f"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "g"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "d"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "e"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "f"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "g"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "lift7",
+      "comment": "",
+      "raw": "lift7 : (a -\u003e b -\u003e c -\u003e d -\u003e e -\u003e f -\u003e g -\u003e h)\n      -\u003e Signal a -\u003e Signal b -\u003e Signal c -\u003e Signal d -\u003e Signal e -\u003e Signal f -\u003e Signal g -\u003e Signal h",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              },
+              {
+                "tag": "var",
+                "name": "c"
+              },
+              {
+                "tag": "var",
+                "name": "d"
+              },
+              {
+                "tag": "var",
+                "name": "e"
+              },
+              {
+                "tag": "var",
+                "name": "f"
+              },
+              {
+                "tag": "var",
+                "name": "g"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "h"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "d"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "e"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "f"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "g"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "h"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "lift8",
+      "comment": "",
+      "raw": "lift8 : (a -\u003e b -\u003e c -\u003e d -\u003e e -\u003e f -\u003e g -\u003e h -\u003e i)\n      -\u003e Signal a -\u003e Signal b -\u003e Signal c -\u003e Signal d -\u003e Signal e -\u003e Signal f -\u003e Signal g -\u003e Signal h -\u003e Signal i",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              },
+              {
+                "tag": "var",
+                "name": "c"
+              },
+              {
+                "tag": "var",
+                "name": "d"
+              },
+              {
+                "tag": "var",
+                "name": "e"
+              },
+              {
+                "tag": "var",
+                "name": "f"
+              },
+              {
+                "tag": "var",
+                "name": "g"
+              },
+              {
+                "tag": "var",
+                "name": "h"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "i"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "c"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "d"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "e"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "f"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "g"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "h"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "i"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "merge",
+      "comment": "Merge two signals into one, biased towards the first signal if both signals\nupdate at the same time.",
+      "raw": "merge : Signal a -\u003e Signal a -\u003e Signal a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "merges",
+      "comment": "Merge many signals into one, biased towards the left-most signal if multiple\nsignals update simultaneously.",
+      "raw": "merges : [Signal a] -\u003e Signal a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Signal",
+                "args": [
+                  {
+                    "tag": "var",
+                    "name": "a"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "sampleOn",
+      "comment": "Sample from the second input every time an event occurs on the first input.\nFor example, `(sampleOn clicks (every second))` will give the approximate time\nof the latest click.",
+      "raw": "sampleOn : Signal a -\u003e Signal b -\u003e Signal b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "~",
+      "comment": "Informally, an alias for `liftN`. Intersperse it between additional signal\narguments of the lifted function.\n\nFormally, signal application. This takes two signals, holding a function and\na value. It applies the current function to the current value.\n\nThe following expressions are equivalent:\n\n         scene \u003c~ Window.dimensions ~ Mouse.position\n         lift2 scene Window.dimensions Mouse.position",
+      "raw": "(~) : Signal (a -\u003e b) -\u003e Signal a -\u003e Signal b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "function",
+                "args": [
+                  {
+                    "tag": "var",
+                    "name": "a"
+                  }
+                ],
+                "result": {
+                  "tag": "var",
+                  "name": "b"
+                }
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "b"
+            }
+          ]
+        }
+      },
+      "associativity": "left",
+      "precedence": 4
+    }
+  ]
+},
+{
+  "name": "String",
+  "document": "A built-in representation for efficient string manipulation. String literals\nare enclosed in `\"double quotes\"`. Strings are *not* lists of characters.\n\n# Basics\n@docs isEmpty, length, reverse, repeat\n\n# Building and Splitting\n@docs cons, uncons, append, concat, split, join, words, lines\n\n# Get Substrings\n@docs slice, left, right, dropLeft, dropRight\n\n# Check for Substrings\n@docs contains, startsWith, endsWith, indexes, indices\n\n# Conversions\n@docs show, toInt, toFloat, toList, fromList\n\n# Formatting\nCosmetic operations such as padding with extra characters or trimming whitespace.\n\n@docs toUpper, toLower,\n      pad, padLeft, padRight,\n      trim, trimLeft, trimRight\n\n# Higher-Order Functions\n@docs map, filter, foldl, foldr, any, all",
+  "aliases": [],
+  "datatypes": [],
+  "values": [
+    {
+      "name": "all",
+      "comment": "Check to see if *all* characters satisfy a predicate.\n\n      all isDigit \"90210\" == True\n      all isDigit \"R2-D2\" == False\n      all isDigit \"heart\" == False",
+      "raw": "all : (Char -\u003e Bool) -\u003e String -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Char",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "any",
+      "comment": "Check to see if *any* characters satisfy a predicate.\n\n      any isDigit \"90210\" == True\n      any isDigit \"R2-D2\" == True\n      any isDigit \"heart\" == False",
+      "raw": "any : (Char -\u003e Bool) -\u003e String -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Char",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "append",
+      "comment": "Append two strings. You can also use [the `(++)` operator](/library/List.elm#++)\nto do this.\n\n      append \"butter\" \"fly\" == \"butterfly\"",
+      "raw": "append : String -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "concat",
+      "comment": "Concatenate many strings into one.\n\n      concat [\"never\",\"the\",\"less\"] == \"nevertheless\"",
+      "raw": "concat : [String] -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "String",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "cons",
+      "comment": "Add a character to the beginning of a string",
+      "raw": "cons : Char -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "contains",
+      "comment": "See if the second string contains the first one.\n\n      contains \"the\" \"theory\" == True\n      contains \"hat\" \"theory\" == False\n      contains \"THE\" \"theory\" == False\n\nUse `Regex.contains` if you need something more flexible.",
+      "raw": "contains : String -\u003e String -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "dropLeft",
+      "comment": "Drop N characters from the left side of a string.",
+      "raw": "dropLeft : Int -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "dropRight",
+      "comment": "Drop N characters from the right side of a string.",
+      "raw": "dropRight : Int -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "endsWith",
+      "comment": "See if the second string ends with the first one.\n\n      endsWith \"the\" \"theory\" == False\n      endsWith \"ory\" \"theory\" == True",
+      "raw": "endsWith : String -\u003e String -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "filter",
+      "comment": "Keep only the characters that satisfy the predicate:\n\n      filter isDigit \"R2-D2\" == \"22\"",
+      "raw": "filter : (Char -\u003e Bool) -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Char",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "foldl",
+      "comment": "Reduce a string from the left:\n\n      foldl cons \"\" \"time\" == \"emit\"",
+      "raw": "foldl : (Char -\u003e b -\u003e b) -\u003e b -\u003e String -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Char",
+                "args": []
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      }
+    },
+    {
+      "name": "foldr",
+      "comment": "Reduce a string from the right:\n\n      foldr cons \"\" \"time\" == \"time\"",
+      "raw": "foldr : (Char -\u003e b -\u003e b) -\u003e b -\u003e String -\u003e b",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Char",
+                "args": []
+              },
+              {
+                "tag": "var",
+                "name": "b"
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "b"
+            }
+          },
+          {
+            "tag": "var",
+            "name": "b"
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "b"
+        }
+      }
+    },
+    {
+      "name": "fromList",
+      "comment": "Convert a list of characters into a String. Can be useful if you\nwant to create a string primarly by consing, perhaps for decoding\nsomething.\n\n      fromList ['a','b','c'] == \"abc\"",
+      "raw": "fromList : [Char] -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Char",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "indexes",
+      "comment": "Get all of the indexes for a substring in another string.\n\n      indexes \"i\" \"Mississippi\"   == [1,4,7,10]\n      indexes \"ss\" \"Mississippi\"  == [2,5]\n      indexes \"needle\" \"haystack\" == []",
+      "raw": "indexes : String -\u003e String -\u003e [Int]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "indices",
+      "comment": "Alias for `indexes`",
+      "raw": "indices : String -\u003e String -\u003e [Int]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "isEmpty",
+      "comment": "Check if a string is empty.\n\n      isEmpty \"\" == True\n      isEmpty \"the world\" == False",
+      "raw": "isEmpty : String -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "join",
+      "comment": "Put many strings together with a given separator.\n\n      join \"a\" [\"H\",\"w\",\"ii\",\"n\"]        == \"Hawaiian\"\n      join \" \" [\"cat\",\"dog\",\"cow\"]       == \"cat dog cow\"\n      join \"/\" [\"home\",\"evan\",\"Desktop\"] == \"home/evan/Desktop\"",
+      "raw": "join : String -\u003e [String] -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "String",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "left",
+      "comment": "Take N characters from the left side of a string.",
+      "raw": "left : Int -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "length",
+      "comment": "Get the length of a string.\n\n      length \"innumerable\" == 11\n      length \"\" == 0",
+      "raw": "length : String -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "lines",
+      "comment": "Break a string into lines, splitting on newlines.\n\n      lines \"How are you?\\nGood?\" == [\"How are you?\", \"Good?\"]",
+      "raw": "lines : String -\u003e [String]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "map",
+      "comment": "Transform every character in a string\n\n      map (\\c -\u003e if c == '/' then '.' else c) \"a/b/c\" == \"a.b.c\"",
+      "raw": "map : (Char -\u003e Char) -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Char",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Char",
+              "args": []
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "pad",
+      "comment": "Pad a string on both sides until it has a given length.\n\n      pad 5 ' ' \"1\"   == \"  1  \"\n      pad 5 ' ' \"11\"  == \"  11 \"\n      pad 5 ' ' \"121\" == \" 121 \"",
+      "raw": "pad : Int -\u003e Char -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "padLeft",
+      "comment": "Pad a string on the left until it has a given length.\n\n      padLeft 5 '.' \"1\"   == \"....1\"\n      padLeft 5 '.' \"11\"  == \"...11\"\n      padLeft 5 '.' \"121\" == \"..121\"",
+      "raw": "padLeft : Int -\u003e Char -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "padRight",
+      "comment": "Pad a string on the right until it has a given length.\n\n      padRight 5 '.' \"1\"   == \"1....\"\n      padRight 5 '.' \"11\"  == \"11...\"\n      padRight 5 '.' \"121\" == \"121..\"",
+      "raw": "padRight : Int -\u003e Char -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Char",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "repeat",
+      "comment": "Repeat a string N times.\n\n      repeat 3 \"ha\" == \"hahaha\"",
+      "raw": "repeat : Int -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "reverse",
+      "comment": "Reverse a string.\n\n      reverse \"stressed\" == \"desserts\"",
+      "raw": "reverse : String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "right",
+      "comment": "Take N characters from the right side of a string.",
+      "raw": "right : Int -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "show",
+      "comment": "Turn any kind of value into a string.\n\n      show 42    == \"42\"\n      show [1,2] == \"[1,2]\"",
+      "raw": "show : a -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "slice",
+      "comment": "Take a substring given a start and end index. Negative indexes\nare taken starting from the *end* of the list.\n\n      slice  7  9 \"snakes on a plane!\" == \"on\"\n      slice  0  6 \"snakes on a plane!\" == \"snakes\"\n      slice  0 -7 \"snakes on a plane!\" == \"snakes on a\"\n      slice -6 -1 \"snakes on a plane!\" == \"plane\"",
+      "raw": "slice : Int -\u003e Int -\u003e String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "split",
+      "comment": "Split a string using a given separator.\n\n      split \",\" \"cat,dog,cow\"        == [\"cat\",\"dog\",\"cow\"]\n      split \"/\" \"home/evan/Desktop/\" == [\"home\",\"evan\",\"Desktop\", \"\"]\n\nUse `Regex.split` if you need something more flexible.",
+      "raw": "split : String -\u003e String -\u003e [String]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "startsWith",
+      "comment": "See if the second string starts with the first one.\n\n      startsWith \"the\" \"theory\" == True\n      startsWith \"ory\" \"theory\" == False",
+      "raw": "startsWith : String -\u003e String -\u003e Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Bool",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toFloat",
+      "comment": "Try to convert a string into a float, failing on improperly formatted strings.\n\n      toFloat \"123\" == Just 123.0\n      toFloat \"-42\" == Just -42.0\n      toFloat \"3.1\" == Just 3.1\n      toFloat \"31a\" == Nothing",
+      "raw": "toFloat : String -\u003e Maybe Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Maybe",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "toInt",
+      "comment": "Try to convert a string into an int, failing on improperly formatted strings.\n\n      toInt \"123\" == Just 123\n      toInt \"-42\" == Just -42\n      toInt \"3.1\" == Nothing\n      toInt \"31a\" == Nothing",
+      "raw": "toInt : String -\u003e Maybe Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Maybe",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "toList",
+      "comment": "Convert a string to a list of characters.\n\n      toList \"abc\" == ['a','b','c']",
+      "raw": "toList : String -\u003e [Char]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Char",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "toLower",
+      "comment": "Convert a string to all lower case. Useful for case insensitive comparisons.",
+      "raw": "toLower : String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toUpper",
+      "comment": "Convert a string to all upper case. Useful for case insensitive comparisons\nand VIRTUAL YELLING.",
+      "raw": "toUpper : String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "trim",
+      "comment": "Get rid of whitespace on both sides of a string.\n\n      trim \"  hats  \\n\" == \"hats\"",
+      "raw": "trim : String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "trimLeft",
+      "comment": "Get rid of whitespace on the left of a string.\n\n      trimLeft \"  hats  \\n\" == \"hats  \\n\"",
+      "raw": "trimLeft : String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "trimRight",
+      "comment": "Get rid of whitespace on the right of a string.\n\n      trimRight \"  hats  \\n\" == \"  hats\"",
+      "raw": "trimRight : String -\u003e String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "String",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "uncons",
+      "comment": "Split a non-empty string into its head and tail. This lets you\npattern match on strings exactly as you would with lists.\n\n      uncons \"abc\" == Just ('a',\"bc\")\n      uncons \"\"    == Nothing",
+      "raw": "uncons : String -\u003e Maybe (Char, String)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Maybe",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "_Tuple2",
+              "args": [
+                {
+                  "tag": "adt",
+                  "name": "Char",
+                  "args": []
+                },
+                {
+                  "tag": "adt",
+                  "name": "String",
+                  "args": []
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "words",
+      "comment": "Break a string into words, splitting on chunks of whitespace.\n\n      words \"How are \\t you? \\n Good?\" == [\"How\",\"are\",\"you?\",\"Good?\"]",
+      "raw": "words : String -\u003e [String]",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_List",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ]
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Text",
+  "document": "A library for styling and displaying text. Whlie the `String` library\nfocuses on representing and manipulating strings of character strings, the\n`Text` library focuses on how those strings should look on screen. It lets\nyou make text bold or italic, set the typeface, set the text size, etc.\n\n# Creating Text\n@docs toText\n\n# Creating Elements\n\nEach of the following functions places `Text` into a box. The function you use\ndetermines the alignment of the text.\n\n@docs leftAligned, rightAligned, centered, justified\n\n# Links and Style\n@docs link, Style, style, defaultStyle, Line\n\n# Convenience Functions\n\nThere are two convenience functions for creating an `Element` which can be\nuseful when debugging or prototyping:\n\n@docs plainText, asText\n\nThere are also a bunch of functions to set parts of a `Style` individually:\n\n@docs typeface, monospace, height, color, bold, italic, line",
+  "aliases": [
+    {
+      "name": "Style",
+      "comment": "Representation of all the ways you can style `Text`. If the `typeface` list\nis empty or the `height` is `Nothing`, the users will fall back on their\nbrowser's default settings. The following `Style` is black, 16 pixel tall,\nunderlined, and Times New Roman (assuming that typeface is available on the\nuser's computer):\n\n      { typeface = [ \"Times New Roman\", \"serif\" ]\n      , height   = Just 16\n      , color    = black\n      , bold     = False\n      , italic   = False\n      , line     = Just Under\n      }",
+      "raw": "type Style =\n  { typeface : [String]\n  , height   : Maybe Float\n  , color    : Color\n  , bold     : Bool\n  , italic   : Bool\n  , line     : Maybe Line\n  }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "typeface",
+            {
+              "tag": "adt",
+              "name": "_List",
+              "args": [
+                {
+                  "tag": "adt",
+                  "name": "String",
+                  "args": []
+                }
+              ]
+            }
+          ],
+          [
+            "height",
+            {
+              "tag": "adt",
+              "name": "Maybe",
+              "args": [
+                {
+                  "tag": "adt",
+                  "name": "Float",
+                  "args": []
+                }
+              ]
+            }
+          ],
+          [
+            "color",
+            {
+              "tag": "adt",
+              "name": "Color",
+              "args": []
+            }
+          ],
+          [
+            "bold",
+            {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          ],
+          [
+            "italic",
+            {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          ],
+          [
+            "line",
+            {
+              "tag": "adt",
+              "name": "Maybe",
+              "args": [
+                {
+                  "tag": "adt",
+                  "name": "Line",
+                  "args": []
+                }
+              ]
+            }
+          ]
+        ]
+      }
+    }
+  ],
+  "datatypes": [
+    {
+      "name": "Line",
+      "comment": "Styles for lines on text. This allows you to add an underline, an overline,\nor a strike out text:\n\n      line Under   (toText \"underline\")\n      line Over    (toText \"overline\")\n      line Through (toText \"strike out\")",
+      "raw": "data Line = Under | Over | Through",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Under",
+          "type": {
+            "tag": "adt",
+            "name": "Line",
+            "args": []
+          }
+        },
+        {
+          "name": "Over",
+          "type": {
+            "tag": "adt",
+            "name": "Line",
+            "args": []
+          }
+        },
+        {
+          "name": "Through",
+          "type": {
+            "tag": "adt",
+            "name": "Line",
+            "args": []
+          }
+        }
+      ]
+    },
+    {
+      "name": "Text",
+      "comment": "",
+      "raw": "data Text = Text",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Text",
+          "type": {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "asText",
+      "comment": "Convert anything to its textual representation and make it displayable in\nthe browser:\n\n        asText value = leftAligned (monospace (toText (show value)))\n\nExcellent for debugging.",
+      "raw": "asText : a -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "bold",
+      "comment": "Make text bold:\n\n      toText \"sometimes you want \" ++ bold (toText \"emphasis\")",
+      "raw": "bold : Text -\u003e Text",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Text",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "centered",
+      "comment": "`Text` is centered in the text block. There is equal spacing on either side\nof a line of text.",
+      "raw": "centered : Text -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "color",
+      "comment": "Set the color of some text:\n\n      color red (toText \"Red\")",
+      "raw": "color : Color -\u003e Text -\u003e Text",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Color",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Text",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "defaultStyle",
+      "comment": "Plain black text. It uses the browsers default typeface and text height.\nNo decorations are used:\n\n      { typeface = []\n      , height = Nothing\n      , color = black\n      , bold = False\n      , italic = False\n      , line = Nothing\n      }",
+      "raw": "defaultStyle : Style",
+      "type": {
+        "tag": "adt",
+        "name": "Style",
+        "args": []
+      }
+    },
+    {
+      "name": "height",
+      "comment": "Set the height of some text:\n\n      height 40 (toText \"Title\")",
+      "raw": "height : Float -\u003e Text -\u003e Text",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Text",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "italic",
+      "comment": "Make text italic:\n\n      toText \"make it \" ++ italic (toText \"important\")",
+      "raw": "italic : Text -\u003e Text",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Text",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "justified",
+      "comment": "`Text` is aligned along the left and right sides of the text block. Word\nspacing is adjusted to make this possible.",
+      "raw": "justified : Text -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "leftAligned",
+      "comment": "`Text` is aligned along the left side of the text block. This is sometimes\nknown as *ragged right*.",
+      "raw": "leftAligned : Text -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "line",
+      "comment": "Put lines on text:\n\n      line Under   (toText \"underlined\")\n      line Over    (toText \"overlined\")\n      line Through (toText \"strike out\")",
+      "raw": "line : Line -\u003e Text -\u003e Text",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Line",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Text",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "link",
+      "comment": "Create a link by providing a URL and the text of the link:\n\n      link \"http://elm-lang.org\" (toText \"Elm Website\")",
+      "raw": "link : String -\u003e Text -\u003e Text",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Text",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "markdown",
+      "comment": "for internal use only",
+      "raw": "markdown : Element",
+      "type": {
+        "tag": "adt",
+        "name": "Element",
+        "args": []
+      }
+    },
+    {
+      "name": "monospace",
+      "comment": "Switch to a monospace typeface. Good for code snippets.\n\n      monospace (toText \"foldl (+) 0 [1,2,3]\")",
+      "raw": "monospace : Text -\u003e Text",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Text",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "plainText",
+      "comment": "Display a string with no styling:\n\n      plainText string = leftAligned (toText string)",
+      "raw": "plainText : String -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "rightAligned",
+      "comment": "`Text` is aligned along the right side of the text block. This is sometimes\nknown as *ragged left*.",
+      "raw": "rightAligned : Text -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "style",
+      "comment": "Set the style of some text. For example, if you design a `Style` called\n`footerStyle` that is specifically for the bottom of your page, you could apply\nit to text like this:\n\n      style footerStyle (toText \"the old prince / 2007\")",
+      "raw": "style : Style -\u003e Text -\u003e Text",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Style",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Text",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toText",
+      "comment": "Convert a string into text which can be styled and displayed. To show the\nstring `\"Hello World!\"` on screen in italics, you could say:\n\n      main = leftAligned (italic (toText \"Hello World!\"))",
+      "raw": "toText : String -\u003e Text",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Text",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "typeface",
+      "comment": "Provide a list of prefered typefaces for some text.\n\n      [\"helvetica\",\"arial\",\"sans-serif\"]\n\nNot every browser has access to the same typefaces, so rendering will use the\nfirst typeface in the list that is found on the user's computer. If there are\nno matches, it will use their default typeface. This works the same as the CSS\nfont-family property.",
+      "raw": "typeface : [String] -\u003e Text -\u003e Text",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "String",
+                "args": []
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Text",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Text",
+          "args": []
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Time",
+  "document": "Library for working with time.\n\n# Units\n@docs Time, millisecond, second, minute, hour,\n      inMilliseconds, inSeconds, inMinutes, inHours\n\n# Tickers\n@docs fps, fpsWhen, every\n\n# Timing\n@docs timestamp, delay, since",
+  "aliases": [
+    {
+      "name": "Time",
+      "comment": "Type alias to make it clearer when you are working with time values.\nUsing the `Time` constants instead of raw numbers is very highly recommended.",
+      "raw": "type Time = Float",
+      "typeVariables": [],
+      "type": {
+        "tag": "adt",
+        "name": "Float",
+        "args": []
+      }
+    }
+  ],
+  "datatypes": [],
+  "values": [
+    {
+      "name": "delay",
+      "comment": "Delay a signal by a certain amount of time. So `(delay second Mouse.clicks)`\nwill update one second later than any mouse click.",
+      "raw": "delay : Time -\u003e Signal a -\u003e Signal a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Time",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "every",
+      "comment": "Takes a time interval t. The resulting signal is the current time, updated\nevery t.",
+      "raw": "every : Time -\u003e Signal Time",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Time",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Time",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "fps",
+      "comment": "Takes desired number of frames per second (fps). The resulting signal\ngives a sequence of time deltas as quickly as possible until it reaches\nthe desired FPS. A time delta is the time between the last frame and the\ncurrent frame.",
+      "raw": "fps : number -\u003e Signal Time",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "number"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Time",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "fpsWhen",
+      "comment": "Same as the fps function, but you can turn it on and off. Allows you\nto do brief animations based on user input without major inefficiencies.\nThe first time delta after a pause is always zero, no matter how long\nthe pause was. This way summing the deltas will actually give the amount\nof time that the output signal has been running.",
+      "raw": "fpsWhen : number -\u003e Signal Bool -\u003e Signal Time",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "number"
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Bool",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Time",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "hour",
+      "comment": "",
+      "raw": "hour : Time",
+      "type": {
+        "tag": "adt",
+        "name": "Time",
+        "args": []
+      }
+    },
+    {
+      "name": "inHours",
+      "comment": "",
+      "raw": "inHours : Time -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Time",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "inMilliseconds",
+      "comment": "",
+      "raw": "inMilliseconds : Time -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Time",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "inMinutes",
+      "comment": "",
+      "raw": "inMinutes : Time -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Time",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "inSeconds",
+      "comment": "",
+      "raw": "inSeconds : Time -\u003e Float",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Time",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Float",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "millisecond",
+      "comment": "Units of time, making it easier to specify things like a half-second\n`(500 * milliseconds)` without remembering Elm&rsquo;s underlying units of time.",
+      "raw": "millisecond : Time",
+      "type": {
+        "tag": "adt",
+        "name": "Time",
+        "args": []
+      }
+    },
+    {
+      "name": "minute",
+      "comment": "",
+      "raw": "minute : Time",
+      "type": {
+        "tag": "adt",
+        "name": "Time",
+        "args": []
+      }
+    },
+    {
+      "name": "second",
+      "comment": "",
+      "raw": "second : Time",
+      "type": {
+        "tag": "adt",
+        "name": "Time",
+        "args": []
+      }
+    },
+    {
+      "name": "since",
+      "comment": "Takes a time `t` and any signal. The resulting boolean signal is true for\ntime `t` after every event on the input signal. So ``(second `since`\nMouse.clicks)`` would result in a signal that is true for one second after\neach mouse click and false otherwise.",
+      "raw": "since : Time -\u003e Signal a -\u003e Signal Bool",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Time",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Bool",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "timestamp",
+      "comment": "Add a timestamp to any signal. Timestamps increase monotonically. When you\ncreate `(timestamp Mouse.x)`, an initial timestamp is produced. The timestamp\nupdates whenever `Mouse.x` updates.\n\nTimestamp updates are tied to individual events, so\n`(timestamp Mouse.x)` and `(timestamp Mouse.y)` will always have the same\ntimestamp because they rely on the same underlying event (`Mouse.position`).",
+      "raw": "timestamp : Signal a -\u003e Signal (Time, a)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "_Tuple2",
+              "args": [
+                {
+                  "tag": "adt",
+                  "name": "Time",
+                  "args": []
+                },
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Touch",
+  "document": "This is an early version of the touch library. It will likely grow to\ninclude gestures that would be useful for both games and web-pages.\n\n# Touches\n@docs Touch, touches\n\n# Gestures\n@docs taps",
+  "aliases": [
+    {
+      "name": "Touch",
+      "comment": "Every `Touch` has `xy` coordinates. It also has an identifier\n`id` to distinguish one touch from another.\n\nA touch also keeps info about the initial point and time of contact:\n`x0`, `y0`, and `t0`. This helps compute more complicated gestures\nlike taps, drags, and swipes which need to know about timing or direction.",
+      "raw": "type Touch = { x:Int, y:Int, id:Int, x0:Int, y0:Int, t0:Time }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "x",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "y",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "id",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "x0",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "y0",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "t0",
+            {
+              "tag": "adt",
+              "name": "Time",
+              "args": []
+            }
+          ]
+        ]
+      }
+    }
+  ],
+  "datatypes": [],
+  "values": [
+    {
+      "name": "taps",
+      "comment": "The last position that was tapped. Default value is `{x=0,y=0}`.\nUpdates whenever the user taps the screen.",
+      "raw": "taps : Signal { x:Int, y:Int }",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "record",
+            "extension": null,
+            "fields": [
+              [
+                "x",
+                {
+                  "tag": "adt",
+                  "name": "Int",
+                  "args": []
+                }
+              ],
+              [
+                "y",
+                {
+                  "tag": "adt",
+                  "name": "Int",
+                  "args": []
+                }
+              ]
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "name": "touches",
+      "comment": "A list of ongoing touches.",
+      "raw": "touches : Signal [Touch]",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Touch",
+                "args": []
+              }
+            ]
+          }
+        ]
+      }
+    }
+  ]
+},
+{
+  "name": "Trampoline",
+  "document": "A [trampoline](http://en.wikipedia.org/wiki/Tail-recursive_function#Through_trampolining)\nmakes it possible to recursively call a function without growing the stack.\n\nPopular JavaScript implementations do not perform any tail-call elimination, so\nrecursive functions can cause a stack overflow if they go to deep. Trampolines\npermit unbounded recursion despite limitations in JavaScript.\n\nThis strategy may create many intermediate closures, which is very expensive in\nJavaScript, so use this library only when it is essential that you recurse deeply.\n\n# Trampolines\n@docs trampoline, Trampoline",
+  "aliases": [],
+  "datatypes": [
+    {
+      "name": "Trampoline",
+      "comment": "A way to build computations that may be deeply recursive. We will take an\nexample of a tail-recursive function and rewrite it in a way that lets us use\na trampoline:\n\n      length : [a] -\u003e Int\n      length list = length' 0 list\n\n      length' : Int -\u003e [a] -\u003e Int\n      length' accum list =\n          case list of\n            []     -\u003e accum\n            hd::tl -\u003e length' (accum+1) tl\n\nThis finds the length of a list, but if the list is too long, it may cause a\nstack overflow. We can rewrite it as follows:\n\n      length : [a] -\u003e Int\n      length list = trampoline (length' 0 list)\n\n      length' : Int -\u003e [a] -\u003e Trampoline Int\n      length' accum list =\n          case list of\n            []     -\u003e Done accum\n            hd::tl -\u003e Continue (\\() -\u003e length' (accum+1) tl)\n\nNow it uses a trampoline and can recurse without growing the stack!",
+      "raw": "data Trampoline a = Done a | Continue (() -\u003e Trampoline a)",
+      "typeVariables": [
+        "a"
+      ],
+      "constructors": [
+        {
+          "name": "Done",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Trampoline",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            }
+          }
+        },
+        {
+          "name": "Continue",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "function",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "_Tuple0",
+                    "args": []
+                  }
+                ],
+                "result": {
+                  "tag": "adt",
+                  "name": "Trampoline",
+                  "args": [
+                    {
+                      "tag": "var",
+                      "name": "a"
+                    }
+                  ]
+                }
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Trampoline",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            }
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "trampoline",
+      "comment": "Evaluate a trampolined value in constant space.",
+      "raw": "trampoline : Trampoline a -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Trampoline",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Transform2D",
+  "document": "A library for performing [2D matrix transformations][affine].\nIt is used primarily with the `groupTransform` function from `Graphics.Collage` and\nallows you to do things like rotation, scaling, translation, shearing, and reflection.\n\nNote that all the matrices in this library are 3x3 matrices of homogeneous\ncoordinates, used for [affine transformations][affine]. Since the bottom row as\nalways `0 0 1` in these matrices, it is omitted in the diagrams below.\n\n [affine]: http://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations\n\n# Transforms\n@docs identity, matrix, rotation, translation, scale, scaleX, scaleY\n\n# Multiplication\n@docs multiply",
+  "aliases": [],
+  "datatypes": [
+    {
+      "name": "Transform2D",
+      "comment": "",
+      "raw": "data Transform2D = Transform2D",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Transform2D",
+          "type": {
+            "tag": "adt",
+            "name": "Transform2D",
+            "args": []
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "identity",
+      "comment": "Create an identity transform. Transforming by the identity does\nnot change anything, but it can come in handy as a default or\nbase case.\n\n          / 1 0 0 \\\n          \\ 0 1 0 /",
+      "raw": "identity : Transform2D",
+      "type": {
+        "tag": "adt",
+        "name": "Transform2D",
+        "args": []
+      }
+    },
+    {
+      "name": "matrix",
+      "comment": "Creates a transformation matrix. This lets you create transforms\nsuch as scales, shears, reflections, and translations.\n\n      matrix a b c d x y\n\n          / a b x \\\n          \\ c d y /\n\nNote that `x` and `y` are the translation values.",
+      "raw": "matrix : Float -\u003e Float -\u003e Float -\u003e Float -\u003e Float -\u003e Float -\u003e Transform2D",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Transform2D",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "multiply",
+      "comment": "Multiplies two transforms together:\n\n      multiply m n\n\n          / ma mb mx \\     / na nb nx \\\n          | mc md my |  .  | nc nd ny |\n          \\  0  0  1 /     \\  0  0  1 /",
+      "raw": "multiply : Transform2D -\u003e Transform2D -\u003e Transform2D",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Transform2D",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Transform2D",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Transform2D",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "rotation",
+      "comment": "Creates a [rotation matrix](http://en.wikipedia.org/wiki/Rotation_matrix).\nGiven an angle t, it creates a counterclockwise rotation matrix:\n\n          / cos t  -sin t  0 \\\n          \\ sin t   cos t  0 /",
+      "raw": "rotation : Float -\u003e Transform2D",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Transform2D",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "scale",
+      "comment": "Creates a transformation matrix for scaling by a all directions:\n\n    scale s\n\n        / s 0 0 \\\n        \\ 0 s 0 /",
+      "raw": "scale : Float -\u003e Transform2D",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Transform2D",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "scaleX",
+      "comment": "Creates a transformation for horizontal scaling",
+      "raw": "scaleX : Float -\u003e Transform2D",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Transform2D",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "scaleY",
+      "comment": "Creates a transformation for vertical scaling",
+      "raw": "scaleY : Float -\u003e Transform2D",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Transform2D",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "translation",
+      "comment": "Creates a transformation matrix for translation:\n\n    translation x y\n\n          / 1 0 x \\\n          \\ 0 1 y /",
+      "raw": "translation : Float -\u003e Float -\u003e Transform2D",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Transform2D",
+          "args": []
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "WebSocket",
+  "document": "A library for low latency HTTP communication. See the HTTP library for\nstandard requests like GET, POST, etc. The API of this library is likely to\nchange to make it more flexible.\n\n# Open a Connection\n@docs connect",
+  "aliases": [],
+  "datatypes": [],
+  "values": [
+    {
+      "name": "connect",
+      "comment": "Create a web-socket. The first argument is the URL of the desired\nweb-socket server. The input signal holds the outgoing messages,\nand the resulting signal contains the incoming ones.",
+      "raw": "connect : String -\u003e Signal String -\u003e Signal String",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Signal",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "String",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Signal",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ]
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Window",
+  "document": "Provides information about the container that your Elm program lives in.\nWhen you embed Elm in a `\u003cdiv\u003e` it gives the dimensions of the container, not\nthe whole window.\n\n# Dimensions\n@docs dimensions, width, height",
+  "aliases": [],
+  "datatypes": [],
+  "values": [
+    {
+      "name": "dimensions",
+      "comment": "The current width and height of the window (i.e. the area viewable to the\nuser, not including scroll bars).",
+      "raw": "dimensions : Signal (Int,Int)",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "name": "height",
+      "comment": "The current height of the window.",
+      "raw": "height : Signal Int",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ]
+      }
+    },
+    {
+      "name": "width",
+      "comment": "The current width of the window.",
+      "raw": "width : Signal Int",
+      "type": {
+        "tag": "adt",
+        "name": "Signal",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ]
+      }
+    }
+  ]
+},
+{
+  "name": "Graphics.Collage",
+  "document": "The collage API is for freeform graphics. You can move, rotate, scale, etc.\nall sorts of forms including lines, shapes, images, and elements.\n\n# Unstructured Graphics\n@docs collage\n \n# Creating Forms\n@docs toForm, filled, textured, gradient, outlined, traced\n \n# Transforming Forms\n@docs move, moveX, moveY, scale, rotate, alpha\n \n# Grouping Forms\nGrouping forms makes it easier to write modular graphics code. You can create\na form that is a composite of many subforms. From there it is easy to transform\nit as a single unit.\n\n@docs group, groupTransform\n \n# Shapes\n@docs rect, oval, square, circle, ngon, polygon\n\n# Paths\n@docs segment, path\n \n# Line Styles\n@docs solid, dashed, dotted, LineStyle, LineCap, LineJoin, defaultLine",
+  "aliases": [
+    {
+      "name": "Form",
+      "comment": "",
+      "raw": "type Form = {\n  theta : Float,\n  scale : Float,\n  x : Float,\n  y : Float,\n  alpha : Float,\n  form : BasicForm\n }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "theta",
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            }
+          ],
+          [
+            "scale",
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            }
+          ],
+          [
+            "x",
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            }
+          ],
+          [
+            "y",
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            }
+          ],
+          [
+            "alpha",
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            }
+          ],
+          [
+            "form",
+            {
+              "tag": "adt",
+              "name": "BasicForm",
+              "args": []
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "name": "LineStyle",
+      "comment": "All of the attributes of a line style. This lets you build up a line style\nhowever you want. You can also update existing line styles with record updates.",
+      "raw": "type LineStyle = {\n  color : Color,\n  width : Float,\n  cap   : LineCap,\n  join  : LineJoin,\n  dashing    : [Int],\n  dashOffset : Int\n }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "color",
+            {
+              "tag": "adt",
+              "name": "Color",
+              "args": []
+            }
+          ],
+          [
+            "width",
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            }
+          ],
+          [
+            "cap",
+            {
+              "tag": "adt",
+              "name": "LineCap",
+              "args": []
+            }
+          ],
+          [
+            "join",
+            {
+              "tag": "adt",
+              "name": "LineJoin",
+              "args": []
+            }
+          ],
+          [
+            "dashing",
+            {
+              "tag": "adt",
+              "name": "_List",
+              "args": [
+                {
+                  "tag": "adt",
+                  "name": "Int",
+                  "args": []
+                }
+              ]
+            }
+          ],
+          [
+            "dashOffset",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "name": "Path",
+      "comment": "",
+      "raw": "type Path = [(Float,Float)]",
+      "typeVariables": [],
+      "type": {
+        "tag": "adt",
+        "name": "_List",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "name": "Shape",
+      "comment": "",
+      "raw": "type Shape = [(Float,Float)]",
+      "typeVariables": [],
+      "type": {
+        "tag": "adt",
+        "name": "_List",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ]
+          }
+        ]
+      }
+    }
+  ],
+  "datatypes": [
+    {
+      "name": "BasicForm",
+      "comment": "",
+      "raw": "data BasicForm\n  = FPath LineStyle Path\n  | FShape (Either LineStyle FillStyle) Shape\n  | FImage Int Int (Int,Int) String\n  | FElement Element\n  | FGroup Transform2D [Form]",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "FPath",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "LineStyle",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Path",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "BasicForm",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "FShape",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Either",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "LineStyle",
+                    "args": []
+                  },
+                  {
+                    "tag": "adt",
+                    "name": "FillStyle",
+                    "args": []
+                  }
+                ]
+              },
+              {
+                "tag": "adt",
+                "name": "Shape",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "BasicForm",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "FImage",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "Int",
+                    "args": []
+                  },
+                  {
+                    "tag": "adt",
+                    "name": "Int",
+                    "args": []
+                  }
+                ]
+              },
+              {
+                "tag": "adt",
+                "name": "String",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "BasicForm",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "FElement",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Element",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "BasicForm",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "FGroup",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Transform2D",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "_List",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "Form",
+                    "args": []
+                  }
+                ]
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "BasicForm",
+              "args": []
+            }
+          }
+        }
+      ]
+    },
+    {
+      "name": "FillStyle",
+      "comment": "",
+      "raw": "data FillStyle\n  = Solid Color\n  | Texture String\n  | Grad Gradient",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Solid",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Color",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "FillStyle",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "Texture",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "String",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "FillStyle",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "Grad",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Gradient",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "FillStyle",
+              "args": []
+            }
+          }
+        }
+      ]
+    },
+    {
+      "name": "LineCap",
+      "comment": "The shape of the ends of a line.",
+      "raw": "data LineCap = Flat | Round | Padded",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Flat",
+          "type": {
+            "tag": "adt",
+            "name": "LineCap",
+            "args": []
+          }
+        },
+        {
+          "name": "Round",
+          "type": {
+            "tag": "adt",
+            "name": "LineCap",
+            "args": []
+          }
+        },
+        {
+          "name": "Padded",
+          "type": {
+            "tag": "adt",
+            "name": "LineCap",
+            "args": []
+          }
+        }
+      ]
+    },
+    {
+      "name": "LineJoin",
+      "comment": "The shape of the &ldquo;joints&rdquo; of a line, where each line segment\nmeets. `Sharp` takes an argument to limit the length of the joint. This\ndefaults to 10.",
+      "raw": "data LineJoin = Smooth | Sharp Float | Clipped",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Smooth",
+          "type": {
+            "tag": "adt",
+            "name": "LineJoin",
+            "args": []
+          }
+        },
+        {
+          "name": "Sharp",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "LineJoin",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "Clipped",
+          "type": {
+            "tag": "adt",
+            "name": "LineJoin",
+            "args": []
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "alpha",
+      "comment": "Set the alpha of a `Form`. The default is 1, and 0 is totally transparent.",
+      "raw": "alpha : Float -\u003e Form -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Form",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "circle",
+      "comment": "A circle with a given radius.",
+      "raw": "circle : Float -\u003e Shape",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Shape",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "collage",
+      "comment": "A collage is a collection of 2D forms. There are no strict positioning\nrelationships between forms, so you are free to do all kinds of 2D graphics.",
+      "raw": "collage : Int -\u003e Int -\u003e [Form] -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Form",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "dashed",
+      "comment": "Create a dashed line style with a given color. Dashing equals `[8,4]`.",
+      "raw": "dashed : Color -\u003e LineStyle",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Color",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "LineStyle",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "defaultLine",
+      "comment": "The default line style, which is solid black with flat caps and sharp joints.\nYou can use record updates to build the line style you\nwant. For example, to make a thicker line, you could say:\n\n        { defaultLine | width \u003c- 10 }",
+      "raw": "defaultLine : LineStyle",
+      "type": {
+        "tag": "adt",
+        "name": "LineStyle",
+        "args": []
+      }
+    },
+    {
+      "name": "dotted",
+      "comment": "Create a dotted line style with a given color. Dashing equals `[3,3]`.",
+      "raw": "dotted : Color -\u003e LineStyle",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Color",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "LineStyle",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "filled",
+      "comment": "Create a filled in shape.",
+      "raw": "filled : Color -\u003e Shape -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Color",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Shape",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "form",
+      "comment": "",
+      "raw": "form : BasicForm -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "BasicForm",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "gradient",
+      "comment": "Fill a shape with a [gradient](/library/Color.elm#linear).",
+      "raw": "gradient : Gradient -\u003e Shape -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Gradient",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Shape",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "group",
+      "comment": "Flatten many forms into a single `Form`. This lets you move and rotate them\nas a single unit, making it possible to build small, modular components.",
+      "raw": "group : [Form] -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Form",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "groupTransform",
+      "comment": "Flatten many forms into a single `Form` and then apply a matrix\ntransformation.",
+      "raw": "groupTransform : Transform2D -\u003e [Form] -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Transform2D",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Form",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "move",
+      "comment": "Move a form by the given amount. This is a relative translation so\n`(move (10,10) form)` would move `form` ten pixels up and ten pixels to the\nright.",
+      "raw": "move : (Float,Float) -\u003e Form -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Form",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "moveX",
+      "comment": "Move a shape in the x direction. This is relative so `(moveX 10 form)` moves\n`form` 10 pixels to the right.",
+      "raw": "moveX : Float -\u003e Form -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Form",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "moveY",
+      "comment": "Move a shape in the y direction. This is relative so `(moveY 10 form)` moves\n`form` upwards by 10 pixels.",
+      "raw": "moveY : Float -\u003e Form -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Form",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "ngon",
+      "comment": "A regular polygon with N sides. The first argument specifies the number\nof sides and the second is the radius. So to create a pentagon with radius\n30 you would say:\n\n        ngon 5 30",
+      "raw": "ngon : Int -\u003e Float -\u003e Shape",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Shape",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "outlined",
+      "comment": "Outline a shape with a given line style.",
+      "raw": "outlined : LineStyle -\u003e Shape -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "LineStyle",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Shape",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "oval",
+      "comment": "An oval with a given width and height.",
+      "raw": "oval : Float -\u003e Float -\u003e Shape",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Shape",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "path",
+      "comment": "Create a path that follows a sequence of points.",
+      "raw": "path : [(Float,Float)] -\u003e Path",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  },
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Path",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "polygon",
+      "comment": "Create an arbitrary polygon by specifying its corners in order.\n`polygon` will automatically close all shapes, so the given list\nof points does not need to start and end with the same position.",
+      "raw": "polygon : [(Float,Float)] -\u003e Shape",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  },
+                  {
+                    "tag": "adt",
+                    "name": "Float",
+                    "args": []
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Shape",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "rect",
+      "comment": "A rectangle with a given width and height.",
+      "raw": "rect : Float -\u003e Float -\u003e Shape",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Shape",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "rotate",
+      "comment": "Rotate a form by a given angle. Rotate takes standard Elm angles (radians)\nand turns things counterclockwise. So to turn `form` 30&deg; to the left\nyou would say, `(rotate (degrees 30) form)`.",
+      "raw": "rotate : Float -\u003e Form -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Form",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "scale",
+      "comment": "Scale a form by a given factor. Scaling by 2 doubles the size.",
+      "raw": "scale : Float -\u003e Form -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Form",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "segment",
+      "comment": "Create a path along a given line segment.",
+      "raw": "segment : (Float,Float) -\u003e (Float,Float) -\u003e Path",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Path",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "solid",
+      "comment": "Create a solid line style with a given color.",
+      "raw": "solid : Color -\u003e LineStyle",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Color",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "LineStyle",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "sprite",
+      "comment": "Create a sprite from a sprite sheet. It cuts out a rectangle\nat a given position.",
+      "raw": "sprite : Int -\u003e Int -\u003e (Int,Int) -\u003e String -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "square",
+      "comment": "A square with a given edge length.",
+      "raw": "square : Float -\u003e Shape",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Shape",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "textured",
+      "comment": "Create a textured shape. The texture is described by some url and is\ntiled to fill the entire shape.",
+      "raw": "textured : String -\u003e Shape -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Shape",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toForm",
+      "comment": "Turn any `Element` into a `Form`. This lets you use text, gifs, and video\nin your collage. This means you can move, rotate, and scale\nan `Element` however you want.",
+      "raw": "toForm : Element -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "traced",
+      "comment": "Trace a path with a given line style.",
+      "raw": "traced : LineStyle -\u003e Path -\u003e Form",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "LineStyle",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Path",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Form",
+          "args": []
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Graphics.Element",
+  "document": "Graphical elements that snap together to build complex widgets and layouts.\nEach Element is a rectangle with a known width and height, making them easy to\ncombine and position.\n\n# Images\n@docs image, fittedImage, croppedImage, tiledImage\n\n# Styling\n@docs width, height, size, color, opacity, link, tag\n\n# Inspection\n@docs widthOf, heightOf, sizeOf\n\n# Layout\n@docs flow, up, down, left, right, inward, outward\n\n## Layout Aliases\nThere are also some convenience functions for working\nwith `flow` in specific cases:\n\n@docs layers, above, below, beside\n\n# Positioning\n@docs empty, spacer, container\n\n## Specific Positions\n\nTo create a `Position` you can use any of the built-in positions\nwhich cover nine common positions.\n@docs middle, midTop, midBottom, midLeft, midRight, topLeft, topRight,\n      bottomLeft, bottomRight\n\nIf you need more precision, you can create custom positions.\n\n@docs absolute, relative, middleAt, midTopAt, midBottomAt, midLeftAt,\n      midRightAt, topLeftAt, topRightAt, bottomLeftAt, bottomRightAt",
+  "aliases": [
+    {
+      "name": "Element",
+      "comment": "",
+      "raw": "type Element = { props : Properties, element : ElementPrim }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "props",
+            {
+              "tag": "adt",
+              "name": "Properties",
+              "args": []
+            }
+          ],
+          [
+            "element",
+            {
+              "tag": "adt",
+              "name": "ElementPrim",
+              "args": []
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "name": "Position",
+      "comment": "",
+      "raw": "type Position = { horizontal : Three, vertical : Three, x : Pos, y : Pos }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "horizontal",
+            {
+              "tag": "adt",
+              "name": "Three",
+              "args": []
+            }
+          ],
+          [
+            "vertical",
+            {
+              "tag": "adt",
+              "name": "Three",
+              "args": []
+            }
+          ],
+          [
+            "x",
+            {
+              "tag": "adt",
+              "name": "Pos",
+              "args": []
+            }
+          ],
+          [
+            "y",
+            {
+              "tag": "adt",
+              "name": "Pos",
+              "args": []
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "name": "Properties",
+      "comment": "",
+      "raw": "type Properties = {\n  id      : Int,\n  width   : Int,\n  height  : Int,\n  opacity : Float,\n  color   : Maybe Color,\n  href    : String,\n  tag     : String,\n  hover   : (),\n  click   : ()\n }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "id",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "width",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "height",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "opacity",
+            {
+              "tag": "adt",
+              "name": "Float",
+              "args": []
+            }
+          ],
+          [
+            "color",
+            {
+              "tag": "adt",
+              "name": "Maybe",
+              "args": [
+                {
+                  "tag": "adt",
+                  "name": "Color",
+                  "args": []
+                }
+              ]
+            }
+          ],
+          [
+            "href",
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ],
+          [
+            "tag",
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ],
+          [
+            "hover",
+            {
+              "tag": "adt",
+              "name": "_Tuple0",
+              "args": []
+            }
+          ],
+          [
+            "click",
+            {
+              "tag": "adt",
+              "name": "_Tuple0",
+              "args": []
+            }
+          ]
+        ]
+      }
+    }
+  ],
+  "datatypes": [
+    {
+      "name": "Direction",
+      "comment": "",
+      "raw": "data Direction = DUp | DDown | DLeft | DRight | DIn | DOut",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "DUp",
+          "type": {
+            "tag": "adt",
+            "name": "Direction",
+            "args": []
+          }
+        },
+        {
+          "name": "DDown",
+          "type": {
+            "tag": "adt",
+            "name": "Direction",
+            "args": []
+          }
+        },
+        {
+          "name": "DLeft",
+          "type": {
+            "tag": "adt",
+            "name": "Direction",
+            "args": []
+          }
+        },
+        {
+          "name": "DRight",
+          "type": {
+            "tag": "adt",
+            "name": "Direction",
+            "args": []
+          }
+        },
+        {
+          "name": "DIn",
+          "type": {
+            "tag": "adt",
+            "name": "Direction",
+            "args": []
+          }
+        },
+        {
+          "name": "DOut",
+          "type": {
+            "tag": "adt",
+            "name": "Direction",
+            "args": []
+          }
+        }
+      ]
+    },
+    {
+      "name": "ElementPrim",
+      "comment": "",
+      "raw": "data ElementPrim\n  = Image ImageStyle Int Int String\n  | Container Position Element\n  | Flow Direction [Element]\n  | Spacer\n  | RawHtml\n  | Custom",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Image",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "ImageStyle",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "String",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "ElementPrim",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "Container",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Position",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Element",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "ElementPrim",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "Flow",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Direction",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "_List",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "Element",
+                    "args": []
+                  }
+                ]
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "ElementPrim",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "Spacer",
+          "type": {
+            "tag": "adt",
+            "name": "ElementPrim",
+            "args": []
+          }
+        },
+        {
+          "name": "RawHtml",
+          "type": {
+            "tag": "adt",
+            "name": "ElementPrim",
+            "args": []
+          }
+        },
+        {
+          "name": "Custom",
+          "type": {
+            "tag": "adt",
+            "name": "ElementPrim",
+            "args": []
+          }
+        }
+      ]
+    },
+    {
+      "name": "ImageStyle",
+      "comment": "",
+      "raw": "data ImageStyle = Plain | Fitted | Cropped (Int,Int) | Tiled",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Plain",
+          "type": {
+            "tag": "adt",
+            "name": "ImageStyle",
+            "args": []
+          }
+        },
+        {
+          "name": "Fitted",
+          "type": {
+            "tag": "adt",
+            "name": "ImageStyle",
+            "args": []
+          }
+        },
+        {
+          "name": "Cropped",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "Int",
+                    "args": []
+                  },
+                  {
+                    "tag": "adt",
+                    "name": "Int",
+                    "args": []
+                  }
+                ]
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "ImageStyle",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "Tiled",
+          "type": {
+            "tag": "adt",
+            "name": "ImageStyle",
+            "args": []
+          }
+        }
+      ]
+    },
+    {
+      "name": "Pos",
+      "comment": "",
+      "raw": "data Pos = Absolute Int | Relative Float",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Absolute",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Pos",
+              "args": []
+            }
+          }
+        },
+        {
+          "name": "Relative",
+          "type": {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Float",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "adt",
+              "name": "Pos",
+              "args": []
+            }
+          }
+        }
+      ]
+    },
+    {
+      "name": "Three",
+      "comment": "",
+      "raw": "data Three = P | Z | N",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "P",
+          "type": {
+            "tag": "adt",
+            "name": "Three",
+            "args": []
+          }
+        },
+        {
+          "name": "Z",
+          "type": {
+            "tag": "adt",
+            "name": "Three",
+            "args": []
+          }
+        },
+        {
+          "name": "N",
+          "type": {
+            "tag": "adt",
+            "name": "Three",
+            "args": []
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "above",
+      "comment": "Stack elements vertically.\nTo put `a` above `b` you would say: ``a `above` b``",
+      "raw": "above : Element -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "absolute",
+      "comment": "",
+      "raw": "absolute : Int -\u003e Pos",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Pos",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "below",
+      "comment": "Stack elements vertically.\nTo put `a` below `b` you would say: ``a `below` b``",
+      "raw": "below : Element -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "beside",
+      "comment": "Put elements beside each other horizontally.\nTo put `a` beside `b` you would say: ``a `beside` b``",
+      "raw": "beside : Element -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "bottomLeft",
+      "comment": "",
+      "raw": "bottomLeft  : Position",
+      "type": {
+        "tag": "adt",
+        "name": "Position",
+        "args": []
+      }
+    },
+    {
+      "name": "bottomLeftAt",
+      "comment": "",
+      "raw": "bottomLeftAt      : Pos -\u003e Pos -\u003e Position",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Position",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "bottomRight",
+      "comment": "",
+      "raw": "bottomRight : Position",
+      "type": {
+        "tag": "adt",
+        "name": "Position",
+        "args": []
+      }
+    },
+    {
+      "name": "bottomRightAt",
+      "comment": "",
+      "raw": "bottomRightAt     : Pos -\u003e Pos -\u003e Position",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Position",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "color",
+      "comment": "Create an `Element` with a given background color.",
+      "raw": "color : Color -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Color",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "container",
+      "comment": "Put an element in a container. This lets you position the element really\neasily, and there are tons of ways to set the `Position`.\nTo center `element` exactly in a 300-by-300 square you would say:\n\n        container 300 300 middle element\n\nBy setting the color of the container, you can create borders.",
+      "raw": "container : Int -\u003e Int -\u003e Position -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Position",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "croppedImage",
+      "comment": "Create a cropped image. Take a rectangle out of the picture starting\nat the given top left coordinate. If you have a 140-by-140 image,\nthe following will cut a 100-by-100 square out of the middle of it.\n\n        croppedImage (20,20) 100 100 \"yogi.jpg\"",
+      "raw": "croppedImage : (Int,Int) -\u003e Int -\u003e Int -\u003e String -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_Tuple2",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              },
+              {
+                "tag": "adt",
+                "name": "Int",
+                "args": []
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "down",
+      "comment": "",
+      "raw": "down : Direction",
+      "type": {
+        "tag": "adt",
+        "name": "Direction",
+        "args": []
+      }
+    },
+    {
+      "name": "empty",
+      "comment": "An Element that takes up no space. Good for things that appear conditionally:\n\n    flow down [ img1, if showMore then img2 else empty ]",
+      "raw": "empty : Element",
+      "type": {
+        "tag": "adt",
+        "name": "Element",
+        "args": []
+      }
+    },
+    {
+      "name": "fittedImage",
+      "comment": "Create a fitted image given a width, height, and image source.\nThis will crop the picture to best fill the given dimensions.",
+      "raw": "fittedImage : Int -\u003e Int -\u003e String -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "flow",
+      "comment": "Have a list of elements flow in a particular direction.\nThe `Direction` starts from the first element in the list.\n\n        flow right [a,b,c]\n\n          +---+---+---+\n          | a | b | c |\n          +---+---+---+",
+      "raw": "flow : Direction -\u003e [Element] -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Direction",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Element",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "height",
+      "comment": "Create an `Element` with a given height.",
+      "raw": "height : Int -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "heightOf",
+      "comment": "Get the height of an Element",
+      "raw": "heightOf : Element -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "image",
+      "comment": "Create an image given a width, height, and image source.",
+      "raw": "image : Int -\u003e Int -\u003e String -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "inward",
+      "comment": "",
+      "raw": "inward : Direction",
+      "type": {
+        "tag": "adt",
+        "name": "Direction",
+        "args": []
+      }
+    },
+    {
+      "name": "layers",
+      "comment": "Layer elements on top of each other, starting from the bottom:\n`layers == flow outward`",
+      "raw": "layers : [Element] -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Element",
+                "args": []
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "left",
+      "comment": "",
+      "raw": "left : Direction",
+      "type": {
+        "tag": "adt",
+        "name": "Direction",
+        "args": []
+      }
+    },
+    {
+      "name": "link",
+      "comment": "Create an `Element` that is a hyper-link.",
+      "raw": "link : String -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "midBottom",
+      "comment": "",
+      "raw": "midBottom   : Position",
+      "type": {
+        "tag": "adt",
+        "name": "Position",
+        "args": []
+      }
+    },
+    {
+      "name": "midBottomAt",
+      "comment": "",
+      "raw": "midBottomAt       : Pos -\u003e Pos -\u003e Position",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Position",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "midLeft",
+      "comment": "",
+      "raw": "midLeft     : Position",
+      "type": {
+        "tag": "adt",
+        "name": "Position",
+        "args": []
+      }
+    },
+    {
+      "name": "midLeftAt",
+      "comment": "",
+      "raw": "midLeftAt         : Pos -\u003e Pos -\u003e Position",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Position",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "midRight",
+      "comment": "",
+      "raw": "midRight    : Position",
+      "type": {
+        "tag": "adt",
+        "name": "Position",
+        "args": []
+      }
+    },
+    {
+      "name": "midRightAt",
+      "comment": "",
+      "raw": "midRightAt        : Pos -\u003e Pos -\u003e Position",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Position",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "midTop",
+      "comment": "",
+      "raw": "midTop      : Position",
+      "type": {
+        "tag": "adt",
+        "name": "Position",
+        "args": []
+      }
+    },
+    {
+      "name": "midTopAt",
+      "comment": "",
+      "raw": "midTopAt          : Pos -\u003e Pos -\u003e Position",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Position",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "middle",
+      "comment": "",
+      "raw": "middle      : Position",
+      "type": {
+        "tag": "adt",
+        "name": "Position",
+        "args": []
+      }
+    },
+    {
+      "name": "middleAt",
+      "comment": "",
+      "raw": "middleAt          : Pos -\u003e Pos -\u003e Position",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Position",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "opacity",
+      "comment": "Create an `Element` with a given opacity. Opacity is a number between 0 and 1\nwhere 0 means totally clear.",
+      "raw": "opacity : Float -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "outward",
+      "comment": "",
+      "raw": "outward : Direction",
+      "type": {
+        "tag": "adt",
+        "name": "Direction",
+        "args": []
+      }
+    },
+    {
+      "name": "relative",
+      "comment": "",
+      "raw": "relative : Float -\u003e Pos",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Float",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Pos",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "right",
+      "comment": "",
+      "raw": "right : Direction",
+      "type": {
+        "tag": "adt",
+        "name": "Direction",
+        "args": []
+      }
+    },
+    {
+      "name": "size",
+      "comment": "Create an `Element` with a new width and height.",
+      "raw": "size : Int -\u003e Int -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "sizeOf",
+      "comment": "Get the width and height of an Element",
+      "raw": "sizeOf : Element -\u003e (Int,Int)",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "_Tuple2",
+          "args": [
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            },
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name": "spacer",
+      "comment": "Create an empty box. This is useful for getting your spacing right and\nfor making borders.",
+      "raw": "spacer : Int -\u003e Int -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "tag",
+      "comment": "Create an `Element` with a tag. This lets you link directly to it.\nThe element `(tag \"all-about-badgers\" thirdParagraph)` can be reached\nwith a link like this: `/facts-about-animals.elm#all-about-badgers`",
+      "raw": "tag : String -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "tiledImage",
+      "comment": "",
+      "raw": "tiledImage : Int -\u003e Int -\u003e String -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "topLeft",
+      "comment": "",
+      "raw": "topLeft     : Position",
+      "type": {
+        "tag": "adt",
+        "name": "Position",
+        "args": []
+      }
+    },
+    {
+      "name": "topLeftAt",
+      "comment": "",
+      "raw": "topLeftAt         : Pos -\u003e Pos -\u003e Position",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Position",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "topRight",
+      "comment": "",
+      "raw": "topRight    : Position",
+      "type": {
+        "tag": "adt",
+        "name": "Position",
+        "args": []
+      }
+    },
+    {
+      "name": "topRightAt",
+      "comment": "",
+      "raw": "topRightAt        : Pos -\u003e Pos -\u003e Position",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Pos",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Position",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "up",
+      "comment": "",
+      "raw": "up : Direction",
+      "type": {
+        "tag": "adt",
+        "name": "Direction",
+        "args": []
+      }
+    },
+    {
+      "name": "width",
+      "comment": "Create an `Element` with a given width.",
+      "raw": "width : Int -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "widthOf",
+      "comment": "Get the width of an Element",
+      "raw": "widthOf : Element -\u003e Int",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Int",
+          "args": []
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Graphics.Input",
+  "document": "This module is for creating standard input widgets such as buttons and\ntext fields. All functions in this library follow a general pattern in which\nyou create an `Input` that many elements can report to:\n\n```haskell\nclicks : Input ()\nclicks = input ()\n\nclickableYogi : Element\nclickableYogi = clickable clicks.handle () (image 40 40 \"/yogi.jpg\")\n```\n\nWhenever the user clicks on the resulting `clickableYogi` element, it sends an\nupdate to the `clicks` input. You will see this pattern again and again in\nexamples in this library, so just read on to get a better idea of how it works!\n\n# Creating Inputs\n@docs Input, input\n\n# Basic Input Elements\n\nTo learn about text fields, see the\n[`Graphics.Input.Field`](Graphics-Input-Field) library.\n\n@docs button, customButton, checkbox, dropDown\n\n# Clicks and Hovers\n@docs clickable, hoverable",
+  "aliases": [
+    {
+      "name": "Input",
+      "comment": "This is the key abstraction of this library. An `Input` is a record\nof two fields:\n\n  1. `signal` &mdash; all values coming to this input from &ldquo;the world&rdquo;\n  2. `handle` &mdash; a way to refer to this particular input and send it values\n\nThis will make more sense as you see more examples.",
+      "raw": "type Input a = { signal : Signal a, handle : Handle a }",
+      "typeVariables": [
+        "a"
+      ],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "signal",
+            {
+              "tag": "adt",
+              "name": "Signal",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            }
+          ],
+          [
+            "handle",
+            {
+              "tag": "adt",
+              "name": "Handle",
+              "args": [
+                {
+                  "tag": "var",
+                  "name": "a"
+                }
+              ]
+            }
+          ]
+        ]
+      }
+    }
+  ],
+  "datatypes": [
+    {
+      "name": "Handle",
+      "comment": "",
+      "raw": "data Handle a = Handle",
+      "typeVariables": [
+        "a"
+      ],
+      "constructors": [
+        {
+          "name": "Handle",
+          "type": {
+            "tag": "adt",
+            "name": "Handle",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "button",
+      "comment": "Create a standard button. The following example begins making a basic\ncalculator:\n\n      data Keys = Number Int | Plus | Minus | Clear\n\n      keys : Input Keys\n      keys = input Clear\n\n      calculator : Element\n      calculator =\n          flow right [ button keys.handle (Number 1) \"1\"\n                     , button keys.handle (Number 2) \"2\"\n                     , button keys.handle    Plus    \"+\"\n                     ]\n\nIf the user presses the \"+\" button, `keys.signal` will update to `Plus`. If the\nusers presses \"2\", `keys.signal` will update to `(Number 2)`.",
+      "raw": "button : Handle a -\u003e a -\u003e String -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Handle",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "checkbox",
+      "comment": "Create a checkbox. The following example creates three synced checkboxes:\n\n      check : Input Bool\n      check = input False\n\n      boxes : Bool -\u003e Element\n      boxes checked =\n          let box = container 40 40 middle (checkbox check.handle id checked)\n          in  flow right [ box, box, box ]\n\n      main : Signal Element\n      main = boxes \u003c~ check.signal",
+      "raw": "checkbox : Handle a -\u003e (Bool -\u003e a) -\u003e Bool -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Handle",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Bool",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "a"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Bool",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "clickable",
+      "comment": "Detect mouse clicks on a specific `Element`. In the following example,\nwe will create a clickable picture called `cat`.\n\n      data Picture = Cat | Hat\n\n      picture : Input Picture\n      picture = input Cat\n\n      cat : Element\n      cat = image 30 30 \"/cat.jpg\"\n               |\u003e clickable picture.handle Cat\n\n      hat : Element\n      hat = image 30 30 \"/hat.jpg\"\n               |\u003e clickable picture.handle Hat\n\nWhen the user clicks on the `cat` element, `picture.signal` receives\nan update containing the value `Cat`. When the user clicks on the `hat` element,\n`picture.signal` receives an update containing the value `Hat`. This lets you\ndistinguish which element was clicked. In a more complex example, they could be\ndistinguished with IDs or more complex data structures.",
+      "raw": "clickable : Handle a -\u003e a -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Handle",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "customButton",
+      "comment": "Same as `button` but lets you customize buttons to look however you want.\n\n      click : Input ()\n      click = input ()\n\n      prettyButton : Element\n      prettyButton =\n          customButton click.handle ()\n              (image 100 40 \"/button_up.jpg\")\n              (image 100 40 \"/button_hover.jpg\")\n              (image 100 40 \"/button_down.jpg\")",
+      "raw": "customButton : Handle a -\u003e a -\u003e Element -\u003e Element -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Handle",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "var",
+            "name": "a"
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "dropDown",
+      "comment": "Create a drop-down menu.  The following drop-down lets you choose your\nfavorite British sport:\n\n      data Sport = Football | Cricket | Snooker\n\n      sport : Input (Maybe Sport)\n      sport = input Nothing\n\n      sportDropDown : Element\n      sportDropDown =\n          dropDown sport.handle\n            [ (\"\"        , Nothing)\n            , (\"Football\", Just Football)\n            , (\"Cricket\" , Just Cricket)\n            , (\"Snooker\" , Just Snooker)\n            ]\n\nIf the user selects \"Football\" from the drop down menue, `sport.signal`\nwill update to `Just Football`.",
+      "raw": "dropDown : Handle a -\u003e [(String,a)] -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Handle",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "adt",
+            "name": "_List",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "_Tuple2",
+                "args": [
+                  {
+                    "tag": "adt",
+                    "name": "String",
+                    "args": []
+                  },
+                  {
+                    "tag": "var",
+                    "name": "a"
+                  }
+                ]
+              }
+            ]
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "hoverable",
+      "comment": "Detect mouse hovers over a specific `Element`. In the following example,\nwe will create a hoverable picture called `cat`.\n\n      hover : Input Bool\n      hover = input False\n\n      cat : Element\n      cat = image 30 30 \"/cat.jpg\"\n              |\u003e hoverable hover.handle id\n\nWhen the mouse hovers above the `cat` element, `hover.signal` will become\n`True`. When the mouse leaves it, `hover.signal` will become `False`.",
+      "raw": "hoverable : Handle a -\u003e (Bool -\u003e a) -\u003e Element -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Handle",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Bool",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "a"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "Element",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "input",
+      "comment": "This creates a new `Input`. You provide a single argument that will serve\nas the initial value of the input&rsquo;s `signal`. For example:\n\n      numbers : Input Int\n      numbers = input 42\n\nThe initial value of `numbers.signal` is 42, and you will be able\nto pipe updates to the input using `numbers.handle`.\n\nNote: This is an inherently impure function. Specifically, `(input ())` and\n`(input ())` are actually two different inputs with different signals and handles.",
+      "raw": "input : a -\u003e Input a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Input",
+          "args": [
+            {
+              "tag": "var",
+              "name": "a"
+            }
+          ]
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "Graphics.Input.Field",
+  "document": "This library provides an API for creating and updating text fields.\nText fields use exactly the same approach as [`Graphics.Input`](Graphics-Input)\nfor modelling user input, allowing you to keep track of new events and update\ntext fields programmatically.\n\n# Create Fields\n@docs field, password, email\n\n# Field Content\n@docs Content, Selection, Direction, noContent\n\n# Field Style\n@docs Style, Outline, noOutline, Highlight, noHighlight, Dimensions, uniformly",
+  "aliases": [
+    {
+      "name": "Content",
+      "comment": "Represents the current content of a text field. For example:\n\n      content = Content \"She sells sea shells\" (Selection 0 3 Backward)\n\nThis means the user highlighted the substring `\"She\"` backwards. The value of\n`content.string` is `\"She sells sea shells\"`.",
+      "raw": "type Content = { string:String, selection:Selection }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "string",
+            {
+              "tag": "adt",
+              "name": "String",
+              "args": []
+            }
+          ],
+          [
+            "selection",
+            {
+              "tag": "adt",
+              "name": "Selection",
+              "args": []
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "name": "Dimensions",
+      "comment": "For setting dimensions of a field's padding or outline. The left, right,\ntop, and bottom may all have different sizes. The following example creates\ndimensions such that the left and right are twice as wide as the top and bottom:\n\n      myDimensions : Int -\u003e Dimensions\n      myDimensions n = { left = 2 * n, right = 2 * n, top = n, bottom = n }",
+      "raw": "type Dimensions = { left:Int, right:Int, top:Int, bottom:Int }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "left",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "right",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "top",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "bottom",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "name": "Highlight",
+      "comment": "When a field has focus, it has a blue highlight around it by default. The\n`Highlight` lets you set the `color` and `width` of this highlight. Set the\n`width` to zero to turn the highlight off. Here is an example highlight that\nis blue and thin:\n\n      { color = blue, width = 1 }",
+      "raw": "type Highlight = { color:Color, width:Int }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "color",
+            {
+              "tag": "adt",
+              "name": "Color",
+              "args": []
+            }
+          ],
+          [
+            "width",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "name": "Outline",
+      "comment": "A field can have a outline around it. This lets you set its color, width,\nand radius. The radius allows you to round the corners of your field. Set the\nwidth to zero to make it invisible. Here is an example outline that is grey\nand thin with slightly rounded corners:\n\n      { color = grey, width = uniformly 1, radius = 4 }",
+      "raw": "type Outline = { color:Color, width:Dimensions, radius:Int }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "color",
+            {
+              "tag": "adt",
+              "name": "Color",
+              "args": []
+            }
+          ],
+          [
+            "width",
+            {
+              "tag": "adt",
+              "name": "Dimensions",
+              "args": []
+            }
+          ],
+          [
+            "radius",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "name": "Selection",
+      "comment": "The selection within a text field. `start` is never greater than `end`:\n\n      Selection 0 0 Forward  -- cursor precedes all characters\n\n      Selection 5 9 Backward -- highlighting characters starting after\n                             -- the 5th and ending after the 9th",
+      "raw": "type Selection = { start:Int, end:Int, direction:Direction }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "start",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "end",
+            {
+              "tag": "adt",
+              "name": "Int",
+              "args": []
+            }
+          ],
+          [
+            "direction",
+            {
+              "tag": "adt",
+              "name": "Direction",
+              "args": []
+            }
+          ]
+        ]
+      }
+    },
+    {
+      "name": "Style",
+      "comment": "Describe the style of a text box. `style` describes the style of the text\nitself using [`Text.Style`](/Text#Style). `highlight` describes the glowing blue\nhighlight that shows up when the field has focus. `outline` describes the line\nsurrounding the text field, and `padding` adds whitespace between the `outline`\nand the text.\n\nThe width and height of the text box *includes* the `padding` and `outline`.\nSay we have a text box that is 40 pixels tall. It has a uniform outline of\n1 pixel and a uniform padding of 5 pixels. Both of these must be subtracted\nfrom the total height to determine how much room there is for text. The\n`padding` and `outline` appear on the top and bottom, so there will be 28\nvertical pixels remaining for the text (40 - 1 - 5 - 5 - 1).",
+      "raw": "type Style =\n  { padding   : Dimensions\n  , outline   : Outline\n  , highlight : Highlight\n  , style     : Text.Style\n  }",
+      "typeVariables": [],
+      "type": {
+        "tag": "record",
+        "extension": null,
+        "fields": [
+          [
+            "padding",
+            {
+              "tag": "adt",
+              "name": "Dimensions",
+              "args": []
+            }
+          ],
+          [
+            "outline",
+            {
+              "tag": "adt",
+              "name": "Outline",
+              "args": []
+            }
+          ],
+          [
+            "highlight",
+            {
+              "tag": "adt",
+              "name": "Highlight",
+              "args": []
+            }
+          ],
+          [
+            "style",
+            {
+              "tag": "adt",
+              "name": "Text.Style",
+              "args": []
+            }
+          ]
+        ]
+      }
+    }
+  ],
+  "datatypes": [
+    {
+      "name": "Direction",
+      "comment": "The direction of selection. When the user highlights a selection in a text\nfield, they must do it in a particular direction. This determines which end of\nthe selection moves when they change the selection by pressing Shift-Left or\nShift-Right.",
+      "raw": "data Direction = Forward | Backward",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "Forward",
+          "type": {
+            "tag": "adt",
+            "name": "Direction",
+            "args": []
+          }
+        },
+        {
+          "name": "Backward",
+          "type": {
+            "tag": "adt",
+            "name": "Direction",
+            "args": []
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "defaultStyle",
+      "comment": "The default style for a text field. The outline is `Color.grey` with width\n1 and radius 2. The highlight is `Color.blue` with width 1, and the default\ntext color is black.",
+      "raw": "defaultStyle : Style",
+      "type": {
+        "tag": "adt",
+        "name": "Style",
+        "args": []
+      }
+    },
+    {
+      "name": "email",
+      "comment": "Same as `field` but it adds an annotation that this field is for email\naddresses. This is helpful for auto-complete and for mobile users who may\nget a custom keyboard with an `@` and `.com` button.",
+      "raw": "email : Style -\u003e Handle a -\u003e (Content -\u003e a) -\u003e String -\u003e Content -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Style",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Handle",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Content",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "a"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Content",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "field",
+      "comment": "Create a text field. The following example creates a time-varying element\ncalled `nameField`. As the user types their name, the field will be updated\nto match what they have entered.\n\n      name : Input Content\n      name = input noContent\n\n      nameField : Signal Element\n      nameField = field defaultStyle name.handle id \"Name\" \u003c~ name.signal\n\nWhen we use the `field` function, we first give it a visual style. This is\nthe first argument so that it is easier to define your own custom field\n(`myField = field myStyle`). The next two arguments are a `Handle` and a\nhandler function that processes or augments events before sending them along\nto the associated `Input`. In the example above we use the `id` function to\npass events along unchanged to the `name` `Input`. We then provide the\nplace-holder message to use when no input has been provided yet. Finally,\nwe give the current `Content` of the field. This argument is last because\nit is most likely to change frequently, making function composition easier.",
+      "raw": "field : Style -\u003e Handle a -\u003e (Content -\u003e a) -\u003e String -\u003e Content -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Style",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Handle",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Content",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "a"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Content",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "noContent",
+      "comment": "A field with no content:\n\n      Content \"\" (Selection 0 0 Forward)",
+      "raw": "noContent : Content",
+      "type": {
+        "tag": "adt",
+        "name": "Content",
+        "args": []
+      }
+    },
+    {
+      "name": "noHighlight",
+      "comment": "An highlight with zero width, so you cannot see it.",
+      "raw": "noHighlight : Highlight",
+      "type": {
+        "tag": "adt",
+        "name": "Highlight",
+        "args": []
+      }
+    },
+    {
+      "name": "noOutline",
+      "comment": "An outline with zero width, so you cannot see it.",
+      "raw": "noOutline : Outline",
+      "type": {
+        "tag": "adt",
+        "name": "Outline",
+        "args": []
+      }
+    },
+    {
+      "name": "password",
+      "comment": "Same as `field` but the UI element blocks out each characters.",
+      "raw": "password : Style -\u003e Handle a -\u003e (Content -\u003e a) -\u003e String -\u003e Content -\u003e Element",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Style",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Handle",
+            "args": [
+              {
+                "tag": "var",
+                "name": "a"
+              }
+            ]
+          },
+          {
+            "tag": "function",
+            "args": [
+              {
+                "tag": "adt",
+                "name": "Content",
+                "args": []
+              }
+            ],
+            "result": {
+              "tag": "var",
+              "name": "a"
+            }
+          },
+          {
+            "tag": "adt",
+            "name": "String",
+            "args": []
+          },
+          {
+            "tag": "adt",
+            "name": "Content",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Element",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "uniformly",
+      "comment": "Create uniform dimensions:\n\n      uniformly 4 == { left=4, right=4, top=4, bottom=4 }\n\nThe following example creates an outline where the left, right, top, and bottom\nedges all have width 1:\n\n      Outline grey (uniformly 1) 4",
+      "raw": "uniformly : Int -\u003e Dimensions",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Int",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Dimensions",
+          "args": []
+        }
+      }
+    }
+  ]
+},
+{
+  "name": "JavaScript.Experimental",
+  "document": "A pair of very experimental functions for converting between\nElm records and JavaScript objects. It currently uses a best effort\nconversion that can cause runtime errors. This API should change and\nimprove as we find its key failings.\n\n# Converting between Elm records and JS Objects\n@docs toRecord, fromRecord",
+  "aliases": [],
+  "datatypes": [
+    {
+      "name": "RawObject",
+      "comment": "",
+      "raw": "data RawObject = RawObject",
+      "typeVariables": [],
+      "constructors": [
+        {
+          "name": "RawObject",
+          "type": {
+            "tag": "adt",
+            "name": "RawObject",
+            "args": []
+          }
+        }
+      ]
+    }
+  ],
+  "values": [
+    {
+      "name": "fromJson",
+      "comment": "Turn a `Json.Value` (as described in the `Json` library) into a raw\nJavaScript object.",
+      "raw": "fromJson : Json.Value -\u003e RawObject",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "Json.Value",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "RawObject",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "fromRecord",
+      "comment": "Turn arbitrary Elm records into JavaScript objects.\nLists become arrays, nested records are allowed. No ADTs.\n\n      -- OK records\n      { student=\"Steve\", scores=[83,94,99,72] }\n      { errorLevel=10, critical=True }\n\n      -- BAD records\n      { answer = Nothing }\n      { result = Left \"An error occurred\" }",
+      "raw": "fromRecord : a -\u003e RawObject",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "var",
+            "name": "a"
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "RawObject",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toJson",
+      "comment": "Turn a raw JavaScript object into a `Json.Value` as described in the\n`Json` library.",
+      "raw": "toJson : RawObject -\u003e Json.Value",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "RawObject",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "adt",
+          "name": "Json.Value",
+          "args": []
+        }
+      }
+    },
+    {
+      "name": "toRecord",
+      "comment": "Turn arbitrary JavaScript objects into Elm records.\nArrays are converted into lists, nested objects are allowed.\nNo `null` values or non-homogeneous arrays.\n\n      -- OK objects\n      { student:\"Steve\", scores:[83,94,99,72] }\n      { errorLevel:10, critical:true }\n\n      -- BAD objects\n      { answer:null }\n      { info:[true,42,'what'] }",
+      "raw": "toRecord : RawObject -\u003e a",
+      "type": {
+        "tag": "function",
+        "args": [
+          {
+            "tag": "adt",
+            "name": "RawObject",
+            "args": []
+          }
+        ],
+        "result": {
+          "tag": "var",
+          "name": "a"
+        }
+      }
     }
   ]
 }
diff --git a/data/elm-runtime.js b/data/elm-runtime.js
--- a/data/elm-runtime.js
+++ b/data/elm-runtime.js
@@ -1,7278 +1,10284 @@
-var Elm = {}; Elm.Native = {}; Elm.Native.Graphics = {};
-var ElmRuntime = {}; ElmRuntime.Render = {};
-
-Elm.Native.Basics = {};
-Elm.Native.Basics.make = function(elm) {
-  elm.Native = elm.Native || {};
-  elm.Native.Basics = elm.Native.Basics || {};
-  if (elm.Native.Basics.values) return elm.Native.Basics.values;
-
-  var JS = Elm.Native.JavaScript.make(elm);
-  var Utils = Elm.Native.Utils.make(elm);
-
-  function div(a,b) { return (a/b)|0; }
-  function rem(a,b) { return a % b; }
-  var mod = Utils.mod;
-  function abs(x) { return x < 0 ? -x : x; }
-  function logBase(base,n) { return Math.log(n) / Math.log(base); }
-  function min(a,b) { return Utils.cmp(a,b) < 0 ? a : b; }
-  function max(a,b) { return Utils.cmp(a,b) > 0 ? a : b; }
-  function clamp(lo,hi,n) {
-      return Utils.cmp(n,lo) < 0 ? lo : Utils.cmp(n,hi) > 0 ? hi : n; }
-  function xor(a,b) { return a !== b; }
-  function not(b) { return !b; }
-
-  function truncate(n) { return n|0; }
-
-  var basics = {
-      div:F2(div),
-      rem:F2(rem),
-      mod:mod,
-
-      pi:Math.PI,
-      e:Math.E,
-      cos:Math.cos,
-      sin:Math.sin,
-      tan:Math.tan,
-      acos:Math.acos,
-      asin:Math.asin,
-      atan:Math.atan,
-      atan2:F2(Math.atan2),
-
-      sqrt:Math.sqrt,
-      abs:abs,
-      logBase:F2(logBase),
-      min:F2(min),
-      max:F2(max),
-      clamp:F3(clamp),
-      compare:Utils.compare,
-
-      xor:F2(xor),
-      not:not,
-
-      truncate:truncate,
-      ceiling:Math.ceil,
-      floor:Math.floor,
-      round:Math.round,
-      toFloat:function(x) { return x; },
-  };
-
-  return elm.Native.Basics.values = basics;
-};
-Elm.Native.Bitwise = {};
-Elm.Native.Bitwise.make = function(elm) {
-    elm.Native = elm.Native || {};
-    elm.Native.Bitwise = elm.Native.Bitwise || {};
-    if (elm.Native.Bitwise.values) return elm.Native.Bitwise.values;
-
-    function and(a,b) { return a & b; }
-    function or (a,b) { return a | b; }
-    function xor(a,b) { return a ^ b; }
-    function not(a) { return ~a; }
-    function sll(a,offset) { return a << offset; }
-    function sra(a,offset) { return a >> offset; }
-    function srl(a,offset) { return a >>> offset; }
-
-    return elm.Native.Bitwise.values = {
-        and: A2(and),
-        or : A2(or ),
-        xor: A2(xor),
-        complement: not,
-        shiftLeft           : A2(sll),
-        shiftRightArithmatic: A2(sra),
-        shiftRightLogical   : A2(srl),
-    };
-    
-};
-Elm.Native.Char = {};
-Elm.Native.Char.make = function(elm) {
-    elm.Native = elm.Native || {};
-    elm.Native.Char = elm.Native.Char || {};
-    if (elm.Native.Char.values) return elm.Native.Char.values;
-
-    function isBetween(lo,hi) { return function(chr) {
-	var c = chr.charCodeAt(0);
-	return lo <= c && c <= hi;
-    };
-                              }
-    var isDigit = isBetween('0'.charCodeAt(0),'9'.charCodeAt(0));
-    var chk1 = isBetween('a'.charCodeAt(0),'f'.charCodeAt(0));
-    var chk2 = isBetween('A'.charCodeAt(0),'F'.charCodeAt(0));
-
-    return elm.Native.Char.values = {
-        fromCode : function(c) { return String.fromCharCode(c); },
-        toCode   : function(c) { return c.toUpperCase().charCodeAt(0); },
-        toUpper  : function(c) { return c.toUpperCase(); },
-        toLower  : function(c) { return c.toLowerCase(); },
-        toLocaleUpper : function(c) { return c.toLocaleUpperCase(); },
-        toLocaleLower : function(c) { return c.toLocaleLowerCase(); },
-        isLower    : isBetween('a'.charCodeAt(0),'z'.charCodeAt(0)),
-        isUpper    : isBetween('A'.charCodeAt(0),'Z'.charCodeAt(0)),
-        isDigit    : isDigit,
-        isOctDigit : isBetween('0'.charCodeAt(0),'7'.charCodeAt(0)),
-        isHexDigit : function(c) { return isDigit(c) || chk1(c) || chk2(c); }
-    };
-};
-Elm.Native.Color = {};
-Elm.Native.Color.make = function(elm) {
-    elm.Native = elm.Native || {};
-    elm.Native.Color = elm.Native.Color || {};
-    if (elm.Native.Color.values) return elm.Native.Color.values;
-
-    var Utils = Elm.Native.Utils.make(elm);
-
-    function complement(rgb) {
-        var hsv = toHSV(rgb);
-        hsv.hue = (hsv.hue + 180) % 360;
-        return toRGB(hsv);
-    }
-
-    function hsva(h,s,v,a) {
-        var degree = A2(Utils.mod, h * 180 / Math.PI, 360);
-        var clr = toRGB({hue:degree, saturation:s, value:v});
-        clr._3 = a;
-        return clr;
-    }
-
-    function hsv(h,s,v) {
-        var degree = A2(Utils.mod, h * 180 / Math.PI, 360);
-        return toRGB({hue:degree, saturation:s, value:v});
-    }
-
-    function toHSV(rgb) {
-        var hsv = {};
-        var r = rgb._0 / 255.0, g = rgb._1 / 255.0, b = rgb._2 / 255.0;
-        var M = Math.max(r,g,b);
-        var m = Math.min(r,g,b);
-        var c = M - m;
-
-        var h = 0;
-             if (c === 0) { h = 0; }
-        else if (M === r) { h = ((g - b) / c) % 6; }
-        else if (M === g) { h = ((b - r) / c) + 2; }
-        else if (M === b) { h = ((r - g) / c) + 4; }
-        h *= 60;
-
-        return { value : M, hue : h, saturation : (M === 0 ? 0 : c / M) };
-    }
-
-    function between(lo,hi,x) { return lo <= x && x < hi; }
-    function norm(n) { return Math.round(n*255); }
-
-    function toRGB(hsv) {
-        var c = hsv.value * hsv.saturation;
-        var hue = hsv.hue / 60;
-        var x = c * (1 - Math.abs((hue % 2) - 1));
-        var r = 0, g = 0, b = 0;
-             if (between(0,1,hue)) { r = c; g = x; b = 0; }
-        else if (between(1,2,hue)) { r = x; g = c; b = 0; }
-        else if (between(2,3,hue)) { r = 0; g = c; b = x; }
-        else if (between(3,4,hue)) { r = 0; g = x; b = c; }
-        else if (between(4,5,hue)) { r = x; g = 0; b = c; }
-        else if (between(5,6,hue)) { r = c; g = 0; b = x; }
-
-        var m = hsv.value - c;
-        return { ctor:"Color", _0:norm(r+m), _1:norm(g+m), _2:norm(b+m), _3:1 };
-    }
-
-    return elm.Native.Color.values = {
-        hsva:F4(hsva),
-        hsv:F3(hsv),
-        complement:complement
-    };
-
-};Elm.Native.Date = {};
-Elm.Native.Date.make = function(elm) {
- elm.Native = elm.Native || {};
- elm.Native.Date = elm.Native.Date || {};
- if (elm.Native.Date.values) return elm.Native.Date.values;
-
- var JS = Elm.JavaScript.make(elm);
- var Maybe = Elm.Maybe.make(elm);
-
- function dateNow() { return new window.Date; }
- function readDate(str) {
-     var d = new window.Date(JS.fromString(str));
-     if (isNaN(d.getTime())) return Maybe.Nothing;
-     return Maybe.Just(d);
- }
-
- var dayTable = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
- var monthTable = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
-		   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; 
-
- return elm.Native.Date.values = {
-     read    : readDate,
-     year    : function(d) { return d.getFullYear(); },
-     month   : function(d) { return { ctor:monthTable[d.getMonth()] }; },
-     day     : function(d) { return d.getDate(); },
-     hour    : function(d) { return d.getHours(); },
-     minute  : function(d) { return d.getMinutes(); },
-     second  : function(d) { return d.getSeconds(); },
-     toTime  : function(d) { return d.getTime(); },
-     dayOfWeek : function(d) { return { ctor:dayTable[d.getDay()] }; }
- };
-
-};
-Elm.Native.Error = {};
-Elm.Native.Error.make = function(elm) {
-    elm.Native = elm.Native || {};
-    elm.Native.Error = elm.Native.Error || {};
-    if (elm.Native.Error.values) return elm.Native.Error.values;
-
-    var fromString = Elm.Native.JavaScript.make(elm).fromString;
-
-    function indent(lines) {
-        var msg = '';
-        for (var i = 0; i < lines.length; ++i) {
-            msg += '<br/>&nbsp; &nbsp; ' + lines[i];
-        }
-        return msg;
-    }
-
-    function Case(moduleName, span) { 
-	var msg = indent(['Non-exhaustive pattern match in case-expression.',
-                          'Make sure your patterns cover every case!']);
-	throw new Error('Runtime error in module ' + moduleName + ' (' + span + '):' + msg);
-    }
-
-    function If(moduleName, span) { 
-	var msg = indent(['Non-exhaustive pattern match in multi-way-if expression.',
-                          'It is best to use \'otherwise\' as the last branch of multi-way-if.']);
-	throw new Error('Runtime error in module ' + moduleName + ' (' + span + '):' + msg);
-    }
-
-    function raise(str) { throw new Error(fromString(str)); }
-
-    return elm.Native.Error.values = { Case: Case, If: If, raise: raise };
-};
-function F2(fun) {
-  function wrapper(a) { return function(b) { return fun(a,b) } }
-  wrapper.arity = 2;
-  wrapper.func = fun;
-  return wrapper;
-}
-
-function F3(fun) {
-  function wrapper(a) {
-    return function(b) { return function(c) { return fun(a,b,c) }}
-  }
-  wrapper.arity = 3;
-  wrapper.func = fun;
-  return wrapper;
-}
-
-function F4(fun) {
-  function wrapper(a) { return function(b) { return function(c) {
-    return function(d) { return fun(a,b,c,d) }}}
-  }
-  wrapper.arity = 4;
-  wrapper.func = fun;
-  return wrapper;
-}
-
-function F5(fun) {
-  function wrapper(a) { return function(b) { return function(c) {
-    return function(d) { return function(e) { return fun(a,b,c,d,e) }}}}
-  }
-  wrapper.arity = 5;
-  wrapper.func = fun;
-  return wrapper;
-}
-
-function F6(fun) {
-  function wrapper(a) { return function(b) { return function(c) {
-    return function(d) { return function(e) { return function(f) {
-      return fun(a,b,c,d,e,f) }}}}}
-  }
-  wrapper.arity = 6;
-  wrapper.func = fun;
-  return wrapper;
-}
-
-function F7(fun) {
-  function wrapper(a) { return function(b) { return function(c) {
-    return function(d) { return function(e) { return function(f) {
-      return function(g) { return fun(a,b,c,d,e,f,g) }}}}}}
-  }
-  wrapper.arity = 7;
-  wrapper.func = fun;
-  return wrapper;
-}
-
-function F8(fun) {
-  function wrapper(a) { return function(b) { return function(c) {
-    return function(d) { return function(e) { return function(f) {
-	return function(g) { return function(h) {return fun(a,b,c,d,e,f,g,h)}}}}}}}
-  }
-  wrapper.arity = 8;
-  wrapper.func = fun;
-  return wrapper;
-}
-
-function F9(fun) {
-  function wrapper(a) { return function(b) { return function(c) {
-    return function(d) { return function(e) { return function(f) {
-	return function(g) { return function(h) { return function(i) {
-        return fun(a,b,c,d,e,f,g,h,i) }}}}}}}}
-  }
-  wrapper.arity = 9;
-  wrapper.func = fun;
-  return wrapper;
-}
-
-function A2(fun,a,b) {
-  return fun.arity === 2 ? fun.func(a,b) : fun(a)(b);
-}
-function A3(fun,a,b,c) {
-  return fun.arity === 3 ? fun.func(a,b,c) : fun(a)(b)(c);
-}
-function A4(fun,a,b,c,d) {
-  return fun.arity === 4 ? fun.func(a,b,c,d) : fun(a)(b)(c)(d);
-}
-function A5(fun,a,b,c,d,e) {
-  return fun.arity === 5 ? fun.func(a,b,c,d,e) : fun(a)(b)(c)(d)(e);
-}
-function A6(fun,a,b,c,d,e,f) {
-  return fun.arity === 6 ? fun.func(a,b,c,d,e,f) : fun(a)(b)(c)(d)(e)(f);
-}
-function A7(fun,a,b,c,d,e,f,g) {
-  return fun.arity === 7 ? fun.func(a,b,c,d,e,f,g) : fun(a)(b)(c)(d)(e)(f)(g);
-}
-function A8(fun,a,b,c,d,e,f,g,h) {
-  return fun.arity === 8 ? fun.func(a,b,c,d,e,f,g,h) : fun(a)(b)(c)(d)(e)(f)(g)(h);
-}
-function A9(fun,a,b,c,d,e,f,g,h,i) {
-  return fun.arity === 9 ? fun.func(a,b,c,d,e,f,g,h,i)
-                         : fun(a)(b)(c)(d)(e)(f)(g)(h)(i);
-}
-Elm.Native.JavaScript = {};
-Elm.Native.JavaScript.make = function(elm) {
-  elm.Native = elm.Native || {};
-  elm.Native.JavaScript = elm.Native.JavaScript || {};
-  if (elm.Native.JavaScript.values) return elm.Native.JavaScript.values;
-
-  var List = Elm.Native.List.make(elm);
-  var Render = ElmRuntime.use(ElmRuntime.Render.Element);
-
-  function fromJS(v) {
-      var type = typeof v;
-      if (type === 'number' ) return v;
-      if (type === 'boolean') return v;
-      if (type === 'string' ) return v;
-      if (v instanceof Array) {
-          var arr = [];
-          var len = v.length;
-          for (var i = 0; i < len; ++i) {
-              var x = fromJS(v[i]);
-              if (x !== null) arr.push(x);
-          }
-          return List.fromArray(arr);
-      }
-      if (type === 'object') {
-          var rec = { _:{} };
-          for (var f in v) {
-              var x = fromJS(v[f]);
-              if (x !== null) rec[f] = x;
-          }
-          return rec;
-      }
-      return null;
-  }
-
-  function toJS(v) {
-      var type = typeof v;
-      if (type === 'number' || type === 'boolean' || type === 'string') return v;
-      if (type === 'object' && '_' in v) {
-          var obj = {};
-          for (var k in v) {
-              var x = toJS(v[k]);
-              if (x !== null) obj[k] = x;
-          }
-          return obj;
-      }
-      if (type === 'object' && (v.ctor === '::' || v.ctor === '[]')) {
-          var array = List.toArray(v);
-          for (var i = array.length; i--; ) {
-              array[i] = toJS(array[i]);
-          }
-          return array;
-      }
-      return null;
-  }
-
-  function fromRecord(r) {
-      if (typeof r === 'object' && '_' in r) {
-          return toJS(r);
-      }
-      throw new Error("'fromRecord' must be called on a record.");
-  }
-
-  function id(n) { return n; }
-
-  function toElement(w,h,domNode) {
-      return A3( newElement, w, h, {
-              ctor: 'Custom',
-              type: 'DomNode',
-              render: function(node) { return node; },
-              update: function(node,oldNode,newNode) {
-                  if (node === newNode) return;
-                  node.parentNode.replaceChild(newNode, node);
-              },
-              model: domNode
-          });
-  }
-
-  function fromElement(element) {
-      return Render.render(element);
-  }
-
-  return elm.Native.JavaScript.values = {
-      toInt      : function(n) { return n|0; },
-      toFloat    : function(n) { return +n; },
-      toBool     : id,
-      toString   : id,
-      toList     : List.fromArray,
-      fromString : id,
-      fromList   : List.toArray,
-      fromInt    : id,
-      fromFloat  : id,
-      fromBool   : id,
-
-      toElement   : toElement,
-      fromElement : fromElement,
-      toRecord    : fromJS,
-      fromRecord  : fromRecord
-  };
-
-};
-Elm.Native.Json = {};
-Elm.Native.Json.make = function(elm) {
-
-  elm.Native = elm.Native || {};
-  elm.Native.Json = elm.Native.Json || {};
-  if (elm.Native.Json.values) return elm.Native.Json.values;
-
-  var Maybe = Elm.Maybe.make(elm);
-  var Dict = Elm.Dict.make(elm);
-  var List = Elm.List.make(elm);
-  var JS = Elm.JavaScript.make(elm);
-  var Utils = Elm.Native.Utils.make(elm);
-
-  function fromValue(v) {
-    switch (v.ctor) {
-    case 'Null'   : return null;
-    case 'String' : return JS.fromString(v._0);
-    case 'Object' :
-      var obj = {};
-      var array = JS.fromList(Dict.toList(v._0));
-      for (var i = array.length; i--; ) {
-	obj[JS.fromString(array[i]._0)] = fromValue(array[i]._1);
-      }
-      return obj;
-    case 'Array'  :
-      var array = JS.fromList(v._0);
-      for (var i = array.length; i--; ) {
-	array[i] = fromValue(array[i]);
-      }
-      return array;
-    default :
-      return v._0;
-    }
-  }
-
-  function toPrettyJSString(sep, obj) {
-    return JSON.stringify(fromValue(obj), null, JS.fromString(sep));
-  }
-
-  function toValue(v) {
-    switch (typeof v) {
-    case 'string' : return { ctor:"String", _0: JS.toString(v) };
-    case 'number' : return { ctor:"Number", _0: JS.toFloat(v)  };
-    case 'boolean': return { ctor:"Boolean"  , _0: JS.toBool(v)   };
-    case 'object' :
-      if (v === null) return { ctor:"Null" };
-      if (v instanceof Array) {
-          for (var i = v.length; i--; ) { v[i] = toValue(v[i]); }
-	  return { ctor:"Array", _0: JS.toList(v) };
-      }
-      var array = [];
-      for (var k in v) array.push(Utils.Tuple2(JS.toString(k), toValue(v[k])));
-      return { ctor:"Object", _0: Dict.fromList(JS.toList(array)) };
-    }
-  }
-
-  function fromJSString(str) {
-    try {
-	return Maybe.Just(toValue(JSON.parse(str)));
-    } catch (e) {
-	return Maybe.Nothing;
-    }
-  }
-
-  return elm.Native.Json.values = {
-      toJSString : F2(toPrettyJSString),
-      fromJSString : fromJSString,
-      toJSObject : fromValue,
-      fromJSObject : toValue
-  };
-
-};
-Elm.Native.List = {};
-Elm.Native.List.make = function(elm) {
-    elm.Native = elm.Native || {};
-    elm.Native.List = elm.Native.List || {};
-    if (elm.Native.List.values) return elm.Native.List.values;
-    if ('values' in Elm.Native.List)
-        return elm.Native.List.values = Elm.Native.List.values;
-
-    var Utils = Elm.Native.Utils.make(elm);
-
-    // TODO: Improve Nil handling
-    // We can change places like:  if (xs.ctor === '[]') ... to if (xs === Nil) ...
-    // but only if we're confident Nil can only be defined once.
-    // Currently (27Mar2013) each module can have different instantiations, so multiple Nil objects can exist
-    // (and if they're used interchangeably then direct object comparison fails where ctor doesn't).
-    // So, this can only be fixed when modules initialisation is also fixed.
-    // The performance overhead of the .ctor calls is 5-10% according to jsperf (depending on fn + list size)
-    // (on firefox 19)
-
-    var Nil = { ctor:'[]' };
-
-    // using freeze for every cons would be nice but is a huge (9x on firefox 19)
-    // performance penalty
-    function Cons(hd,tl) { return { ctor:"::", _0:hd, _1:tl }; }
-
-    function throwError(f) {
-        throw new Error("Function '" + f + "' expects a non-empty list!");
-    }
-
-    function toArray(xs) {
-        var out = [];
-        while (xs.ctor !== '[]') {
-            out.push(xs._0);
-            xs = xs._1;
-        }
-        return out;
-    }
-
-    function fromArray(arr) {
-        var out = Nil;
-        for (var i = arr.length; i--; ) {
-            out = Cons(arr[i], out);
-        }
-        return out;
-    }
-
-    function range(lo,hi) {
-        var lst = Nil;
-        if (lo <= hi) {
-            do { lst = Cons(hi,lst) } while (hi-->lo);
-        }
-        return lst
-    }
-
-    function append(xs,ys) {
-        // append Text
-        if (xs.text || ys.text) {
-            return Utils.txt(Utils.makeText(xs) + Utils.makeText(ys));
-        }
-
-        // append Strings
-        if (typeof xs === "string") return xs + ys;
-
-        // append Lists
-        if (xs.ctor === '[]') { return ys; }
-        var root = Cons(xs._0, Nil);
-        var curr = root;
-        xs = xs._1;
-        while (xs.ctor !== '[]') {
-	    curr._1 = Cons(xs._0, Nil);
-	    xs = xs._1;
-	    curr = curr._1;
-        }
-        curr._1 = ys;
-        return root;
-    }
-
-    function head(v) { return v.ctor === '[]' ? throwError('head') : v._0; }
-    function tail(v) { return v.ctor === '[]' ? throwError('tail') : v._1; }
-
-    function last(xs) {
-        if (xs.ctor === '[]') { throwError('last'); }
-        var out = xs._0;
-        while (xs.ctor !== '[]') {
-            out = xs._0;
-            xs = xs._1;
-        }
-        return out;
-    }
-
-    function map(f, xs) {
-        var arr = [];
-        while (xs.ctor !== '[]') {
-            arr.push(f(xs._0));
-            xs = xs._1;
-        }
-        return fromArray(arr);
-    }
-
-    // f defined similarly for both foldl and foldr (NB: different from Haskell)
-    // ie, foldl : (a -> b -> b) -> b -> [a] -> b
-    function foldl(f, b, xs) {
-        var acc = b;
-        while (xs.ctor !== '[]') {
-            acc = A2(f, xs._0, acc);
-            xs = xs._1;
-        }
-        return acc;
-    }
-
-    function foldr(f, b, xs) {
-        var arr = toArray(xs);
-        var acc = b;
-        for (var i = arr.length; i--; ) {
-            acc = A2(f, arr[i], acc);
-        }
-        return acc;
-    }
-
-    function foldl1(f, xs) {
-        return xs.ctor === '[]' ? throwError('foldl1') : foldl(f, xs._0, xs._1);
-    }
-
-    function foldr1(f, xs) {
-        if (xs.ctor === '[]') { throwError('foldr1'); }
-        var arr = toArray(xs);
-        var acc = arr.pop();
-        for (var i = arr.length; i--; ) {
-            acc = A2(f, arr[i], acc);
-        }
-        return acc;
-    }
-
-    function scanl(f, b, xs) {
-        var arr = toArray(xs);
-        arr.unshift(b);
-        var len = arr.length;
-        for (var i = 1; i < len; ++i) {
-            arr[i] = A2(f, arr[i], arr[i-1]);
-        }
-        return fromArray(arr);
-    }
-
-    function scanl1(f, xs) {
-        return xs.ctor === '[]' ? throwError('scanl1') : scanl(f, xs._0, xs._1);
-    }
-
-    function filter(pred, xs) {
-        var arr = [];
-        while (xs.ctor !== '[]') {
-            if (pred(xs._0)) { arr.push(xs._0); }
-            xs = xs._1;
-        }
-        return fromArray(arr);
-    }
-
-    function length(xs) {
-        var out = 0;
-        while (xs.ctor !== '[]') {
-            out += 1;
-            xs = xs._1;
-        }
-        return out;
-    }
-
-    function member(x, xs) {
-        while (xs.ctor !== '[]') {
-            if (Utils.eq(x,xs._0)) return true;
-            xs = xs._1;
-        }
-        return false;
-    }
-
-    function reverse(xs) { return fromArray(toArray(xs).reverse()); }
-
-    function concat(xss) {
-        if (xss.ctor === '[]') return xss;
-        var arr = toArray(xss);
-        var xs = arr[arr.length-1];
-        for (var i = arr.length-1; i--; ) {
-	    xs = append(arr[i], xs);
-        }
-        return xs;
-    }
-
-    function all(pred, xs) {
-        while (xs.ctor !== '[]') {
-            if (!pred(xs._0)) return false;
-            xs = xs._1;
-        }
-        return true;
-    }
-
-    function any(pred, xs) {
-        while (xs.ctor !== '[]') {
-            if (pred(xs._0)) return true;
-            xs = xs._1;
-        }
-        return false;
-    }
-
-    function zipWith(f, xs, ys) {
-        var arr = [];
-        while (xs.ctor !== '[]' && ys.ctor !== '[]') {
-            arr.push(A2(f, xs._0, ys._0));
-            xs = xs._1;
-            ys = ys._1;
-        }
-        return fromArray(arr);
-    }
-
-    function zip(xs, ys) {
-        var arr = [];
-        while (xs.ctor !== '[]' && ys.ctor !== '[]') {
-            arr.push(Utils.Tuple2(xs._0, ys._0));
-            xs = xs._1;
-            ys = ys._1;
-        }
-        return fromArray(arr);
-    }
-
-    function sort(xs) {
-        return fromArray(toArray(xs).sort(Utils.cmp));
-    }
-
-    function sortBy(f, xs) {
-        return fromArray(toArray(xs).sort(function(a,b){
-            return Utils.cmp(f(a), f(b));
-        }));
-    }
-
-    function sortWith(f, xs) {
-        return fromArray(toArray(xs).sort(function(a,b){
-            var ord = f(a)(b).ctor;
-            return ord === 'EQ' ? 0 : ord === 'LT' ? -1 : 1;
-        }));
-    }
-
-    function nth(xs, n) {
-        return toArray(xs)[n];
-    }
-
-    function take(n, xs) {
-        var arr = [];
-        while (xs.ctor !== '[]' && n > 0) {
-            arr.push(xs._0);
-            xs = xs._1;
-            --n;
-        }
-        return fromArray(arr);
-    }
-
-    function drop(n, xs) {
-        while (xs.ctor !== '[]' && n > 0) {
-            xs = xs._1;
-            --n;
-        }
-        return xs;
-    }
-
-    function repeat(n, x) {
-        var arr = [];
-        var pattern = [x];
-        while (n > 0) {
-            if (n & 1) arr = arr.concat(pattern);
-            n >>= 1, pattern = pattern.concat(pattern);
-        }
-        return fromArray(arr);
-    }
-
-    function join(sep, xss) {
-        if (sep.text) {
-            sep = Utils.makeText(sep);
-            xss = toArray(xss);
-            for (var i = xss.length; i--; ) {
-                xss[i] = Utils.makeText(xss[i]);
-            }
-            return Utils.txt(xss.join(sep));
-        }
-        if (typeof sep === 'string') return toArray(xss).join(sep);
-        if (xss.ctor === '[]') return Nil;
-        var s = toArray(sep);
-        var out = toArray(xss._0);
-        xss = xss._1;
-        while (xss.ctor !== '[]') {
-            out = out.concat(s, toArray(xss._0));
-            xss = xss._1;
-        }
-        return fromArray(out);
-    }
-
-    Elm.Native.List.values = {
-        Nil:Nil,
-        Cons:Cons,
-        cons:F2(Cons),
-        toArray:toArray,
-        fromArray:fromArray,
-        range:range,
-        append:append,
-
-        head:head,
-        tail:tail,
-        last:last,
-
-        map:F2(map),
-        foldl:F3(foldl),
-        foldr:F3(foldr),
-
-        foldl1:F2(foldl1),
-        foldr1:F2(foldr1),
-        scanl:F3(scanl),
-        scanl1:F2(scanl1),
-        filter:F2(filter),
-        length:length,
-        member:F2(member),
-        reverse:reverse,
-        concat:concat,
-
-        all:F2(all),
-        any:F2(any),
-        zipWith:F3(zipWith),
-        zip:F2(zip),
-        sort:sort,
-        sortBy:F2(sortBy),
-        sortWith:F2(sortWith),
-        nth:F2(nth),
-        take:F2(take),
-        drop:F2(drop),
-        repeat:F2(repeat),
-
-        join:F2(join)
-    };
-    return elm.Native.List.values = Elm.Native.List.values;
-
-};
-Elm.Native.Ports = {};
-Elm.Native.Ports.make = function(elm) {
-    elm.Native = elm.Native || {};
-    elm.Native.Ports = elm.Native.Ports || {};
-    if (elm.Native.Ports.values) return elm.Native.Ports.values;
-
-    var Signal = Elm.Signal.make(elm);
-
-    function incomingSignal(converter) {
-        converter.isSignal = true;
-        return converter;
-    }
-
-    function outgoingSignal(converter) {
-        return function(signal) {
-            var subscribers = []
-            function subscribe(handler) {
-                subscribers.push(handler);
-            }
-            function unsubscribe(handler) {
-                subscribers.pop(subscribers.indexOf(handler));
-            }
-            A2( Signal.lift, function(value) {
-                var val = converter(value);
-                var len = subscribers.length;
-                for (var i = 0; i < len; ++i) {
-                    subscribers[i](val);
-                }
-            }, signal);
-            return { subscribe:subscribe, unsubscribe:unsubscribe };
-        }
-    }
-
-    function portIn(name, converter) {
-        var jsValue = elm.ports.incoming[name];
-        if (jsValue === undefined) {
-            throw new Error("Initialization Error: port '" + name +
-                            "' was not given an input!");
-        }
-        elm.ports.uses[name] += 1;
-        try {
-            var elmValue = converter(jsValue);
-        } catch(e) {
-            throw new Error("Initialization Error on port '" + name + "': \n" + e.message);
-        }
-
-        // just return a static value if it is not a signal
-        if (!converter.isSignal) {
-            return elmValue;
-        }
-
-        // create a signal if necessary
-        var signal = Signal.constant(elmValue);
-        function send(jsValue) {
-            try {
-                var elmValue = converter(jsValue);
-            } catch(e) {
-                throw new Error("Error sending to port '" + name + "': \n" + e.message);
-            }
-            setTimeout(function() {
-                elm.notify(signal.id, elmValue);
-            }, 0);
-        }
-        elm.ports.outgoing[name] = { send:send };
-        return signal;
-    }
-
-    function portOut(name, converter, value) {
-        try {
-            elm.ports.outgoing[name] = converter(value);
-        } catch(e) {
-            throw new Error("Initialization Error on port '" + name + "': \n" + e.message);
-        }
-        return value;
-    }
-
-    return elm.Native.Ports.values = {
-        incomingSignal: incomingSignal,
-        outgoingSignal: outgoingSignal,
-        portOut: portOut,
-        portIn: portIn
-    };
-};
-Elm.Native.Regex = {};
-Elm.Native.Regex.make = function(elm) {
-    elm.Native = elm.Native || {};
-    elm.Native.Regex = elm.Native.Regex || {};
-    if (elm.Native.Regex.values) return elm.Native.Regex.values;
-    if ('values' in Elm.Native.Regex)
-        return elm.Native.Regex.values = Elm.Native.Regex.values;
-
-    var Maybe = Elm.Maybe.make(elm);
-    var JS = Elm.JavaScript.make(elm);
-
-    function escape(str) {
-        return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
-    }
-    function caseInsensitive(re) {
-        return new RegExp(re.source, 'gi');
-    }
-    function pattern(raw) {
-        return new RegExp(raw, 'g');
-    }
-
-    function contains(re, string) {
-        return re.test(JS.fromString(string));
-    }
-
-    function findAll(re, string) {
-        return find(Infinity, re, string);
-    }
-    function find(n, re, str) {
-        var out = [];
-        var number = 0;
-        var string = JS.fromString(str);
-        var result;
-        while (number++ < n && (result = re.exec(string))) {
-            var i = result.length - 1;
-            var subs = new Array(i);
-            while (i > 0) {
-                var submatch = result[i];
-                subs[--i] = submatch === undefined
-                    ? Maybe.Nothing
-                    : Maybe.Just(JS.toString(submatch));
-            }
-            out.push({
-                _:{},
-                match: JS.toString(result[0]),
-                submatches: JS.toList(subs),
-                index: result.index,
-                number: number,
-            });
-        }
-        return JS.toList(out);
-    }
-
-    function replaceAll(re, replacer, string) {
-        return replace(Infinity, re, replacer, string);
-    }
-    function replace(n, re, replacer, string) {
-        var count = 0;
-        function jsReplacer(match) {
-            if (count++ > n) return match;
-            var i = arguments.length-3;
-            var submatches = new Array(i);
-            while (i > 0) {
-                var submatch = arguments[i];
-                submatches[--i] = submatch === undefined
-                    ? Maybe.Nothing
-                    : Maybe.Just(JS.toString(submatch));
-            }
-            return JS.fromString(replacer({
-                _:{},
-                match:match,
-                submatches:JS.toList(submatches),
-                index:arguments[i-1],
-                number:count
-            }));
-        }
-        return string.replace(re, jsReplacer);
-    }
-
-    function split(re, string) {
-        return JS.toList(JS.fromString(string).split(re));
-    }
-    function splitN(n, re, str) {
-        var string = JS.fromString(str);
-        var result;
-        var out = [];
-        var start = re.lastIndex;
-        while (n--) {
-            if (!(result = re.exec(string))) break;
-            out.push(string.slice(start, result.index));
-            start = re.lastIndex;
-        }
-        out.push(string.slice(start));
-        return JS.toList(out);
-    }
-
-    return Elm.Native.Regex.values = {
-        pattern: pattern,
-        caseInsensitive: caseInsensitive,
-        escape: escape,
-
-        contains: F2(contains),
-        findAll: F2(findAll),
-        find: F3(find),
-
-        replaceAll: F3(replaceAll),
-        replace: F4(replace),
-
-        split: F2(split),
-        splitN: F3(splitN),
-    };
-};Elm.Native.Show = {};
-Elm.Native.Show.make = function(elm) {
-    elm.Native = elm.Native || {};
-    elm.Native.Show = elm.Native.Show || {};
-    if (elm.Native.Show.values) return elm.Native.Show.values;
-
-    var NList = Elm.Native.List.make(elm);
-    var List = Elm.List.make(elm);
-    var Maybe = Elm.Maybe.make(elm);
-    var JS = Elm.JavaScript.make(elm);
-    var Dict = Elm.Dict.make(elm);
-    var Json = Elm.Json.make(elm);
-    var Tuple2 = Elm.Native.Utils.make(elm).Tuple2;
-
-    var toString = function(v) {
-        var type = typeof v;
-        if (type === "function") {
-            var name = v.func ? v.func.name : v.name;
-            return '<function' + (name === '' ? '' : ': ') + name + '>';
-        } else if (type === "boolean") {
-            return v ? "True" : "False";
-        } else if (type === "number") {
-            return v+"";
-        } else if ((v instanceof String) && v.isChar) {
-            return "'" + addSlashes(v) + "'";
-        } else if (type === "string") {
-            return '"' + addSlashes(v) + '"';
-        } else if (type === "object" && '_' in v && probablyPublic(v)) {
-            var output = [];
-            for (var k in v._) {
-                for (var i = v._[k].length; i--; ) {
-                    output.push(k + " = " + toString(v._[k][i]));
-                }
-            }
-            for (var k in v) {
-                if (k === '_') continue;
-                output.push(k + " = " + toString(v[k]));
-            }
-            if (output.length === 0) return "{}";
-            return "{ " + output.join(", ") + " }";
-        } else if (type === "object" && 'ctor' in v) {
-            if (v.ctor.substring(0,6) === "_Tuple") {
-                var output = [];
-                for (var k in v) {
-                    if (k === 'ctor') continue;
-                    output.push(toString(v[k]));
-                }
-                return "(" + output.join(",") + ")";
-            } else if (v.ctor === "::") {
-                var output = '[' + toString(v._0);
-                v = v._1;
-                while (v.ctor === "::") {
-                    output += "," + toString(v._0);
-                    v = v._1;
-                }
-                return output + ']';
-            } else if (v.ctor === "[]") {
-                return "[]";
-            } else if (v.ctor === "RBNode" || v.ctor === "RBEmpty") {
-                var cons = F3(function(k,v,acc){return NList.Cons(Tuple2(k,v),acc)});
-                var list = A3(Dict.foldr, cons, NList.Nil, v);
-                var name = "Dict";
-                if (list.ctor === "::" && list._0._1.ctor === "_Tuple0") {
-                    name = "Set";
-                    list = A2(List.map, function(x){return x._0}, list);
-                }
-                return name + ".fromList " + toString(list);
-            } else {
-                var output = "";
-                for (var i in v) {
-                    if (i === 'ctor') continue;
-                    var str = toString(v[i]);
-                    var parenless = str[0] === '{' || str[0] === '<' || str.indexOf(' ') < 0;
-                    output += ' ' + (parenless ? str : '(' + str + ')');
-                }
-                return v.ctor + output;
-            }
-        }
-        if (type === 'object' && 'recv' in v) return '<signal>';
-        return "<internal structure>";
-    };
-
-    function addSlashes(str) {
-        return str.replace(/\\/g, '\\\\')
-                  .replace(/\n/g, '\\n')
-                  .replace(/\t/g, '\\t')
-                  .replace(/\r/g, '\\r')
-                  .replace(/\v/g, '\\v')
-                  .replace(/\0/g, '\\0')
-                  .replace(/\'/g, "\\'")
-                  .replace(/\"/g, '\\"');
-    }
-
-    function probablyPublic(v) {
-        var keys = Object.keys(v);
-        var len = keys.length;
-        if (len === 3
-            && 'props' in v
-            && 'element' in v) return false;
-        if (len === 5
-            && 'horizontal' in v
-            && 'vertical' in v
-            && 'x' in v
-            && 'y' in v) return false;
-        if (len === 7
-            && 'theta' in v
-            && 'scale' in v
-            && 'x' in v
-            && 'y' in v
-            && 'alpha' in v
-            && 'form' in v) return false;
-        return true;
-    }
-
-    return elm.Native.Show.values = { show:toString };
-};
-Elm.Native.String = {};
-Elm.Native.String.make = function(elm) {
-    elm.Native = elm.Native || {};
-    elm.Native.String = elm.Native.String || {};
-    if (elm.Native.String.values) return elm.Native.String.values;
-    if ('values' in Elm.Native.String)
-        return elm.Native.String.values = Elm.Native.String.values;
-
-    var Char = Elm.Char.make(elm);
-    var Maybe = Elm.Maybe.make(elm);
-    var JS = Elm.JavaScript.make(elm);
-    var Utils = Elm.Native.Utils.make(elm);
-
-    function isEmpty(str) {
-        return str.length === 0;
-    }
-    function cons(chr,str) {
-        return chr + str;
-    }
-    function uncons(str) {
-        var hd;
-        return (hd = str[0]) ? Maybe.Just(Utils.Tuple2(Utils.chr(hd), str.slice(1)))
-                              : Maybe.Nothing;
-    }
-    function append(a,b) {
-        return a + b;
-    }
-    function concat(strs) {
-        return JS.fromList(strs).join('');
-    }
-    function length(str) {
-        return str.length;
-    }
-    function map(f,str) {
-        var out = str.split('');
-        for (var i = out.length; i--; ) {
-            out[i] = f(Utils.chr(out[i]));
-        }
-        return out.join('');
-    }
-    function filter(pred,str) {
-        return str.split('').map(Utils.chr).filter(pred).join('');
-    }
-    function reverse(str) {
-        return str.split('').reverse().join('');
-    }
-    function foldl(f,b,str) {
-        var len = str.length;
-        for (var i = 0; i < len; ++i) {
-            b = A2(f, Utils.chr(str[i]), b);
-        }
-        return b;
-    }
-    function foldr(f,b,str) {
-        for (var i = str.length; i--; ) {
-            b = A2(f, Utils.chr(str[i]), b);
-        }
-        return b;
-    }
-
-    function split(sep, str) {
-        return JS.toList(str.split(sep));
-    }
-    function join(sep, strs) {
-        return JS.fromList(strs).join(sep);
-    }
-    function repeat(n, str) {
-        var result = '';
-        while (n > 0) {
-            if (n & 1) result += str;
-            n >>= 1, str += str;
-        }
-        return result;
-    }
-
-    function sub(start, end, str) {
-        return str.slice(start,end);
-    }
-    function left(n, str) {
-        return n < 1 ? "" : str.slice(0,n);
-    }
-    function right(n, str) {
-        return n < 1 ? "" : str.slice(-n);
-    }
-    function dropLeft(n, str) {
-        return n < 1 ? str : str.slice(n);
-    }
-    function dropRight(n, str) {
-        return n < 1 ? str : str.slice(0,-n);
-    }
-
-    function pad(n,chr,str) {
-        var half = (n - str.length) / 2;
-        return repeat(Math.ceil(half),chr) + str + repeat(half|0,chr);
-    }
-    function padRight(n,chr,str) {
-        return str + repeat(n - str.length, chr);
-    }
-    function padLeft(n,chr,str) {
-        return repeat(n - str.length, chr) + str;
-    }
-
-    function trim(str) {
-        return str.trim();
-    }
-    function trimLeft(str) {
-        return str.trimLeft();
-    }
-    function trimRight(str) {
-        return str.trimRight();
-    }
-
-    function words(str) {
-        return JS.toList(str.split(/\s+/g));
-    }
-    function lines(str) {
-        return JS.toList(str.split(/\r\n|\r|\n/g));
-    }
-
-    function toUpper(str) {
-        return str.toUpperCase();
-    }
-    function toLower(str) {
-        return str.toLowerCase();
-    }
-
-    function any(pred, str) {
-        for (var i = str.length; i--; ) {
-            if (pred(Utils.chr(str[i]))) return true;
-        }
-        return false;
-    }
-    function all(pred, str) {
-        for (var i = str.length; i--; ) {
-            if (!pred(Utils.chr(str[i]))) return false;
-        }
-        return true;
-    }
-
-    function contains(sub, str) {
-        return str.indexOf(sub) > -1;
-    }
-    function startsWith(sub, str) {
-        return str.indexOf(sub) === 0;
-    }
-    function endsWith(sub, str) {
-        return str.lastIndexOf(sub) === str.length - sub.length;
-    }
-    function indexes(sub, str) {
-        var subLen = sub.length;
-        var i = 0;
-        var is = [];
-        while ((i = str.indexOf(sub, i)) > -1) {
-            is.push(i);
-            i = i + subLen;
-        }
-        return JS.toList(is);
-    }
-
-    function toInt(s) {
-        var len = s.length;
-        if (len === 0) { return Maybe.Nothing; }
-        var start = 0;
-        if (s[0] == '-') {
-            if (len === 1) { return Maybe.Nothing; }
-            start = 1;
-        }
-        for (var i = start; i < len; ++i) {
-            if (!Char.isDigit(s[i])) { return Maybe.Nothing; }
-        }
-        return Maybe.Just(parseInt(s, 10));
-    }
-
-    function toFloat(s) {
-        var len = s.length;
-        if (len === 0) { return Maybe.Nothing; }
-        var start = 0;
-        if (s[0] == '-') {
-            if (len === 1) { return Maybe.Nothing; }
-            start = 1;
-        }
-        var dotCount = 0;
-        for (var i = start; i < len; ++i) {
-            if (Char.isDigit(s[i])) { continue; }
-            if (s[i] === '.') {
-                dotCount += 1;
-                if (dotCount <= 1) { continue; }
-            }
-            return Maybe.Nothing;
-        }
-        return Maybe.Just(parseFloat(s));
-    }
-
-    function toList(str) {
-        return JS.toList(str.split('').map(Utils.chr));
-    }
-    function fromList(chars) {
-        return JS.fromList(chars).join('');
-    }
-
-    return Elm.Native.String.values = {
-        isEmpty: isEmpty,
-        cons: F2(cons),
-        uncons: uncons,
-        append: F2(append),
-        concat: concat,
-        length: length,
-        map: F2(map),
-        filter: F2(filter),
-        reverse: reverse,
-        foldl: F3(foldl),
-        foldr: F3(foldr),
-
-        split: F2(split),
-        join: F2(join),
-        repeat: F2(repeat),
-
-        sub: F3(sub),
-        left: F2(left),
-        right: F2(right),
-        dropLeft: F2(dropLeft),
-        dropRight: F2(dropRight),
-
-        pad: F3(pad),
-        padLeft: F3(padLeft),
-        padRight: F3(padRight),
-
-        trim: trim,
-        trimLeft: trimLeft,
-        trimRight: trimRight,
-
-        words: words,
-        lines: lines,
-
-        toUpper: toUpper,
-        toLower: toLower,
-
-        any: F2(any),
-        all: F2(all),
-
-        contains: F2(contains),
-        startsWith: F2(startsWith),
-        endsWith: F2(endsWith),
-        indexes: F2(indexes),
-
-        toInt: toInt,
-        toFloat: toFloat,
-        toList: toList,
-        fromList: fromList,
-    };
-};Elm.Native.Text = {};
-Elm.Native.Text.make = function(elm) {
-    elm.Native = elm.Native || {};
-    elm.Native.Text = elm.Native.Text || {};
-    if (elm.Native.Text.values) return elm.Native.Text.values;
-
-    var JS = Elm.JavaScript.make(elm);
-    var Utils = Elm.Native.Utils.make(elm);
-    var Color = Elm.Native.Color.make(elm);
-    var Element = Elm.Graphics.Element.make(elm);
-    var show = Elm.Native.Show.make(elm).show;
-
-    function makeSpaces(s) {
-        if (s.length == 0) { return s; }
-        var arr = s.split('');
-        if (arr[0] == ' ') { arr[0] = "&nbsp;" }      
-        for (var i = arr.length; --i; ) {
-            if (arr[i][0] == ' ' && arr[i-1] == ' ') {
-                arr[i-1] = arr[i-1] + arr[i];
-                arr[i] = '';
-            }
-        }
-        for (var i = arr.length; i--; ) {
-            if (arr[i].length > 1 && arr[i][0] == ' ') {
-                var spaces = arr[i].split('');
-                for (var j = spaces.length - 2; j >= 0; j -= 2) {
-                    spaces[j] = '&nbsp;';
-                }
-                arr[i] = spaces.join('');
-            }
-        }
-        arr = arr.join('');
-        if (arr[arr.length-1] === " ") {
-	    return arr.slice(0,-1) + '&nbsp;';
-        }
-        return arr;
-    }
-
-    function properEscape(str) {
-        if (str.length == 0) return str;
-        str = str //.replace(/&/g,  "&#38;")
-	    .replace(/"/g,  '&#34;')
-	    .replace(/'/g,  "&#39;")
-	    .replace(/</g,  "&#60;")
-	    .replace(/>/g,  "&#62;")
-	    .replace(/\n/g, "<br/>");
-        var arr = str.split('<br/>');
-        for (var i = arr.length; i--; ) {
-	    arr[i] = makeSpaces(arr[i]);
-        }
-        return arr.join('<br/>');
-    }
-
-    function toText(str) { return Utils.txt(properEscape(JS.fromString(str))); }
-
-    function height(px, text) {
-        return { style: 'font-size:' + px + 'px;', text:text }
-    }
-    function typeface(name, text) {
-        return { style: 'font-family:' + name + ';', text:text }
-    }
-    function monospace(text) {
-        return { style: 'font-family:monospace;', text:text }
-    }
-    function italic(text) {
-        return { style: 'font-style:italic;', text:text }
-    }
-    function bold(text) {
-        return { style: 'font-weight:bold;', text:text }
-    }
-    function link(href, text) {
-        return { href: toText(href), text:text };
-    }
-    function underline(text) {
-        return { line: ' underline', text:text };
-    }
-    function overline(text) {
-        return { line: ' overline', text:text };
-    }
-    function strikeThrough(text) {
-        return { line: ' line-through', text:text };
-    }
-
-    function color(c, text) {
-        var color = (c._3 === 1)
-            ? ('rgb(' + c._0 + ', ' + c._1 + ', ' + c._2 + ')')
-            : ('rgba(' + c._0 + ', ' + c._1 + ', ' + c._2 + ', ' + c._3 + ')');
-        return { style: 'color:' + color + ';', text:text };
-    }
-
-    function position(align) {
-        function create(text) {
-            var raw = {
-                ctor :'RawHtml',
-                html : Utils.makeText(text),
-                align: align,
-                guid : null,
-                args : [],
-            };
-            var pos = A2(Utils.htmlHeight, 0, raw);
-            return A3(Element.newElement, pos._0, pos._1, raw);
-        }
-        return create;
-    }
-
-    function markdown(text, guid) {
-        var raw = {
-            ctor:'RawHtml',
-            html: text,
-            align: null,
-            guid: guid,
-            args: [],
-        };
-        var pos = A2(Utils.htmlHeight, 0, raw);
-        return A3(Element.newElement, pos._0, pos._1, raw);
-    }
-
-    var text = position('left');
-    function asText(v) {
-        return text(monospace(toText(show(v))));
-    }
-
-    function plainText(v) {
-        return text(toText(v));
-    }
-
-    return elm.Native.Text.values = {
-        toText: toText,
-
-        height : F2(height),
-        italic : italic,
-        bold : bold,
-        underline : underline,
-        overline : overline,
-        strikeThrough : strikeThrough,
-        monospace : monospace,
-        typeface : F2(typeface),
-        color : F2(color),
-        link : F2(link),
-
-        justified : position('justify'),
-        centered : position('center'),
-        righted : position('right'),
-        text : text,
-        plainText : plainText,
-        markdown : markdown,
-
-        asText : asText,
-    };
-};
-Elm.Native.Transform2D = {};
-Elm.Native.Transform2D.make = function(elm) {
-
- elm.Native = elm.Native || {};
- elm.Native.Transform2D = elm.Native.Transform2D || {};
- if (elm.Native.Transform2D.values) return elm.Native.Transform2D.values;
-
- var A;
- if (typeof Float32Array === 'undefined') {
-     A = function(arr) {
-         this.length = arr.length;
-         this[0] = arr[0];
-         this[1] = arr[1];
-         this[2] = arr[2];
-         this[3] = arr[3];
-         this[4] = arr[4];
-         this[5] = arr[5];
-     };
- } else {
-     A = Float32Array;
- }
-
- // layout of matrix in an array is
- //
- //   | m11 m12 dx |
- //   | m21 m22 dy |
- //   |  0   0   1 |
- //
- //  new A([ m11, m12, dx, m21, m22, dy ])
-
- var identity = new A([1,0,0,0,1,0]);
- function matrix(m11, m12, m21, m22, dx, dy) {
-     return new A([m11, m12, dx, m21, m22, dy]);
- }
- function rotation(t) {
-     var c = Math.cos(t);
-     var s = Math.sin(t);
-     return new A([c, -s, 0, s, c, 0]);
- }
- function rotate(t,m) {
-     var c = Math.cos(t);
-     var s = Math.sin(t);
-     var m11 = m[0], m12 = m[1], m21 = m[3], m22 = m[4];
-     return new A([m11*c + m12*s, -m11*s + m12*c, m[2],
-                   m21*c + m22*s, -m21*s + m22*c, m[5]]);
- }
- /*
- function move(xy,m) {
-     var x = xy._0;
-     var y = xy._1;
-     var m11 = m[0], m12 = m[1], m21 = m[3], m22 = m[4];
-     return new A([m11, m12, m11*x + m12*y + m[2],
-                   m21, m22, m21*x + m22*y + m[5]]);
- }
- function scale(s,m) { return new A([m[0]*s, m[1]*s, m[2], m[3]*s, m[4]*s, m[5]]); }
- function scaleX(x,m) { return new A([m[0]*x, m[1], m[2], m[3]*x, m[4], m[5]]); }
- function scaleY(y,m) { return new A([m[0], m[1]*y, m[2], m[3], m[4]*y, m[5]]); }
- function reflectX(m) { return new A([-m[0], m[1], m[2], -m[3], m[4], m[5]]); }
- function reflectY(m) { return new A([m[0], -m[1], m[2], m[3], -m[4], m[5]]); }
-
- function transform(m11, m21, m12, m22, mdx, mdy, n) {
-     var n11 = n[0], n12 = n[1], n21 = n[3], n22 = n[4], ndx = n[2], ndy = n[5];
-     return new A([m11*n11 + m12*n21,
-                   m11*n12 + m12*n22,
-                   m11*ndx + m12*ndy + mdx,
-                   m21*n11 + m22*n21,
-                   m21*n12 + m22*n22,
-                   m21*ndx + m22*ndy + mdy]);
- }
- */
- function multiply(m, n) {
-     var m11 = m[0], m12 = m[1], m21 = m[3], m22 = m[4], mdx = m[2], mdy = m[5];
-     var n11 = n[0], n12 = n[1], n21 = n[3], n22 = n[4], ndx = n[2], ndy = n[5];
-     return new A([m11*n11 + m12*n21,
-                   m11*n12 + m12*n22,
-                   m11*ndx + m12*ndy + mdx,
-                   m21*n11 + m22*n21,
-                   m21*n12 + m22*n22,
-                   m21*ndx + m22*ndy + mdy]);
- }
-
- return elm.Native.Transform2D.values = {
-     identity:identity,
-     matrix:F6(matrix),
-     rotation:rotation,
-     multiply:F2(multiply)
-     /*
-     transform:F7(transform),
-     rotate:F2(rotate),
-     move:F2(move),
-     scale:F2(scale),
-     scaleX:F2(scaleX),
-     scaleY:F2(scaleY),
-     reflectX:reflectX,
-     reflectY:reflectY
-     */
- };
-
-};
-Elm.Native.Utils = {};
-Elm.Native.Utils.make = function(elm) {
-
-    elm.Native = elm.Native || {};
-    elm.Native.Utils = elm.Native.Utils || {};
-    if (elm.Native.Utils.values) return elm.Native.Utils.values;
-
-    function eq(x,y) {
-        if (x === y) return true;
-        if (typeof x === "object") {
-            var c = 0;
-            for (var i in x) { ++c; if (!eq(x[i],y[i])) return false; }
-            return c === Object.keys(y).length;
-        }
-        if (typeof x === 'function') {
-            throw new Error('Equality error: general function equality is ' +
-                            'undecidable, and therefore, unsupported');
-        }
-        return x === y;
-    }
-
-    // code in Generate/JavaScript.hs depends on the particular
-    // integer values assigned to LT, EQ, and GT
-    var LT = -1, EQ = 0, GT = 1, ord = ['LT','EQ','GT'];
-    function compare(x,y) { return { ctor: ord[cmp(x,y)+1] } }
-    function cmp(x,y) {
-        var ord;
-        if (typeof x !== 'object' || x instanceof String){
-            return x === y ? EQ : x < y ? LT : GT;
-        }
-
-        if (x.ctor === "::" || x.ctor === "[]") {
-            while (true) {
-                if (x.ctor === "[]" && y.ctor === "[]") return EQ;
-                if (x.ctor !== y.ctor) return x.ctor === '[]' ? LT : GT;
-                ord = cmp(x._0, y._0);
-                if (ord !== EQ) return ord;
-                x = x._1;
-                y = y._1;
-            }
-        }
-
-        if (x.ctor.slice(0,6) === '_Tuple') {
-            var n = x.ctor.slice(6) - 0;
-            var err = 'cannot compare tuples with more than 6 elements.';
-            if (n === 0) return EQ;
-            if (n >= 1) { ord = cmp(x._0, y._0); if (ord !== EQ) return ord;
-            if (n >= 2) { ord = cmp(x._1, y._1); if (ord !== EQ) return ord;
-            if (n >= 3) { ord = cmp(x._2, y._2); if (ord !== EQ) return ord;
-            if (n >= 4) { ord = cmp(x._3, y._3); if (ord !== EQ) return ord;
-            if (n >= 5) { ord = cmp(x._4, y._4); if (ord !== EQ) return ord;
-            if (n >= 6) { ord = cmp(x._5, y._5); if (ord !== EQ) return ord;
-            if (n >= 7) throw new Error('Comparison error: ' + err); } } } } } }
-            return EQ;
-        }
-        throw new Error('Comparison error: comparison is only defined on ints, ' +
-                        'floats, times, chars, strings, lists of comparable values, ' +
-                        'and tuples of comparable values.')
-    }
-
-
-    var Tuple0 = { ctor: "_Tuple0" };
-    function Tuple2(x,y) { return { ctor:"_Tuple2", _0:x, _1:y } }
-
-    function chr(c) {
-        var x = new String(c);
-        x.isChar = true;
-        return x;
-    }
-
-    function txt(str) {
-        var t = new String(str);
-        t.text = true;
-        return t;
-    }
-
-    function makeText(text) {
-        var style = '';
-        var line = '';
-        var href = '';
-        while (true) {
-            if (text.line) {
-                line += text.line;
-                text = text.text;
-                continue;
-            }
-            if (text.style) {
-                style += text.style;
-                text = text.text;
-                continue;
-            }
-            if (text.href) {
-                href = text.href;
-                text = text.text;
-                continue;
-            }
-            if (href) text = '<a href="' + href + '">' + text + '</a>';
-            if (line) style += 'text-decoration:' + line + ';';
-            if (style) text = '<span style="' + style + '">' + text + '</span>';
-            return text;
-        }
-    }
-
-    var count = 0;
-    function guid(_) { return count++ }
-
-    function copy(r) {
-        var o = {};
-        for (var i in r) { o[i] = r[i]; }
-        return o;
-    }
-
-    function remove(x,r) {
-        var o = copy(r);
-        if (x in o._) {
-            o[x] = o._[x][0];
-            o._[x] = o._[x].slice(1);
-            if (o._[x].length === 0) { delete o._[x]; }
-        } else {
-            delete o[x];
-        }
-        return o;
-    }
-
-    function replace(kvs,r) {
-        var o = copy(r);
-        for (var i = kvs.length; i--; ) {
-            var kvsi = kvs[i];
-            o[kvsi[0]] = kvsi[1];
-        }
-        return o;
-    }
-
-    function insert(x,v,r) {
-        var o = copy(r);
-        if (x in o) o._[x] = [o[x]].concat(x in o._ ? o._[x].slice(0) : []);
-        o[x] = v;
-        return o;
-    }
-
-    function max(a,b) { return a > b ? a : b }
-    function min(a,b) { return a < b ? a : b }
-
-    function mod(a,b) {
-        if (b === 0) {
-            throw new Error("Cannot perform mod 0. Division by zero error.");
-        }
-        var r = a % b;
-        var m = a === 0 ? 0 : (b > 0 ? (a >= 0 ? r : r+b) : -mod(-a,-b));
-
-        return m === b ? 0 : m;
-    }
-
-    function htmlHeight(width, rawHtml) {
-        // create dummy node
-        var html = rawHtml.html;
-        var t = document.createElement('div');
-        t.innerHTML = html;
-        if (width > 0) { t.style.width = width + "px"; }
-        t.style.visibility = "hidden";
-        t.style.styleFloat = "left";
-        t.style.cssFloat   = "left";
-
-        document.body.appendChild(t);
-
-        // insert interpolated values
-        var args = rawHtml.args;
-        var guid = rawHtml.guid;
-        for (var i = args.length; i--; ) {
-            var arg = args[i];
-            var span = document.getElementById('md-' + guid + '-' + i);
-            if (arg.isElement) {
-                span.style.width = arg.props.width + 'px';
-                span.style.height = arg.props.height + 'px';
-            } else {
-                span.innerHTML = arg;
-            }
-        }
-
-        // get dimensions
-        var style = window.getComputedStyle(t, null);
-        var w = Math.ceil(style.getPropertyValue("width").slice(0,-2) - 0);
-        var h = Math.ceil(style.getPropertyValue("height").slice(0,-2) - 0);
-        document.body.removeChild(t);
-        return Tuple2(w,h);
-    }
-
-    function getXY(e) {
-        var posx = 0;
-        var posy = 0;
-        if (e.pageX || e.pageY) {
-            posx = e.pageX;
-            posy = e.pageY;
-        } else if (e.clientX || e.clientY) {
-            posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
-            posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
-        }
-
-        if (elm.display === ElmRuntime.Display.COMPONENT) {
-            var rect = elm.node.getBoundingClientRect();
-            var relx = rect.left + document.body.scrollLeft + document.documentElement.scrollLeft;
-            var rely = rect.top + document.body.scrollTop + document.documentElement.scrollTop;
-            // TODO: figure out if there is a way to avoid rounding here
-            posx = posx - Math.round(relx) - elm.node.clientLeft;
-            posy = posy - Math.round(rely) - elm.node.clientTop;
-        }
-        return Tuple2(posx, posy);
-    }
-
-    return elm.Native.Utils.values = {
-        eq:eq,
-        cmp:cmp,
-        compare:F2(compare),
-        Tuple0:Tuple0,
-        Tuple2:Tuple2,
-        chr:chr,
-        txt:txt,
-        makeText:makeText,
-        copy: copy,
-        remove: remove,
-        replace: replace,
-        insert: insert,
-        guid: guid,
-        max : F2(max),
-        min : F2(min),
-        mod : F2(mod),
-        htmlHeight: F2(htmlHeight),
-        getXY: getXY,
-        toFloat: function(x) { return +x; }
-    };
-};
-Elm.Native.Graphics.Collage = {};
-Elm.Native.Graphics.Collage.make = function(elm) {
-
- elm.Native = elm.Native || {};
- elm.Native.Graphics = elm.Native.Graphics || {};
- elm.Native.Graphics.Collage = elm.Native.Graphics.Collage || {};
- if (elm.Native.Graphics.Collage.values) return elm.Native.Graphics.Collage.values;
-
- var newElement = Elm.Graphics.Element.make(elm).newElement;
- var C = ElmRuntime.use(ElmRuntime.Render.Collage);
-
- function collage(w,h,forms) {
-     return A3(newElement, w, h, {
-                 ctor: 'Custom',
-		 type: 'Collage',
-		 render: C.render,
-		 update: C.update,
-		 model: {w:w, h:h, forms:forms}
-	 });
- }
- return elm.Native.Graphics.Collage.values = { collage:F3(collage) };
-
-};Elm.Native.Graphics.Input = {};
-Elm.Native.Graphics.Input.make = function(elm) {
-
- elm.Native = elm.Native || {};
- elm.Native.Graphics = elm.Native.Graphics || {};
- elm.Native.Graphics.Input = elm.Native.Graphics.Input || {};
- if (elm.Native.Graphics.Input.values) return elm.Native.Graphics.Input.values;
-
- var Render = ElmRuntime.use(ElmRuntime.Render.Element);
- var newNode = ElmRuntime.use(ElmRuntime.Render.Utils).newElement;
-
- var Signal = Elm.Signal.make(elm);
- var newElement = Elm.Graphics.Element.make(elm).newElement;
- var JS = Elm.Native.JavaScript.make(elm);
- var Utils = Elm.Native.Utils.make(elm);
- var Tuple2 = Utils.Tuple2;
-
- function dropDown(values) {
-     var entries = JS.fromList(values);
-     var events = Signal.constant(entries[0]._1);
-
-     var drop = newNode('select');
-     drop.style.border = '0 solid';
-     for (var i = 0; i < entries.length; ++i) {
-         var option = newNode('option');
-         var name = JS.fromString(entries[i]._0);
-         option.value = name;
-         option.innerHTML = name;
-         drop.appendChild(option);
-     }
-     drop.addEventListener('change', function() {
-             elm.notify(events.id, entries[drop.selectedIndex]._1);
-         });
-
-     var t = drop.cloneNode(true);
-     t.style.visibility = "hidden";
-
-     elm.node.appendChild(t);
-     var style = window.getComputedStyle(t, null);
-     var w = Math.ceil(style.getPropertyValue("width").slice(0,-2) - 0);
-     var h = Math.ceil(style.getPropertyValue("height").slice(0,-2) - 0);
-     elm.node.removeChild(t);
-     
-     var element = A3(newElement, w, h, {
-             ctor: 'Custom',
-             type: 'DropDown',
-             render: function render(model) { return drop; },
-             update: function update(node, oldModel, newModel) {},
-             model: {}
-         });
-
-     return Tuple2(Signal.constant(element), events);
- }
-
- function buttons(defaultValue) {
-     var events = Signal.constant(defaultValue);
-
-     function render(model) {
-         var b = newNode('button');
-         b.style.display = 'block';
-         b.elmEvent = model.event;
-         function click() { elm.notify(events.id, b.elmEvent); }
-         b.addEventListener('click', click);
-         b.innerHTML = model.text;
-         return b;
-     }
-
-     function update(node, oldModel, newModel) {
-         node.elmEvent = newModel.event;
-         var txt = newModel.text;
-         if (oldModel.text !== txt) node.innerHTML = txt;
-     }
-
-     function button(evnt, txt) {
-         return A3(newElement, 100, 40, {
-                     ctor: 'Custom',
-                     type: 'Button',
-                     render: render,
-                     update: update,
-                     model: { event:evnt, text:JS.fromString(txt) }
-             });
-     }
-
-     return { _:{}, button:F2(button), events:events };
- }
-
- function customButtons(defaultValue) {
-     var events = Signal.constant(defaultValue);
-
-     function render(model) {
-         var btn = newNode('div');
-         btn.elmEvent = model.event;
-
-         btn.elmUp    = Render.render(model.up);
-         btn.elmHover = Render.render(model.hover);
-         btn.elmDown  = Render.render(model.down);
-
-         function replace(node) {
-           if (node !== btn.firstChild) btn.replaceChild(node, btn.firstChild);
-         }
-         var overCount = 0;
-         function over(e) {
-             if (overCount++ > 0) return;
-             replace(btn.elmHover);
-         }
-         function out(e) {
-             if (btn.contains(e.toElement || e.relatedTarget)) return;
-             overCount = 0;
-             replace(btn.elmUp);
-         }
-         function up() {
-             replace(btn.elmHover);
-             elm.notify(events.id, btn.elmEvent);
-         }
-         function down() { replace(btn.elmDown); }
-         btn.addEventListener('mouseover', over);
-         btn.addEventListener('mouseout' , out);
-         btn.addEventListener('mousedown', down);
-         btn.addEventListener('mouseup'  , up);
-
-         btn.appendChild(btn.elmUp);
-
-         var clicker = newNode('div');
-         clicker.style.width = btn.elmUp.style.width;
-         clicker.style.height = btn.elmUp.style.height;
-         clicker.style.position = 'absolute';
-         clicker.style.top = 0;
-         btn.appendChild(clicker);
-
-         return btn;
-     }
-
-     function update(node, oldModel, newModel) {
-         node.elmEvent = newModel.event;
-         Render.update(node.elmUp, oldModel.up, newModel.up)
-         Render.update(node.elmHover, oldModel.hover, newModel.hover)
-         Render.update(node.elmDown, oldModel.down, newModel.down)
-     }
-
-     function button(evnt, up, hover, down) {
-         return A3(newElement,
-                   Math.max(up.props.width, hover.props.width, down.props.width),
-                   Math.max(up.props.height, hover.props.height, down.props.height),
-                   { ctor: 'Custom',
-                     type: 'CustomButton',
-                     render: render,
-                     update: update,
-                     model: { event:evnt, up:up, hover:hover, down:down }
-                   });
-     }
-
-     return { _:{}, customButton:F4(button), events:events };
- }
-
-
- function hoverables(defaultValue) {
-     var events = Signal.constant(defaultValue);
-     function hoverable(handler, elem) {
-         function onHover(bool) {
-             elm.notify(events.id, handler(bool));
-         }
-         var props = Utils.replace([['hover',onHover]], elem.props);
-         return { props:props, element:elem.element };
-     }
-     return { _:{}, hoverable:F2(hoverable), events:events };
- }
-
-
- function checkboxes(defaultValue) {
-     var events = Signal.constant(defaultValue);
-
-     function render(model) {
-         var b = newNode('input');
-         b.type = 'checkbox';
-         b.checked = model.checked;
-         b.style.display = 'block';
-         b.elmHandler = model.handler;
-         function change() { elm.notify(events.id, b.elmHandler(b.checked)); }
-         b.addEventListener('change', change);
-         return b;
-     }
-
-     function update(node, oldModel, newModel) {
-         node.elmHandler = newModel.handler;
-         node.checked = newModel.checked;
-         return true;
-     }
-
-     function box(handler, checked) {
-         return A3(newElement, 13, 13, {
-                     ctor: 'Custom',
-                     type: 'CheckBox',
-                     render: render,
-                     update: update,
-                     model: { checked:checked, handler:handler  }
-             });
-     }
-
-     return { _:{}, checkbox:F2(box), events:events };
- }
-
- function setRange(node, start, end, dir) {
-     if (node.parentNode) {
-         node.setSelectionRange(start, end, dir);
-     } else {
-         setTimeout(function(){node.setSelectionRange(start, end, dir);}, 0);
-     }
- }
-
- function mkTextPool(type) { return function fields(defaultValue) {
-     var events = Signal.constant(defaultValue);
-
-     var state = null;
-
-     function render(model) {
-         var field = newNode('input');
-         field.elmHandler = model.handler;
-
-         field.id = 'test';
-         field.type = type;
-         field.placeholder = JS.fromString(model.placeHolder);
-         field.value = JS.fromString(model.state.string);
-         setRange(field, model.state.selectionStart, model.state.selectionEnd, 'forward');
-         field.style.border = 'none';
-         state = model.state;
-
-         function update() {
-             var start = field.selectionStart,
-                 end = field.selectionEnd;
-             if (field.selectionDirection === 'backward') {
-                 start = end;
-                 end = field.selectionStart;
-             }
-             state = { _:{},
-                       string:JS.toString(field.value),
-                       selectionStart:start,
-                       selectionEnd:end };
-             elm.notify(events.id, field.elmHandler(state));
-         }
-         function mousedown() {
-             update();
-             elm.node.addEventListener('mouseup', mouseup);
-         }
-         function mouseup() {
-             update();
-             elm.node.removeEventListener('mouseup', mouseup)
-         }
-         field.addEventListener('keyup', update);
-         field.addEventListener('mousedown', mousedown);
-
-         return field;
-     }
-
-     function update(node, oldModel, newModel) {
-         node.elmHandler = newModel.handler;
-         if (state === newModel.state) return;
-         var newStr = JS.fromString(newModel.state.string);
-         if (node.value !== newStr) node.value = newStr;
-
-         var start = newModel.state.selectionStart;
-         var end = newModel.state.selectionEnd;
-         var direction = 'forward';
-         if (end < start) {
-             start = end;
-             end = newModel.state.selectionStart;
-             direction = 'backward';
-         }
- 
-         if (node.selectionStart !== start
-             || node.selectionEnd !== end
-             || node.selectionDirection !== direction) {
-             setRange(node, start, end, direction);
-         }
-     }
-
-     function field(handler, placeHolder, state) {
-         return A3(newElement, 200, 30,
-                   { ctor: 'Custom',
-                     type: type + 'Input',
-                     render: render,
-                     update: update,
-                     model: { handler:handler,
-                              placeHolder:placeHolder,
-                              state:state }
-                   });
-     }
-
-     return { _:{}, field:F3(field), events:events };
-   }
- }
-
- return elm.Native.Graphics.Input.values = {
-     buttons:buttons,
-     customButtons:customButtons,
-     hoverables:hoverables,
-     checkboxes:checkboxes,
-     fields:mkTextPool('text'),
-     emails:mkTextPool('email'),
-     passwords:mkTextPool('password'),
-     dropDown:dropDown
- };
-
-};
-Elm.Native.Http = {};
-Elm.Native.Http.make = function(elm) {
-
-  elm.Native = elm.Native || {};
-  elm.Native.Http = elm.Native.Http || {};
-  if (elm.Native.Http.values) return elm.Native.Http.values;
-
-
-  var JS = Elm.JavaScript.make(elm);
-  var List = Elm.List.make(elm);
-  var Signal = Elm.Signal.make(elm);
-
-
-  function registerReq(queue,responses) { return function(req) {
-    if (req.url.ctor !== '[]') { sendReq(queue,responses,req); }
-   };
-  }
-
-  function updateQueue(queue,responses) {
-    if (queue.length > 0) {
-      elm.notify(responses.id, queue[0].value);
-      if (queue[0].value.ctor !== 'Waiting') {
-        queue.shift();
-        setTimeout(function() { updateQueue(queue,responses); }, 0);
-      }
-    }
-  }
-
-  function sendReq(queue,responses,req) {
-    var response = { value: { ctor:'Waiting' } };
-    queue.push(response);
-
-    var request = null;
-    if (window.ActiveXObject)  { request = new ActiveXObject("Microsoft.XMLHTTP"); }
-    if (window.XMLHttpRequest) { request = new XMLHttpRequest(); }
-    request.onreadystatechange = function(e) {
-      if (request.readyState === 4) {
-        response.value = (request.status >= 200 && request.status < 300 ?
-        { ctor:'Success', _0:JS.toString(request.responseText) } :
-        { ctor:'Failure', _0:request.status, _1:JS.toString(request.statusText) });
-        setTimeout(function() { updateQueue(queue,responses); }, 0);
-      }
-    };
-    request.open(JS.fromString(req.verb), JS.fromString(req.url), true);
-    function setHeader(pair) {
-      request.setRequestHeader( JS.fromString(pair._0), JS.fromString(pair._1) );
-    }
-    List.map(setHeader)(req.headers);
-    request.send(JS.fromString(req.body));
-  }
-
-  function send(requests) {
-    var responses = Signal.constant(elm.Http.values.Waiting);
-    var sender = A2( Signal.lift, registerReq([],responses), requests );
-    function f(x) { return function(y) { return x; } }
-    return A3( Signal.lift2, f, responses, sender );
-  }
-
-  return elm.Native.Http.values = {send:send};
-
-};
-Elm.Native.Keyboard = {};
-Elm.Native.Keyboard.make = function(elm) {
-
-  elm.Native = elm.Native || {};
-  elm.Native.Keyboard = elm.Native.Keyboard || {};
-  if (elm.Native.Keyboard.values) return elm.Native.Keyboard.values;
-
-  // Duplicated from Native.Signal
-  function send(node, timestep, changed) {
-    var kids = node.kids;
-    for (var i = kids.length; i--; ) {
-      kids[i].recv(timestep, changed, node.id);
-    }
-  }
-
-  var Signal = Elm.Signal.make(elm);
-  var NList = Elm.Native.List.make(elm);
-  var Utils = Elm.Native.Utils.make(elm);
-
-  var downEvents = Signal.constant(0);
-  var upEvents = Signal.constant(0);
-  var blurEvents = Signal.constant(0);
-
-  elm.addListener([downEvents.id], document, 'keydown', function down(e) {
-    elm.notify(downEvents.id, e.keyCode);
-  });
-
-  elm.addListener([upEvents.id], document, 'keyup', function up(e) {
-    elm.notify(upEvents.id, e.keyCode);
-  });
-
-  elm.addListener([blurEvents.id], document, 'blur', function blur(e) {
-    elm.notify(blurEvents.id, NList.Nil);
-  });
-
-  function KeyMerge(down, up, blur) {
-    var args = [down,up,blur];
-    this.id = Utils.guid();
-    // Ignore starting values here
-    this.value = NList.Nil
-    this.kids = [];
-    
-    var n = args.length;
-    var count = 0;
-    var isChanged = false;
-
-    this.recv = function(timestep, changed, parentID) {
-      ++count;
-      if (changed) { 
-        // We know this a change must only be one of the following cases
-        if (parentID === down.id && !(NList.member(down.value)(this.value))) {
-          isChanged = true;
-          this.value = NList.Cons(down.value, this.value); 
-        } 
-        if (parentID === up.id) {
-          isChanged = true;
-          var notEq = function(kc) { return kc !== up.value };
-          this.value = NList.filter(notEq)(this.value);
-        } 
-        if (parentID === blur.id) {
-          isChanged = true;
-          this.value = NList.Nil;
-        }
-      }
-      if (count == n) {
-        send(this, timestep, isChanged);
-        isChanged = false;
-        count = 0;
-      }
-    };
-
-    for (var i = n; i--; ) { args[i].kids.push(this); }
-
-  }
-
-  var keysDown = Signal.dropRepeats(new KeyMerge(downEvents,upEvents,blurEvents));
-
-  function keySignal(f) {
-    var signal = A2(Signal.lift, f, keysDown);
-    // must set the default number of kids to make it possible to filter
-    // these signals if they are not actually used.
-    keysDown.defaultNumberOfKids += 1;
-    signal.defaultNumberOfKids = 1;
-    var filtered = Signal.dropRepeats(signal)
-    filtered.defaultNumberOfKids = 0;
-    return filtered;
-  }
-
-  function dir(up, down, left, right) {
-    function f(ks) {
-      var x = 0, y = 0;
-      while (ks.ctor === "::") {
-        switch (ks._0) {
-          case left : --x; break;
-          case right: ++x; break;
-          case up   : ++y; break;
-          case down : --y; break;
-        }
-        ks = ks._1;
-      }
-      return { _:{}, x:x, y:y };
-    }
-    return keySignal(f);
-  }
-
-  function is(key) { return keySignal(NList.member(key)); }
-
-  var lastPressed = downEvents;
-
-  return elm.Native.Keyboard.values = {
-    isDown:is,
-    directions:F4(dir),
-    keysDown:keysDown,
-    lastPressed:lastPressed
-  };
-
-};
-Elm.Native.Mouse = {};
-Elm.Native.Mouse.make = function(elm) {
-
-    elm.Native = elm.Native || {};
-    elm.Native.Mouse = elm.Native.Mouse || {};
-    if (elm.Native.Mouse.values) return elm.Native.Mouse.values;
-
-    var Signal = Elm.Signal.make(elm);
-    var Utils = Elm.Native.Utils.make(elm);
-
-    var position  = Signal.constant(Utils.Tuple2(0,0));
-    position.defaultNumberOfKids = 2;
-
-    // do not move x and y into Elm. By setting their default number
-    // of kids, it is possible to detatch the mouse listeners if
-    // they are not needed.
-    var x = A2( Signal.lift, function(p){return p._0}, position);
-    x.defaultNumberOfKids = 0;
-    var y = A2( Signal.lift, function(p){return p._1}, position);
-    y.defaultNumberOfKids = 0;
-
-    var isDown    = Signal.constant(false);
-    var isClicked = Signal.constant(false);
-    var clicks = Signal.constant(Utils.Tuple0);
-
-    var node = elm.display === ElmRuntime.Display.FULLSCREEN ? document : elm.node;
-
-    elm.addListener([isClicked.id, clicks.id], node, 'click', function click() {
-        elm.notify(isClicked.id, true);
-        elm.notify(clicks.id, Utils.Tuple0);
-        elm.notify(isClicked.id, false);
-    });
-    elm.addListener([isDown.id], node, 'mousedown', function down() {
-        elm.notify(isDown.id, true);
-    });
-    elm.addListener([isDown.id], node, 'mouseup', function up() {
-        elm.notify(isDown.id, false);
-    });
-    elm.addListener([position.id], node, 'mousemove', function move(e) {
-        elm.notify(position.id, Utils.getXY(e));
-    });
-
-    return elm.Native.Mouse.values = {
-        position: position,
-        x:x,
-        y:y,
-        isClicked: isClicked,
-        isDown: isDown,
-        clicks: clicks
-    };
-};Elm.Native.Random = {};
-Elm.Native.Random.make = function(elm) {
-
-    elm.Native = elm.Native || {};
-    elm.Native.Random = elm.Native.Random || {};
-    if (elm.Native.Random.values) return elm.Native.Random.values;
-
-    var Signal = Elm.Signal.make(elm);
-    var List = Elm.Native.List.make(elm);
-
-    function range(min, max, signal) {
-        function f(x) { return Math.floor(Math.random() * (max-min+1)) + min; }
-        return A2( Signal.lift, f, signal );
-    }
-
-    function float_(signal) {
-        function f(x) { return Math.random(); }
-        return A2( Signal.lift, f, signal );
-    }
-
-    function floatList(signal) {
-        function f(n) {
-            if (n < 0) return List.Nil;
-            var arr = new Array(n);
-            for (var i = n; i--; ) {
-                arr[i] = Math.random();
-            }
-            return List.fromArray(arr);
-        }
-        return A2( Signal.lift, f, signal );
-    }
-
-    return elm.Native.Random.values = {
-        range: F3(range),
-        float_: float_,
-        floatList: floatList
-    };
-
-};
-
-Elm.Native.Signal = {};
-Elm.Native.Signal.make = function(elm) {
-
-  elm.Native = elm.Native || {};
-  elm.Native.Signal = elm.Native.Signal || {};
-  if (elm.Native.Signal.values) return elm.Native.Signal.values;
-
-  var Utils = Elm.Native.Utils.make(elm);
-  var foldr1 = Elm.List.make(elm).foldr1;
-
-  function send(node, timestep, changed) {
-    var kids = node.kids;
-    for (var i = kids.length; i--; ) {
-      kids[i].recv(timestep, changed, node.id);
-    }
-  }
-
-  function Input(base) {
-    this.id = Utils.guid();
-    this.value = base;
-    this.kids = [];
-    this.defaultNumberOfKids = 0;
-    this.recv = function(timestep, eid, v) {
-      var changed = eid === this.id;
-      if (changed) { this.value = v; }
-      send(this, timestep, changed);
-      return changed;
-    };
-    elm.inputs.push(this);
-  }
-
-  function LiftN(update, args) {
-    this.id = Utils.guid();
-    this.value = update();
-    this.kids = [];
-
-    var n = args.length;
-    var count = 0;
-    var isChanged = false;
-
-    this.recv = function(timestep, changed, parentID) {
-      ++count;
-      if (changed) { isChanged = true; }
-      if (count == n) {
-        if (isChanged) { this.value = update(); }
-        send(this, timestep, isChanged);
-        isChanged = false;
-        count = 0;
-      }
-    };
-    for (var i = n; i--; ) { args[i].kids.push(this); }
-  }
-
-  function lift(func, a) {
-    function update() { return func(a.value); }
-    return new LiftN(update, [a]);
-  }
-  function lift2(func, a, b) {
-    function update() { return A2( func, a.value, b.value ); }
-    return new LiftN(update, [a,b]);
-  }
-  function lift3(func, a, b, c) {
-    function update() { return A3( func, a.value, b.value, c.value ); }
-    return new LiftN(update, [a,b,c]);
-  }
-  function lift4(func, a, b, c, d) {
-    function update() { return A4( func, a.value, b.value, c.value, d.value ); }
-    return new LiftN(update, [a,b,c,d]);
-  }
-  function lift5(func, a, b, c, d, e) {
-    function update() { return A5( func, a.value, b.value, c.value, d.value, e.value ); }
-    return new LiftN(update, [a,b,c,d,e]);
-  }
-  function lift6(func, a, b, c, d, e, f) {
-    function update() { return A6( func, a.value, b.value, c.value, d.value, e.value, f.value ); }
-    return new LiftN(update, [a,b,c,d,e,f]);
-  }
-  function lift7(func, a, b, c, d, e, f, g) {
-    function update() { return A7( func, a.value, b.value, c.value, d.value, e.value, f.value, g.value ); }
-    return new LiftN(update, [a,b,c,d,e,f,g]);
-  }
-  function lift8(func, a, b, c, d, e, f, g, h) {
-    function update() { return A8( func, a.value, b.value, c.value, d.value, e.value, f.value, g.value, h.value ); }
-    return new LiftN(update, [a,b,c,d,e,f,g,h]);
-  }
-
-  function Foldp(step, state, input) {
-    this.id = Utils.guid();
-    this.value = state;
-    this.kids = [];
-
-    this.recv = function(timestep, changed, parentID) {
-      if (changed) {
-          this.value = A2( step, input.value, this.value );
-      }
-      send(this, timestep, changed);
-    };
-    input.kids.push(this);
-  }
-
-  function foldp(step, state, input) {
-      return new Foldp(step, state, input);
-  }
-
-  function DropIf(pred,base,input) {
-    this.id = Utils.guid();
-    this.value = pred(input.value) ? base : input.value;
-    this.kids = [];
-    this.recv = function(timestep, changed, parentID) {
-      var chng = changed && !pred(input.value);
-      if (chng) { this.value = input.value; }
-      send(this, timestep, chng);
-    };
-    input.kids.push(this);
-  }
-
-  function DropRepeats(input) {
-    this.id = Utils.guid();
-    this.value = input.value;
-    this.kids = [];
-    this.recv = function(timestep, changed, parentID) {
-      var chng = changed && !Utils.eq(this.value,input.value);
-      if (chng) { this.value = input.value; }
-      send(this, timestep, chng);
-    };
-    input.kids.push(this);
-  }
-
-  function dropWhen(s1,b,s2) {
-    var pairs = lift2( F2(function(x,y){return {x:x,y:y};}), s1, s2 );
-    var dropped = new DropIf(function(p){return p.x;},{x:true,y:b},pairs);
-    return lift(function(p){return p.y;}, dropped);
-  }
-
-  function timestamp(a) {
-    function update() { return Utils.Tuple2(Date.now(), a.value); }
-    return new LiftN(update, [a]);
-  }
-
-  function SampleOn(s1,s2) {
-    this.id = Utils.guid();
-    this.value = s2.value;
-    this.kids = [];
-
-    var count = 0;
-    var isChanged = false;
-
-    this.recv = function(timestep, changed, parentID) {
-      if (parentID === s1.id) isChanged = changed;
-      ++count;
-      if (count == 2) {
-        if (isChanged) { this.value = s2.value; }
-        send(this, timestep, isChanged);
-        count = 0;
-        isChanged = false;
-      }
-    };
-    s1.kids.push(this);
-    s2.kids.push(this);
-  }
-
-  function sampleOn(s1,s2) { return new SampleOn(s1,s2); }
-
-  function delay(t,s) {
-      var delayed = new Input(s.value);
-      var firstEvent = true;
-      function update(v) {
-        if (firstEvent) { firstEvent = false; return; }
-        setTimeout(function() { elm.notify(delayed.id, v); }, t);
-      }
-      function first(a,b) { return a; }
-      return new SampleOn(delayed, lift2(F2(first), delayed, lift(update,s)));
-  }
-
-  function Merge(s1,s2) {
-      this.id = Utils.guid();
-      this.value = s1.value;
-      this.kids = [];
-
-      var next = null;
-      var count = 0;
-      var isChanged = false;
-
-      this.recv = function(timestep, changed, parentID) {
-        ++count;
-        if (changed) {
-            isChanged = true;
-            if (parentID == s2.id && next === null) { next = s2.value; }
-            if (parentID == s1.id) { next = s1.value; }
-        }
-
-        if (count == 2) {
-            if (isChanged) { this.value = next; next = null; }
-            send(this, timestep, isChanged);
-            isChanged = false;
-            count = 0;
-        }
-      };
-      s1.kids.push(this);
-      s2.kids.push(this);
-  }
-
-  function merge(s1,s2) { return new Merge(s1,s2); }
-  function merges(ss) { return A2(foldr1, F2(merge), ss); }
-
-  return elm.Native.Signal.values = {
-    constant : function(v) { return new Input(v); },
-    lift  : F2(lift ),
-    lift2 : F3(lift2),
-    lift3 : F4(lift3),
-    lift4 : F5(lift4),
-    lift5 : F6(lift5),
-    lift6 : F7(lift6),
-    lift7 : F8(lift7),
-    lift8 : F9(lift8),
-    foldp : F3(foldp),
-    delay : F2(delay),
-    merge : F2(merge),
-    merges : merges,
-    count : function(s) { return foldp(F2(function(_,c) { return c+1; }), 0, s); },
-    countIf : F2(function(pred,s) {
-      return foldp(F2(function(x,c){
-        return pred(x) ? c+1 : c; }), 0, s)}),
-    keepIf : F3(function(pred,base,sig) {
-      return new DropIf(function(x) {return !pred(x);},base,sig); }),
-    dropIf : F3(function(pred,base,sig) { return new DropIf(pred,base,sig); }),
-    keepWhen : F3(function(s1,b,s2) {
-      return dropWhen(lift(function(b){return !b;},s1), b, s2); }),
-    dropWhen : F3(dropWhen),
-    dropRepeats : function(s) { return new DropRepeats(s);},
-    sampleOn : F2(sampleOn),
-    timestamp : timestamp
-  };
-};
-Elm.Native.Time = {};
-Elm.Native.Time.make = function(elm) {
-
-  elm.Native = elm.Native || {};
-  elm.Native.Time = elm.Native.Time || {};
-  if (elm.Native.Time.values) return elm.Native.Time.values;
-
-  var Signal = Elm.Signal.make(elm);
-  var NS = Elm.Native.Signal.make(elm);
-  var Maybe = Elm.Maybe.make(elm);
-  var Utils = Elm.Native.Utils.make(elm);
-
-  function fpsWhen(desiredFPS, isOn) {
-    var msPerFrame = 1000 / desiredFPS;
-    var prev = Date.now(), curr = prev, diff = 0, wasOn = true;
-    var ticker = Signal.constant(diff);
-    function tick(zero) { return function() {
-        curr = Date.now();
-        diff = zero ? 0 : curr - prev;
-        prev = curr;
-        elm.notify(ticker.id, diff);
-      };
-    }
-    var timeoutID = 0;
-    function f(isOn, t) {
-      if (isOn) {
-        timeoutID = setTimeout(tick(!wasOn && isOn), msPerFrame);
-      } else if (wasOn) {
-        clearTimeout(timeoutID);
-      }
-      wasOn = isOn;
-      return t;
-    }
-    return A3( Signal.lift2, F2(f), isOn, ticker );
-  }
-
-  function every(t) {
-    var clock = Signal.constant(Date.now());
-    setInterval(function() {
-        elm.notify(clock.id, Date.now());
-    }, t);
-    return clock;
-  }
-
-  function since(t, s) {
-    function cmp(a,b) { return !Utils.eq(a,b); }
-    var dcount = Signal.count(A2(NS.delay, t, s));
-    return A3( Signal.lift2, F2(cmp), Signal.count(s), dcount );
-  }
-  function read(s) {
-      var t = Date.parse(s);
-      return isNaN(t) ? Maybe.Nothing : Maybe.Just(t);
-  }
-  return elm.Native.Time.values = {
-      fpsWhen : F2(fpsWhen),
-      fps : function(t) { return fpsWhen(t, Signal.constant(true)); },
-      every : every,
-      delay : NS.delay,
-      timestamp : NS.timestamp,
-      since : F2(since),
-      toDate : function(t) { return new window.Date(t); },
-      read   : read
-  };
-
-};
-Elm.Native.Touch = {};
-Elm.Native.Touch.make = function(elm) {
-
-    elm.Native = elm.Native || {};
-    elm.Native.Touch = elm.Native.Touch || {};
-    if (elm.Native.Touch.values) return elm.Native.Touch.values;
-
-    var Signal = Elm.Signal.make(elm);
-    var JS = Elm.JavaScript.make(elm);
-    var Utils = Elm.Native.Utils.make(elm);
-
-    function Dict() {
-        this.keys = [];
-        this.values = [];
-
-        this.insert = function(key,value) {
-            this.keys.push(key);
-            this.values.push(value);
-        };
-        this.lookup = function(key) {
-            var i = this.keys.indexOf(key)
-            return i >= 0 ? this.values[i] : {x:0,y:0,t:0};
-        };
-        this.remove = function(key) {
-            var i = this.keys.indexOf(key);
-            if (i < 0) return;
-            var t = this.values[i];
-            this.keys.splice(i,1);
-            this.values.splice(i,1);
-            return t;
-        };
-        this.clear = function() {
-            this.keys = [];
-            this.values = [];
-        };
-    }
-    
-    var root = Signal.constant([]),
-    tapTime = 500,
-    hasTap = false,
-    tap = {_:{},x:0,y:0},
-    dict = new Dict();
-
-    function touch(t) {
-        var r = dict.lookup(t.identifier);
-        var point = Utils.getXY(t);
-        return {_ : {},
-	        id: t.identifier,
-	        x : point._0,
-	        y : point._1,
-	        x0: r.x,
-	        y0: r.y,
-	        t0: r.t
-	       };
-    }
-
-    var node = elm.display === ElmRuntime.Display.FULLSCREEN ? document : elm.node;
-
-    function start(e) {
-        var point = Utils.getXY(e);
-        dict.insert(e.identifier,
-                    {x: point._0,
-                     y: point._1,
-                     t: Date.now()});
-    }
-    function end(e) {
-        var t = dict.remove(e.identifier);
-        if (Date.now() - t.t < tapTime) {
-            hasTap = true;
-            tap = {_:{}, x:t.x, y:t.y};
-        }
-    }
-
-    function listen(name, f) {
-        function update(e) {
-            for (var i = e.changedTouches.length; i--; ) { f(e.changedTouches[i]); }
-            var ts = new Array(e.touches.length);
-            for (var i = e.touches.length; i--; ) { ts[i] = touch(e.touches[i]); }
-            elm.notify(root.id, ts);
-            e.preventDefault();
-        }
-        elm.addListener([root.id], node, name, update);
-    }
-
-    listen("touchstart", start);
-    listen("touchmove", function(_){});
-    listen("touchend", end);
-    listen("touchcancel", end);
-    listen("touchleave", end);
-
-    var mouseID = -1;
-    function move(e) {
-        var point = Utils.getXY(e);
-        for (var i = root.value.length; i--; ) {
-            if (root.value[i].id === mouseID) {
-                root.value[i].x = point._0;
-                root.value[i].y = point._1;
-                elm.notify(root.id, root.value);
-                break;
-            }
-        }
-    }
-    elm.addListener([root.id], node, "mousedown", function down(e) {
-        node.addEventListener("mousemove", move);
-        e.identifier = mouseID;
-        start(e);
-        root.value.push(touch(e));
-        elm.notify(root.id, root.value);
-    });
-    elm.addListener([root.id], node, "mouseup", function up(e) {
-        node.removeEventListener("mousemove", move);
-        e.identifier = mouseID;
-        end(e);
-        for (var i = root.value.length; i--; ) {
-            if (root.value[i].id === mouseID) {
-                root.value.splice(i, 1);
-                --mouseID;
-                break;
-            }
-        }
-        elm.notify(root.id, root.value);
-    });
-    elm.addListener([root.id], node, "blur", function blur(e) {
-        node.removeEventListener("mousemove", move);
-        if (root.value.length > 0) {
-            elm.notify(root.id, []);
-            --mouseID;
-        }
-        dict.clear();
-    });
-
-    function dependency(f) {
-        var sig = A2( Signal.lift, f, root );
-        root.defaultNumberOfKids += 1;
-        sig.defaultNumberOfKids = 0;
-        return sig;
-    }
-
-    var touches = dependency(JS.toList);
-
-    var taps = function() {
-        var sig = dependency(function(_) { return tap; });
-        sig.defaultNumberOfKids = 1;
-        function pred(_) { var b = hasTap; hasTap = false; return b; }
-        var sig2 = A3( Signal.keepIf, pred, {_:{},x:0,y:0}, sig);
-        sig2.defaultNumberOfKids = 0;
-        return sig2;
-    }();
-
-    return elm.Native.Touch.values = { touches: touches, taps: taps };
-
-};Elm.Native.WebSocket = {};
-Elm.Native.WebSocket.make = function(elm) {
-
-  elm.Native = elm.Native || {};
-  elm.Native.WebSocket = elm.Native.WebSocket || {};
-  if (elm.Native.WebSocket.values) return elm.Native.WebSocket.values;
-
-  var Signal = Elm.Signal.make(elm);
-  var JS = Elm.JavaScript.make(elm);
-  var List = Elm.Native.List.make(elm);
-
-  function open(url, outgoing) {
-    var incoming = Signal.constant(List.Nil);
-    var ws = new WebSocket(JS.fromString(url));
-
-    var pending = [];
-    var ready = false;
-    
-    ws.onopen = function(e) {
-      var len = pending.length;
-      for (var i = 0; i < len; ++i) { ws.send(pending[i]); }
-      ready = true;
-    };
-    ws.onmessage = function(event) {
-      elm.notify(incoming.id, JS.toString(event.data));
-    };
-    
-    function send(msg) {
-      var s = JS.fromString(msg);
-      ready ? ws.send(s) : pending.push(s);
-    }
-    
-    function take1(x,y) { return x }
-    return A3(Signal.lift2, F2(take1), incoming, A2(Signal.lift, send, outgoing));
-  }
-
-  return elm.Native.WebSocket.values = { connect: F2(open) };
-};
-Elm.Native.Window = {};
-Elm.Native.Window.make = function(elm) {
-
-  elm.Native = elm.Native || {};
-  elm.Native.Window = elm.Native.Window || {};
-  if (elm.Native.Window.values) return elm.Native.Window.values;
-
-  var Signal = Elm.Signal.make(elm);
-  var Tuple2 = Elm.Native.Utils.make(elm).Tuple2;
-
-  function getWidth() { return elm.node.clientWidth; }
-  function getHeight() {
-      if (elm.display === ElmRuntime.Display.FULLSCREEN) {
-          return window.innerHeight;
-      }
-      return elm.node.clientHeight;
-  }
-
-  var dimensions = Signal.constant(Tuple2(getWidth(), getHeight()));
-  dimensions.defaultNumberOfKids = 2;
-
-  // Do not move width and height into Elm. By setting the default number of kids,
-  // the resize listener can be detached.
-  var width  = A2(Signal.lift, function(p){return p._0;}, dimensions);
-  width.defaultNumberOfKids = 0;
-
-  var height = A2(Signal.lift, function(p){return p._1;}, dimensions);
-  height.defaultNumberOfKids = 0;
-
-  function resizeIfNeeded() {
-      // Do not trigger event if the dimensions have not changed.
-      // This should be most of the time.
-      var w = getWidth();
-      var h = getHeight();
-      if (dimensions.value._0 === w && dimensions.value._1 === h) return;
-
-      setTimeout(function () {
-          // Check again to see if the dimensions have changed.
-          // It is conceivable that the dimensions have changed
-          // again while some other event was being processed.
-          var w = getWidth();
-          var h = getHeight();
-          if (dimensions.value._0 === w && dimensions.value._1 === h) return;
-          elm.notify(dimensions.id, Tuple2(w,h));
-      }, 0);
-  }
-  elm.addListener([dimensions.id], window, 'resize', resizeIfNeeded);
-
-  return elm.Native.Window.values = {
-      dimensions:dimensions,
-      width:width,
-      height:height,
-      resizeIfNeeded:resizeIfNeeded
-  };
-
-};
-Elm.Basics = Elm.Basics || {};
-Elm.Basics.make = function (_elm)
-                  {
-                    _elm.Basics = _elm.Basics || {};
-                    if (_elm.Basics.values)
-                    return _elm.Basics.values
-                    var _N = Elm.Native,
-                        _U = _N.Utils.make(_elm),
-                        _L = _N.List.make(_elm),
-                        _E = _N.Error.make(_elm),
-                        _J = _N.JavaScript.make(_elm),
-                        $moduleName = "Basics";
-                    var Native = Native || {};
-                    Native.Basics = Elm.Native.Basics.make(_elm);
-                    var _op = {};
-                    var uncurry = F2(function (f,_v0)
-                                     {
-                                       return function ()
-                                              {
-                                                switch (_v0.ctor)
-                                                {case
-                                                 "_Tuple2" :
-                                                   return A2(f,_v0._0,_v0._1)}
-                                                _E.Case($moduleName,"on line 354, column 19 to 24");
-                                              }()
-                                     });
-                    var curry = F3(function (f,a,b)
-                                   {
-                                     return f({ctor: "_Tuple2", _0: a, _1: b})
-                                   });
-                    var flip = F3(function (f,b,a)
-                                  {
-                                    return A2(f,a,b)
-                                  });
-                    var snd = function (_v4)
-                              {
-                                return function ()
-                                       {
-                                         switch (_v4.ctor)
-                                         {case
-                                          "_Tuple2" :
-                                            return _v4._1}
-                                         _E.Case($moduleName,"on line 338, column 13 to 14");
-                                       }()
-                              };
-                    var fst = function (_v8)
-                              {
-                                return function ()
-                                       {
-                                         switch (_v8.ctor)
-                                         {case
-                                          "_Tuple2" :
-                                            return _v8._0}
-                                         _E.Case($moduleName,"on line 334, column 13 to 14");
-                                       }()
-                              };
-                    var always = F2(function (a,_v12)
-                                    {
-                                      return function ()
-                                             {
-                                               return a
-                                             }()
-                                    });
-                    var id = function (x)
-                             {
-                               return x
-                             };
-                    _op["<|"] = F2(function (f,x)
-                                   {
-                                     return f(x)
-                                   });
-                    _op["|>"] = F2(function (x,f)
-                                   {
-                                     return f(x)
-                                   });
-                    _op["."] = F3(function (f,g,x)
-                                  {
-                                    return f(g(x))
-                                  });
-                    var toFloat = Native.Basics.toFloat;
-                    var ceiling = Native.Basics.ceiling;
-                    var floor = Native.Basics.floor;
-                    var truncate = Native.Basics.truncate;
-                    var round = Native.Basics.round;
-                    var otherwise = true;
-                    var not = Native.Basics.not;
-                    var xor = Native.Basics.xor;
-                    _op["||"] = Native.Basics.or;
-                    _op["&&"] = Native.Basics.and;
-                    var max = Native.Basics.max;
-                    var min = Native.Basics.min;
-                    var GT = {ctor: "GT"};
-                    var EQ = {ctor: "EQ"};
-                    var LT = {ctor: "LT"};
-                    var compare = Native.Basics.compare;
-                    _op[">="] = Native.Basics.ge;
-                    _op["<="] = Native.Basics.le;
-                    _op[">"] = Native.Basics.gt;
-                    _op["<"] = Native.Basics.lt;
-                    _op["/="] = Native.Basics.neq;
-                    _op["=="] = Native.Basics.eq;
-                    var e = Native.Basics.e;
-                    var pi = Native.Basics.pi;
-                    var clamp = Native.Basics.clamp;
-                    var logBase = Native.Basics.logBase;
-                    var abs = Native.Basics.abs;
-                    var sqrt = Native.Basics.sqrt;
-                    var atan2 = Native.Basics.atan2;
-                    var atan = Native.Basics.atan;
-                    var asin = Native.Basics.asin;
-                    var acos = Native.Basics.acos;
-                    var tan = Native.Basics.tan;
-                    var sin = Native.Basics.sin;
-                    var cos = Native.Basics.cos;
-                    _op["^"] = Native.Basics.exp;
-                    var mod = Native.Basics.mod;
-                    var rem = Native.Basics.rem;
-                    var div = Native.Basics.div;
-                    _op["/"] = Native.Basics.floatDiv;
-                    _op["*"] = Native.Basics.mul;
-                    _op["-"] = Native.Basics.sub;
-                    _op["+"] = Native.Basics.add;
-                    var toPolar = function (_v14)
-                                  {
-                                    return function ()
-                                           {
-                                             switch (_v14.ctor)
-                                             {case
-                                              "_Tuple2" :
-                                                return {ctor: "_Tuple2", _0: Native.Basics.sqrt(Math.pow(_v14._0,
-                                                                                                         2) + Math.pow(_v14._1,
-                                                                                                                       2)), _1: A2(Native.Basics.atan2,
-                                                                                                                                   _v14._1,
-                                                                                                                                   _v14._0)}}
-                                             _E.Case($moduleName,"on line 76, column 18 to 73");
-                                           }()
-                                  };
-                    var fromPolar = function (_v18)
-                                    {
-                                      return function ()
-                                             {
-                                               switch (_v18.ctor)
-                                               {case
-                                                "_Tuple2" :
-                                                  return {ctor: "_Tuple2", _0: _v18._0 * Native.Basics.cos(_v18._1), _1: _v18._0 * Native.Basics.sin(_v18._1)}}
-                                               _E.Case($moduleName,"on line 70, column 20 to 68");
-                                             }()
-                                    };
-                    var turns = function (r)
-                                {
-                                  return 2 * Native.Basics.pi * r
-                                };
-                    var degrees = function (d)
-                                  {
-                                    return d * Native.Basics.pi / 180
-                                  };
-                    var radians = function (t)
-                                  {
-                                    return t
-                                  };
-                    _elm.Basics.values = {_op: _op, radians: radians, degrees: degrees, turns: turns, fromPolar: fromPolar, toPolar: toPolar, div: div, rem: rem, mod: mod, cos: cos, sin: sin, tan: tan, acos: acos, asin: asin, atan: atan, atan2: atan2, sqrt: sqrt, abs: abs, logBase: logBase, clamp: clamp, pi: pi, e: e, compare: compare, min: min, max: max, xor: xor, not: not, otherwise: otherwise, round: round, truncate: truncate, floor: floor, ceiling: ceiling, toFloat: toFloat, id: id, always: always, fst: fst, snd: snd, flip: flip, curry: curry, uncurry: uncurry, LT: LT, EQ: EQ, GT: GT};
-                    return _elm.Basics.values
-                  };Elm.Bitwise = Elm.Bitwise || {};
-Elm.Bitwise.make = function (_elm)
-                   {
-                     _elm.Bitwise = _elm.Bitwise || {};
-                     if (_elm.Bitwise.values)
-                     return _elm.Bitwise.values
-                     var _N = Elm.Native,
-                         _U = _N.Utils.make(_elm),
-                         _L = _N.List.make(_elm),
-                         _E = _N.Error.make(_elm),
-                         _J = _N.JavaScript.make(_elm),
-                         $moduleName = "Bitwise";
-                     var Native = Native || {};
-                     Native.Bitwise = Elm.Native.Bitwise.make(_elm);
-                     var _op = {};
-                     var shiftRightLogical = Native.Bitwise.shiftRightLogical;
-                     var shiftRight = Native.Bitwise.shiftRightArithmatic;
-                     var shiftLeft = Native.Bitwise.shiftLeft;
-                     var complement = Native.Bitwise.complement;
-                     var xor = Native.Bitwise.xor;
-                     var or = Native.Bitwise.or;
-                     var and = Native.Bitwise.and;
-                     _elm.Bitwise.values = {_op: _op, and: and, or: or, xor: xor, complement: complement, shiftLeft: shiftLeft, shiftRight: shiftRight, shiftRightLogical: shiftRightLogical};
-                     return _elm.Bitwise.values
-                   };Elm.Char = Elm.Char || {};
-Elm.Char.make = function (_elm)
-                {
-                  _elm.Char = _elm.Char || {};
-                  if (_elm.Char.values)
-                  return _elm.Char.values
-                  var _N = Elm.Native,
-                      _U = _N.Utils.make(_elm),
-                      _L = _N.List.make(_elm),
-                      _E = _N.Error.make(_elm),
-                      _J = _N.JavaScript.make(_elm),
-                      $moduleName = "Char";
-                  var Native = Native || {};
-                  Native.Char = Elm.Native.Char.make(_elm);
-                  var _op = {};
-                  var fromCode = Native.Char.fromCode;
-                  var toCode = Native.Char.toCode;
-                  var toLocaleLower = Native.Char.toLocaleLower;
-                  var toLocaleUpper = Native.Char.toLocaleUpper;
-                  var toLower = Native.Char.toLower;
-                  var toUpper = Native.Char.toUpper;
-                  var isHexDigit = Native.Char.isHexDigit;
-                  var isOctDigit = Native.Char.isOctDigit;
-                  var isDigit = Native.Char.isDigit;
-                  var isLower = Native.Char.isLower;
-                  var isUpper = Native.Char.isUpper;
-                  _elm.Char.values = {_op: _op, isUpper: isUpper, isLower: isLower, isDigit: isDigit, isOctDigit: isOctDigit, isHexDigit: isHexDigit, toUpper: toUpper, toLower: toLower, toLocaleUpper: toLocaleUpper, toLocaleLower: toLocaleLower, toCode: toCode, fromCode: fromCode};
-                  return _elm.Char.values
-                };Elm.Color = Elm.Color || {};
-Elm.Color.make = function (_elm)
-                 {
-                   _elm.Color = _elm.Color || {};
-                   if (_elm.Color.values)
-                   return _elm.Color.values
-                   var _N = Elm.Native,
-                       _U = _N.Utils.make(_elm),
-                       _L = _N.List.make(_elm),
-                       _E = _N.Error.make(_elm),
-                       _J = _N.JavaScript.make(_elm),
-                       $moduleName = "Color";
-                   var Basics = Elm.Basics.make(_elm);
-                   var Native = Native || {};
-                   Native.Color = Elm.Native.Color.make(_elm);
-                   var _op = {};
-                   var Radial = F5(function (a,b,c,d,e)
-                                   {
-                                     return {ctor: "Radial", _0: a, _1: b, _2: c, _3: d, _4: e}
-                                   });
-                   var radial = Radial;
-                   var Linear = F3(function (a,b,c)
-                                   {
-                                     return {ctor: "Linear", _0: a, _1: b, _2: c}
-                                   });
-                   var linear = Linear;
-                   var hsv = Native.Color.hsv;
-                   var hsva = Native.Color.hsva;
-                   var complement = Native.Color.complement;
-                   var greyscale = function (p)
-                                   {
-                                     return A3(hsv,0,0,1 - p)
-                                   };
-                   var grayscale = function (p)
-                                   {
-                                     return A3(hsv,0,0,1 - p)
-                                   };
-                   var Color = F4(function (a,b,c,d)
-                                  {
-                                    return {ctor: "Color", _0: a, _1: b, _2: c, _3: d}
-                                  });
-                   var rgba = Color;
-                   var rgb = F3(function (r,g,b)
-                                {
-                                  return A4(Color,r,g,b,1)
-                                });
-                   var lightRed = A4(Color,239,41,41,1);
-                   var red = A4(Color,204,0,0,1);
-                   var darkRed = A4(Color,164,0,0,1);
-                   var lightOrange = A4(Color,252,175,62,1);
-                   var orange = A4(Color,245,121,0,1);
-                   var darkOrange = A4(Color,206,92,0,1);
-                   var lightYellow = A4(Color,255,233,79,1);
-                   var yellow = A4(Color,237,212,0,1);
-                   var darkYellow = A4(Color,196,160,0,1);
-                   var lightGreen = A4(Color,138,226,52,1);
-                   var green = A4(Color,115,210,22,1);
-                   var darkGreen = A4(Color,78,154,6,1);
-                   var lightBlue = A4(Color,114,159,207,1);
-                   var blue = A4(Color,52,101,164,1);
-                   var darkBlue = A4(Color,32,74,135,1);
-                   var lightPurple = A4(Color,173,127,168,1);
-                   var purple = A4(Color,117,80,123,1);
-                   var darkPurple = A4(Color,92,53,102,1);
-                   var lightBrown = A4(Color,233,185,110,1);
-                   var brown = A4(Color,193,125,17,1);
-                   var darkBrown = A4(Color,143,89,2,1);
-                   var black = A4(Color,0,0,0,1);
-                   var white = A4(Color,255,255,255,1);
-                   var lightGrey = A4(Color,238,238,236,1);
-                   var grey = A4(Color,211,215,207,1);
-                   var darkGrey = A4(Color,186,189,182,1);
-                   var lightGray = A4(Color,238,238,236,1);
-                   var gray = A4(Color,211,215,207,1);
-                   var darkGray = A4(Color,186,189,182,1);
-                   var lightCharcoal = A4(Color,136,138,133,1);
-                   var charcoal = A4(Color,85,87,83,1);
-                   var darkCharcoal = A4(Color,46,52,54,1);
-                   _elm.Color.values = {_op: _op, rgba: rgba, rgb: rgb, lightRed: lightRed, red: red, darkRed: darkRed, lightOrange: lightOrange, orange: orange, darkOrange: darkOrange, lightYellow: lightYellow, yellow: yellow, darkYellow: darkYellow, lightGreen: lightGreen, green: green, darkGreen: darkGreen, lightBlue: lightBlue, blue: blue, darkBlue: darkBlue, lightPurple: lightPurple, purple: purple, darkPurple: darkPurple, lightBrown: lightBrown, brown: brown, darkBrown: darkBrown, black: black, white: white, lightGrey: lightGrey, grey: grey, darkGrey: darkGrey, lightGray: lightGray, gray: gray, darkGray: darkGray, lightCharcoal: lightCharcoal, charcoal: charcoal, darkCharcoal: darkCharcoal, grayscale: grayscale, greyscale: greyscale, complement: complement, hsva: hsva, hsv: hsv, linear: linear, radial: radial, Color: Color, Linear: Linear, Radial: Radial};
-                   return _elm.Color.values
-                 };Elm.Date = Elm.Date || {};
-Elm.Date.make = function (_elm)
-                {
-                  _elm.Date = _elm.Date || {};
-                  if (_elm.Date.values)
-                  return _elm.Date.values
-                  var _N = Elm.Native,
-                      _U = _N.Utils.make(_elm),
-                      _L = _N.List.make(_elm),
-                      _E = _N.Error.make(_elm),
-                      _J = _N.JavaScript.make(_elm),
-                      $moduleName = "Date";
-                  var Maybe = Elm.Maybe.make(_elm);
-                  var Native = Native || {};
-                  Native.Date = Elm.Native.Date.make(_elm);
-                  var Time = Elm.Time.make(_elm);
-                  var _op = {};
-                  var second = Native.Date.second;
-                  var minute = Native.Date.minute;
-                  var hour = Native.Date.hour;
-                  var dayOfWeek = Native.Date.dayOfWeek;
-                  var day = Native.Date.day;
-                  var month = Native.Date.month;
-                  var year = Native.Date.year;
-                  var toTime = Native.Date.toTime;
-                  var read = Native.Date.read;
-                  var Dec = {ctor: "Dec"};
-                  var Nov = {ctor: "Nov"};
-                  var Oct = {ctor: "Oct"};
-                  var Sep = {ctor: "Sep"};
-                  var Aug = {ctor: "Aug"};
-                  var Jul = {ctor: "Jul"};
-                  var Jun = {ctor: "Jun"};
-                  var May = {ctor: "May"};
-                  var Apr = {ctor: "Apr"};
-                  var Mar = {ctor: "Mar"};
-                  var Feb = {ctor: "Feb"};
-                  var Jan = {ctor: "Jan"};
-                  var Sun = {ctor: "Sun"};
-                  var Sat = {ctor: "Sat"};
-                  var Fri = {ctor: "Fri"};
-                  var Thu = {ctor: "Thu"};
-                  var Wed = {ctor: "Wed"};
-                  var Tue = {ctor: "Tue"};
-                  var Mon = {ctor: "Mon"};
-                  var Date = {ctor: "Date"};
-                  _elm.Date.values = {_op: _op, read: read, toTime: toTime, year: year, month: month, day: day, dayOfWeek: dayOfWeek, hour: hour, minute: minute, second: second, Date: Date, Mon: Mon, Tue: Tue, Wed: Wed, Thu: Thu, Fri: Fri, Sat: Sat, Sun: Sun, Jan: Jan, Feb: Feb, Mar: Mar, Apr: Apr, May: May, Jun: Jun, Jul: Jul, Aug: Aug, Sep: Sep, Oct: Oct, Nov: Nov, Dec: Dec};
-                  return _elm.Date.values
-                };Elm.Dict = Elm.Dict || {};
-Elm.Dict.make = function (_elm)
-                {
-                  _elm.Dict = _elm.Dict || {};
-                  if (_elm.Dict.values)
-                  return _elm.Dict.values
-                  var _N = Elm.Native,
-                      _U = _N.Utils.make(_elm),
-                      _L = _N.List.make(_elm),
-                      _E = _N.Error.make(_elm),
-                      _J = _N.JavaScript.make(_elm),
-                      $moduleName = "Dict";
-                  var Basics = Elm.Basics.make(_elm);
-                  var List = Elm.List.make(_elm);
-                  var Maybe = Elm.Maybe.make(_elm);
-                  var Native = Native || {};
-                  Native.Error = Elm.Native.Error.make(_elm);
-                  var Native = Native || {};
-                  Native.Utils = Elm.Native.Utils.make(_elm);
-                  var String = Elm.String.make(_elm);
-                  var _op = {};
-                  var Same = {ctor: "Same"};
-                  var Remove = {ctor: "Remove"};
-                  var Insert = {ctor: "Insert"};
-                  var showFlag = function (f)
-                                 {
-                                   return function ()
-                                          {
-                                            switch (f.ctor)
-                                            {case
-                                             "Insert" :
-                                               return "Insert"
-                                             case
-                                             "Remove" :
-                                               return "Remove"
-                                             case
-                                             "Same" :
-                                               return "Same"}
-                                            _E.Case($moduleName,"between lines 137 and 142");
-                                          }()
-                                 };
-                  var RBEmpty = function (a)
-                                {
-                                  return {ctor: "RBEmpty", _0: a}
-                                };
-                  var RBNode = F5(function (a,b,c,d,e)
-                                  {
-                                    return {ctor: "RBNode", _0: a, _1: b, _2: c, _3: d, _4: e}
-                                  });
-                  var max = function (t)
-                            {
-                              return function ()
-                                     {
-                                       switch (t.ctor)
-                                       {case
-                                        "RBEmpty" :
-                                          return Native.Error.raise("(max Empty) is not defined")
-                                        case
-                                        "RBNode" :
-                                          switch (t._4.ctor)
-                                          {case
-                                           "RBEmpty" :
-                                             return {ctor: "_Tuple2", _0: t._1, _1: t._2}}
-                                          return max(t._4)}
-                                       _E.Case($moduleName,"between lines 83 and 88");
-                                     }()
-                            };
-                  var LBBlack = {ctor: "LBBlack"};
-                  var LBlack = {ctor: "LBlack"};
-                  var showLColor = function (c)
-                                   {
-                                     return function ()
-                                            {
-                                              switch (c.ctor)
-                                              {case
-                                               "LBBlack" :
-                                                 return "LBBlack"
-                                               case
-                                               "LBlack" :
-                                                 return "LBlack"}
-                                              _E.Case($moduleName,"between lines 63 and 65");
-                                            }()
-                                   };
-                  var empty = RBEmpty(LBlack);
-                  var min = function (t)
-                            {
-                              return function ()
-                                     {
-                                       switch (t.ctor)
-                                       {case
-                                        "RBEmpty" :
-                                          switch (t._0.ctor)
-                                          {case
-                                           "LBlack" :
-                                             return Native.Error.raise("(min Empty) is not defined")}
-                                          break;
-                                        case
-                                        "RBNode" :
-                                          switch (t._3.ctor)
-                                          {case
-                                           "RBEmpty" :
-                                             switch (t._3._0.ctor)
-                                             {case
-                                              "LBlack" :
-                                                return {ctor: "_Tuple2", _0: t._1, _1: t._2}}
-                                             break;}
-                                          return min(t._3)}
-                                       _E.Case($moduleName,"between lines 76 and 79");
-                                     }()
-                            };
-                  var lookup = F2(function (k,t)
-                                  {
-                                    return function ()
-                                           {
-                                             switch (t.ctor)
-                                             {case
-                                              "RBEmpty" :
-                                                switch (t._0.ctor)
-                                                {case
-                                                 "LBlack" :
-                                                   return Maybe.Nothing}
-                                                break;
-                                              case
-                                              "RBNode" :
-                                                return function ()
-                                                       {
-                                                         var _v25 = A2(Native.Utils.compare,k,t._1);
-                                                         switch (_v25.ctor)
-                                                         {case
-                                                          "EQ" :
-                                                            return Maybe.Just(t._2)
-                                                          case
-                                                          "GT" :
-                                                            return A2(lookup,k,t._4)
-                                                          case
-                                                          "LT" :
-                                                            return A2(lookup,k,t._3)}
-                                                         _E.Case($moduleName,
-                                                                 "between lines 94 and 100");
-                                                       }()}
-                                             _E.Case($moduleName,"between lines 91 and 100");
-                                           }()
-                                  });
-                  var member = F2(function (k,t)
-                                  {
-                                    return Maybe.isJust(A2(lookup,k,t))
-                                  });
-                  var findWithDefault = F3(function (base,k,t)
-                                           {
-                                             return function ()
-                                                    {
-                                                      switch (t.ctor)
-                                                      {case
-                                                       "RBEmpty" :
-                                                         switch (t._0.ctor)
-                                                         {case
-                                                          "LBlack" :
-                                                            return base}
-                                                         break;
-                                                       case
-                                                       "RBNode" :
-                                                         return function ()
-                                                                {
-                                                                  var _v33 = A2(Native.Utils.compare,
-                                                                                k,
-                                                                                t._1);
-                                                                  switch (_v33.ctor)
-                                                                  {case
-                                                                   "EQ" :
-                                                                     return t._2
-                                                                   case
-                                                                   "GT" :
-                                                                     return A3(findWithDefault,
-                                                                               base,
-                                                                               k,
-                                                                               t._4)
-                                                                   case
-                                                                   "LT" :
-                                                                     return A3(findWithDefault,
-                                                                               base,
-                                                                               k,
-                                                                               t._3)}
-                                                                  _E.Case($moduleName,
-                                                                          "between lines 106 and 111");
-                                                                }()}
-                                                      _E.Case($moduleName,
-                                                              "between lines 103 and 111");
-                                                    }()
-                                           });
-                  var map = F2(function (f,t)
-                               {
-                                 return function ()
-                                        {
-                                          switch (t.ctor)
-                                          {case
-                                           "RBEmpty" :
-                                             switch (t._0.ctor)
-                                             {case
-                                              "LBlack" :
-                                                return RBEmpty(LBlack)}
-                                             break;
-                                           case
-                                           "RBNode" :
-                                             return A5(RBNode,
-                                                       t._0,
-                                                       t._1,
-                                                       f(t._2),
-                                                       A2(map,f,t._3),
-                                                       A2(map,f,t._4))}
-                                          _E.Case($moduleName,"between lines 303 and 308");
-                                        }()
-                               });
-                  var foldl = F3(function (f,acc,t)
-                                 {
-                                   return function ()
-                                          {
-                                            switch (t.ctor)
-                                            {case
-                                             "RBEmpty" :
-                                               switch (t._0.ctor)
-                                               {case
-                                                "LBlack" :
-                                                  return acc}
-                                               break;
-                                             case
-                                             "RBNode" :
-                                               return A3(foldl,
-                                                         f,
-                                                         A3(f,t._1,t._2,A3(foldl,f,acc,t._3)),
-                                                         t._4)}
-                                            _E.Case($moduleName,"between lines 311 and 316");
-                                          }()
-                                 });
-                  var foldr = F3(function (f,acc,t)
-                                 {
-                                   return function ()
-                                          {
-                                            switch (t.ctor)
-                                            {case
-                                             "RBEmpty" :
-                                               switch (t._0.ctor)
-                                               {case
-                                                "LBlack" :
-                                                  return acc}
-                                               break;
-                                             case
-                                             "RBNode" :
-                                               return A3(foldr,
-                                                         f,
-                                                         A3(f,t._1,t._2,A3(foldr,f,acc,t._4)),
-                                                         t._3)}
-                                            _E.Case($moduleName,"between lines 319 and 324");
-                                          }()
-                                 });
-                  var keys = function (t)
-                             {
-                               return A3(foldr,
-                                         F3(function (k,v,acc)
-                                            {
-                                              return {ctor: "::", _0: k, _1: acc}
-                                            }),
-                                         _J.toList([]),
-                                         t)
-                             };
-                  var values = function (t)
-                               {
-                                 return A3(foldr,
-                                           F3(function (k,v,acc)
-                                              {
-                                                return {ctor: "::", _0: v, _1: acc}
-                                              }),
-                                           _J.toList([]),
-                                           t)
-                               };
-                  var toList = function (t)
-                               {
-                                 return A3(foldr,
-                                           F3(function (k,v,acc)
-                                              {
-                                                return {ctor: "::", _0: {ctor: "_Tuple2", _0: k, _1: v}, _1: acc}
-                                              }),
-                                           _J.toList([]),
-                                           t)
-                               };
-                  var NBlack = {ctor: "NBlack"};
-                  var BBlack = {ctor: "BBlack"};
-                  var isBBlack = function (t)
-                                 {
-                                   return function ()
-                                          {
-                                            switch (t.ctor)
-                                            {case
-                                             "RBEmpty" :
-                                               switch (t._0.ctor)
-                                               {case
-                                                "LBBlack" :
-                                                  return true}
-                                               break;
-                                             case
-                                             "RBNode" :
-                                               switch (t._0.ctor)
-                                               {case
-                                                "BBlack" :
-                                                  return true}
-                                               break;}
-                                            return false
-                                          }()
-                                 };
-                  var Black = {ctor: "Black"};
-                  var blackish = function (t)
-                                 {
-                                   return function ()
-                                          {
-                                            switch (t.ctor)
-                                            {case
-                                             "RBEmpty" :
-                                               return true
-                                             case
-                                             "RBNode" :
-                                               return _U.eq(t._0,Black) || _U.eq(t._0,BBlack)}
-                                            _E.Case($moduleName,"between lines 254 and 256");
-                                          }()
-                                 };
-                  var blacken = function (t)
-                                {
-                                  return function ()
-                                         {
-                                           switch (t.ctor)
-                                           {case
-                                            "RBEmpty" :
-                                              return RBEmpty(LBlack)
-                                            case
-                                            "RBNode" :
-                                              return A5(RBNode,Black,t._1,t._2,t._3,t._4)}
-                                           _E.Case($moduleName,"between lines 290 and 292");
-                                         }()
-                                };
-                  var Red = {ctor: "Red"};
-                  var showNColor = function (c)
-                                   {
-                                     return function ()
-                                            {
-                                              switch (c.ctor)
-                                              {case
-                                               "BBlack" :
-                                                 return "BBlack"
-                                               case
-                                               "Black" :
-                                                 return "Black"
-                                               case
-                                               "NBlack" :
-                                                 return "NBlack"
-                                               case
-                                               "Red" :
-                                                 return "Red"}
-                                              _E.Case($moduleName,"between lines 52 and 56");
-                                            }()
-                                   };
-                  var reportRemBug = F4(function (msg,c,lgot,rgot)
-                                        {
-                                          return Native.Error.raise(String.concat(_J.toList(["Internal red-black tree invariant violated, expected ",
-                                                                                             msg,
-                                                                                             "and got",
-                                                                                             showNColor(c),
-                                                                                             " ",
-                                                                                             lgot,
-                                                                                             " ",
-                                                                                             rgot,
-                                                                                             "\nPlease report this bug to https://github.com/evancz/Elm/issues"])))
-                                        });
-                  var ensureBlackRoot = function (t)
-                                        {
-                                          return function ()
-                                                 {
-                                                   switch (t.ctor)
-                                                   {case
-                                                    "RBEmpty" :
-                                                      switch (t._0.ctor)
-                                                      {case
-                                                       "LBlack" :
-                                                         return t}
-                                                      break;
-                                                    case
-                                                    "RBNode" :
-                                                      switch (t._0.ctor)
-                                                      {case
-                                                       "Black" :
-                                                         return t
-                                                       case
-                                                       "Red" :
-                                                         return A5(RBNode,
-                                                                   Black,
-                                                                   t._1,
-                                                                   t._2,
-                                                                   t._3,
-                                                                   t._4)}
-                                                      break;}
-                                                   _E.Case($moduleName,"between lines 118 and 124");
-                                                 }()
-                                        };
-                  var moreBlack = function (c)
-                                  {
-                                    return function ()
-                                           {
-                                             switch (c.ctor)
-                                             {case
-                                              "BBlack" :
-                                                return Native.Error.raise("Can\'t make a double black node more black!")
-                                              case
-                                              "Black" :
-                                                return BBlack
-                                              case
-                                              "NBlack" :
-                                                return Red
-                                              case
-                                              "Red" :
-                                                return Black}
-                                             _E.Case($moduleName,"between lines 180 and 184");
-                                           }()
-                                  };
-                  var lessBlack = function (c)
-                                  {
-                                    return function ()
-                                           {
-                                             switch (c.ctor)
-                                             {case
-                                              "BBlack" :
-                                                return Black
-                                              case
-                                              "Black" :
-                                                return Red
-                                              case
-                                              "NBlack" :
-                                                return Native.Error.raise("Can\'t make a negative black node less black!")
-                                              case
-                                              "Red" :
-                                                return NBlack}
-                                             _E.Case($moduleName,"between lines 187 and 191");
-                                           }()
-                                  };
-                  var lessBlackTree = function (t)
-                                      {
-                                        return function ()
-                                               {
-                                                 switch (t.ctor)
-                                                 {case
-                                                  "RBEmpty" :
-                                                    switch (t._0.ctor)
-                                                    {case
-                                                     "LBBlack" :
-                                                       return RBEmpty(LBlack)}
-                                                    break;
-                                                  case
-                                                  "RBNode" :
-                                                    return A5(RBNode,
-                                                              lessBlack(t._0),
-                                                              t._1,
-                                                              t._2,
-                                                              t._3,
-                                                              t._4)}
-                                                 _E.Case($moduleName,"between lines 194 and 196");
-                                               }()
-                                      };
-                  var redden = function (t)
-                               {
-                                 return function ()
-                                        {
-                                          switch (t.ctor)
-                                          {case
-                                           "RBEmpty" :
-                                             return Native.Error.raise("can\'t make a Leaf red")
-                                           case
-                                           "RBNode" :
-                                             return A5(RBNode,Red,t._1,t._2,t._3,t._4)}
-                                          _E.Case($moduleName,"between lines 296 and 300");
-                                        }()
-                               };
-                  var balance_node = function (t)
-                                     {
-                                       return function ()
-                                              {
-                                                var assemble = function (col)
-                                                               {
-                                                                 return function (xk)
-                                                                        {
-                                                                          return function (xv)
-                                                                                 {
-                                                                                   return function (yk)
-                                                                                          {
-                                                                                            return function (yv)
-                                                                                                   {
-                                                                                                     return function (zk)
-                                                                                                            {
-                                                                                                              return function (zv)
-                                                                                                                     {
-                                                                                                                       return function (a)
-                                                                                                                              {
-                                                                                                                                return function (b)
-                                                                                                                                       {
-                                                                                                                                         return function (c)
-                                                                                                                                                {
-                                                                                                                                                  return function (d)
-                                                                                                                                                         {
-                                                                                                                                                           return A5(RBNode,
-                                                                                                                                                                     lessBlack(col),
-                                                                                                                                                                     yk,
-                                                                                                                                                                     yv,
-                                                                                                                                                                     A5(RBNode,
-                                                                                                                                                                        Black,
-                                                                                                                                                                        xk,
-                                                                                                                                                                        xv,
-                                                                                                                                                                        a,
-                                                                                                                                                                        b),
-                                                                                                                                                                     A5(RBNode,
-                                                                                                                                                                        Black,
-                                                                                                                                                                        zk,
-                                                                                                                                                                        zv,
-                                                                                                                                                                        c,
-                                                                                                                                                                        d))
-                                                                                                                                                         }
-                                                                                                                                                }
-                                                                                                                                       }
-                                                                                                                              }
-                                                                                                                     }
-                                                                                                            }
-                                                                                                   }
-                                                                                          }
-                                                                                 }
-                                                                        }
-                                                               };
-                                                return blackish(t) ? function ()
-                                                                     {
-                                                                       switch (t.ctor)
-                                                                       {case
-                                                                        "RBNode" :
-                                                                          switch (t._3.ctor)
-                                                                          {case
-                                                                           "RBNode" :
-                                                                             switch (t._3._0.ctor)
-                                                                             {case
-                                                                              "Red" :
-                                                                                switch (t._3._3.ctor)
-                                                                                {case
-                                                                                 "RBNode" :
-                                                                                   switch (t._3._3._0.ctor)
-                                                                                   {case
-                                                                                    "Red" :
-                                                                                      return assemble(t._0)(t._3._3._1)(t._3._3._2)(t._3._1)(t._3._2)(t._1)(t._2)(t._3._3._3)(t._3._3._4)(t._3._4)(t._4)}
-                                                                                   break;}
-                                                                                switch (t._3._4.ctor)
-                                                                                {case
-                                                                                 "RBNode" :
-                                                                                   switch (t._3._4._0.ctor)
-                                                                                   {case
-                                                                                    "Red" :
-                                                                                      return assemble(t._0)(t._3._1)(t._3._2)(t._3._4._1)(t._3._4._2)(t._1)(t._2)(t._3._3)(t._3._4._3)(t._3._4._4)(t._4)}
-                                                                                   break;}
-                                                                                break;}
-                                                                             break;}
-                                                                          switch (t._4.ctor)
-                                                                          {case
-                                                                           "RBNode" :
-                                                                             switch (t._4._0.ctor)
-                                                                             {case
-                                                                              "Red" :
-                                                                                switch (t._4._3.ctor)
-                                                                                {case
-                                                                                 "RBNode" :
-                                                                                   switch (t._4._3._0.ctor)
-                                                                                   {case
-                                                                                    "Red" :
-                                                                                      return assemble(t._0)(t._1)(t._2)(t._4._3._1)(t._4._3._2)(t._4._1)(t._4._2)(t._3)(t._4._3._3)(t._4._3._4)(t._4._4)}
-                                                                                   break;}
-                                                                                switch (t._4._4.ctor)
-                                                                                {case
-                                                                                 "RBNode" :
-                                                                                   switch (t._4._4._0.ctor)
-                                                                                   {case
-                                                                                    "Red" :
-                                                                                      return assemble(t._0)(t._1)(t._2)(t._4._1)(t._4._2)(t._4._4._1)(t._4._4._2)(t._3)(t._4._3)(t._4._4._3)(t._4._4._4)}
-                                                                                   break;}
-                                                                                break;}
-                                                                             break;}
-                                                                          switch (t._0.ctor)
-                                                                          {case
-                                                                           "BBlack" :
-                                                                             switch (t._4.ctor)
-                                                                             {case
-                                                                              "RBNode" :
-                                                                                switch (t._4._0.ctor)
-                                                                                {case
-                                                                                 "NBlack" :
-                                                                                   switch (t._4._3.ctor)
-                                                                                   {case
-                                                                                    "RBNode" :
-                                                                                      switch (t._4._3._0.ctor)
-                                                                                      {case
-                                                                                       "Black" :
-                                                                                         return function ()
-                                                                                                {
-                                                                                                  switch (t._4._4.ctor)
-                                                                                                  {case
-                                                                                                   "RBNode" :
-                                                                                                     switch (t._4._4._0.ctor)
-                                                                                                     {case
-                                                                                                      "Black" :
-                                                                                                        return A5(RBNode,
-                                                                                                                  Black,
-                                                                                                                  t._4._3._1,
-                                                                                                                  t._4._3._2,
-                                                                                                                  A5(RBNode,
-                                                                                                                     Black,
-                                                                                                                     t._1,
-                                                                                                                     t._2,
-                                                                                                                     t._3,
-                                                                                                                     t._4._3._3),
-                                                                                                                  A5(balance,
-                                                                                                                     Black,
-                                                                                                                     t._4._1,
-                                                                                                                     t._4._2,
-                                                                                                                     t._4._3._4,
-                                                                                                                     redden(t._4._4)))}
-                                                                                                     break;}
-                                                                                                  return t
-                                                                                                }()}
-                                                                                      break;}
-                                                                                   break;}
-                                                                                break;}
-                                                                             switch (t._3.ctor)
-                                                                             {case
-                                                                              "RBNode" :
-                                                                                switch (t._3._0.ctor)
-                                                                                {case
-                                                                                 "NBlack" :
-                                                                                   switch (t._3._4.ctor)
-                                                                                   {case
-                                                                                    "RBNode" :
-                                                                                      switch (t._3._4._0.ctor)
-                                                                                      {case
-                                                                                       "Black" :
-                                                                                         return function ()
-                                                                                                {
-                                                                                                  switch (t._3._3.ctor)
-                                                                                                  {case
-                                                                                                   "RBNode" :
-                                                                                                     switch (t._3._3._0.ctor)
-                                                                                                     {case
-                                                                                                      "Black" :
-                                                                                                        return A5(RBNode,
-                                                                                                                  Black,
-                                                                                                                  t._3._4._1,
-                                                                                                                  t._3._4._2,
-                                                                                                                  A5(balance,
-                                                                                                                     Black,
-                                                                                                                     t._3._1,
-                                                                                                                     t._3._2,
-                                                                                                                     redden(t._3._3),
-                                                                                                                     t._3._4._3),
-                                                                                                                  A5(RBNode,
-                                                                                                                     Black,
-                                                                                                                     t._1,
-                                                                                                                     t._2,
-                                                                                                                     t._3._4._4,
-                                                                                                                     t._4))}
-                                                                                                     break;}
-                                                                                                  return t
-                                                                                                }()}
-                                                                                      break;}
-                                                                                   break;}
-                                                                                break;}
-                                                                             break;}
-                                                                          break;}
-                                                                       return t
-                                                                     }() : t
-                                              }()
-                                     };
-                  var balance = F5(function (c,k,v,l,r)
-                                   {
-                                     return balance_node(A5(RBNode,c,k,v,l,r))
-                                   });
-                  var bubble = F5(function (c,k,v,l,r)
-                                  {
-                                    return isBBlack(l) || isBBlack(r) ? A5(balance,
-                                                                           moreBlack(c),
-                                                                           k,
-                                                                           v,
-                                                                           lessBlackTree(l),
-                                                                           lessBlackTree(r)) : A5(RBNode,
-                                                                                                  c,
-                                                                                                  k,
-                                                                                                  v,
-                                                                                                  l,
-                                                                                                  r)
-                                  });
-                  var remove_max = F5(function (c,k,v,l,r)
-                                      {
-                                        return function ()
-                                               {
-                                                 switch (r.ctor)
-                                                 {case
-                                                  "RBEmpty" :
-                                                    return A3(rem,c,l,r)
-                                                  case
-                                                  "RBNode" :
-                                                    return A5(bubble,
-                                                              c,
-                                                              k,
-                                                              v,
-                                                              l,
-                                                              A5(remove_max,
-                                                                 r._0,
-                                                                 r._1,
-                                                                 r._2,
-                                                                 r._3,
-                                                                 r._4))}
-                                                 _E.Case($moduleName,"between lines 242 and 245");
-                                               }()
-                                      });
-                  var rem = F3(function (c,l,r)
-                               {
-                                 return function ()
-                                        {
-                                          var _v175 = {ctor: "_Tuple2", _0: l, _1: r};
-                                          switch (_v175.ctor)
-                                          {case
-                                           "_Tuple2" :
-                                             switch (_v175._0.ctor)
-                                             {case
-                                              "RBEmpty" :
-                                                switch (_v175._1.ctor)
-                                                {case
-                                                 "RBEmpty" :
-                                                   return function ()
-                                                          {
-                                                            switch (c.ctor)
-                                                            {case
-                                                             "Black" :
-                                                               return RBEmpty(LBBlack)
-                                                             case
-                                                             "Red" :
-                                                               return RBEmpty(LBlack)}
-                                                            _E.Case($moduleName,
-                                                                    "between lines 215 and 218");
-                                                          }()
-                                                 case
-                                                 "RBNode" :
-                                                   return function ()
-                                                          {
-                                                            var _v197 = {ctor: "_Tuple3", _0: c, _1: _v175._0._0, _2: _v175._1._0};
-                                                            switch (_v197.ctor)
-                                                            {case
-                                                             "_Tuple3" :
-                                                               switch (_v197._0.ctor)
-                                                               {case
-                                                                "Black" :
-                                                                  switch (_v197._1.ctor)
-                                                                  {case
-                                                                   "LBlack" :
-                                                                     switch (_v197._2.ctor)
-                                                                     {case
-                                                                      "Red" :
-                                                                        return A5(RBNode,
-                                                                                  Black,
-                                                                                  _v175._1._1,
-                                                                                  _v175._1._2,
-                                                                                  _v175._1._3,
-                                                                                  _v175._1._4)}
-                                                                     break;}
-                                                                  break;}
-                                                               break;}
-                                                            return A4(reportRemBug,
-                                                                      "Black, LBlack, Red",
-                                                                      c,
-                                                                      showLColor(_v175._0._0),
-                                                                      showNColor(_v175._1._0))
-                                                          }()}
-                                                break;
-                                              case
-                                              "RBNode" :
-                                                switch (_v175._1.ctor)
-                                                {case
-                                                 "RBEmpty" :
-                                                   return function ()
-                                                          {
-                                                            var _v201 = {ctor: "_Tuple3", _0: c, _1: _v175._0._0, _2: _v175._1._0};
-                                                            switch (_v201.ctor)
-                                                            {case
-                                                             "_Tuple3" :
-                                                               switch (_v201._0.ctor)
-                                                               {case
-                                                                "Black" :
-                                                                  switch (_v201._1.ctor)
-                                                                  {case
-                                                                   "Red" :
-                                                                     switch (_v201._2.ctor)
-                                                                     {case
-                                                                      "LBlack" :
-                                                                        return A5(RBNode,
-                                                                                  Black,
-                                                                                  _v175._0._1,
-                                                                                  _v175._0._2,
-                                                                                  _v175._0._3,
-                                                                                  _v175._0._4)}
-                                                                     break;}
-                                                                  break;}
-                                                               break;}
-                                                            return A4(reportRemBug,
-                                                                      "Black, Red, LBlack",
-                                                                      c,
-                                                                      showNColor(_v175._0._0),
-                                                                      showLColor(_v175._1._0))
-                                                          }()
-                                                 case
-                                                 "RBNode" :
-                                                   return function ()
-                                                          {
-                                                            var l$ = A5(remove_max,
-                                                                        _v175._0._0,
-                                                                        _v175._0._1,
-                                                                        _v175._0._2,
-                                                                        _v175._0._3,
-                                                                        _v175._0._4);
-                                                            var r = A5(RBNode,
-                                                                       _v175._1._0,
-                                                                       _v175._1._1,
-                                                                       _v175._1._2,
-                                                                       _v175._1._3,
-                                                                       _v175._1._4);
-                                                            var l = A5(RBNode,
-                                                                       _v175._0._0,
-                                                                       _v175._0._1,
-                                                                       _v175._0._2,
-                                                                       _v175._0._3,
-                                                                       _v175._0._4);
-                                                            var $ = max(l),k = $._0,v = $._1;
-                                                            return A5(bubble,c,k,v,l$,r)
-                                                          }()}
-                                                break;}
-                                             break;}
-                                          _E.Case($moduleName,"between lines 214 and 232");
-                                        }()
-                               });
-                  var update = F3(function (k,u,t)
-                                  {
-                                    return function ()
-                                           {
-                                             var up = function (t)
-                                                      {
-                                                        return function ()
-                                                               {
-                                                                 switch (t.ctor)
-                                                                 {case
-                                                                  "RBEmpty" :
-                                                                    switch (t._0.ctor)
-                                                                    {case
-                                                                     "LBlack" :
-                                                                       return function ()
-                                                                              {
-                                                                                var _v212 = u(Maybe.Nothing);
-                                                                                switch (_v212.ctor)
-                                                                                {case
-                                                                                 "Just" :
-                                                                                   return {ctor: "_Tuple2", _0: Insert, _1: A5(RBNode,
-                                                                                                                               Red,
-                                                                                                                               k,
-                                                                                                                               _v212._0,
-                                                                                                                               empty,
-                                                                                                                               empty)}
-                                                                                 case
-                                                                                 "Nothing" :
-                                                                                   return {ctor: "_Tuple2", _0: Same, _1: empty}}
-                                                                                _E.Case($moduleName,
-                                                                                        "between lines 146 and 149");
-                                                                              }()}
-                                                                    break;
-                                                                  case
-                                                                  "RBNode" :
-                                                                    return function ()
-                                                                           {
-                                                                             var _v214 = A2(Native.Utils.compare,
-                                                                                            k,
-                                                                                            t._1);
-                                                                             switch (_v214.ctor)
-                                                                             {case
-                                                                              "EQ" :
-                                                                                return function ()
-                                                                                       {
-                                                                                         var _v215 = u(Maybe.Just(t._2));
-                                                                                         switch (_v215.ctor)
-                                                                                         {case
-                                                                                          "Just" :
-                                                                                            return {ctor: "_Tuple2", _0: Same, _1: A5(RBNode,
-                                                                                                                                      t._0,
-                                                                                                                                      t._1,
-                                                                                                                                      _v215._0,
-                                                                                                                                      t._3,
-                                                                                                                                      t._4)}
-                                                                                          case
-                                                                                          "Nothing" :
-                                                                                            return {ctor: "_Tuple2", _0: Remove, _1: A3(rem,
-                                                                                                                                        t._0,
-                                                                                                                                        t._3,
-                                                                                                                                        t._4)}}
-                                                                                         _E.Case($moduleName,
-                                                                                                 "between lines 150 and 153");
-                                                                                       }()
-                                                                              case
-                                                                              "GT" :
-                                                                                return function ()
-                                                                                       {
-                                                                                         var $ = up(t._4),
-                                                                                             fl = $._0,
-                                                                                             r$ = $._1;
-                                                                                         return function ()
-                                                                                                {
-                                                                                                  switch (fl.ctor)
-                                                                                                  {case
-                                                                                                   "Insert" :
-                                                                                                     return {ctor: "_Tuple2", _0: Insert, _1: A5(balance,
-                                                                                                                                                 t._0,
-                                                                                                                                                 t._1,
-                                                                                                                                                 t._2,
-                                                                                                                                                 t._3,
-                                                                                                                                                 r$)}
-                                                                                                   case
-                                                                                                   "Remove" :
-                                                                                                     return {ctor: "_Tuple2", _0: Remove, _1: A5(bubble,
-                                                                                                                                                 t._0,
-                                                                                                                                                 t._1,
-                                                                                                                                                 t._2,
-                                                                                                                                                 t._3,
-                                                                                                                                                 r$)}
-                                                                                                   case
-                                                                                                   "Same" :
-                                                                                                     return {ctor: "_Tuple2", _0: Same, _1: A5(RBNode,
-                                                                                                                                               t._0,
-                                                                                                                                               t._1,
-                                                                                                                                               t._2,
-                                                                                                                                               t._3,
-                                                                                                                                               r$)}}
-                                                                                                  _E.Case($moduleName,
-                                                                                                          "between lines 159 and 163");
-                                                                                                }()
-                                                                                       }()
-                                                                              case
-                                                                              "LT" :
-                                                                                return function ()
-                                                                                       {
-                                                                                         var $ = up(t._3),
-                                                                                             fl = $._0,
-                                                                                             l$ = $._1;
-                                                                                         return function ()
-                                                                                                {
-                                                                                                  switch (fl.ctor)
-                                                                                                  {case
-                                                                                                   "Insert" :
-                                                                                                     return {ctor: "_Tuple2", _0: Insert, _1: A5(balance,
-                                                                                                                                                 t._0,
-                                                                                                                                                 t._1,
-                                                                                                                                                 t._2,
-                                                                                                                                                 l$,
-                                                                                                                                                 t._4)}
-                                                                                                   case
-                                                                                                   "Remove" :
-                                                                                                     return {ctor: "_Tuple2", _0: Remove, _1: A5(bubble,
-                                                                                                                                                 t._0,
-                                                                                                                                                 t._1,
-                                                                                                                                                 t._2,
-                                                                                                                                                 l$,
-                                                                                                                                                 t._4)}
-                                                                                                   case
-                                                                                                   "Same" :
-                                                                                                     return {ctor: "_Tuple2", _0: Same, _1: A5(RBNode,
-                                                                                                                                               t._0,
-                                                                                                                                               t._1,
-                                                                                                                                               t._2,
-                                                                                                                                               l$,
-                                                                                                                                               t._4)}}
-                                                                                                  _E.Case($moduleName,
-                                                                                                          "between lines 154 and 158");
-                                                                                                }()
-                                                                                       }()}
-                                                                             _E.Case($moduleName,
-                                                                                     "between lines 149 and 163");
-                                                                           }()}
-                                                                 _E.Case($moduleName,
-                                                                         "between lines 145 and 163");
-                                                               }()
-                                                      };
-                                             var $ = up(t),fl = $._0,t$ = $._1;
-                                             return function ()
-                                                    {
-                                                      switch (fl.ctor)
-                                                      {case
-                                                       "Insert" :
-                                                         return ensureBlackRoot(t$)
-                                                       case
-                                                       "Remove" :
-                                                         return blacken(t$)
-                                                       case
-                                                       "Same" :
-                                                         return t$}
-                                                      _E.Case($moduleName,
-                                                              "between lines 164 and 169");
-                                                    }()
-                                           }()
-                                  });
-                  var insert = F3(function (k,v,t)
-                                  {
-                                    return function ()
-                                           {
-                                             var u = function (_v220)
-                                                     {
-                                                       return function ()
-                                                              {
-                                                                return Maybe.Just(v)
-                                                              }()
-                                                     };
-                                             return A3(update,k,u,t)
-                                           }()
-                                  });
-                  var singleton = F2(function (k,v)
-                                     {
-                                       return A3(insert,k,v,RBEmpty(LBlack))
-                                     });
-                  var union = F2(function (t1,t2)
-                                 {
-                                   return A3(foldl,insert,t2,t1)
-                                 });
-                  var intersect = F2(function (t1,t2)
-                                     {
-                                       return function ()
-                                              {
-                                                var combine = F3(function (k,v,t)
-                                                                 {
-                                                                   return A2(member,
-                                                                             k,
-                                                                             t2) ? A3(insert,
-                                                                                      k,
-                                                                                      v,
-                                                                                      t) : t
-                                                                 });
-                                                return A3(foldl,combine,empty,t1)
-                                              }()
-                                     });
-                  var fromList = function (assocs)
-                                 {
-                                   return A3(List.foldl,
-                                             F2(function (_v222,d)
-                                                {
-                                                  return function ()
-                                                         {
-                                                           switch (_v222.ctor)
-                                                           {case
-                                                            "_Tuple2" :
-                                                              return A3(insert,_v222._0,_v222._1,d)}
-                                                           _E.Case($moduleName,
-                                                                   "on line 354, column 43 to 55");
-                                                         }()
-                                                }),
-                                             empty,
-                                             assocs)
-                                 };
-                  var remove = F2(function (k,t)
-                                  {
-                                    return function ()
-                                           {
-                                             var u = function (_v226)
-                                                     {
-                                                       return function ()
-                                                              {
-                                                                return Maybe.Nothing
-                                                              }()
-                                                     };
-                                             return A3(update,k,u,t)
-                                           }()
-                                  });
-                  var diff = F2(function (t1,t2)
-                                {
-                                  return A3(foldl,
-                                            F3(function (k,v,t)
-                                               {
-                                                 return A2(remove,k,t)
-                                               }),
-                                            t1,
-                                            t2)
-                                });
-                  _elm.Dict.values = {_op: _op, empty: empty, singleton: singleton, insert: insert, update: update, lookup: lookup, findWithDefault: findWithDefault, remove: remove, member: member, foldl: foldl, foldr: foldr, map: map, union: union, intersect: intersect, diff: diff, keys: keys, values: values, toList: toList, fromList: fromList};
-                  return _elm.Dict.values
-                };Elm.Either = Elm.Either || {};
-Elm.Either.make = function (_elm)
-                  {
-                    _elm.Either = _elm.Either || {};
-                    if (_elm.Either.values)
-                    return _elm.Either.values
-                    var _N = Elm.Native,
-                        _U = _N.Utils.make(_elm),
-                        _L = _N.List.make(_elm),
-                        _E = _N.Error.make(_elm),
-                        _J = _N.JavaScript.make(_elm),
-                        $moduleName = "Either";
-                    var List = Elm.List.make(_elm);
-                    var _op = {};
-                    var Right = function (a)
-                                {
-                                  return {ctor: "Right", _0: a}
-                                };
-                    var isRight = function (e)
-                                  {
-                                    return function ()
-                                           {
-                                             switch (e.ctor)
-                                             {case
-                                              "Right" :
-                                                return true}
-                                             return false
-                                           }()
-                                  };
-                    var Left = function (a)
-                               {
-                                 return {ctor: "Left", _0: a}
-                               };
-                    var either = F3(function (f,g,e)
-                                    {
-                                      return function ()
-                                             {
-                                               switch (e.ctor)
-                                               {case
-                                                "Left" :
-                                                  return f(e._0)
-                                                case
-                                                "Right" :
-                                                  return g(e._0)}
-                                               _E.Case($moduleName,"on line 31, column 16 to 60");
-                                             }()
-                                    });
-                    var isLeft = function (e)
-                                 {
-                                   return function ()
-                                          {
-                                            switch (e.ctor)
-                                            {case
-                                             "Left" :
-                                               return true}
-                                            return false
-                                          }()
-                                 };
-                    var consLeft = F2(function (e,vs)
-                                      {
-                                        return function ()
-                                               {
-                                                 switch (e.ctor)
-                                                 {case
-                                                  "Left" :
-                                                    return {ctor: "::", _0: e._0, _1: vs}
-                                                  case
-                                                  "Right" :
-                                                    return vs}
-                                                 _E.Case($moduleName,"between lines 56 and 58");
-                                               }()
-                                      });
-                    var lefts = function (es)
-                                {
-                                  return A3(List.foldr,consLeft,_J.toList([]),es)
-                                };
-                    var consRight = F2(function (e,vs)
-                                       {
-                                         return function ()
-                                                {
-                                                  switch (e.ctor)
-                                                  {case
-                                                   "Left" :
-                                                     return vs
-                                                   case
-                                                   "Right" :
-                                                     return {ctor: "::", _0: e._0, _1: vs}}
-                                                  _E.Case($moduleName,"between lines 61 and 63");
-                                                }()
-                                       });
-                    var rights = function (es)
-                                 {
-                                   return A3(List.foldr,consRight,_J.toList([]),es)
-                                 };
-                    var consEither = F2(function (e,_v13)
-                                        {
-                                          return function ()
-                                                 {
-                                                   switch (_v13.ctor)
-                                                   {case
-                                                    "_Tuple2" :
-                                                      return function ()
-                                                             {
-                                                               switch (e.ctor)
-                                                               {case
-                                                                "Left" :
-                                                                  return {ctor: "_Tuple2", _0: {ctor: "::", _0: e._0, _1: _v13._0}, _1: _v13._1}
-                                                                case
-                                                                "Right" :
-                                                                  return {ctor: "_Tuple2", _0: _v13._0, _1: {ctor: "::", _0: e._0, _1: _v13._1}}}
-                                                               _E.Case($moduleName,
-                                                                       "between lines 66 and 68");
-                                                             }()}
-                                                   _E.Case($moduleName,"between lines 66 and 68");
-                                                 }()
-                                        });
-                    var partition = function (es)
-                                    {
-                                      return A3(List.foldr,
-                                                consEither,
-                                                {ctor: "_Tuple2", _0: _J.toList([]), _1: _J.toList([])},
-                                                es)
-                                    };
-                    _elm.Either.values = {_op: _op, either: either, isLeft: isLeft, isRight: isRight, lefts: lefts, rights: rights, partition: partition, consLeft: consLeft, consRight: consRight, consEither: consEither, Left: Left, Right: Right};
-                    return _elm.Either.values
-                  };Elm.Http = Elm.Http || {};
-Elm.Http.make = function (_elm)
-                {
-                  _elm.Http = _elm.Http || {};
-                  if (_elm.Http.values)
-                  return _elm.Http.values
-                  var _N = Elm.Native,
-                      _U = _N.Utils.make(_elm),
-                      _L = _N.List.make(_elm),
-                      _E = _N.Error.make(_elm),
-                      _J = _N.JavaScript.make(_elm),
-                      $moduleName = "Http";
-                  var Native = Native || {};
-                  Native.Http = Elm.Native.Http.make(_elm);
-                  var Signal = Elm.Signal.make(_elm);
-                  var _op = {};
-                  var send = Native.Http.send;
-                  var Request = F4(function (a,b,c,d)
-                                   {
-                                     return {_: {}, body: c, headers: d, url: b, verb: a}
-                                   });
-                  var request = Request;
-                  var get = function (url)
-                            {
-                              return A4(Request,"GET",url,"",_J.toList([]))
-                            };
-                  var sendGet = function (reqs)
-                                {
-                                  return send(A2(Signal.lift,get,reqs))
-                                };
-                  var post = F2(function (url,body)
-                                {
-                                  return A4(Request,"POST",url,body,_J.toList([]))
-                                });
-                  var Failure = F2(function (a,b)
-                                   {
-                                     return {ctor: "Failure", _0: a, _1: b}
-                                   });
-                  var Waiting = {ctor: "Waiting"};
-                  var Success = function (a)
-                                {
-                                  return {ctor: "Success", _0: a}
-                                };
-                  _elm.Http.values = {_op: _op, request: request, get: get, post: post, send: send, sendGet: sendGet, Success: Success, Waiting: Waiting, Failure: Failure, Request: Request};
-                  return _elm.Http.values
-                };Elm.JavaScript = Elm.JavaScript || {};
-Elm.JavaScript.make = function (_elm)
-                      {
-                        _elm.JavaScript = _elm.JavaScript || {};
-                        if (_elm.JavaScript.values)
-                        return _elm.JavaScript.values
-                        var _N = Elm.Native,
-                            _U = _N.Utils.make(_elm),
-                            _L = _N.List.make(_elm),
-                            _E = _N.Error.make(_elm),
-                            _J = _N.JavaScript.make(_elm),
-                            $moduleName = "JavaScript";
-                        var Native = Native || {};
-                        Native.JavaScript = Elm.Native.JavaScript.make(_elm);
-                        var _op = {};
-                        var fromString = Native.JavaScript.fromString;
-                        var fromBool = Native.JavaScript.fromBool;
-                        var fromFloat = Native.JavaScript.fromFloat;
-                        var fromInt = Native.JavaScript.fromInt;
-                        var fromList = Native.JavaScript.fromList;
-                        var toString = Native.JavaScript.toString;
-                        var toBool = Native.JavaScript.toBool;
-                        var toFloat = Native.JavaScript.toFloat;
-                        var toInt = Native.JavaScript.toInt;
-                        var toList = Native.JavaScript.toList;
-                        var JSObject = {ctor: "JSObject"};
-                        var JSDomNode = {ctor: "JSDomNode"};
-                        var JSArray = function (a)
-                                      {
-                                        return {ctor: "JSArray", _0: a}
-                                      };
-                        var JSString = {ctor: "JSString"};
-                        var JSBool = {ctor: "JSBool"};
-                        var JSNumber = {ctor: "JSNumber"};
-                        _elm.JavaScript.values = {_op: _op, toList: toList, toInt: toInt, toFloat: toFloat, toBool: toBool, toString: toString, fromList: fromList, fromInt: fromInt, fromFloat: fromFloat, fromBool: fromBool, fromString: fromString, JSNumber: JSNumber, JSBool: JSBool, JSString: JSString, JSArray: JSArray, JSDomNode: JSDomNode, JSObject: JSObject};
-                        return _elm.JavaScript.values
-                      };Elm.Json = Elm.Json || {};
-Elm.Json.make = function (_elm)
-                {
-                  _elm.Json = _elm.Json || {};
-                  if (_elm.Json.values)
-                  return _elm.Json.values
-                  var _N = Elm.Native,
-                      _U = _N.Utils.make(_elm),
-                      _L = _N.List.make(_elm),
-                      _E = _N.Error.make(_elm),
-                      _J = _N.JavaScript.make(_elm),
-                      $moduleName = "Json";
-                  var Basics = Elm.Basics.make(_elm);
-                  var Dict = Elm.Dict.make(_elm);
-                  var JavaScript = Elm.JavaScript.make(_elm);
-                  var Maybe = Elm.Maybe.make(_elm);
-                  var Native = Native || {};
-                  Native.Json = Elm.Native.Json.make(_elm);
-                  var _op = {};
-                  var toJSObject = Native.Json.toJSObject;
-                  var fromJSObject = Native.Json.fromJSObject;
-                  var fromJSString = Native.Json.fromJSString;
-                  var fromString = function (s)
-                                   {
-                                     return Native.Json.fromJSString(JavaScript.fromString(s))
-                                   };
-                  var toJSString = Native.Json.toJSString;
-                  var toString = F2(function (sep,v)
-                                    {
-                                      return JavaScript.toString(A2(Native.Json.toJSString,sep,v))
-                                    });
-                  var Object = function (a)
-                               {
-                                 return {ctor: "Object", _0: a}
-                               };
-                  var Array = function (a)
-                              {
-                                return {ctor: "Array", _0: a}
-                              };
-                  var Null = {ctor: "Null"};
-                  var Boolean = function (a)
-                                {
-                                  return {ctor: "Boolean", _0: a}
-                                };
-                  var Number = function (a)
-                               {
-                                 return {ctor: "Number", _0: a}
-                               };
-                  var String = function (a)
-                               {
-                                 return {ctor: "String", _0: a}
-                               };
-                  _elm.Json.values = {_op: _op, toString: toString, toJSString: toJSString, fromString: fromString, fromJSString: fromJSString, fromJSObject: fromJSObject, toJSObject: toJSObject, String: String, Number: Number, Boolean: Boolean, Null: Null, Array: Array, Object: Object};
-                  return _elm.Json.values
-                };Elm.Keyboard = Elm.Keyboard || {};
-Elm.Keyboard.make = function (_elm)
-                    {
-                      _elm.Keyboard = _elm.Keyboard || {};
-                      if (_elm.Keyboard.values)
-                      return _elm.Keyboard.values
-                      var _N = Elm.Native,
-                          _U = _N.Utils.make(_elm),
-                          _L = _N.List.make(_elm),
-                          _E = _N.Error.make(_elm),
-                          _J = _N.JavaScript.make(_elm),
-                          $moduleName = "Keyboard";
-                      var Native = Native || {};
-                      Native.Keyboard = Elm.Native.Keyboard.make(_elm);
-                      var Signal = Elm.Signal.make(_elm);
-                      var _op = {};
-                      var lastPressed = Native.Keyboard.lastPressed;
-                      var keysDown = Native.Keyboard.keysDown;
-                      var isDown = Native.Keyboard.isDown;
-                      var shift = isDown(16);
-                      var ctrl = isDown(17);
-                      var space = isDown(32);
-                      var enter = isDown(13);
-                      var directions = Native.Keyboard.directions;
-                      var arrows = A4(directions,38,40,37,39);
-                      var wasd = A4(directions,87,83,65,68);
-                      _elm.Keyboard.values = {_op: _op, directions: directions, arrows: arrows, wasd: wasd, isDown: isDown, shift: shift, ctrl: ctrl, space: space, enter: enter, keysDown: keysDown, lastPressed: lastPressed};
-                      return _elm.Keyboard.values
-                    };Elm.List = Elm.List || {};
-Elm.List.make = function (_elm)
-                {
-                  _elm.List = _elm.List || {};
-                  if (_elm.List.values)
-                  return _elm.List.values
-                  var _N = Elm.Native,
-                      _U = _N.Utils.make(_elm),
-                      _L = _N.List.make(_elm),
-                      _E = _N.Error.make(_elm),
-                      _J = _N.JavaScript.make(_elm),
-                      $moduleName = "List";
-                  var Basics = Elm.Basics.make(_elm);
-                  var Native = Native || {};
-                  Native.List = Elm.Native.List.make(_elm);
-                  var _op = {};
-                  var sortWith = Native.List.sortWith;
-                  var sortBy = Native.List.sortBy;
-                  var sort = Native.List.sort;
-                  var repeat = Native.List.repeat;
-                  var drop = Native.List.drop;
-                  var take = Native.List.take;
-                  var join = Native.List.join;
-                  var zipWith = Native.List.zipWith;
-                  var zip = Native.List.zip;
-                  var concat = Native.List.concat;
-                  var any = Native.List.any;
-                  var all = Native.List.all;
-                  var reverse = Native.List.reverse;
-                  var length = Native.List.length;
-                  var filter = Native.List.filter;
-                  var scanl1 = Native.List.scanl1;
-                  var scanl = Native.List.scanl;
-                  var foldr1 = Native.List.foldr1;
-                  var foldl1 = Native.List.foldl1;
-                  var maximum = foldl1(Basics.max);
-                  var minimum = foldl1(Basics.min);
-                  var foldr = Native.List.foldr;
-                  var foldl = Native.List.foldl;
-                  var and = A2(foldl,
-                               F2(function (x,y)
-                                  {
-                                    return x && y
-                                  }),
-                               true);
-                  var or = A2(foldl,
-                              F2(function (x,y)
-                                 {
-                                   return x || y
-                                 }),
-                              false);
-                  var sum = A2(foldl,
-                               F2(function (x,y)
-                                  {
-                                    return x + y
-                                  }),
-                               0);
-                  var product = A2(foldl,
-                                   F2(function (x,y)
-                                      {
-                                        return x * y
-                                      }),
-                                   1);
-                  var map = Native.List.map;
-                  var concatMap = F2(function (f,list)
-                                     {
-                                       return concat(A2(map,f,list))
-                                     });
-                  var isEmpty = function (xs)
-                                {
-                                  return function ()
-                                         {
-                                           switch (xs.ctor)
-                                           {case
-                                            "[]" :
-                                              return true}
-                                           return false
-                                         }()
-                                };
-                  var last = Native.List.last;
-                  var tail = Native.List.tail;
-                  var head = Native.List.head;
-                  _op["++"] = Native.List.append;
-                  _op["::"] = Native.List.cons;
-                  var partition = F2(function (pred,lst)
-                                     {
-                                       return function ()
-                                              {
-                                                switch (lst.ctor)
-                                                {case
-                                                 "::" :
-                                                   return function ()
-                                                          {
-                                                            var $ = A2(partition,pred,lst._1),
-                                                                bs = $._0,
-                                                                cs = $._1;
-                                                            return pred(lst._0) ? {ctor: "_Tuple2", _0: {ctor: "::", _0: lst._0, _1: bs}, _1: cs} : {ctor: "_Tuple2", _0: bs, _1: {ctor: "::", _0: lst._0, _1: cs}}
-                                                          }()
-                                                 case
-                                                 "[]" :
-                                                   return {ctor: "_Tuple2", _0: _J.toList([]), _1: _J.toList([])}}
-                                                _E.Case($moduleName,"between lines 169 and 179");
-                                              }()
-                                     });
-                  var unzip = function (pairs)
-                              {
-                                return function ()
-                                       {
-                                         switch (pairs.ctor)
-                                         {case
-                                          "::" :
-                                            switch (pairs._0.ctor)
-                                            {case
-                                             "_Tuple2" :
-                                               return function ()
-                                                      {
-                                                        var $ = unzip(pairs._1),xs = $._0,ys = $._1;
-                                                        return {ctor: "_Tuple2", _0: {ctor: "::", _0: pairs._0._0, _1: xs}, _1: {ctor: "::", _0: pairs._0._1, _1: ys}}
-                                                      }()}
-                                            break;
-                                          case
-                                          "[]" :
-                                            return {ctor: "_Tuple2", _0: _J.toList([]), _1: _J.toList([])}}
-                                         _E.Case($moduleName,"between lines 194 and 202");
-                                       }()
-                              };
-                  var intersperse = F2(function (sep,xs)
-                                       {
-                                         return function ()
-                                                {
-                                                  switch (xs.ctor)
-                                                  {case
-                                                   "::" :
-                                                     switch (xs._1.ctor)
-                                                     {case
-                                                      "::" :
-                                                        return {ctor: "::", _0: xs._0, _1: {ctor: "::", _0: sep, _1: A2(intersperse,
-                                                                                                                        sep,
-                                                                                                                        {ctor: "::", _0: xs._1._0, _1: xs._1._1})}}
-                                                      case
-                                                      "[]" :
-                                                        return _J.toList([xs._0])}
-                                                     break;
-                                                   case
-                                                   "[]" :
-                                                     return _J.toList([])}
-                                                  _E.Case($moduleName,"between lines 212 and 217");
-                                                }()
-                                       });
-                  _elm.List.values = {_op: _op, head: head, tail: tail, last: last, isEmpty: isEmpty, map: map, foldl: foldl, foldr: foldr, foldl1: foldl1, foldr1: foldr1, scanl: scanl, scanl1: scanl1, filter: filter, length: length, reverse: reverse, all: all, any: any, and: and, or: or, concat: concat, concatMap: concatMap, sum: sum, product: product, maximum: maximum, minimum: minimum, partition: partition, zip: zip, zipWith: zipWith, unzip: unzip, join: join, intersperse: intersperse, take: take, drop: drop, repeat: repeat, sort: sort, sortBy: sortBy, sortWith: sortWith};
-                  return _elm.List.values
-                };Elm.Maybe = Elm.Maybe || {};
-Elm.Maybe.make = function (_elm)
-                 {
-                   _elm.Maybe = _elm.Maybe || {};
-                   if (_elm.Maybe.values)
-                   return _elm.Maybe.values
-                   var _N = Elm.Native,
-                       _U = _N.Utils.make(_elm),
-                       _L = _N.List.make(_elm),
-                       _E = _N.Error.make(_elm),
-                       _J = _N.JavaScript.make(_elm),
-                       $moduleName = "Maybe";
-                   var Basics = Elm.Basics.make(_elm);
-                   var List = Elm.List.make(_elm);
-                   var _op = {};
-                   var Nothing = {ctor: "Nothing"};
-                   var Just = function (a)
-                              {
-                                return {ctor: "Just", _0: a}
-                              };
-                   var maybe = F3(function (b,f,m)
-                                  {
-                                    return function ()
-                                           {
-                                             switch (m.ctor)
-                                             {case
-                                              "Just" :
-                                                return f(m._0)
-                                              case
-                                              "Nothing" :
-                                                return b}
-                                             _E.Case($moduleName,"between lines 28 and 33");
-                                           }()
-                                  });
-                   var isJust = A2(maybe,
-                                   false,
-                                   function (_v2)
-                                   {
-                                     return function ()
-                                            {
-                                              return true
-                                            }()
-                                   });
-                   var isNothing = function ($)
-                                   {
-                                     return Basics.not(isJust($))
-                                   };
-                   var cons = F2(function (mx,xs)
-                                 {
-                                   return A3(maybe,
-                                             xs,
-                                             function (x)
-                                             {
-                                               return {ctor: "::", _0: x, _1: xs}
-                                             },
-                                             mx)
-                                 });
-                   var justs = A2(List.foldr,cons,_J.toList([]));
-                   _elm.Maybe.values = {_op: _op, maybe: maybe, isJust: isJust, isNothing: isNothing, cons: cons, justs: justs, Just: Just, Nothing: Nothing};
-                   return _elm.Maybe.values
-                 };Elm.Mouse = Elm.Mouse || {};
-Elm.Mouse.make = function (_elm)
-                 {
-                   _elm.Mouse = _elm.Mouse || {};
-                   if (_elm.Mouse.values)
-                   return _elm.Mouse.values
-                   var _N = Elm.Native,
-                       _U = _N.Utils.make(_elm),
-                       _L = _N.List.make(_elm),
-                       _E = _N.Error.make(_elm),
-                       _J = _N.JavaScript.make(_elm),
-                       $moduleName = "Mouse";
-                   var Native = Native || {};
-                   Native.Mouse = Elm.Native.Mouse.make(_elm);
-                   var Signal = Elm.Signal.make(_elm);
-                   var _op = {};
-                   var clicks = Native.Mouse.clicks;
-                   var isClicked = Native.Mouse.isClicked;
-                   var isDown = Native.Mouse.isDown;
-                   var y = Native.Mouse.y;
-                   var x = Native.Mouse.x;
-                   var position = Native.Mouse.position;
-                   _elm.Mouse.values = {_op: _op, position: position, x: x, y: y, isDown: isDown, isClicked: isClicked, clicks: clicks};
-                   return _elm.Mouse.values
-                 };Elm.Prelude = Elm.Prelude || {};
-Elm.Prelude.make = function (_elm)
-                   {
-                     _elm.Prelude = _elm.Prelude || {};
-                     if (_elm.Prelude.values)
-                     return _elm.Prelude.values
-                     var _N = Elm.Native,
-                         _U = _N.Utils.make(_elm),
-                         _L = _N.List.make(_elm),
-                         _E = _N.Error.make(_elm),
-                         _J = _N.JavaScript.make(_elm),
-                         $moduleName = "Prelude";
-                     var Native = Native || {};
-                     Native.Show = Elm.Native.Show.make(_elm);
-                     var _op = {};
-                     var show = Native.Show.show;
-                     _elm.Prelude.values = {_op: _op, show: show};
-                     return _elm.Prelude.values
-                   };Elm.Random = Elm.Random || {};
-Elm.Random.make = function (_elm)
-                  {
-                    _elm.Random = _elm.Random || {};
-                    if (_elm.Random.values)
-                    return _elm.Random.values
-                    var _N = Elm.Native,
-                        _U = _N.Utils.make(_elm),
-                        _L = _N.List.make(_elm),
-                        _E = _N.Error.make(_elm),
-                        _J = _N.JavaScript.make(_elm),
-                        $moduleName = "Random";
-                    var Native = Native || {};
-                    Native.Random = Elm.Native.Random.make(_elm);
-                    var Signal = Elm.Signal.make(_elm);
-                    var _op = {};
-                    var floatList = Native.Random.floatList;
-                    var $float = Native.Random.float_;
-                    var range = Native.Random.range;
-                    _elm.Random.values = {_op: _op, range: range, $float: $float, floatList: floatList};
-                    return _elm.Random.values
-                  };Elm.Regex = Elm.Regex || {};
-Elm.Regex.make = function (_elm)
-                 {
-                   _elm.Regex = _elm.Regex || {};
-                   if (_elm.Regex.values)
-                   return _elm.Regex.values
-                   var _N = Elm.Native,
-                       _U = _N.Utils.make(_elm),
-                       _L = _N.List.make(_elm),
-                       _E = _N.Error.make(_elm),
-                       _J = _N.JavaScript.make(_elm),
-                       $moduleName = "Regex";
-                   var Maybe = Elm.Maybe.make(_elm);
-                   var Native = Native || {};
-                   Native.Regex = Elm.Native.Regex.make(_elm);
-                   var _op = {};
-                   var splitN = Native.Regex.splitN;
-                   var split = Native.Regex.split;
-                   var replace = Native.Regex.replace;
-                   var replaceAll = Native.Regex.replaceAll;
-                   var find = Native.Regex.find;
-                   var findAll = Native.Regex.findAll;
-                   var Match = F4(function (a,b,c,d)
-                                  {
-                                    return {_: {}, index: c, match: a, number: d, submatches: b}
-                                  });
-                   var contains = Native.Regex.contains;
-                   var caseInsensitive = Native.Regex.caseInsensitive;
-                   var pattern = Native.Regex.pattern;
-                   var escape = Native.Regex.escape;
-                   var Regex = {ctor: "Regex"};
-                   _elm.Regex.values = {_op: _op, escape: escape, pattern: pattern, caseInsensitive: caseInsensitive, contains: contains, findAll: findAll, find: find, replaceAll: replaceAll, replace: replace, split: split, splitN: splitN, Regex: Regex, Match: Match};
-                   return _elm.Regex.values
-                 };Elm.Set = Elm.Set || {};
-Elm.Set.make = function (_elm)
-               {
-                 _elm.Set = _elm.Set || {};
-                 if (_elm.Set.values)
-                 return _elm.Set.values
-                 var _N = Elm.Native,
-                     _U = _N.Utils.make(_elm),
-                     _L = _N.List.make(_elm),
-                     _E = _N.Error.make(_elm),
-                     _J = _N.JavaScript.make(_elm),
-                     $moduleName = "Set";
-                 var Dict = Elm.Dict.make(_elm);
-                 var List = Elm.List.make(_elm);
-                 var Maybe = Elm.Maybe.make(_elm);
-                 var _op = {};
-                 var foldr = F3(function (f,b,s)
-                                {
-                                  return A3(Dict.foldr,
-                                            F3(function (k,_v0,b)
-                                               {
-                                                 return function ()
-                                                        {
-                                                          return A2(f,k,b)
-                                                        }()
-                                               }),
-                                            b,
-                                            s)
-                                });
-                 var foldl = F3(function (f,b,s)
-                                {
-                                  return A3(Dict.foldl,
-                                            F3(function (k,_v2,b)
-                                               {
-                                                 return function ()
-                                                        {
-                                                          return A2(f,k,b)
-                                                        }()
-                                               }),
-                                            b,
-                                            s)
-                                });
-                 var toList = Dict.keys;
-                 var diff = Dict.diff;
-                 var intersect = Dict.intersect;
-                 var union = Dict.union;
-                 var member = Dict.member;
-                 var remove = Dict.remove;
-                 var insert = function (k)
-                              {
-                                return A2(Dict.insert,k,{ctor: "_Tuple0"})
-                              };
-                 var singleton = function (k)
-                                 {
-                                   return A2(Dict.singleton,k,{ctor: "_Tuple0"})
-                                 };
-                 var empty = Dict.empty;
-                 var fromList = function (xs)
-                                {
-                                  return A3(List.foldl,insert,empty,xs)
-                                };
-                 var map = F2(function (f,s)
-                              {
-                                return fromList(A2(List.map,f,toList(s)))
-                              });
-                 _elm.Set.values = {_op: _op, empty: empty, singleton: singleton, insert: insert, remove: remove, member: member, foldl: foldl, foldr: foldr, map: map, union: union, intersect: intersect, diff: diff, toList: toList, fromList: fromList};
-                 return _elm.Set.values
-               };Elm.Signal = Elm.Signal || {};
-Elm.Signal.make = function (_elm)
-                  {
-                    _elm.Signal = _elm.Signal || {};
-                    if (_elm.Signal.values)
-                    return _elm.Signal.values
-                    var _N = Elm.Native,
-                        _U = _N.Utils.make(_elm),
-                        _L = _N.List.make(_elm),
-                        _E = _N.Error.make(_elm),
-                        _J = _N.JavaScript.make(_elm),
-                        $moduleName = "Signal";
-                    var List = Elm.List.make(_elm);
-                    var Native = Native || {};
-                    Native.Signal = Elm.Native.Signal.make(_elm);
-                    var _op = {};
-                    _op["~"] = F2(function (sf,s)
-                                  {
-                                    return A3(Native.Signal.lift2,
-                                              F2(function (f,x)
-                                                 {
-                                                   return f(x)
-                                                 }),
-                                              sf,
-                                              s)
-                                  });
-                    _op["<~"] = F2(function (f,s)
-                                   {
-                                     return A2(Native.Signal.lift,f,s)
-                                   });
-                    var sampleOn = Native.Signal.sampleOn;
-                    var dropRepeats = Native.Signal.dropRepeats;
-                    var dropWhen = Native.Signal.dropWhen;
-                    var keepWhen = Native.Signal.keepWhen;
-                    var dropIf = Native.Signal.dropIf;
-                    var keepIf = Native.Signal.keepIf;
-                    var countIf = Native.Signal.countIf;
-                    var count = Native.Signal.count;
-                    var combine = A2(List.foldr,
-                                     Native.Signal.lift2(F2(function (x,y)
-                                                            {
-                                                              return {ctor: "::", _0: x, _1: y}
-                                                            })),
-                                     Native.Signal.constant(_J.toList([])));
-                    var merges = Native.Signal.merges;
-                    var merge = Native.Signal.merge;
-                    var foldp = Native.Signal.foldp;
-                    var lift8 = Native.Signal.lift8;
-                    var lift7 = Native.Signal.lift7;
-                    var lift6 = Native.Signal.lift6;
-                    var lift5 = Native.Signal.lift5;
-                    var lift4 = Native.Signal.lift4;
-                    var lift3 = Native.Signal.lift3;
-                    var lift2 = Native.Signal.lift2;
-                    var lift = Native.Signal.lift;
-                    var constant = Native.Signal.constant;
-                    var Signal = {ctor: "Signal"};
-                    _elm.Signal.values = {_op: _op, constant: constant, lift: lift, lift2: lift2, lift3: lift3, lift4: lift4, lift5: lift5, lift6: lift6, lift7: lift7, lift8: lift8, foldp: foldp, merge: merge, merges: merges, combine: combine, count: count, countIf: countIf, keepIf: keepIf, dropIf: dropIf, keepWhen: keepWhen, dropWhen: dropWhen, dropRepeats: dropRepeats, sampleOn: sampleOn, Signal: Signal};
-                    return _elm.Signal.values
-                  };Elm.String = Elm.String || {};
-Elm.String.make = function (_elm)
-                  {
-                    _elm.String = _elm.String || {};
-                    if (_elm.String.values)
-                    return _elm.String.values
-                    var _N = Elm.Native,
-                        _U = _N.Utils.make(_elm),
-                        _L = _N.List.make(_elm),
-                        _E = _N.Error.make(_elm),
-                        _J = _N.JavaScript.make(_elm),
-                        $moduleName = "String";
-                    var Maybe = Elm.Maybe.make(_elm);
-                    var Native = Native || {};
-                    Native.String = Elm.Native.String.make(_elm);
-                    var _op = {};
-                    var fromList = Native.String.fromList;
-                    var toList = Native.String.toList;
-                    var toFloat = Native.String.toFloat;
-                    var toInt = Native.String.toInt;
-                    var indices = Native.String.indexes;
-                    var indexes = Native.String.indexes;
-                    var endsWith = Native.String.endsWith;
-                    var startsWith = Native.String.startsWith;
-                    var contains = Native.String.contains;
-                    var all = Native.String.all;
-                    var any = Native.String.any;
-                    var toLower = Native.String.toLower;
-                    var toUpper = Native.String.toUpper;
-                    var lines = Native.String.lines;
-                    var words = Native.String.words;
-                    var trimRight = Native.String.trimRight;
-                    var trimLeft = Native.String.trimLeft;
-                    var trim = Native.String.trim;
-                    var padRight = Native.String.padRight;
-                    var padLeft = Native.String.padLeft;
-                    var pad = Native.String.pad;
-                    var dropRight = Native.String.dropRight;
-                    var dropLeft = Native.String.dropLeft;
-                    var right = Native.String.right;
-                    var left = Native.String.left;
-                    var sub = Native.String.sub;
-                    var repeat = Native.String.repeat;
-                    var join = Native.String.join;
-                    var split = Native.String.split;
-                    var foldr = Native.String.foldr;
-                    var foldl = Native.String.foldl;
-                    var reverse = Native.String.reverse;
-                    var filter = Native.String.filter;
-                    var map = Native.String.map;
-                    var length = Native.String.length;
-                    var concat = Native.String.concat;
-                    var append = Native.String.append;
-                    var uncons = Native.String.uncons;
-                    var cons = Native.String.cons;
-                    var isEmpty = Native.String.isEmpty;
-                    _elm.String.values = {_op: _op, isEmpty: isEmpty, cons: cons, uncons: uncons, append: append, concat: concat, length: length, map: map, filter: filter, reverse: reverse, foldl: foldl, foldr: foldr, split: split, join: join, repeat: repeat, sub: sub, left: left, right: right, dropLeft: dropLeft, dropRight: dropRight, pad: pad, padLeft: padLeft, padRight: padRight, trim: trim, trimLeft: trimLeft, trimRight: trimRight, words: words, lines: lines, toUpper: toUpper, toLower: toLower, any: any, all: all, contains: contains, startsWith: startsWith, endsWith: endsWith, indexes: indexes, indices: indices, toInt: toInt, toFloat: toFloat, toList: toList, fromList: fromList};
-                    return _elm.String.values
-                  };Elm.Text = Elm.Text || {};
-Elm.Text.make = function (_elm)
-                {
-                  _elm.Text = _elm.Text || {};
-                  if (_elm.Text.values)
-                  return _elm.Text.values
-                  var _N = Elm.Native,
-                      _U = _N.Utils.make(_elm),
-                      _L = _N.List.make(_elm),
-                      _E = _N.Error.make(_elm),
-                      _J = _N.JavaScript.make(_elm),
-                      $moduleName = "Text";
-                  var Basics = Elm.Basics.make(_elm);
-                  var Color = Elm.Color.make(_elm);
-                  var Graphics = Graphics || {};
-                  Graphics.Element = Elm.Graphics.Element.make(_elm);
-                  var JavaScript = Elm.JavaScript.make(_elm);
-                  var Maybe = Elm.Maybe.make(_elm);
-                  var Native = Native || {};
-                  Native.Text = Elm.Native.Text.make(_elm);
-                  var _op = {};
-                  var asText = Native.Text.asText;
-                  var markdown = Native.Text.markdown;
-                  var plainText = Native.Text.plainText;
-                  var text = Native.Text.text;
-                  var righted = Native.Text.righted;
-                  var centered = Native.Text.centered;
-                  var justified = Native.Text.justified;
-                  var strikeThrough = Native.Text.strikeThrough;
-                  var underline = Native.Text.underline;
-                  var overline = Native.Text.overline;
-                  var italic = Native.Text.italic;
-                  var bold = Native.Text.bold;
-                  var color = Native.Text.color;
-                  var height = Native.Text.height;
-                  var link = Native.Text.link;
-                  var monospace = Native.Text.monospace;
-                  var typeface = Native.Text.typeface;
-                  var toText = Native.Text.toText;
-                  var Text = {ctor: "Text"};
-                  _elm.Text.values = {_op: _op, toText: toText, typeface: typeface, monospace: monospace, link: link, height: height, color: color, bold: bold, italic: italic, overline: overline, underline: underline, strikeThrough: strikeThrough, justified: justified, centered: centered, righted: righted, text: text, plainText: plainText, markdown: markdown, asText: asText, Text: Text};
-                  return _elm.Text.values
-                };Elm.Time = Elm.Time || {};
-Elm.Time.make = function (_elm)
-                {
-                  _elm.Time = _elm.Time || {};
-                  if (_elm.Time.values)
-                  return _elm.Time.values
-                  var _N = Elm.Native,
-                      _U = _N.Utils.make(_elm),
-                      _L = _N.List.make(_elm),
-                      _E = _N.Error.make(_elm),
-                      _J = _N.JavaScript.make(_elm),
-                      $moduleName = "Time";
-                  var Basics = Elm.Basics.make(_elm);
-                  var Native = Native || {};
-                  Native.Time = Elm.Native.Time.make(_elm);
-                  var Signal = Elm.Signal.make(_elm);
-                  var _op = {};
-                  var delay = Native.Time.delay;
-                  var timestamp = Native.Time.timestamp;
-                  var since = Native.Time.since;
-                  var every = Native.Time.every;
-                  var fpsWhen = Native.Time.fpsWhen;
-                  var fps = Native.Time.fps;
-                  var inMilliseconds = function (t)
-                                       {
-                                         return t
-                                       };
-                  var millisecond = 1;
-                  var second = 1000 * millisecond;
-                  var minute = 60 * second;
-                  var hour = 60 * minute;
-                  var inHours = function (t)
-                                {
-                                  return t / hour
-                                };
-                  var inMinutes = function (t)
-                                  {
-                                    return t / minute
-                                  };
-                  var inSeconds = function (t)
-                                  {
-                                    return t / second
-                                  };
-                  _elm.Time.values = {_op: _op, millisecond: millisecond, second: second, minute: minute, hour: hour, inMilliseconds: inMilliseconds, inSeconds: inSeconds, inMinutes: inMinutes, inHours: inHours, fps: fps, fpsWhen: fpsWhen, every: every, since: since, timestamp: timestamp, delay: delay};
-                  return _elm.Time.values
-                };Elm.Touch = Elm.Touch || {};
-Elm.Touch.make = function (_elm)
-                 {
-                   _elm.Touch = _elm.Touch || {};
-                   if (_elm.Touch.values)
-                   return _elm.Touch.values
-                   var _N = Elm.Native,
-                       _U = _N.Utils.make(_elm),
-                       _L = _N.List.make(_elm),
-                       _E = _N.Error.make(_elm),
-                       _J = _N.JavaScript.make(_elm),
-                       $moduleName = "Touch";
-                   var Native = Native || {};
-                   Native.Touch = Elm.Native.Touch.make(_elm);
-                   var Signal = Elm.Signal.make(_elm);
-                   var Time = Elm.Time.make(_elm);
-                   var _op = {};
-                   var taps = Native.Touch.taps;
-                   var touches = Native.Touch.touches;
-                   var Touch = F6(function (a,b,c,d,e,f)
-                                  {
-                                    return {_: {}, id: c, t0: f, x: a, x0: d, y: b, y0: e}
-                                  });
-                   _elm.Touch.values = {_op: _op, touches: touches, taps: taps, Touch: Touch};
-                   return _elm.Touch.values
-                 };Elm.Transform2D = Elm.Transform2D || {};
-Elm.Transform2D.make = function (_elm)
-                       {
-                         _elm.Transform2D = _elm.Transform2D || {};
-                         if (_elm.Transform2D.values)
-                         return _elm.Transform2D.values
-                         var _N = Elm.Native,
-                             _U = _N.Utils.make(_elm),
-                             _L = _N.List.make(_elm),
-                             _E = _N.Error.make(_elm),
-                             _J = _N.JavaScript.make(_elm),
-                             $moduleName = "Transform2D";
-                         var Native = Native || {};
-                         Native.Transform2D = Elm.Native.Transform2D.make(_elm);
-                         var _op = {};
-                         var multiply = Native.Transform2D.multiply;
-                         var rotation = Native.Transform2D.rotation;
-                         var matrix = Native.Transform2D.matrix;
-                         var translation = F2(function (x,y)
-                                              {
-                                                return A6(matrix,1,0,0,1,x,y)
-                                              });
-                         var scale = function (s)
-                                     {
-                                       return A6(matrix,s,0,0,s,0,0)
-                                     };
-                         var scaleX = function (x)
-                                      {
-                                        return A6(matrix,x,0,0,1,0,0)
-                                      };
-                         var scaleY = function (y)
-                                      {
-                                        return A6(matrix,1,0,0,y,0,0)
-                                      };
-                         var identity = Native.Transform2D.identity;
-                         var Transform2D = {ctor: "Transform2D"};
-                         _elm.Transform2D.values = {_op: _op, identity: identity, matrix: matrix, rotation: rotation, translation: translation, scale: scale, scaleX: scaleX, scaleY: scaleY, multiply: multiply, Transform2D: Transform2D};
-                         return _elm.Transform2D.values
-                       };Elm.WebSocket = Elm.WebSocket || {};
-Elm.WebSocket.make = function (_elm)
-                     {
-                       _elm.WebSocket = _elm.WebSocket || {};
-                       if (_elm.WebSocket.values)
-                       return _elm.WebSocket.values
-                       var _N = Elm.Native,
-                           _U = _N.Utils.make(_elm),
-                           _L = _N.List.make(_elm),
-                           _E = _N.Error.make(_elm),
-                           _J = _N.JavaScript.make(_elm),
-                           $moduleName = "WebSocket";
-                       var Basics = Elm.Basics.make(_elm);
-                       var Native = Native || {};
-                       Native.WebSocket = Elm.Native.WebSocket.make(_elm);
-                       var Signal = Elm.Signal.make(_elm);
-                       var _op = {};
-                       var connect = Native.WebSocket.connect;
-                       _elm.WebSocket.values = {_op: _op, connect: connect};
-                       return _elm.WebSocket.values
-                     };Elm.Window = Elm.Window || {};
-Elm.Window.make = function (_elm)
-                  {
-                    _elm.Window = _elm.Window || {};
-                    if (_elm.Window.values)
-                    return _elm.Window.values
-                    var _N = Elm.Native,
-                        _U = _N.Utils.make(_elm),
-                        _L = _N.List.make(_elm),
-                        _E = _N.Error.make(_elm),
-                        _J = _N.JavaScript.make(_elm),
-                        $moduleName = "Window";
-                    var Native = Native || {};
-                    Native.Window = Elm.Native.Window.make(_elm);
-                    var Signal = Elm.Signal.make(_elm);
-                    var _op = {};
-                    var height = Native.Window.height;
-                    var width = Native.Window.width;
-                    var dimensions = Native.Window.dimensions;
-                    _elm.Window.values = {_op: _op, dimensions: dimensions, width: width, height: height};
-                    return _elm.Window.values
-                  };Elm.Graphics = Elm.Graphics || {};
-Elm.Graphics.Collage = Elm.Graphics.Collage || {};
-Elm.Graphics.Collage.make = function (_elm)
-                            {
-                              _elm.Graphics = _elm.Graphics || {};
-                              _elm.Graphics.Collage = _elm.Graphics.Collage || {};
-                              if (_elm.Graphics.Collage.values)
-                              return _elm.Graphics.Collage.values
-                              var _N = Elm.Native,
-                                  _U = _N.Utils.make(_elm),
-                                  _L = _N.List.make(_elm),
-                                  _E = _N.Error.make(_elm),
-                                  _J = _N.JavaScript.make(_elm),
-                                  $moduleName = "Graphics.Collage";
-                              var Basics = Elm.Basics.make(_elm);
-                              var Color = Elm.Color.make(_elm);
-                              var Either = Elm.Either.make(_elm);
-                              var Graphics = Graphics || {};
-                              Graphics.Element = Elm.Graphics.Element.make(_elm);
-                              var JavaScript = Elm.JavaScript.make(_elm);
-                              var List = Elm.List.make(_elm);
-                              var Maybe = Elm.Maybe.make(_elm);
-                              var Native = Native || {};
-                              Native.Graphics = Native.Graphics || {};
-                              Native.Graphics.Collage = Elm.Native.Graphics.Collage.make(_elm);
-                              var Transform2D = Elm.Transform2D.make(_elm);
-                              var _op = {};
-                              var ngon = F2(function (n,r)
-                                            {
-                                              return function ()
-                                                     {
-                                                       var m = Basics.toFloat(n);
-                                                       var t = 2 * Basics.pi / m;
-                                                       var f = function (i)
-                                                               {
-                                                                 return {ctor: "_Tuple2", _0: r * Basics.cos(t * i), _1: r * Basics.sin(t * i)}
-                                                               };
-                                                       return A2(List.map,f,_L.range(0,m - 1))
-                                                     }()
-                                            });
-                              var oval = F2(function (w,h)
-                                            {
-                                              return function ()
-                                                     {
-                                                       var hh = h / 2;
-                                                       var hw = w / 2;
-                                                       var n = 50;
-                                                       var t = 2 * Basics.pi / n;
-                                                       var f = function (i)
-                                                               {
-                                                                 return {ctor: "_Tuple2", _0: hw * Basics.cos(t * i), _1: hh * Basics.sin(t * i)}
-                                                               };
-                                                       return A2(List.map,f,_L.range(0,n - 1))
-                                                     }()
-                                            });
-                              var circle = function (r)
-                                           {
-                                             return A2(oval,2 * r,2 * r)
-                                           };
-                              var rect = F2(function (w,h)
-                                            {
-                                              return function ()
-                                                     {
-                                                       var hh = h / 2;
-                                                       var hw = w / 2;
-                                                       return _J.toList([{ctor: "_Tuple2", _0: 0 - hw, _1: 0 - hh},
-                                                                         {ctor: "_Tuple2", _0: 0 - hw, _1: hh},
-                                                                         {ctor: "_Tuple2", _0: hw, _1: hh},
-                                                                         {ctor: "_Tuple2", _0: hw, _1: 0 - hh}])
-                                                     }()
-                                            });
-                              var square = function (n)
-                                           {
-                                             return A2(rect,n,n)
-                                           };
-                              var polygon = function (points)
-                                            {
-                                              return points
-                                            };
-                              var segment = F2(function (p1,p2)
-                                               {
-                                                 return _J.toList([p1,p2])
-                                               });
-                              var path = function (ps)
-                                         {
-                                           return ps
-                                         };
-                              var collage = Native.Graphics.Collage.collage;
-                              var alpha = F2(function (a,f)
-                                             {
-                                               return _U.replace([["alpha",a]],f)
-                                             });
-                              var rotate = F2(function (t,f)
-                                              {
-                                                return _U.replace([["theta",f.theta + t]],f)
-                                              });
-                              var scale = F2(function (s,f)
-                                             {
-                                               return _U.replace([["scale",f.scale * s]],f)
-                                             });
-                              var moveY = F2(function (y,f)
-                                             {
-                                               return _U.replace([["y",f.y + y]],f)
-                                             });
-                              var moveX = F2(function (x,f)
-                                             {
-                                               return _U.replace([["x",f.x + x]],f)
-                                             });
-                              var move = F2(function (_v0,f)
-                                            {
-                                              return function ()
-                                                     {
-                                                       switch (_v0.ctor)
-                                                       {case
-                                                        "_Tuple2" :
-                                                          return _U.replace([["x",f.x + _v0._0],
-                                                                             ["y",f.y + _v0._1]],
-                                                                            f)}
-                                                       _E.Case($moduleName,
-                                                               "on line 170, column 20 to 48");
-                                                     }()
-                                            });
-                              var form = function (f)
-                                         {
-                                           return {_: {}, alpha: 1, form: f, scale: 1, theta: 0, x: 0, y: 0}
-                                         };
-                              var FGroup = F2(function (a,b)
-                                              {
-                                                return {ctor: "FGroup", _0: a, _1: b}
-                                              });
-                              var group = function (fs)
-                                          {
-                                            return form(A2(FGroup,Transform2D.identity,fs))
-                                          };
-                              var groupTransform = F2(function (matrix,fs)
-                                                      {
-                                                        return form(A2(FGroup,matrix,fs))
-                                                      });
-                              var FElement = function (a)
-                                             {
-                                               return {ctor: "FElement", _0: a}
-                                             };
-                              var toForm = function (e)
-                                           {
-                                             return form(FElement(e))
-                                           };
-                              var FImage = F4(function (a,b,c,d)
-                                              {
-                                                return {ctor: "FImage", _0: a, _1: b, _2: c, _3: d}
-                                              });
-                              var sprite = F4(function (w,h,pos,src)
-                                              {
-                                                return form(A4(FImage,w,h,pos,src))
-                                              });
-                              var FShape = F2(function (a,b)
-                                              {
-                                                return {ctor: "FShape", _0: a, _1: b}
-                                              });
-                              var fill = F2(function (style,shape)
-                                            {
-                                              return form(A2(FShape,Either.Right(style),shape))
-                                            });
-                              var outlined = F2(function (style,shape)
-                                                {
-                                                  return form(A2(FShape,Either.Left(style),shape))
-                                                });
-                              var FPath = F2(function (a,b)
-                                             {
-                                               return {ctor: "FPath", _0: a, _1: b}
-                                             });
-                              var traced = F2(function (style,path)
-                                              {
-                                                return form(A2(FPath,style,path))
-                                              });
-                              var LineStyle = F6(function (a,b,c,d,e,f)
-                                                 {
-                                                   return {_: {}, cap: c, color: a, dashOffset: f, dashing: e, join: d, width: b}
-                                                 });
-                              var Clipped = {ctor: "Clipped"};
-                              var Sharp = function (a)
-                                          {
-                                            return {ctor: "Sharp", _0: a}
-                                          };
-                              var Smooth = {ctor: "Smooth"};
-                              var Padded = {ctor: "Padded"};
-                              var Round = {ctor: "Round"};
-                              var Flat = {ctor: "Flat"};
-                              var defaultLine = {_: {}, cap: Flat, color: Color.black, dashOffset: 0, dashing: _J.toList([]), join: Sharp(10), width: 1};
-                              var solid = function (clr)
-                                          {
-                                            return _U.replace([["color",clr]],defaultLine)
-                                          };
-                              var dashed = function (clr)
-                                           {
-                                             return _U.replace([["color",clr],
-                                                                ["dashing",_J.toList([8,4])]],
-                                                               defaultLine)
-                                           };
-                              var dotted = function (clr)
-                                           {
-                                             return _U.replace([["color",clr],
-                                                                ["dashing",_J.toList([3,3])]],
-                                                               defaultLine)
-                                           };
-                              var Grad = function (a)
-                                         {
-                                           return {ctor: "Grad", _0: a}
-                                         };
-                              var gradient = F2(function (grad,shape)
-                                                {
-                                                  return A2(fill,Grad(grad),shape)
-                                                });
-                              var Texture = function (a)
-                                            {
-                                              return {ctor: "Texture", _0: a}
-                                            };
-                              var textured = F2(function (src,shape)
-                                                {
-                                                  return A2(fill,Texture(src),shape)
-                                                });
-                              var Solid = function (a)
-                                          {
-                                            return {ctor: "Solid", _0: a}
-                                          };
-                              var filled = F2(function (color,shape)
-                                              {
-                                                return A2(fill,Solid(color),shape)
-                                              });
-                              var Form = F6(function (a,b,c,d,e,f)
-                                            {
-                                              return {_: {}, alpha: e, form: f, scale: b, theta: a, x: c, y: d}
-                                            });
-                              _elm.Graphics.Collage.values = {_op: _op, defaultLine: defaultLine, solid: solid, dashed: dashed, dotted: dotted, form: form, fill: fill, filled: filled, textured: textured, gradient: gradient, outlined: outlined, traced: traced, sprite: sprite, toForm: toForm, group: group, groupTransform: groupTransform, move: move, moveX: moveX, moveY: moveY, scale: scale, rotate: rotate, alpha: alpha, collage: collage, path: path, segment: segment, polygon: polygon, rect: rect, square: square, oval: oval, circle: circle, ngon: ngon, Solid: Solid, Texture: Texture, Grad: Grad, Flat: Flat, Round: Round, Padded: Padded, Smooth: Smooth, Sharp: Sharp, Clipped: Clipped, FPath: FPath, FShape: FShape, FImage: FImage, FElement: FElement, FGroup: FGroup, Form: Form, LineStyle: LineStyle};
-                              return _elm.Graphics.Collage.values
-                            };Elm.Graphics = Elm.Graphics || {};
-Elm.Graphics.Element = Elm.Graphics.Element || {};
-Elm.Graphics.Element.make = function (_elm)
-                            {
-                              _elm.Graphics = _elm.Graphics || {};
-                              _elm.Graphics.Element = _elm.Graphics.Element || {};
-                              if (_elm.Graphics.Element.values)
-                              return _elm.Graphics.Element.values
-                              var _N = Elm.Native,
-                                  _U = _N.Utils.make(_elm),
-                                  _L = _N.List.make(_elm),
-                                  _E = _N.Error.make(_elm),
-                                  _J = _N.JavaScript.make(_elm),
-                                  $moduleName = "Graphics.Element";
-                              var Basics = Elm.Basics.make(_elm);
-                              var Color = Elm.Color.make(_elm);
-                              var JavaScript = Elm.JavaScript.make(_elm);
-                              var List = Elm.List.make(_elm);
-                              var Maybe = Elm.Maybe.make(_elm);
-                              var Native = Native || {};
-                              Native.Utils = Elm.Native.Utils.make(_elm);
-                              var _op = {};
-                              var DOut = {ctor: "DOut"};
-                              var outward = DOut;
-                              var DIn = {ctor: "DIn"};
-                              var inward = DIn;
-                              var DRight = {ctor: "DRight"};
-                              var right = DRight;
-                              var DLeft = {ctor: "DLeft"};
-                              var left = DLeft;
-                              var DDown = {ctor: "DDown"};
-                              var down = DDown;
-                              var DUp = {ctor: "DUp"};
-                              var up = DUp;
-                              var Position = F4(function (a,b,c,d)
-                                                {
-                                                  return {_: {}, horizontal: a, vertical: b, x: c, y: d}
-                                                });
-                              var Relative = function (a)
-                                             {
-                                               return {ctor: "Relative", _0: a}
-                                             };
-                              var relative = Relative;
-                              var Absolute = function (a)
-                                             {
-                                               return {ctor: "Absolute", _0: a}
-                                             };
-                              var absolute = Absolute;
-                              var N = {ctor: "N"};
-                              var bottomLeftAt = F2(function (x,y)
-                                                    {
-                                                      return {_: {}, horizontal: N, vertical: N, x: x, y: y}
-                                                    });
-                              var Z = {ctor: "Z"};
-                              var middle = {_: {}, horizontal: Z, vertical: Z, x: Relative(0.5), y: Relative(0.5)};
-                              var midLeft = _U.replace([["horizontal",N],["x",Absolute(0)]],
-                                                       middle);
-                              var middleAt = F2(function (x,y)
-                                                {
-                                                  return {_: {}, horizontal: Z, vertical: Z, x: x, y: y}
-                                                });
-                              var midLeftAt = F2(function (x,y)
-                                                 {
-                                                   return {_: {}, horizontal: N, vertical: Z, x: x, y: y}
-                                                 });
-                              var midBottomAt = F2(function (x,y)
-                                                   {
-                                                     return {_: {}, horizontal: Z, vertical: N, x: x, y: y}
-                                                   });
-                              var P = {ctor: "P"};
-                              var topLeft = {_: {}, horizontal: N, vertical: P, x: Absolute(0), y: Absolute(0)};
-                              var bottomLeft = _U.replace([["vertical",N]],topLeft);
-                              var topRight = _U.replace([["horizontal",P]],topLeft);
-                              var bottomRight = _U.replace([["horizontal",P]],bottomLeft);
-                              var midRight = _U.replace([["horizontal",P]],midLeft);
-                              var midTop = _U.replace([["vertical",P],["y",Absolute(0)]],middle);
-                              var midBottom = _U.replace([["vertical",N]],midTop);
-                              var topLeftAt = F2(function (x,y)
-                                                 {
-                                                   return {_: {}, horizontal: N, vertical: P, x: x, y: y}
-                                                 });
-                              var topRightAt = F2(function (x,y)
-                                                  {
-                                                    return {_: {}, horizontal: P, vertical: P, x: x, y: y}
-                                                  });
-                              var bottomRightAt = F2(function (x,y)
-                                                     {
-                                                       return {_: {}, horizontal: P, vertical: N, x: x, y: y}
-                                                     });
-                              var midRightAt = F2(function (x,y)
-                                                  {
-                                                    return {_: {}, horizontal: P, vertical: Z, x: x, y: y}
-                                                  });
-                              var midTopAt = F2(function (x,y)
-                                                {
-                                                  return {_: {}, horizontal: Z, vertical: P, x: x, y: y}
-                                                });
-                              var Tiled = {ctor: "Tiled"};
-                              var Cropped = function (a)
-                                            {
-                                              return {ctor: "Cropped", _0: a}
-                                            };
-                              var Fitted = {ctor: "Fitted"};
-                              var Plain = {ctor: "Plain"};
-                              var Custom = {ctor: "Custom"};
-                              var RawHtml = {ctor: "RawHtml"};
-                              var Spacer = {ctor: "Spacer"};
-                              var Flow = F2(function (a,b)
-                                            {
-                                              return {ctor: "Flow", _0: a, _1: b}
-                                            });
-                              var Container = F2(function (a,b)
-                                                 {
-                                                   return {ctor: "Container", _0: a, _1: b}
-                                                 });
-                              var Image = F4(function (a,b,c,d)
-                                             {
-                                               return {ctor: "Image", _0: a, _1: b, _2: c, _3: d}
-                                             });
-                              var emptyStr = JavaScript.fromString("");
-                              var link = F2(function (href,e)
-                                            {
-                                              return function ()
-                                                     {
-                                                       var p = e.props;
-                                                       return {_: {}, element: e.element, props: _U.replace([["href",
-                                                                                                              JavaScript.fromString(href)]],
-                                                                                                            p)}
-                                                     }()
-                                            });
-                              var tag = F2(function (name,e)
-                                           {
-                                             return function ()
-                                                    {
-                                                      var p = e.props;
-                                                      return {_: {}, element: e.element, props: _U.replace([["tag",
-                                                                                                             JavaScript.fromString(name)]],
-                                                                                                           p)}
-                                                    }()
-                                           });
-                              var color = F2(function (c,e)
-                                             {
-                                               return function ()
-                                                      {
-                                                        var p = e.props;
-                                                        return {_: {}, element: e.element, props: _U.replace([["color",
-                                                                                                               Maybe.Just(c)]],
-                                                                                                             p)}
-                                                      }()
-                                             });
-                              var opacity = F2(function (o,e)
-                                               {
-                                                 return function ()
-                                                        {
-                                                          var p = e.props;
-                                                          return {_: {}, element: e.element, props: _U.replace([["opacity",
-                                                                                                                 o]],
-                                                                                                               p)}
-                                                        }()
-                                               });
-                              var height = F2(function (nh,e)
-                                              {
-                                                return function ()
-                                                       {
-                                                         var p = e.props;
-                                                         var props = function ()
-                                                                     {
-                                                                       var _v0 = e.element;
-                                                                       switch (_v0.ctor)
-                                                                       {case
-                                                                        "Image" :
-                                                                          return _U.replace([["width",
-                                                                                              Basics.round(Basics.toFloat(_v0._1) / Basics.toFloat(_v0._2) * Basics.toFloat(nh))]],
-                                                                                            p)}
-                                                                       return p
-                                                                     }();
-                                                         return {_: {}, element: e.element, props: _U.replace([["height",
-                                                                                                                nh]],
-                                                                                                              p)}
-                                                       }()
-                                              });
-                              var width = F2(function (nw,e)
-                                             {
-                                               return function ()
-                                                      {
-                                                        var p = e.props;
-                                                        var props = function ()
-                                                                    {
-                                                                      var _v5 = e.element;
-                                                                      switch (_v5.ctor)
-                                                                      {case
-                                                                       "Image" :
-                                                                         return _U.replace([["height",
-                                                                                             Basics.round(Basics.toFloat(_v5._2) / Basics.toFloat(_v5._1) * Basics.toFloat(nw))]],
-                                                                                           p)
-                                                                       case
-                                                                       "RawHtml" :
-                                                                         return _U.replace([["height",
-                                                                                             Basics.snd(A2(Native.Utils.htmlHeight,
-                                                                                                           nw,
-                                                                                                           e.element))]],
-                                                                                           p)}
-                                                                      return p
-                                                                    }();
-                                                        return {_: {}, element: e.element, props: _U.replace([["width",
-                                                                                                               nw]],
-                                                                                                             props)}
-                                                      }()
-                                             });
-                              var size = F3(function (w,h,e)
-                                            {
-                                              return A2(height,h,A2(width,w,e))
-                                            });
-                              var sizeOf = function (e)
-                                           {
-                                             return {ctor: "_Tuple2", _0: e.props.width, _1: e.props.height}
-                                           };
-                              var heightOf = function (e)
-                                             {
-                                               return e.props.height
-                                             };
-                              var widthOf = function (e)
-                                            {
-                                              return e.props.width
-                                            };
-                              var Element = F2(function (a,b)
-                                               {
-                                                 return {_: {}, element: b, props: a}
-                                               });
-                              var Properties = F8(function (a,b,c,d,e,f,g,h)
-                                                  {
-                                                    return {_: {}, color: e, height: c, hover: h, href: f, id: a, opacity: d, tag: g, width: b}
-                                                  });
-                              var newElement = F3(function (w,h,e)
-                                                  {
-                                                    return {_: {}, element: e, props: A8(Properties,
-                                                                                         Native.Utils.guid({ctor: "_Tuple0"}),
-                                                                                         w,
-                                                                                         h,
-                                                                                         1,
-                                                                                         Maybe.Nothing,
-                                                                                         emptyStr,
-                                                                                         emptyStr,
-                                                                                         {ctor: "_Tuple0"})}
-                                                  });
-                              var image = F3(function (w,h,src)
-                                             {
-                                               return A3(newElement,
-                                                         w,
-                                                         h,
-                                                         A4(Image,
-                                                            Plain,
-                                                            w,
-                                                            h,
-                                                            JavaScript.fromString(src)))
-                                             });
-                              var fittedImage = F3(function (w,h,src)
-                                                   {
-                                                     return A3(newElement,
-                                                               w,
-                                                               h,
-                                                               A4(Image,
-                                                                  Fitted,
-                                                                  w,
-                                                                  h,
-                                                                  JavaScript.fromString(src)))
-                                                   });
-                              var croppedImage = F4(function (pos,w,h,src)
-                                                    {
-                                                      return A3(newElement,
-                                                                w,
-                                                                h,
-                                                                A4(Image,
-                                                                   Cropped(pos),
-                                                                   w,
-                                                                   h,
-                                                                   JavaScript.fromString(src)))
-                                                    });
-                              var tiledImage = F3(function (w,h,src)
-                                                  {
-                                                    return A3(newElement,
-                                                              w,
-                                                              h,
-                                                              A4(Image,
-                                                                 Tiled,
-                                                                 w,
-                                                                 h,
-                                                                 JavaScript.fromString(src)))
-                                                  });
-                              var container = F4(function (w,h,pos,e)
-                                                 {
-                                                   return A3(newElement,w,h,A2(Container,pos,e))
-                                                 });
-                              var spacer = F2(function (w,h)
-                                              {
-                                                return A3(newElement,w,h,Spacer)
-                                              });
-                              var empty = A2(spacer,0,0);
-                              var flow = F2(function (dir,es)
-                                            {
-                                              return function ()
-                                                     {
-                                                       var newFlow = F2(function (w,h)
-                                                                        {
-                                                                          return A3(newElement,
-                                                                                    w,
-                                                                                    h,
-                                                                                    A2(Flow,dir,es))
-                                                                        });
-                                                       var hs = A2(List.map,heightOf,es);
-                                                       var ws = A2(List.map,widthOf,es);
-                                                       return _U.eq(es,
-                                                                    _J.toList([])) ? empty : function ()
-                                                                                             {
-                                                                                               switch (dir.ctor)
-                                                                                               {case
-                                                                                                "DDown" :
-                                                                                                  return A2(newFlow,
-                                                                                                            List.maximum(ws),
-                                                                                                            List.sum(hs))
-                                                                                                case
-                                                                                                "DIn" :
-                                                                                                  return A2(newFlow,
-                                                                                                            List.maximum(ws),
-                                                                                                            List.maximum(hs))
-                                                                                                case
-                                                                                                "DLeft" :
-                                                                                                  return A2(newFlow,
-                                                                                                            List.sum(ws),
-                                                                                                            List.maximum(hs))
-                                                                                                case
-                                                                                                "DOut" :
-                                                                                                  return A2(newFlow,
-                                                                                                            List.maximum(ws),
-                                                                                                            List.maximum(hs))
-                                                                                                case
-                                                                                                "DRight" :
-                                                                                                  return A2(newFlow,
-                                                                                                            List.sum(ws),
-                                                                                                            List.maximum(hs))
-                                                                                                case
-                                                                                                "DUp" :
-                                                                                                  return A2(newFlow,
-                                                                                                            List.maximum(ws),
-                                                                                                            List.sum(hs))}
-                                                                                               _E.Case($moduleName,
-                                                                                                       "between lines 206 and 216");
-                                                                                             }()
-                                                     }()
-                                            });
-                              var above = F2(function (hi,lo)
-                                             {
-                                               return A3(newElement,
-                                                         A2(Basics.max,widthOf(hi),widthOf(lo)),
-                                                         heightOf(hi) + heightOf(lo),
-                                                         A2(Flow,DDown,_J.toList([hi,lo])))
-                                             });
-                              var below = F2(function (lo,hi)
-                                             {
-                                               return A3(newElement,
-                                                         A2(Basics.max,widthOf(hi),widthOf(lo)),
-                                                         heightOf(hi) + heightOf(lo),
-                                                         A2(Flow,DDown,_J.toList([hi,lo])))
-                                             });
-                              var beside = F2(function (lft,rht)
-                                              {
-                                                return A3(newElement,
-                                                          widthOf(lft) + widthOf(rht),
-                                                          A2(Basics.max,
-                                                             heightOf(lft),
-                                                             heightOf(rht)),
-                                                          A2(Flow,right,_J.toList([lft,rht])))
-                                              });
-                              var layers = function (es)
-                                           {
-                                             return function ()
-                                                    {
-                                                      var hs = A2(List.map,heightOf,es);
-                                                      var ws = A2(List.map,widthOf,es);
-                                                      return A3(newElement,
-                                                                List.maximum(ws),
-                                                                List.maximum(hs),
-                                                                A2(Flow,DOut,es))
-                                                    }()
-                                           };
-                              _elm.Graphics.Element.values = {_op: _op, empty: empty, widthOf: widthOf, heightOf: heightOf, sizeOf: sizeOf, width: width, height: height, size: size, opacity: opacity, color: color, tag: tag, link: link, emptyStr: emptyStr, newElement: newElement, image: image, fittedImage: fittedImage, croppedImage: croppedImage, tiledImage: tiledImage, container: container, spacer: spacer, flow: flow, above: above, below: below, beside: beside, layers: layers, absolute: absolute, relative: relative, middle: middle, topLeft: topLeft, topRight: topRight, bottomLeft: bottomLeft, bottomRight: bottomRight, midLeft: midLeft, midRight: midRight, midTop: midTop, midBottom: midBottom, middleAt: middleAt, topLeftAt: topLeftAt, topRightAt: topRightAt, bottomLeftAt: bottomLeftAt, bottomRightAt: bottomRightAt, midLeftAt: midLeftAt, midRightAt: midRightAt, midTopAt: midTopAt, midBottomAt: midBottomAt, up: up, down: down, left: left, right: right, inward: inward, outward: outward, Image: Image, Container: Container, Flow: Flow, Spacer: Spacer, RawHtml: RawHtml, Custom: Custom, Plain: Plain, Fitted: Fitted, Cropped: Cropped, Tiled: Tiled, P: P, Z: Z, N: N, Absolute: Absolute, Relative: Relative, DUp: DUp, DDown: DDown, DLeft: DLeft, DRight: DRight, DIn: DIn, DOut: DOut, Properties: Properties, Element: Element, Position: Position};
-                              return _elm.Graphics.Element.values
-                            };Elm.Graphics = Elm.Graphics || {};
-Elm.Graphics.Input = Elm.Graphics.Input || {};
-Elm.Graphics.Input.make = function (_elm)
-                          {
-                            _elm.Graphics = _elm.Graphics || {};
-                            _elm.Graphics.Input = _elm.Graphics.Input || {};
-                            if (_elm.Graphics.Input.values)
-                            return _elm.Graphics.Input.values
-                            var _N = Elm.Native,
-                                _U = _N.Utils.make(_elm),
-                                _L = _N.List.make(_elm),
-                                _E = _N.Error.make(_elm),
-                                _J = _N.JavaScript.make(_elm),
-                                $moduleName = "Graphics.Input";
-                            var Basics = Elm.Basics.make(_elm);
-                            var Graphics = Graphics || {};
-                            Graphics.Element = Elm.Graphics.Element.make(_elm);
-                            var JavaScript = Elm.JavaScript.make(_elm);
-                            var List = Elm.List.make(_elm);
-                            var Maybe = Elm.Maybe.make(_elm);
-                            var Native = Native || {};
-                            Native.Graphics = Native.Graphics || {};
-                            Native.Graphics.Input = Elm.Native.Graphics.Input.make(_elm);
-                            var Signal = Elm.Signal.make(_elm);
-                            var _op = {};
-                            var dropDown = Native.Graphics.Input.dropDown;
-                            var stringDropDown = function (strs)
-                                                 {
-                                                   return dropDown(A2(List.map,
-                                                                      function (s)
-                                                                      {
-                                                                        return {ctor: "_Tuple2", _0: s, _1: s}
-                                                                      },
-                                                                      strs))
-                                                 };
-                            var emptyFieldState = {_: {}, selectionEnd: 0, selectionStart: 0, string: ""};
-                            var fields = Native.Graphics.Input.fields;
-                            var FieldState = F3(function (a,b,c)
-                                                {
-                                                  return {_: {}, selectionEnd: c, selectionStart: b, string: a}
-                                                });
-                            var hoverables = Native.Graphics.Input.hoverables;
-                            var checkboxes = Native.Graphics.Input.checkboxes;
-                            var customButtons = Native.Graphics.Input.customButtons;
-                            var customButton = F3(function (up,hover,down)
-                                                  {
-                                                    return function ()
-                                                           {
-                                                             var pool = customButtons({ctor: "_Tuple0"});
-                                                             return {ctor: "_Tuple2", _0: A4(pool.customButton,
-                                                                                             {ctor: "_Tuple0"},
-                                                                                             up,
-                                                                                             hover,
-                                                                                             down), _1: pool.events}
-                                                           }()
-                                                  });
-                            var buttons = Native.Graphics.Input.buttons;
-                            var button = function (txt)
-                                         {
-                                           return function ()
-                                                  {
-                                                    var pool = buttons({ctor: "_Tuple0"});
-                                                    return {ctor: "_Tuple2", _0: A2(pool.button,
-                                                                                    {ctor: "_Tuple0"},
-                                                                                    txt), _1: pool.events}
-                                                  }()
-                                         };
-                            var id = function (x)
-                                     {
-                                       return x
-                                     };
-                            var checkbox = function (b)
-                                           {
-                                             return function ()
-                                                    {
-                                                      var cbs = checkboxes(b);
-                                                      return {ctor: "_Tuple2", _0: A2(Signal.lift,
-                                                                                      cbs.checkbox(id),
-                                                                                      cbs.events), _1: cbs.events}
-                                                    }()
-                                           };
-                            var hoverable = function (elem)
-                                            {
-                                              return function ()
-                                                     {
-                                                       var pool = hoverables(false);
-                                                       return {ctor: "_Tuple2", _0: A2(pool.hoverable,
-                                                                                       id,
-                                                                                       elem), _1: pool.events}
-                                                     }()
-                                            };
-                            var field = function (placeHolder)
-                                        {
-                                          return function ()
-                                                 {
-                                                   var tfs = fields(emptyFieldState);
-                                                   var changes = Signal.dropRepeats(tfs.events);
-                                                   return {ctor: "_Tuple2", _0: A2(Signal.lift,
-                                                                                   A2(tfs.field,
-                                                                                      id,
-                                                                                      placeHolder),
-                                                                                   changes), _1: Signal.dropRepeats(A2(Signal.lift,
-                                                                                                                       function (_)
-                                                                                                                       {
-                                                                                                                         return _.string
-                                                                                                                       },
-                                                                                                                       changes))}
-                                                 }()
-                                        };
-                            var password = function (placeHolder)
-                                           {
-                                             return function ()
-                                                    {
-                                                      var tfs = Native.Graphics.Input.passwords(emptyFieldState);
-                                                      var changes = Signal.dropRepeats(tfs.events);
-                                                      return {ctor: "_Tuple2", _0: A2(Signal.lift,
-                                                                                      A2(tfs.field,
-                                                                                         id,
-                                                                                         placeHolder),
-                                                                                      changes), _1: Signal.dropRepeats(A2(Signal.lift,
-                                                                                                                          function (_)
-                                                                                                                          {
-                                                                                                                            return _.string
-                                                                                                                          },
-                                                                                                                          changes))}
-                                                    }()
-                                           };
-                            var email = function (placeHolder)
-                                        {
-                                          return function ()
-                                                 {
-                                                   var tfs = Native.Graphics.Input.emails(emptyFieldState);
-                                                   var changes = Signal.dropRepeats(tfs.events);
-                                                   return {ctor: "_Tuple2", _0: A2(Signal.lift,
-                                                                                   A2(tfs.field,
-                                                                                      id,
-                                                                                      placeHolder),
-                                                                                   changes), _1: Signal.dropRepeats(A2(Signal.lift,
-                                                                                                                       function (_)
-                                                                                                                       {
-                                                                                                                         return _.string
-                                                                                                                       },
-                                                                                                                       changes))}
-                                                 }()
-                                        };
-                            _elm.Graphics.Input.values = {_op: _op, id: id, buttons: buttons, button: button, customButtons: customButtons, customButton: customButton, checkboxes: checkboxes, checkbox: checkbox, hoverables: hoverables, hoverable: hoverable, fields: fields, emptyFieldState: emptyFieldState, field: field, password: password, email: email, dropDown: dropDown, stringDropDown: stringDropDown, FieldState: FieldState};
-                            return _elm.Graphics.Input.values
-                          };Elm.JavaScript = Elm.JavaScript || {};
-Elm.JavaScript.Experimental = Elm.JavaScript.Experimental || {};
-Elm.JavaScript.Experimental.make = function (_elm)
-                                   {
-                                     _elm.JavaScript = _elm.JavaScript || {};
-                                     _elm.JavaScript.Experimental = _elm.JavaScript.Experimental || {};
-                                     if (_elm.JavaScript.Experimental.values)
-                                     return _elm.JavaScript.Experimental.values
-                                     var _N = Elm.Native,
-                                         _U = _N.Utils.make(_elm),
-                                         _L = _N.List.make(_elm),
-                                         _E = _N.Error.make(_elm),
-                                         _J = _N.JavaScript.make(_elm),
-                                         $moduleName = "JavaScript.Experimental";
-                                     var JavaScript = Elm.JavaScript.make(_elm);
-                                     var Native = Native || {};
-                                     Native.JavaScript = Elm.Native.JavaScript.make(_elm);
-                                     var _op = {};
-                                     var fromRecord = Native.JavaScript.fromRecord;
-                                     var toRecord = Native.JavaScript.toRecord;
-                                     _elm.JavaScript.Experimental.values = {_op: _op, toRecord: toRecord, fromRecord: fromRecord};
-                                     return _elm.JavaScript.Experimental.values
-                                   };(function() {
-
-// Returns boolean indicating if the swap was successful.
-// Requires that the two signal graphs have exactly the same
-// structure.
-ElmRuntime.swap = function(from, to) {
-    function similar(nodeOld,nodeNew) {
-        idOkay = nodeOld.id === nodeNew.id;
-        lengthOkay = nodeOld.kids.length === nodeNew.kids.length;
-        return idOkay && lengthOkay;
-    }
-    function swap(nodeOld,nodeNew) {
-        nodeNew.value = nodeOld.value;
-        return true;
-    }
-    var canSwap = depthFirstTraversals(similar, from.inputs, to.inputs);
-    if (canSwap) { depthFirstTraversals(swap, from.inputs, to.inputs); }
-    from.node.parentNode.replaceChild(to.node, from.node);
-    return canSwap;
-}
-
-// Returns false if the node operation f ever fails.
-function depthFirstTraversals(f, queueOld, queueNew) {
-    if (queueOld.length !== queueNew.length) return false;
-    queueOld = queueOld.slice(0);
-    queueNew = queueNew.slice(0);
-
-    var seen = [];
-    while (queueOld.length > 0 && queueNew.length > 0) {
-        var nodeOld = queueOld.pop();
-        var nodeNew = queueNew.pop();
-        if (seen.indexOf(nodeOld.id) < 0) {
-            if (!f(nodeOld, nodeNew)) return false;
-            queueOld = queueOld.concat(nodeOld.kids);
-            queueNew = queueNew.concat(nodeNew.kids);
-            seen.push(nodeOld.id);
-        }
-    }
-    return true;
-}
-
-}());
-
-(function() {
-'use strict';
-
-Elm.fullscreen = function(module, ports) {
-    var style = document.createElement('style');
-    style.type = 'text/css';
-    style.innerHTML = "html,head,body { padding:0; margin:0; }" +
-        "body { font-family: calibri, helvetica, arial, sans-serif; }";
-    document.head.appendChild(style);
-    var container = document.createElement('div');
-    document.body.appendChild(container);
-    return init(ElmRuntime.Display.FULLSCREEN, container, module, ports || {});
-};
-
-Elm.embed = function(module, container, ports) {
-    var tag = container.tagName;
-    if (tag !== 'DIV') {
-        throw new Error('Elm.node must be given a DIV, not a ' + tag + '.');
-    } else if (container.hasChildNodes()) {
-        throw new Error('Elm.node must be given an empty DIV. No children allowed!');
-    }
-    return init(ElmRuntime.Display.COMPONENT, container, module, ports || {});
-};
-
-Elm.worker = function(module, ports) {
-    return init(ElmRuntime.Display.NONE, {}, module, ports || {});
-};
-
-function init(display, container, module, ports, moduleToReplace) {
-  // defining state needed for an instance of the Elm RTS
-  var inputs = [];
-
-  var updateInProgress = false;
-  function notify(id, v) {
-      if (updateInProgress) {
-          throw new Error(
-              'The notify function has been called synchronously!\n' +
-              'This can lead to frames being dropped.\n' +
-              'Definitely report this to <https://github.com/evancz/Elm/issues>\n');
-      }
-      updateInProgress = true;
-      var timestep = Date.now();
-      for (var i = inputs.length; i--; ) {
-          inputs[i].recv(timestep, id, v);
-      }
-      updateInProgress = false;
-  }
-
-  var listeners = [];
-  function addListener(relevantInputs, domNode, eventName, func) {
-      domNode.addEventListener(eventName, func);
-      var listener = {
-          relevantInputs: relevantInputs,
-          domNode: domNode,
-          eventName: eventName,
-          func: func
-      };
-      listeners.push(listener);
-  }
-
-  var portUses = {}
-  for (var key in ports) {
-      portUses[key] = 0;
-  }
-  // create the actual RTS. Any impure modules will attach themselves to this
-  // object. This permits many Elm programs to be embedded per document.
-  var elm = {
-      notify:notify,
-      node:container,
-      display:display,
-      id:ElmRuntime.guid(),
-      addListener:addListener,
-      inputs:inputs,
-      ports: { incoming:ports, outgoing:{}, uses:portUses }
-  };
-
-  function swap(newModule) {
-      removeListeners(listeners);
-      var div = document.createElement('div');
-      var newElm = init(display, div, newModule, ports, elm);
-      inputs = [];
-      // elm.swap = newElm.swap;
-      return newElm;
-  }
-
-  var Module = {};
-  var reportAnyErrors = function() {};
-  try {
-      Module = module.make(elm);
-      checkPorts(elm);
-  } catch(e) {
-      var directions = "<br/>&nbsp; &nbsp; Open the developer console for more details."
-      Module.main = Elm.Text.make(elm).text('<code>' + e.message + directions + '</code>');
-      reportAnyErrors = function() { throw e; }
-  }
-  inputs = ElmRuntime.filterDeadInputs(inputs);
-  filterListeners(inputs, listeners);
-  addReceivers(elm.ports.outgoing);
-  if (display !== ElmRuntime.Display.NONE) {
-      var graphicsNode = initGraphics(elm, Module);
-  }
-  if (typeof moduleToReplace !== 'undefined') {
-      ElmRuntime.swap(moduleToReplace, elm);
-
-      // rerender scene if graphics are enabled.
-      if (typeof graphicsNode !== 'undefined') {
-          graphicsNode.recv(0, true, 0);
-      }
-  }
-
-  reportAnyErrors();
-  return { swap:swap, ports:elm.ports.outgoing };
-};
-
-function checkPorts(elm) {
-    var portUses = elm.ports.uses;
-    for (var key in portUses) {
-        var uses = portUses[key]
-        if (uses === 0) {
-            throw new Error(
-                "Initialization Error: provided port '" + key +
-                "' to a module that does not take it as in input.\n" +
-                "Remove '" + key + "' from the module initialization code.");
-        } else if (uses > 1) {
-            throw new Error(
-                "Initialization Error: port '" + key +
-                "' has been declared multiple times in the Elm code.\n" +
-                "Remove declarations until there is exactly one.");
-        }
-    }
-}
-    
-function filterListeners(inputs, listeners) {
-    loop:
-    for (var i = listeners.length; i--; ) {
-        var listener = listeners[i];
-        for (var j = inputs.length; j--; ) {
-            if (listener.relevantInputs.indexOf(inputs[j].id) >= 0) {
-                continue loop;
-            }
-        }
-        listener.domNode.removeEventListener(listener.eventName, listener.func);
-    }
-}
-
-function removeListeners(listeners) {
-    for (var i = listeners.length; i--; ) {
-        var listener = listeners[i];
-        listener.domNode.removeEventListener(listener.eventName, listener.func);
-    }
-}
-
-// add receivers for built-in ports if they are defined
-function addReceivers(ports) {
-    if ('log' in ports) {
-        ports.log.subscribe(function(v) { console.log(v) });
-    }
-    if ('stdout' in ports) {
-        var process = process || {};
-        var handler = process.stdout
-            ? function(v) { process.stdout.write(v); }
-            : function(v) { console.log(v); };
-        ports.stdout.subscribe(handler);
-    }
-    if ('stderr' in ports) {
-        var process = process || {};
-        var handler = process.stderr
-            ? function(v) { process.stderr.write(v); }
-            : function(v) { console.log('Error:' + v); };
-        ports.stderr.subscribe(handler);
-    }
-    if ('title' in ports) {
-        if (typeof ports.title === 'string') {
-            document.title = ports.title;
-        } else {
-            ports.title.subscribe(function(v) { document.title = v; });
-        }
-    }
-    if ('redirect' in ports) {
-        ports.redirect.subscribe(function(v) {
-            if (v.length > 0) window.location = v;
-        });
-    }
-    if ('favicon' in ports) {
-        if (typeof ports.favicon === 'string') {
-            changeFavicon(ports.favicon);
-        } else {
-            ports.favicon.subscribe(changeFavicon);
-        }
-    }
-    function changeFavicon(src) {
-        var link = document.createElement('link');
-        var oldLink = document.getElementById('elm-favicon');
-        link.id = 'elm-favicon';
-        link.rel = 'shortcut icon';
-        link.href = src;
-        if (oldLink) {
-            document.head.removeChild(oldLink);
-        }
-        document.head.appendChild(link);
-    }
-}
-
-function initGraphics(elm, Module) {
-  if (!('main' in Module))
-      throw new Error("'main' is missing! What do I display?!");
-
-  var signalGraph = Module.main;
-
-  // make sure the signal graph is actually a signal & extract the visual model
-  var Signal = Elm.Signal.make(elm);
-  if (!('recv' in signalGraph)) {
-      signalGraph = Signal.constant(signalGraph);
-  }
-  var currentScene = signalGraph.value;
-
- // Add the currentScene to the DOM
-  var Render = ElmRuntime.use(ElmRuntime.Render.Element);
-  elm.node.appendChild(Render.render(currentScene));
-
-  // set up updates so that the DOM is adjusted as necessary.
-  var savedScene = currentScene;
-  function domUpdate(newScene) {
-      ElmRuntime.draw(function(_) {
-          Render.update(elm.node.firstChild, savedScene, newScene);
-          if (elm.Native.Window) elm.Native.Window.values.resizeIfNeeded();
-          savedScene = newScene;
-      });
-  }
-  var renderer = A2(Signal.lift, domUpdate, signalGraph);
-
-  // must check for resize after 'renderer' is created so
-  // that changes show up.
-  if (elm.Native.Window) elm.Native.Window.values.resizeIfNeeded();
-
-  return renderer;
-}
-
-}());
-
-(function() {
-'use strict';
-
-ElmRuntime.Display = { FULLSCREEN: 0, COMPONENT: 1, NONE: 2 };
-
-ElmRuntime.counter = 0;
-ElmRuntime.guid = function() { return ElmRuntime.counter++; }
-
-ElmRuntime.use = function(M) {
-    if (typeof M === 'function') M = M();
-    return M;
-};
-
-function isAlive(input) {
-    if (!('defaultNumberOfKids' in input)) return true;
-    var len = input.kids.length;
-    if (len === 0) return false;
-    if (len > input.defaultNumberOfKids) return true;
-    var alive = false;
-    for (var i = len; i--; ) {
-        alive = alive || isAlive(input.kids[i]);
-    }
-    return alive;
-}
-
-ElmRuntime.filterDeadInputs = function(inputs) {
-    var temp = [];
-    for (var i = inputs.length; i--; ) {
-        if (isAlive(inputs[i])) temp.push(inputs[i]);
-    }
-    return temp;
-};
-
-// define the draw function
-var vendors = ['ms', 'moz', 'webkit', 'o'];
-var win = window || {};
-for (var i = 0; i < vendors.length && !win.requestAnimationFrame; ++i) {
-    win.requestAnimationFrame = win[vendors[i]+'RequestAnimationFrame'];
-    win.cancelAnimationFrame  = win[vendors[i]+'CancelAnimationFrame'] ||
-                                win[vendors[i]+'CancelRequestAnimationFrame'];
-}
-
-if (win.requestAnimationFrame && win.cancelAnimationFrame) {
-    var previous = 0;
-    ElmRuntime.draw = function(callback) {
-        win.cancelAnimationFrame(previous);
-        previous = win.requestAnimationFrame(callback);
-    };
-} else {
-    ElmRuntime.draw = function(callback) { callback(); };
-}
-
-}());
-
-ElmRuntime.Render.Collage = function() {
-
-var Render = ElmRuntime.use(ElmRuntime.Render.Element);
-var Transform = Elm.Transform2D.make({});
-var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
-var newElement = Utils.newElement,
-    extract = Utils.extract, fromList = Utils.fromList,
-    fromString = Utils.fromString, addTransform = Utils.addTransform;
-
-function trace(ctx, path) {
-    var points = fromList(path);
-    var i = points.length - 1;
-    if (i <= 0) return;
-    ctx.moveTo(points[i]._0, points[i]._1);
-    while (i--) { ctx.lineTo(points[i]._0, points[i]._1); }
-    if (path.closed) {
-        i = points.length - 1;
-        ctx.lineTo(points[i]._0, points[i]._1);
-    }
-}
-
-function line(ctx,style,path) {
-    style.dashing.ctor === 'Nil' ? trace(ctx, path) : customLineHelp(ctx, style, path);
-    ctx.scale(1,-1);
-    ctx.stroke();
-}
-
-function customLineHelp(ctx, style, path) {
-    var points = fromList(path);
-    if (path.closed) points.push(points[0]);
-    var pattern = fromList(style.dashing);
-    var i = points.length - 1;
-    if (i <= 0) return;
-    var x0 = points[i]._0, y0 = points[i]._1;
-    var x1=0, y1=0, dx=0, dy=0, remaining=0, nx=0, ny=0;
-    var pindex = 0, plen = pattern.length;
-    var draw = true, segmentLength = pattern[0];
-    ctx.moveTo(x0,y0);
-    while (i--) {
-        x1 = points[i]._0; y1 = points[i]._1;
-        dx = x1 - x0; dy = y1 - y0;
-        remaining = Math.sqrt(dx * dx + dy * dy);
-        while (segmentLength <= remaining) {
-            x0 += dx * segmentLength / remaining;
-            y0 += dy * segmentLength / remaining;
-            ctx[draw ? 'lineTo' : 'moveTo'](x0, y0);
-            // update starting position
-            dx = x1 - x0; dy = y1 - y0;
-            remaining = Math.sqrt(dx * dx + dy * dy);
-            // update pattern
-            draw = !draw;
-            pindex = (pindex + 1) % plen;
-            segmentLength = pattern[pindex];
-        }
-        if (remaining > 0) {
-            ctx[draw ? 'lineTo' : 'moveTo'](x1, y1);
-            segmentLength -= remaining;
-        }
-        x0 = x1; y0 = y1;
-    }
-}
-
-function drawLine(ctx, style, path) {
-    ctx.lineWidth = style.width;
-    var cap = style.cap.ctor;
-    ctx.lineCap = cap === 'Flat' ? 'butt' :
-                  cap === 'Round' ? 'round' : 'square';
-    var join = style.join.ctor;
-    ctx.lineJoin = join === 'Smooth' ? 'round' :
-                   join === 'Sharp' ? 'miter' : 'bevel';
-    ctx.miterLimit = style.join._0 || 10;
-    ctx.strokeStyle = extract(style.color);
-    return line(ctx, style, path);
-}
-
-function texture(redo, ctx, src) {
-    var img = new Image();
-    img.src = fromString(src);
-    img.onload = redo;
-    return ctx.createPattern(img, 'repeat');
-}
-
-function gradient(ctx, grad) {
-  var g;
-  var stops = [];
-  if (grad.ctor === 'Linear') {
-    var p0 = grad._0, p1 = grad._1;
-    g = ctx.createLinearGradient(p0._0, -p0._1, p1._0, -p1._1);
-    stops = fromList(grad._2);
-  } else {
-    var p0 = grad._0, p2 = grad._2;
-    g = ctx.createRadialGradient(p0._0, -p0._1, grad._1, p2._0, -p2._1, grad._3);
-    stops = fromList(grad._4);
-  }
-  var len = stops.length;
-  for (var i = 0; i < len; ++i) {
-    var stop = stops[i];
-    g.addColorStop(stop._0, extract(stop._1));
-  }
-  return g;
-}
-
-function drawShape(redo, ctx, style, path) {
-    trace(ctx, path);
-    var sty = style.ctor;
-    ctx.fillStyle =
-        sty === 'Solid' ? extract(style._0) :
-        sty === 'Texture' ? texture(redo, ctx, style._0) : gradient(ctx, style._0);
-    ctx.scale(1,-1);
-    ctx.fill();
-}
-
-function drawImage(redo, ctx, form) {
-    var img = new Image();
-    img.onload = redo;
-    img.src = fromString(form._3);
-    var w = form._0,
-        h = form._1,
-        pos = form._2,
-        srcX = pos._0,
-        srcY = pos._1,
-        srcW = w,
-        srcH = h,
-        destX = -w/2,
-        destY = -h/2,
-        destW = w,
-        destH = h;
-
-    ctx.scale(1,-1);
-    ctx.drawImage(img, srcX, srcY, srcW, srcH, destX, destY, destW, destH);
-}
-
-function renderForm(redo, ctx, form) {
-    ctx.save();
-    var x = form.x, y = form.y, theta = form.theta, scale = form.scale;
-    if (x !== 0 || y !== 0) ctx.translate(x, y);
-    if (theta !== 0) ctx.rotate(theta);
-    if (scale !== 1) ctx.scale(scale,scale);
-    if (form.alpha !== 1) ctx.globalAlpha = ctx.globalAlpha * form.alpha;
-    ctx.beginPath();
-    var f = form.form;
-    switch(f.ctor) {
-    case 'FPath' : drawLine(ctx, f._0, f._1); break;
-    case 'FImage': drawImage(redo, ctx, f); break;
-    case 'FShape':
-      if (f._0.ctor === 'Left') {
-        f._1.closed = true;
-        drawLine(ctx, f._0._0, f._1);
-      } else {
-        drawShape(redo, ctx, f._0._0, f._1);
-      }
-    break;
-    }
-    ctx.restore();
-}
-
-function formToMatrix(form) {
-   var scale = form.scale;
-   var matrix = A6( Transform.matrix, scale, 0, 0, scale, form.x, form.y );
-
-   var theta = form.theta
-   if (theta !== 0)
-       matrix = A2( Transform.multiply, matrix, Transform.rotation(theta) );
-
-   return matrix;
-}
-
-function str(n) {
-    if (n < 0.00001 && n > -0.00001) return 0;
-    return n;
-}
-
-function makeTransform(w, h, form, matrices) {
-    var props = form.form._0.props;
-    var m = A6( Transform.matrix, 1, 0, 0, -1,
-                (w - props.width ) / 2,
-                (h - props.height) / 2 );
-    var len = matrices.length;
-    for (var i = 0; i < len; ++i) { m = A2( Transform.multiply, m, matrices[i] ); }
-    m = A2( Transform.multiply, m, formToMatrix(form) );
-
-    return 'matrix(' + str( m[0]) + ', ' + str( m[3]) + ', ' +
-                       str(-m[1]) + ', ' + str(-m[4]) + ', ' +
-                       str( m[2]) + ', ' + str( m[5]) + ')';
-}
-
-function stepperHelp(list) {
-    var arr = fromList(list);
-    var i = 0;
-    function peekNext() {
-        return i < arr.length ? arr[i].form.ctor : '';
-    }
-    // assumes that there is a next element
-    function next() {
-        var out = arr[i];
-        ++i;
-        return out;
-    }
-    return { peekNext:peekNext, next:next };
-}
-
-function formStepper(forms) {
-    var ps = [stepperHelp(forms)];
-    var matrices = [];
-    var alphas = [];
-    function peekNext() {
-        var len = ps.length;
-        var formType = '';
-        for (var i = 0; i < len; ++i ) {
-            if (formType = ps[i].peekNext()) return formType;
-        }
-        return '';
-    }
-    // assumes that there is a next element
-    function next(ctx) {
-        while (!ps[0].peekNext()) {
-            ps.shift();
-            matrices.pop();
-            alphas.shift();
-            if (ctx) { ctx.restore(); }
-        }
-        var out = ps[0].next();
-        var f = out.form;
-        if (f.ctor === 'FGroup') {
-            ps.unshift(stepperHelp(f._1));
-            var m = A2(Transform.multiply, f._0, formToMatrix(out));
-            ctx.save();
-            ctx.transform(m[0], m[3], m[1], m[4], m[2], m[5]);
-            matrices.push(m);
-
-            var alpha = (alphas[0] || 1) * out.alpha;
-            alphas.unshift(alpha);
-            ctx.globalAlpha = alpha;
-        }
-        return out;
-    }
-    function transforms() { return matrices; }
-    function alpha() { return alphas[0] || 1; }
-    return { peekNext:peekNext, next:next, transforms:transforms, alpha:alpha };
-}
-
-function makeCanvas(w,h) {
-    var canvas = newElement('canvas');
-    canvas.style.width  = w + 'px';
-    canvas.style.height = h + 'px';
-    canvas.style.display = "block";
-    canvas.style.position = "absolute";
-    canvas.width  = w;
-    canvas.height = h;
-    return canvas;
-}
-
-function render(model) {
-    var div = newElement('div');
-    div.style.overflow = 'hidden';
-    update(div, model, model);
-    return div;
-}
-
-function nodeStepper(w,h,div) {
-    var kids = div.childNodes;
-    var i = 0;
-    function transform(transforms, ctx) {
-        ctx.translate(w/2, h/2);
-        ctx.scale(1,-1);
-        var len = transforms.length;
-        for (var i = 0; i < len; ++i) {
-            var m = transforms[i];
-            ctx.save();
-            ctx.transform(m[0], m[3], m[1], m[4], m[2], m[5]);
-        }
-        return ctx;
-    }
-    function nextContext(transforms) {
-        while (i < kids.length) {
-            var node = kids[i];
-            if (node.getContext) {
-                node.width = w;
-                node.height = h;
-                node.style.width = w + 'px';
-                node.style.height = h + 'px';
-                ++i;
-                return transform(transforms, node.getContext('2d'));
-            }
-            div.removeChild(node);
-        }
-        var canvas = makeCanvas(w,h);
-        div.appendChild(canvas);
-        // we have added a new node, so we must step our position
-        ++i;
-        return transform(transforms, canvas.getContext('2d'));
-    }
-    function addElement(matrices, alpha, form) {
-        var kid = kids[i];
-        var elem = form.form._0;
-
-        var node = (!kid || kid.getContext)
-            ? Render.render(elem)
-            : (Render.update(kid, kid.oldElement, elem), kids[i]);
-
-        node.style.position = 'absolute';
-        node.style.opacity = alpha * form.alpha;
-        addTransform(node.style, makeTransform(w, h, form, matrices));
-        node.oldElement = elem;
-        ++i;
-        if (!kid) {
-            div.appendChild(node);
-        } else if (kid.getContext) {
-            div.insertBefore(node, kid);
-        }
-    }
-    function clearRest() {
-        while (i < kids.length) {
-            div.removeChild(kids[i]);
-        }
-    }
-    return { nextContext:nextContext, addElement:addElement, clearRest:clearRest };
-}
-
-
-function update(div, _, model) {
-    var w = model.w;
-    var h = model.h;
-
-    var forms = formStepper(model.forms);
-    var nodes = nodeStepper(w,h,div);
-    var ctx = null;
-    var formType = '';
-
-    while (formType = forms.peekNext()) {
-        // make sure we have context if we need it
-        if (ctx === null && formType !== 'FElement') {
-            ctx = nodes.nextContext(forms.transforms());
-            ctx.globalAlpha = forms.alpha();
-        }
-
-        var form = forms.next(ctx);
-        // if it is FGroup, all updates are made within formStepper when next is called.
-        if (formType === 'FElement') {
-            // update or insert an element, get a new context
-            nodes.addElement(forms.transforms(), forms.alpha(), form);
-            ctx = null;
-        } else if (formType !== 'FGroup') {
-            renderForm(function() { update(div, model, model); }, ctx, form);
-        }
-    }
-    nodes.clearRest();
-    return false;
-}
-
-return { render:render, update:update };
-
-};
-
-ElmRuntime.Render.Element = function() {
-'use strict';
-
-var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
-var newElement = Utils.newElement, extract = Utils.extract,
-    addTransform = Utils.addTransform, removeTransform = Utils.removeTransform,
-    fromList = Utils.fromList, eq = Utils.eq;
-
-function setProps(props, e) {
-    e.style.width  = (props.width |0) + 'px';
-    e.style.height = (props.height|0) + 'px';
-    if (props.opacity !== 1) { e.style.opacity = props.opacity; }
-    if (props.color.ctor === 'Just') {
-        e.style.backgroundColor = extract(props.color._0);
-    }
-    if (props.tag !== '') { e.id = props.tag; }
-    if (props.href !== '') {
-        var a = newElement('a');
-        a.href = props.href;
-        a.style.width = '100%';
-        a.style.height = '100%';
-        a.style.top = 0;
-        a.style.left = 0;
-        a.style.display = 'block';
-        a.style.position = 'absolute';
-        e.style.position = 'relative';
-        e.appendChild(a);
-    }
-    if (props.hover.ctor !== '_Tuple0') {
-        var overCount = 0;
-        e.addEventListener('mouseover', function() {
-            if (overCount++ > 0) return;
-            props.hover(true);
-        });
-        e.addEventListener('mouseout', function(evt) {
-            if (e.contains(evt.toElement || evt.relatedTarget)) return;
-            overCount = 0;
-            props.hover(false);
-        });
-    }
-    return e;
-}
-
-function image(props, img) {
-    switch (img._0.ctor) {
-    case 'Plain':   return plainImage(img._3);
-    case 'Fitted':  return fittedImage(props.width, props.height, img._3);
-    case 'Cropped': return croppedImage(img,props.width,props.height,img._3);
-    case 'Tiled':   return tiledImage(img._3);
-    }
-}
-
-function plainImage(src) {
-    var img = newElement('img');
-    img.src = src;
-    img.name = src;
-    img.style.display = "block";
-    return img;
-}
-
-function tiledImage(src) {
-    var div = newElement('div');
-    div.style.backgroundImage = 'url(' + src + ')';
-    return div;
-}
-
-function fittedImage(w, h, src) {
-    var div = newElement('div');
-    div.style.background = 'url(' + src + ') no-repeat center';
-    div.style.webkitBackgroundSize = 'cover';
-    div.style.MozBackgroundSize = 'cover';
-    div.style.OBackgroundSize = 'cover';
-    div.style.backgroundSize = 'cover';
-    return div;
-}
-
-function croppedImage(elem, w, h, src) {
-    var pos = elem._0._0;
-    var e = newElement('div');
-    e.style.overflow = "hidden";
-
-    var img = newElement('img');
-    img.onload = function() {
-        var sw = w / elem._1, sh = h / elem._2;
-        img.style.width = ((this.width * sw)|0) + 'px';
-        img.style.height = ((this.height * sh)|0) + 'px';
-        img.style.marginLeft = ((- pos._0 * sw)|0) + 'px';
-        img.style.marginTop = ((- pos._1 * sh)|0) + 'px';
-    };
-    img.src = src;
-    img.name = src;
-    e.appendChild(img);
-    return e;
-}
-
-function goIn(e) { e.style.position = 'absolute'; return e; }
-function goDown(e) { return e }
-function goRight(e) { e.style.styleFloat = e.style.cssFloat = "left"; return e; }
-function flowWith(f, array) {
-    var container = newElement('div');
-    for (var i = array.length; i--; ) {
-        container.appendChild(f(render(array[i])));
-    }
-    return container;
-}
-
-function flow(dir,elist) {
-    var array = fromList(elist);
-    switch(dir.ctor) {
-    case "DDown":  array.reverse();
-    case "DUp":    return flowWith(goDown,array);
-    case "DRight": array.reverse();
-    case "DLeft":  return flowWith(goRight,array);
-    case "DOut":   array.reverse();
-    case "DIn":    return flowWith(goIn,array);
-    }
-}
-
-function toPos(pos) {
-    switch(pos.ctor) {
-    case "Absolute": return  pos._0 + "px";
-    case "Relative": return (pos._0 * 100) + "%";
-    }
-}
-
-// must clear right, left, top, bottom, and transform
-// before calling this function
-function setPos(pos,w,h,e) {
-    e.style.position = 'absolute';
-    e.style.margin = 'auto';
-    var transform = '';
-    switch(pos.horizontal.ctor) {
-    case 'P': e.style.right = toPos(pos.x); e.style.removeProperty('left'); break;
-    case 'Z': transform = 'translateX(' + ((-w/2)|0) + 'px) ';
-    case 'N': e.style.left = toPos(pos.x); e.style.removeProperty('right'); break;
-    }
-    switch(pos.vertical.ctor) {
-    case 'N': e.style.bottom = toPos(pos.y); e.style.removeProperty('top'); break;
-    case 'Z': transform += 'translateY(' + ((-h/2)|0) + 'px)';
-    case 'P': e.style.top = toPos(pos.y); e.style.removeProperty('bottom'); break;
-    }
-    if (transform !== '') addTransform(e.style, transform);
-    return e;
-}
-
-function container(pos,elem) {
-    var e = render(elem);
-    setPos(pos, elem.props.width, elem.props.height, e);
-    var div = newElement('div');
-    div.style.position = 'relative';
-    div.style.overflow = 'hidden';
-    div.appendChild(e);
-    return div;
-}
-
-function rawHtml(elem) {
-    var html = elem.html;
-    var args = elem.args;
-    var guid = elem.guid;
-    var align = elem.align;
-
-    var div = newElement('div');
-    div.innerHTML = html;
-    div.style.visibility = "hidden";
-    if (align) div.style.textAlign = align;
-    document.body.appendChild(div);
-
-    for (var i = args.length; i--; ) {
-        var arg = args[i];
-        var span = document.getElementById('md-' + guid + '-' + i);
-        if (arg.isText) {
-            span.innerHTML = arg;
-        } else {
-            span.style.display = 'block';
-            span.style.width = arg.props.width + 'px';
-            span.style.height = arg.props.height + 'px';
-            span.appendChild(render(arg));
-        }
-    }
-    document.body.removeChild(div);
-    div.style.visibility = 'visible';
-    return div;
-}
-
-function render(elem) { return setProps(elem.props, makeElement(elem)); }
-function makeElement(e) {
-    var elem = e.element;
-    switch(elem.ctor) {
-    case 'Image':     return image(e.props, elem);
-    case 'Flow':      return flow(elem._0, elem._1);
-    case 'Container': return container(elem._0, elem._1);
-    case 'Spacer':    return newElement('div');
-    case 'RawHtml':   return rawHtml(elem);
-    case 'Custom':    return elem.render(elem.model);
-    }
-}
-
-function update(node, curr, next) {
-    if (node.tagName === 'A') { node = node.firstChild; }
-    if (curr.props.id === next.props.id) return updateProps(node, curr, next);
-    if (curr.element.ctor !== next.element.ctor) {
-        node.parentNode.replaceChild(render(next),node);
-        return true;
-    }
-    var nextE = next.element, currE = curr.element;
-    switch(nextE.ctor) {
-    case "Spacer": break;
-    case "RawHtml":
-        // only markdown blocks have guids, so this must be a text block
-        if (nextE.guid === null) {
-            node.innerHTML = nextE.html;
-            break;
-        }
-        if (nextE.guid !== currE.guid) {
-            node.parentNode.replaceChild(render(next),node);
-            return true;
-        }
-        var nargs = nextE.args;
-        var cargs = currE.args;
-        for (var i = nargs.length; i--; ) {
-            var narg = nargs[i];
-            var carg = cargs[i]
-            if (narg == carg) continue;
-            var span = document.getElementById('md-' + currE.guid + '-' + i);
-            if (narg.isElement) {
-                if (carg.isElement) {
-                    update(span, carg, narg);
-                } else {
-                    span.style.display = 'block';
-                    var e = render(narg);
-                    span.innerHTML = '';
-                    span.appendChild(e);
-                }
-            } else {
-                span.style.display = 'inline';
-                span.innerHTML = narg;
-            }
-        }
-        break;
-    case "Image":
-        if (nextE._0.ctor === 'Plain') {
-            if (nextE._3 !== currE._3) node.src = nextE._3;
-        } else if (!eq(nextE,currE) ||
-                   next.props.width !== curr.props.width ||
-                   next.props.height !== curr.props.height) {
-            node.parentNode.replaceChild(render(next),node);
-            return true;
-        }
-        break;
-    case "Flow":
-        var arr = fromList(nextE._1);
-        for (var i = arr.length; i--; ) { arr[i] = arr[i].element.ctor; }
-        if (nextE._0.ctor !== currE._0.ctor) {
-            node.parentNode.replaceChild(render(next),node);
-            return true;
-        }
-        var nexts = fromList(nextE._1);
-        var kids = node.childNodes;
-        if (nexts.length !== kids.length) {
-            node.parentNode.replaceChild(render(next),node);
-            return true;
-        }
-        var currs = fromList(currE._1);
-        var goDir = function(x) { return x; };
-        switch(nextE._0.ctor) {
-        case "DDown":  case "DUp":   goDir = goDown; break;
-        case "DRight": case "DLeft": goDir = goRight; break;
-        case "DOut":   case "DIn":   goDir = goIn; break;
-        }
-        for (var i = kids.length; i-- ;) {
-            update(kids[i],currs[i],nexts[i]);
-            goDir(kids[i]);
-        }
-        break;
-    case "Container":
-        update(node.firstChild, currE._1, nextE._1);
-        setPos(nextE._0, nextE._1.props.width, nextE._1.props.height, node.firstChild);
-        break;
-    case "Custom":
-        if (currE.type === nextE.type) {
-            var done = nextE.update(node, currE.model, nextE.model);
-            if (done) return;
-        } else {
-            return node.parentNode.replaceChild(render(next), node);
-        }
-    }
-    updateProps(node, curr, next);
-}
-
-function updateProps(node, curr, next) {
-    var props = next.props, currP = curr.props, e = node;
-    if (props.width !== currP.width)   e.style.width  = (props.width |0) + 'px';
-    if (props.height !== currP.height) e.style.height = (props.height|0) + 'px';
-    if (props.opacity !== 1 && props.opacity !== currP.opacity) {
-        e.style.opacity = props.opacity;
-    }
-    var nextColor = (props.color.ctor === 'Just' ?
-                     extract(props.color._0) : '');
-    if (e.style.backgroundColor !== nextColor) {
-        e.style.backgroundColor = (nextColor === '' ? 'transparent' : nextColor);
-    }
-    if (props.tag !== currP.tag) { e.id = props.tag; }
-    if (props.href !== currP.href) {
-        if (currP.href === '') {
-            var a = newElement('a');
-            a.href = props.href;
-            a.style.width = '100%';
-            a.style.height = '100%';
-            a.style.top = 0;
-            a.style.left = 0;
-            a.style.display = 'block';
-            a.style.position = 'absolute';
-            e.style.position = 'relative';
-            e.appendChild(a);
-        } else {
-            node.lastNode.href = props.href;
-        }
-    }
-}
-
-return { render:render, update:update };
-
-};
-ElmRuntime.Render.Utils = function() {
-  function newElement(elementType) {
-      var e = document.createElement(elementType);
-      e.style.padding = "0";
-      e.style.margin = "0";
-      return e;
-  }
-
-  function addTo(container, elem) {
-      container.appendChild(elem);
-  }
-
-  function extract(c) {
-      if (c._3 === 1) { return 'rgb(' + c._0 + ', ' + c._1 + ', ' + c._2 + ')'; }
-      return 'rgba(' + c._0 + ', ' + c._1 + ', ' + c._2 + ', ' + c._3 + ')';
-  }
-
-  function addTransform(style, trans) {
-    style.transform       = trans;
-    style.msTransform     = trans;
-    style.MozTransform    = trans;
-    style.webkitTransform = trans;
-    style.OTransform      = trans;
-  }
-
-  function removeTransform(style) {
-    style.transform       = 'none';
-    style.msTransform     = 'none';
-    style.MozTransform    = 'none';
-    style.webkitTransform = 'none';
-    style.OTransform      = 'none';
-  }
-
-  var List = Elm.Native.List.make({});
-
-  return {addTo:addTo,
-          newElement:newElement,
-          extract : extract,
+'use strict';
+var Elm = {}; Elm.Native = {}; Elm.Native.Graphics = {};
+var ElmRuntime = {}; ElmRuntime.Render = {};
+Elm.Native.Array = {};
+Elm.Native.Array.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.Array = elm.Native.Array || {};
+    if (elm.Native.Array.values) return elm.Native.Array.values;
+    if ('values' in Elm.Native.Array)
+      return elm.Native.Array.values = Elm.Native.Array.values;
+
+    var List = Elm.Native.List.make(elm);
+
+    // A RRB-Tree has two distinct data types.
+    // Leaf -> "height"  is always 0
+    //         "table"   is an array of elements
+    // Node -> "height"  is always greater than 0
+    //         "table"   is an array of child nodes
+    //         "lengths" is an array of accumulated lengths of the child nodes
+
+    // M is the maximal table size. 32 seems fast. E is the allowed increase
+    // of search steps when concatting to find an index. Lower values will 
+    // decrease balancing, but will increase search steps.
+    var M = 32;
+    var E = 2;
+
+    // An empty array.
+    var empty = { ctor:"_Array", height:0, table:new Array() };
+
+    function get(i, array) {
+        if (i < 0 || i >= length(array)) {
+            throw new Error("Index " + i + " is out of range. Check the length of " +
+                            "your array first or use getMaybe or getWithDefault.");
+        }
+        return unsafeGet(i, array);
+    }
+
+    function unsafeGet(i, array) {
+      for (var x = array.height; x > 0; x--) {
+        var slot = i >> (x * 5);
+        while (array.lengths[slot] <= i) {
+          slot++;
+        }
+        if (slot > 0) {
+          i -= array.lengths[slot - 1];
+        }
+        array = array.table[slot];
+      }
+      return array.table[i];
+    }
+
+    // Sets the value at the index i. Only the nodes leading to i will get
+    // copied and updated.
+    function set(i, item, array) {
+      if (i < 0 || length(array) <= i) {
+        return array;
+      }
+      return unsafeSet(i, item, array);
+    }
+
+    function unsafeSet(i, item, array) {
+      array = nodeCopy(array);
+
+      if (array.height == 0) {
+        array.table[i] = item;
+      } else {
+        var slot = getSlot(i, array);
+        if (slot > 0) {
+          i -= array.lengths[slot - 1];
+        }
+        array.table[slot] = unsafeSet(i, item, array.table[slot]);
+      }
+      return array;
+    }
+
+    function initialize(len, f) {
+      if (len == 0) { return empty; }
+      var h = Math.floor(Math.log(len)/Math.log(M));
+      return initialize_(f, h, 0, len);
+    }
+
+    function initialize_(f, h, from, to) {
+      if (h == 0) {
+        var table = new Array((to - from) % (M + 1));
+        for (var i = 0; i < table.length; i++) {
+          table[i] = f(from + i);
+        }
+        return { ctor:"_Array", height:0, table:table };
+      }
+
+      var step = Math.pow(M, h);
+      var table = new Array(Math.ceil((to - from) / step));
+      var lengths = new Array(table.length);
+      for (var i = 0; i < table.length; i++) {
+        table[i] = initialize_( f, h - 1, from + (i * step)
+                              , Math.min(from + ((i + 1) * step), to));
+        lengths[i] = length(table[i]) + (i > 0 ? lengths[i-1] : 0);
+      }
+      return { ctor:"_Array", height:h, table:table, lengths:lengths };
+    }
+
+    function fromList(list) {
+      if (list == List.Nil) { return empty; }
+
+      // Allocate M sized blocks (table) and write list elements to it.
+      var table = new Array(M);
+      var nodes = new Array();
+      var i = 0;
+
+      while (list.ctor !== '[]') {
+        table[i] = list._0;
+        list = list._1;
+        i++;
+
+        // table is full, so we can push a leaf containing it into the
+        // next node.
+        if (i == M) {
+          fromListPush({ ctor:"_Array", height:0, table:table }
+                      , nodes);
+          table = new Array(M);
+          i = 0;
+        }
+      }
+
+      // Maybe there is something left on the table.
+      if (i > 0) {
+        fromListPush({ ctor:"_Array", height:0, table:table.splice(0,i) }
+                    , nodes);
+      }
+
+      // Go through all of the nodes and eventually push them into higher nodes.
+      for (var h = 0; h < nodes.length - 1; h++) {
+        if (nodes[h].table.length > 0) {
+          fromListPush(nodes[h], nodes);
+        }
+      }
+
+      var head = nodes[nodes.length - 1];
+      if (head.height > 0 && head.table.length == 1) {
+        return head.table[0];
+      } else {
+        return head;
+      }
+    }
+
+    // Push a node into a higher node as a child.
+    function fromListPush(toPush, nodes) {
+      var h = toPush.height;
+
+      // Maybe the node on this height does not exist.
+      if (nodes.length == h) {
+        nodes.push({ ctor:"_Array", height:h + 1
+                                  , table:new Array()
+                                  , lengths:new Array() });
+      }
+
+      nodes[h].table.push(toPush);
+      var len = length(toPush);
+      if (nodes[h].lengths.length > 0) {
+        len += nodes[h].lengths[nodes[h].lengths.length - 1];
+      }
+      nodes[h].lengths.push(len);
+
+      if (nodes[h].table.length == M) {
+        fromListPush(nodes[h], nodes);
+        nodes[h] = { ctor:"_Array", height:h + 1
+                                  , table:new Array()
+                                  , lengths:new Array() };
+      }
+    }
+
+    // Pushes an item via push_ to the bottom right of a tree.
+    function push(item, a) {
+      var pushed = push_(item, a);
+      if (pushed !== null) {
+        return pushed;
+      }
+
+      var newTree = create(item, a.height);
+      return siblise(a, newTree);
+    }
+
+    // Recursively tries to push an item to the bottom-right most
+    // tree possible. If there is no space left for the item,
+    // null will be returned.
+    function push_(item, a) {
+      // Handle resursion stop at leaf level.
+      if (a.height == 0) {
+        if (a.table.length < M) {
+          var newA = { ctor:"_Array", height:0, table:a.table.slice() };
+          newA.table.push(item);
+          return newA;
+        } else {
+          return null;
+        }
+      }
+
+      // Recursively push
+      var pushed = push_(item, botRight(a));
+
+      // There was space in the bottom right tree, so the slot will
+      // be updated.
+      if (pushed != null) {
+        var newA = nodeCopy(a);
+        newA.table[newA.table.length - 1] = pushed;
+        newA.lengths[newA.lengths.length - 1]++;
+        return newA
+      }
+
+      // When there was no space left, check if there is space left
+      // for a new slot with a tree which contains only the item
+      // at the bottom.
+      if (a.table.length < M) {
+        var newSlot = create(item, a.height - 1);
+        var newA = nodeCopy(a);
+        newA.table.push(newSlot);
+        newA.lengths.push(newA.lengths[newA.lengths.length - 1] + length(newSlot));
+        return newA
+      } else {
+        return null;
+      }
+    }
+
+    // Converts an array into a list of elements.
+    function toList(a) {
+      return toList_(List.Nil, a);
+    }
+
+    function toList_(list, a) {
+      for (var i = a.table.length - 1; i >= 0; i--) {
+        list = a.height == 0 ? List.Cons(a.table[i], list) : toList_(list, a.table[i]);
+      }
+      return list;
+    }
+
+    // Maps a function over the elements of an array.
+    function map(f, a) {
+      var newA = { ctor:"_Array", height:a.height, table:new Array(a.table) };
+      if (a.height > 0) { newA.lengths = a.lengths; }
+      for (var i = 0; i < a.table.length; i++) {
+        newA.table[i] = a.height == 0 ? f(a.table[i]) : map(f, a.table[i]);
+      }
+      return newA;
+    }
+
+    // Maps a function over the elements with their index as first argument.
+    function indexedMap(f, a) {
+      return indexedMap_(f, a, 0);
+    }
+
+    function indexedMap_(f, a, from) {
+      var newA = { ctor:"_Array", height:a.height, table:new Array(a.table) };
+      if (a.height > 0) { newA.lengths = a.lengths; }
+      for (var i = 0; i < a.table.length; i++) {
+        newA.table[i] = a.height == 0 ? A2(f, from + i, a.table[i])
+                                      : indexedMap_( f, a.table[i]
+                                                   , i == 0 ? 0 : a.lengths[i - 1]);
+      }
+      return newA;
+    }
+
+    function foldl(f, b, a) {
+      if (a.height == 0) {
+        for (var i = 0; i < a.table.length; i++) {
+          b = A2(f, a.table[i], b);
+        }
+      } else {
+        for (var i = 0; i < a.table.length; i++) {
+          b = foldl(f, b, a.table[i]);
+        }
+      }
+      return b;
+    }
+
+    function foldr(f, b, a) {
+      if (a.height == 0) {
+        for (var i = a.table.length; i--; ) {
+          b = A2(f, a.table[i], b);
+        }
+      } else {
+        for (var i = a.table.length; i--; ) {
+          b = foldl(f, b, a.table[i]);
+        }
+      }
+      return b;
+    }
+
+    // TODO: currently, it slices the right, then the left. This can be
+    // optimized.
+    function slice(from, to, a) {
+      if (from < 0) { from += length(a); }
+      if (to < 0)   { to += length(a); }
+      return sliceLeft(from, sliceRight(to, a));
+    }
+
+    function sliceRight(to, a) {
+      if (to == length(a)) {
+        return a;
+      }
+
+      // Handle leaf level.
+      if (a.height == 0) {
+        var newA = { ctor:"_Array", height:0 };
+        newA.table = a.table.slice(0, to);
+        return newA;
+      }
+
+      // Slice the right recursively.
+      var right = getSlot(to, a);
+      var sliced = sliceRight(to - (right > 0 ? a.lengths[right - 1] : 0), a.table[right]);
+
+      // Maybe the a node is not even needed, as sliced contains the whole slice.
+      if (right == 0) {
+        return sliced;
+      }
+
+      // Create new node.
+      var newA = { ctor:"_Array", height:a.height
+                                , table:a.table.slice(0, right)
+                                , lengths:a.lengths.slice(0, right) };
+      if (sliced.table.length > 0) {
+        newA.table[right] = sliced;
+        newA.lengths[right] = length(sliced) + (right > 0 ? newA.lengths[right - 1] : 0);
+      }
+      return newA;
+    }
+
+    function sliceLeft(from, a) {
+      if (from == 0) {
+        return a;
+      }
+
+      // Handle leaf level.
+      if (a.height == 0) {
+        var newA = { ctor:"_Array", height:0 };
+        newA.table = a.table.slice(from, a.table.length + 1);
+        return newA;
+      }
+
+      // Slice the left recursively.
+      var left = getSlot(from, a);
+      var sliced = sliceLeft(from - (left > 0 ? a.lengths[left - 1] : 0), a.table[left]);
+
+      // Maybe the a node is not even needed, as sliced contains the whole slice.
+      if (left == a.table.length - 1) {
+        return sliced;
+      }
+
+      // Create new node.
+      var newA = { ctor:"_Array", height:a.height
+                                , table:a.table.slice(left, a.table.length + 1)
+                                , lengths:new Array(a.table.length - left) };
+      newA.table[0] = sliced;
+      var len = 0;
+      for (var i = 0; i < newA.table.length; i++) {
+        len += length(newA.table[i]);
+        newA.lengths[i] = len;
+      }
+
+      return newA;
+    }
+
+    // Appends two trees.
+    function append(a,b) {
+      if (a.table.length === 0) {
+        return b;
+      }
+      if (b.table.length === 0) {
+        return a;
+      }
+
+      var c = append_(a, b);
+
+      // Check if both nodes can be crunshed together.
+      if (c[0].table.length + c[1].table.length <= M) {
+        if (c[0].table.length === 0) {
+          return c[1];
+        }
+        if (c[1].table.length === 0) {
+          return c[0];
+        }
+
+        // Adjust .table and .lengths
+        c[0].table = c[0].table.concat(c[1].table);
+        if (c[0].height > 0) {
+          var len = length(c[0]);
+          for (var i = 0; i < c[1].lengths.length; i++) {
+            c[1].lengths[i] += len;
+          }
+          c[0].lengths = c[0].lengths.concat(c[1].lengths);
+        }
+
+        return c[0];
+      }
+
+      var toRemove = calcToRemove(a, b);
+      if (toRemove > E) {
+        c = shuffle(c[0], c[1], toRemove);
+      }
+
+      return siblise(c[0], c[1]);
+    }
+
+    // Returns an array of two nodes; right and left. One node _may_ be empty.
+    function append_(a, b) {
+      if (a.height === 0 && b.height === 0) {
+        return [a, b];
+      }
+
+      if (a.height !== 1 || b.height !== 1) {
+        if (a.height === b.height) {
+          a = nodeCopy(a);
+          b = nodeCopy(b);
+          var appended = append_(botRight(a), botLeft(b));
+
+          insertRight(a, appended[1]);
+          insertLeft(b, appended[0]);
+        } else if (a.height > b.height) {
+          a = nodeCopy(a);
+          var appended = append_(botRight(a), b);
+
+          insertRight(a, appended[0]);
+          b = parentise(appended[1], appended[1].height + 1);
+        } else {
+          b = nodeCopy(b);
+          var appended = append_(a, botLeft(b));
+
+          var left = appended[0].table.length === 0 ? 0 : 1;
+          var right = left === 0 ? 1 : 0;
+          insertLeft(b, appended[left]);
+          a = parentise(appended[right], appended[right].height + 1);
+        }
+      }
+
+      // Check if balancing is needed and return based on that.
+      if (a.table.length === 0 || b.table.length === 0) {
+        return [a,b];
+      }
+
+      var toRemove = calcToRemove(a, b);
+      if (toRemove <= E) {
+        return [a,b];
+      }
+      return shuffle(a, b, toRemove);
+    }
+
+    // Helperfunctions for append_. Replaces a child node at the side of the parent.
+    function insertRight(parent, node) {
+      var index = parent.table.length - 1;
+      parent.table[index] = node;
+      parent.lengths[index] = length(node)
+      parent.lengths[index] += index > 0 ? parent.lengths[index - 1] : 0;
+    }
+
+    function insertLeft(parent, node) {
+      if (node.table.length > 0) {
+        parent.table[0] = node;
+        parent.lengths[0] = length(node);
+
+        var len = length(parent.table[0]);
+        for (var i = 1; i < parent.lengths.length; i++) {
+          len += length(parent.table[i]);
+          parent.lengths[i] = len;
+        }
+      } else {
+        parent.table.shift();
+        for (var i = 1; i < parent.lengths.length; i++) {
+          parent.lengths[i] = parent.lengths[i] - parent.lengths[0];
+        }
+        parent.lengths.shift();
+      }
+    }
+
+    // Returns the extra search steps for E. Refer to the paper.
+    function calcToRemove(a, b) {
+      var subLengths = 0;
+      for (var i = 0; i < a.table.length; i++) {
+        subLengths += a.table[i].table.length;
+      }
+      for (var i = 0; i < b.table.length; i++) {
+        subLengths += b.table[i].table.length;
+      }
+
+      var toRemove = a.table.length + b.table.length
+      return toRemove - (Math.floor((subLengths - 1) / M) + 1);
+    }
+
+    // get2, set2 and saveSlot are helpers for accessing elements over two arrays.
+    function get2(a, b, index) {
+      return index < a.length ? a[index] : b[index - a.length];
+    }
+
+    function set2(a, b, index, value) {
+      if (index < a.length) {
+        a[index] = value;
+      } else {
+        b[index - a.length] = value;
+      }
+    }
+
+    function saveSlot(a, b, index, slot) {
+      set2(a.table, b.table, index, slot);
+
+      var l = (index == 0 || index == a.lengths.length) ?
+                0 : get2(a.lengths, a.lengths, index - 1);
+      set2(a.lengths, b.lengths, index, l + length(slot));
+    }
+
+    // Creates a node or leaf with a given length at their arrays for perfomance.
+    // Is only used by shuffle.
+    function createNode(h, length) {
+      if (length < 0) { length = 0; }
+      var a = { ctor:"_Array", height:h, table:new Array(length) };
+      if (h > 0) {
+        a.lengths = new Array(length);
+      }
+      return a;
+    }
+
+    // Returns an array of two balanced nodes.
+    function shuffle(a, b, toRemove) {
+      var newA = createNode(a.height, Math.min(M, a.table.length + b.table.length - toRemove));
+      var newB = createNode(a.height, newA.table.length - (a.table.length + b.table.length - toRemove));
+
+      // Skip the slots with size M. More precise: copy the slot references
+      // to the new node
+      var read = 0;
+      while (get2(a.table, b.table, read).table.length % M == 0) {
+        set2(newA.table, newB.table, read, get2(a.table, b.table, read));
+        set2(newA.lengths, newB.lengths, read, get2(a.lengths, b.lengths, read));
+        read++;
+      }
+
+      // Pulling items from left to right, caching in a slot before writing
+      // it into the new nodes.
+      var write = read;
+      var slot = new createNode(a.height - 1, 0);
+      var from = 0;
+
+      // If the current slot is still containing data, then there will be at
+      // least one more write, so we do not break this loop yet.
+      while (read - write - (slot.table.length > 0 ? 1 : 0) < toRemove) {
+        // Find out the max possible items for copying.
+        var source = get2(a.table, b.table, read);
+        var to = Math.min(M - slot.table.length, source.table.length)
+
+        // Copy and adjust size table.
+        slot.table = slot.table.concat(source.table.slice(from, to));
+        if (slot.height > 0) {
+          var len = slot.lengths.length;
+          for (var i = len; i < len + to - from; i++) {
+            slot.lengths[i] = length(slot.table[i]);
+            slot.lengths[i] += (i > 0 ? slot.lengths[i - 1] : 0);
+          }
+        }
+
+        from += to;
+
+        // Only proceed to next slots[i] if the current one was
+        // fully copied.
+        if (source.table.length <= to) {
+          read++; from = 0;
+        }
+
+        // Only create a new slot if the current one is filled up.
+        if (slot.table.length == M) {
+          saveSlot(newA, newB, write, slot);
+          slot = createNode(a.height - 1,0);
+          write++;
+        }
+      }
+
+      // Cleanup after the loop. Copy the last slot into the new nodes.
+      if (slot.table.length > 0) {
+        saveSlot(newA, newB, write, slot);
+        write++;
+      }
+
+      // Shift the untouched slots to the left
+      while (read < a.table.length + b.table.length ) {
+        saveSlot(newA, newB, write, get2(a.table, b.table, read));
+        read++; write++;
+      }
+
+      return [newA, newB];
+    }
+
+    // Navigation functions
+    function botRight(a) { return a.table[a.table.length - 1]; }
+    function botLeft(a)  { return a.table[0]; }
+
+    // Copies a node for updating. Note that you should not use this if
+    // only updating only one of "table" or "lengths" for performance reasons.
+    function nodeCopy(a) {
+      var newA = { ctor:"_Array", height:a.height
+                                , table:a.table.slice() };
+      if (a.height > 0) { newA.lengths = a.lengths.slice(); }
+      return newA;
+    }
+
+    // Returns how many items are in the tree.
+    function length(array) {
+      if (array.height == 0) {
+        return array.table.length;
+      } else {
+        return array.lengths[array.lengths.length - 1];
+      }
+    }
+
+    // Calculates in which slot of "table" the item probably is, then
+    // find the exact slot via forward searching in  "lengths". Returns the index.
+    function getSlot(i, a) {
+      var slot = i >> (5 * a.height);
+      while (a.lengths[slot] <= i) {
+        slot++;
+      }
+      return slot;
+    }
+
+    // Recursively creates a tree with a given height containing
+    // only the given item.
+    function create(item, h) {
+      if (h == 0) {
+        return { ctor:"_Array", height:0
+                              , table:[item] };
+      } else {
+        return { ctor:"_Array", height:h
+                              , table:[create(item, h - 1)]
+                              , lengths:[1] };
+      }
+    }
+
+    // Recursively creates a tree that contains the given tree.
+    function parentise(tree, h) {
+      if (h == tree.height) {
+        return tree;
+      } else {
+        return { ctor:"_Array", height:h
+                              , table:[parentise(tree, h - 1)]
+                              , lengths:[length(tree)] };
+      }
+    }
+
+    // Emphasizes blood brotherhood beneath two trees.
+    function siblise(a, b) {
+      return { ctor:"_Array", height:a.height + 1
+                            , table:[a, b]
+                            , lengths:[length(a), length(a) + length(b)] };
+    }
+
+    function toJSArray(a) {
+      var jsArray = new Array(length(a));
+      toJSArray_(jsArray, 0, a);
+      return jsArray;
+    }
+
+    function toJSArray_(jsArray, i, a) {
+      for (var t = 0; t < a.table.length; t++) {
+        if (a.height == 0) {
+          jsArray[i + t] = a.table[t];
+        } else {
+          var inc = t == 0 ? 0 : a.lengths[t - 1];
+          toJSArray_(jsArray, i + inc, a.table[t]);
+        }
+      }
+    }
+
+    function fromJSArray(jsArray) {
+      if (jsArray.length == 0) { return empty; }
+      var h = Math.floor(Math.log(jsArray.length) / Math.log(M));
+      return fromJSArray_(jsArray, h, 0, jsArray.length);
+    }
+
+    function fromJSArray_(jsArray, h, from, to) {
+      if (h == 0) {
+        return { ctor:"_Array", height:0
+                              , table:jsArray.slice(from, to) };
+      }
+
+      var step = Math.pow(M, h);
+      var table = new Array(Math.ceil((to - from) / step));
+      var lengths = new Array(table.length);
+      for (var i = 0; i < table.length; i++) {
+        table[i] = fromJSArray_( jsArray, h - 1, from + (i * step)
+                               , Math.min(from + ((i + 1) * step), to));
+        lengths[i] = length(table[i]) + (i > 0 ? lengths[i-1] : 0);
+      }
+      return { ctor:"_Array", height:h, table:table, lengths:lengths };
+    }
+
+    Elm.Native.Array.values = {
+      empty:empty,
+      fromList:fromList,
+      toList:toList,
+      initialize:F2(initialize),
+      append:F2(append),
+      push:F2(push),
+      slice:F3(slice),
+      get:F2(get),
+      set:F3(set),
+      map:F2(map),
+      indexedMap:F2(indexedMap),
+      foldl:F3(foldl),
+      foldr:F3(foldr),
+      length:length,
+
+      toJSArray:toJSArray,
+      fromJSArray:fromJSArray
+    };
+
+    return elm.Native.Array.values = Elm.Native.Array.values;
+}
+
+Elm.Native.Basics = {};
+Elm.Native.Basics.make = function(elm) {
+  elm.Native = elm.Native || {};
+  elm.Native.Basics = elm.Native.Basics || {};
+  if (elm.Native.Basics.values) return elm.Native.Basics.values;
+
+  var JS = Elm.Native.JavaScript.make(elm);
+  var Utils = Elm.Native.Utils.make(elm);
+
+  function div(a, b) {
+      return (a/b)|0;
+  }
+  function rem(a, b) {
+      return a % b;
+  }
+  var mod = Utils.mod;
+  function logBase(base, n) {
+      return Math.log(n) / Math.log(base);
+  }
+  function negate(n) {
+      return -n;
+  }
+  function abs(n) {
+      return n < 0 ? -n : n;
+  }
+
+  function min(a, b) {
+      return Utils.cmp(a,b) < 0 ? a : b;
+  }
+  function max(a, b) {
+      return Utils.cmp(a,b) > 0 ? a : b;
+  }
+  function clamp(lo, hi, n) {
+      return Utils.cmp(n,lo) < 0 ? lo : Utils.cmp(n,hi) > 0 ? hi : n;
+  }
+
+  function xor(a, b) {
+      return a !== b;
+  }
+  function not(b) {
+      return !b;
+  }
+  function isInfinite(n) {
+      return n === Infinity || n === -Infinity
+  }
+
+  function truncate(n) {
+      return n|0;
+  }
+
+  function degrees(d) {
+      return d * Math.PI / 180;
+  }
+  function turns(t) {
+      return 2 * Math.PI * t;
+  }
+  function fromPolar(point) {
+      var r = point._0;
+      var t = point._1;
+      return Utils.Tuple2(r * Math.cos(t), r * Math.sin(t));
+  }
+  function toPolar(point) {
+      var x = point._0;
+      var y = point._1;
+      return Utils.Tuple2(Math.sqrt(x * x + y * y), Math.atan2(y,x));
+  }
+
+  var basics = {
+      div: F2(div),
+      rem: F2(rem),
+      mod: mod,
+
+      pi: Math.PI,
+      e: Math.E,
+      cos: Math.cos,
+      sin: Math.sin,
+      tan: Math.tan,
+      acos: Math.acos,
+      asin: Math.asin,
+      atan: Math.atan,
+      atan2: F2(Math.atan2),
+
+      degrees:  degrees,
+      turns:  turns,
+      fromPolar:  fromPolar,
+      toPolar:  toPolar,
+
+      sqrt: Math.sqrt,
+      logBase: F2(logBase),
+      negate: negate,
+      abs: abs,
+      min: F2(min),
+      max: F2(max),
+      clamp: F3(clamp),
+      compare: Utils.compare,
+
+      xor: F2(xor),
+      not: not,
+
+      truncate: truncate,
+      ceiling: Math.ceil,
+      floor: Math.floor,
+      round: Math.round,
+      toFloat: function(x) { return x; },
+      isNaN: isNaN,
+      isInfinite: isInfinite
+  };
+
+  return elm.Native.Basics.values = basics;
+};
+Elm.Native.Bitwise = {};
+Elm.Native.Bitwise.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.Bitwise = elm.Native.Bitwise || {};
+    if (elm.Native.Bitwise.values) return elm.Native.Bitwise.values;
+
+    function and(a,b) { return a & b; }
+    function or (a,b) { return a | b; }
+    function xor(a,b) { return a ^ b; }
+    function not(a) { return ~a; }
+    function sll(a,offset) { return a << offset; }
+    function sra(a,offset) { return a >> offset; }
+    function srl(a,offset) { return a >>> offset; }
+
+    return elm.Native.Bitwise.values = {
+        and: F2(and),
+        or : F2(or ),
+        xor: F2(xor),
+        complement: not,
+        shiftLeft           : F2(sll),
+        shiftRightArithmatic: F2(sra),
+        shiftRightLogical   : F2(srl)
+    };
+    
+};
+Elm.Native.Char = {};
+Elm.Native.Char.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.Char = elm.Native.Char || {};
+    if (elm.Native.Char.values) return elm.Native.Char.values;
+
+    var Utils = Elm.Native.Utils.make(elm);
+
+    function isBetween(lo,hi) { return function(chr) {
+	var c = chr.charCodeAt(0);
+	return lo <= c && c <= hi;
+    };
+                              }
+    var isDigit = isBetween('0'.charCodeAt(0),'9'.charCodeAt(0));
+    var chk1 = isBetween('a'.charCodeAt(0),'f'.charCodeAt(0));
+    var chk2 = isBetween('A'.charCodeAt(0),'F'.charCodeAt(0));
+
+    return elm.Native.Char.values = {
+        fromCode : function(c) { return String.fromCharCode(c); },
+        toCode   : function(c) { return c.toUpperCase().charCodeAt(0); },
+        toUpper  : function(c) { return Utils.chr(c.toUpperCase()); },
+        toLower  : function(c) { return Utils.chr(c.toLowerCase()); },
+        toLocaleUpper : function(c) { return Utils.chr(c.toLocaleUpperCase()); },
+        toLocaleLower : function(c) { return Utils.chr(c.toLocaleLowerCase()); },
+        isLower    : isBetween('a'.charCodeAt(0),'z'.charCodeAt(0)),
+        isUpper    : isBetween('A'.charCodeAt(0),'Z'.charCodeAt(0)),
+        isDigit    : isDigit,
+        isOctDigit : isBetween('0'.charCodeAt(0),'7'.charCodeAt(0)),
+        isHexDigit : function(c) { return isDigit(c) || chk1(c) || chk2(c); }
+    };
+};
+Elm.Native.Color = {};
+Elm.Native.Color.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.Color = elm.Native.Color || {};
+    if (elm.Native.Color.values) return elm.Native.Color.values;
+
+    var Utils = Elm.Native.Utils.make(elm);
+
+    function toCss(c) {
+        var format = '';
+        var colors = '';
+        if (c.ctor === 'RGBA') {
+            format = 'rgb';
+            colors = c._0 + ', ' + c._1 + ', ' + c._2;
+        } else {
+            format = 'hsl';
+            colors = (c._0 * 180 / Math.PI) + ', ' +
+                     (c._1 * 100) + '%, ' +
+                     (c._2 * 100) + '%';
+        }
+        if (c._3 === 1) {
+            return format + '(' + colors + ')';
+        } else {
+            return format + 'a(' + colors + ', ' + c._3 + ')';
+        }
+    }
+
+    return elm.Native.Color.values = {
+        toCss:toCss
+    };
+
+};
+Elm.Native.Date = {};
+Elm.Native.Date.make = function(elm) {
+ elm.Native = elm.Native || {};
+ elm.Native.Date = elm.Native.Date || {};
+ if (elm.Native.Date.values) return elm.Native.Date.values;
+
+ var Maybe = Elm.Maybe.make(elm);
+
+ function dateNow() { return new window.Date; }
+ function readDate(str) {
+     var d = new window.Date(str);
+     if (isNaN(d.getTime())) return Maybe.Nothing;
+     return Maybe.Just(d);
+ }
+
+ var dayTable = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
+ var monthTable = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
+		   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; 
+
+ return elm.Native.Date.values = {
+     read    : readDate,
+     year    : function(d) { return d.getFullYear(); },
+     month   : function(d) { return { ctor:monthTable[d.getMonth()] }; },
+     day     : function(d) { return d.getDate(); },
+     hour    : function(d) { return d.getHours(); },
+     minute  : function(d) { return d.getMinutes(); },
+     second  : function(d) { return d.getSeconds(); },
+     toTime  : function(d) { return d.getTime(); },
+     fromTime: function(t) { return new window.Date(t); },
+     dayOfWeek : function(d) { return { ctor:dayTable[d.getDay()] }; }
+ };
+
+};
+Elm.Native.Debug = {};
+Elm.Native.Debug.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.Debug = elm.Native.Debug || {};
+    if (elm.Native.Debug.values) return elm.Native.Debug.values;
+    if ('values' in Elm.Native.Debug)
+        return elm.Native.Debug.values = Elm.Native.Debug.values;
+
+    var show = Elm.Native.Show.make(elm).show;
+    var replace = Elm.Native.Utils.make(elm).replace;
+
+    function log(tag, value) {
+        var msg = tag + ': ' + show(value);
+        var process = process || {};
+        if (process.stdout) {
+            process.stdout.write(msg);
+        } else {
+            console.log(msg);
+        }
+        return value;
+    }
+
+    function tracePath(debugId, form) {
+        return replace([["debugTracePathId",debugId]], form);
+    }
+
+    function WatchTracker() {
+        this.frames = [{}];
+        this.clear = function() {
+            this.watches = {};
+        };
+        this.pushFrame = function() {
+            var lastFrame = this.frames[this.frames.length - 1];
+            this.frames.push(lastFrame);
+        }
+        this.notify = function(tag, value) {
+            this.frames[this.frames.length - 1][tag] = value;
+        };
+    }
+    var watchTracker = new WatchTracker();
+
+    function watch(tag, value) {
+        watchTracker.notify(tag, value);
+        return value;
+    }
+
+    function watchSummary(tag, f, value) {
+        watchTracker.notify(tag, f(value));
+        return value;
+    }
+
+    Elm.Native.Debug.values = {
+        tracePath: F2(tracePath),
+        log: F2(log),
+        watch: F2(watch),
+        watchSummary:F3(watchSummary),
+        watchTracker: watchTracker
+    };
+    return elm.Native.Debug.values = Elm.Native.Debug.values;
+};
+Elm.Native.Error = {};
+Elm.Native.Error.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.Error = elm.Native.Error || {};
+    if (elm.Native.Error.values) return elm.Native.Error.values;
+
+    function indent(lines) {
+        var msg = '';
+        for (var i = 0; i < lines.length; ++i) {
+            msg += '<br/>&nbsp; &nbsp; ' + lines[i];
+        }
+        return msg;
+    }
+
+    function Case(moduleName, span) { 
+	var msg = indent(['Non-exhaustive pattern match in case-expression.',
+                          'Make sure your patterns cover every case!']);
+	throw new Error('Runtime error in module ' + moduleName + ' (' + span + '):' + msg);
+    }
+
+    function If(moduleName, span) { 
+	var msg = indent(['Non-exhaustive pattern match in multi-way-if expression.',
+                          'It is best to use \'otherwise\' as the last branch of multi-way-if.']);
+	throw new Error('Runtime error in module ' + moduleName + ' (' + span + '):' + msg);
+    }
+
+    function raise(str) { throw new Error(str); }
+
+    return elm.Native.Error.values = { Case: Case, If: If, raise: raise };
+};
+
+function F2(fun) {
+  function wrapper(a) { return function(b) { return fun(a,b) } }
+  wrapper.arity = 2;
+  wrapper.func = fun;
+  return wrapper;
+}
+
+function F3(fun) {
+  function wrapper(a) {
+    return function(b) { return function(c) { return fun(a,b,c) }}
+  }
+  wrapper.arity = 3;
+  wrapper.func = fun;
+  return wrapper;
+}
+
+function F4(fun) {
+  function wrapper(a) { return function(b) { return function(c) {
+    return function(d) { return fun(a,b,c,d) }}}
+  }
+  wrapper.arity = 4;
+  wrapper.func = fun;
+  return wrapper;
+}
+
+function F5(fun) {
+  function wrapper(a) { return function(b) { return function(c) {
+    return function(d) { return function(e) { return fun(a,b,c,d,e) }}}}
+  }
+  wrapper.arity = 5;
+  wrapper.func = fun;
+  return wrapper;
+}
+
+function F6(fun) {
+  function wrapper(a) { return function(b) { return function(c) {
+    return function(d) { return function(e) { return function(f) {
+      return fun(a,b,c,d,e,f) }}}}}
+  }
+  wrapper.arity = 6;
+  wrapper.func = fun;
+  return wrapper;
+}
+
+function F7(fun) {
+  function wrapper(a) { return function(b) { return function(c) {
+    return function(d) { return function(e) { return function(f) {
+      return function(g) { return fun(a,b,c,d,e,f,g) }}}}}}
+  }
+  wrapper.arity = 7;
+  wrapper.func = fun;
+  return wrapper;
+}
+
+function F8(fun) {
+  function wrapper(a) { return function(b) { return function(c) {
+    return function(d) { return function(e) { return function(f) {
+	return function(g) { return function(h) {return fun(a,b,c,d,e,f,g,h)}}}}}}}
+  }
+  wrapper.arity = 8;
+  wrapper.func = fun;
+  return wrapper;
+}
+
+function F9(fun) {
+  function wrapper(a) { return function(b) { return function(c) {
+    return function(d) { return function(e) { return function(f) {
+	return function(g) { return function(h) { return function(i) {
+        return fun(a,b,c,d,e,f,g,h,i) }}}}}}}}
+  }
+  wrapper.arity = 9;
+  wrapper.func = fun;
+  return wrapper;
+}
+
+function A2(fun,a,b) {
+  return fun.arity === 2 ? fun.func(a,b) : fun(a)(b);
+}
+function A3(fun,a,b,c) {
+  return fun.arity === 3 ? fun.func(a,b,c) : fun(a)(b)(c);
+}
+function A4(fun,a,b,c,d) {
+  return fun.arity === 4 ? fun.func(a,b,c,d) : fun(a)(b)(c)(d);
+}
+function A5(fun,a,b,c,d,e) {
+  return fun.arity === 5 ? fun.func(a,b,c,d,e) : fun(a)(b)(c)(d)(e);
+}
+function A6(fun,a,b,c,d,e,f) {
+  return fun.arity === 6 ? fun.func(a,b,c,d,e,f) : fun(a)(b)(c)(d)(e)(f);
+}
+function A7(fun,a,b,c,d,e,f,g) {
+  return fun.arity === 7 ? fun.func(a,b,c,d,e,f,g) : fun(a)(b)(c)(d)(e)(f)(g);
+}
+function A8(fun,a,b,c,d,e,f,g,h) {
+  return fun.arity === 8 ? fun.func(a,b,c,d,e,f,g,h) : fun(a)(b)(c)(d)(e)(f)(g)(h);
+}
+function A9(fun,a,b,c,d,e,f,g,h,i) {
+  return fun.arity === 9 ? fun.func(a,b,c,d,e,f,g,h,i)
+                         : fun(a)(b)(c)(d)(e)(f)(g)(h)(i);
+}
+Elm.Native.JavaScript = {};
+Elm.Native.JavaScript.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.JavaScript = elm.Native.JavaScript || {};
+    if (elm.Native.JavaScript.values) return elm.Native.JavaScript.values;
+
+    var List = Elm.Native.List.make(elm);
+    var Render = ElmRuntime.use(ElmRuntime.Render.Element);
+
+    function fromJS(v) {
+        var type = typeof v;
+        if (type === 'number' ) return v;
+        if (type === 'boolean') return v;
+        if (type === 'string' ) return v;
+        if (v instanceof Array) {
+            var arr = [];
+            var len = v.length;
+            for (var i = 0; i < len; ++i) {
+                var x = fromJS(v[i]);
+                if (x !== null) arr.push(x);
+            }
+            return List.fromArray(arr);
+        }
+        if (type === 'object') {
+            var rec = { _:{} };
+            for (var f in v) {
+                var x = fromJS(v[f]);
+                if (x !== null) rec[f] = x;
+            }
+            return rec;
+        }
+        return null;
+    }
+
+    function toJS(v) {
+        var type = typeof v;
+        if (type === 'number' || type === 'boolean' || type === 'string') return v;
+        if (type === 'object' && '_' in v) {
+            var obj = {};
+            for (var k in v) {
+                var x = toJS(v[k]);
+                if (x !== null) obj[k] = x;
+            }
+            return obj;
+        }
+        if (type === 'object' && (v.ctor === '::' || v.ctor === '[]')) {
+            var array = List.toArray(v);
+            for (var i = array.length; i--; ) {
+                array[i] = toJS(array[i]);
+            }
+            return array;
+        }
+        return null;
+    }
+
+    function fromRecord(r) {
+        if (typeof r === 'object' && '_' in r) {
+            return toJS(r);
+        }
+        throw new Error("'fromRecord' must be called on a record.");
+    }
+
+    return elm.Native.JavaScript.values = {
+        toRecord    : fromJS,
+        fromRecord  : fromRecord
+    };
+
+};
+Elm.Native.Json = {};
+Elm.Native.Json.make = function(elm) {
+
+    elm.Native = elm.Native || {};
+    elm.Native.Json = elm.Native.Json || {};
+    if (elm.Native.Json.values) return elm.Native.Json.values;
+
+    var Maybe = Elm.Maybe.make(elm);
+    var Dict = Elm.Dict.make(elm);
+    var List = Elm.Native.List.make(elm);
+    var Utils = Elm.Native.Utils.make(elm);
+
+    function toJS(v) {
+        switch (v.ctor) {
+        case 'Null'   : return null;
+        case 'String' : return v._0;
+        case 'Number' : return v._0;
+        case 'Boolean': return v._0;
+        case 'Object' :
+            var obj = {};
+            var array = List.toArray(Dict.toList(v._0));
+            for (var i = array.length; i--; ) {
+                var entry = array[i];
+                obj[entry._0] = toJS(entry._1);
+            }
+            return obj;
+        case 'Array'  :
+            var array = List.toArray(v._0);
+            for (var i = array.length; i--; ) {
+	        array[i] = toJS(array[i]);
+            }
+            return array;
+        }
+    }
+
+    function toString(sep, value) {
+        return JSON.stringify(toJS(value), null, sep);
+    }
+
+    function fromJS(v) {
+        switch (typeof v) {
+        case 'string' : return { ctor:"String" , _0: v };
+        case 'number' : return { ctor:"Number" , _0: v };
+        case 'boolean': return { ctor:"Boolean", _0: v };
+        case 'object' :
+            if (v === null) return { ctor:"Null" };
+            if (v instanceof Array) {
+                var array = new Array(v.length);
+                for (var i = v.length; i--; ) {
+                    array[i] = fromJS(v[i]);
+                }
+	        return {
+                    ctor:"Array",
+                    _0: List.fromArray(array)
+                };
+            }
+            var array = [];
+            for (var key in v) {
+                var value = fromJS(v[key]);
+                array.push(Utils.Tuple2(key, value));
+            }
+            var list = List.fromArray(array);
+            return {
+                ctor:"Object",
+                _0: Dict.fromList(list)
+            };
+        }
+    }
+
+    function fromString(str) {
+        try {
+	    return Maybe.Just(fromJS(JSON.parse(str)));
+        } catch (e) {
+	    return Maybe.Nothing;
+        }
+    }
+
+    return elm.Native.Json.values = {
+        toString   : F2(toString),
+        fromString : fromString,
+        fromJS     : fromJS,
+        toJS       : toJS
+    };
+
+};
+Elm.Native.List = {};
+Elm.Native.List.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.List = elm.Native.List || {};
+    if (elm.Native.List.values) return elm.Native.List.values;
+    if ('values' in Elm.Native.List)
+        return elm.Native.List.values = Elm.Native.List.values;
+
+    var Utils = Elm.Native.Utils.make(elm);
+
+    // TODO: Improve Nil handling
+    // We can change places like:  if (xs.ctor === '[]') ... to if (xs === Nil) ...
+    // but only if we're confident Nil can only be defined once.
+    // Currently (27Mar2013) each module can have different instantiations, so multiple Nil objects can exist
+    // (and if they're used interchangeably then direct object comparison fails where ctor doesn't).
+    // So, this can only be fixed when modules initialisation is also fixed.
+    // The performance overhead of the .ctor calls is 5-10% according to jsperf (depending on fn + list size)
+    // (on firefox 19)
+
+    var Nil = { ctor:'[]' };
+
+    // using freeze for every cons would be nice but is a huge (9x on firefox 19)
+    // performance penalty
+    function Cons(hd,tl) { return { ctor:"::", _0:hd, _1:tl }; }
+
+    function throwError(f) {
+        throw new Error("Function '" + f + "' expects a non-empty list!");
+    }
+
+    function toArray(xs) {
+        var out = [];
+        while (xs.ctor !== '[]') {
+            out.push(xs._0);
+            xs = xs._1;
+        }
+        return out;
+    }
+
+    function fromArray(arr) {
+        var out = Nil;
+        for (var i = arr.length; i--; ) {
+            out = Cons(arr[i], out);
+        }
+        return out;
+    }
+
+    function range(lo,hi) {
+        var lst = Nil;
+        if (lo <= hi) {
+            do { lst = Cons(hi,lst) } while (hi-->lo);
+        }
+        return lst
+    }
+
+    function append(xs,ys) {
+        // append Text
+        if (xs.text || ys.text) {
+            return Utils.txt(Utils.makeText(xs) + Utils.makeText(ys));
+        }
+
+        // append Strings
+        if (typeof xs === "string") return xs + ys;
+
+        // append Lists
+        if (xs.ctor === '[]') { return ys; }
+        var root = Cons(xs._0, Nil);
+        var curr = root;
+        xs = xs._1;
+        while (xs.ctor !== '[]') {
+	    curr._1 = Cons(xs._0, Nil);
+	    xs = xs._1;
+	    curr = curr._1;
+        }
+        curr._1 = ys;
+        return root;
+    }
+
+    function head(v) { return v.ctor === '[]' ? throwError('head') : v._0; }
+    function tail(v) { return v.ctor === '[]' ? throwError('tail') : v._1; }
+
+    function last(xs) {
+        if (xs.ctor === '[]') { throwError('last'); }
+        var out = xs._0;
+        while (xs.ctor !== '[]') {
+            out = xs._0;
+            xs = xs._1;
+        }
+        return out;
+    }
+
+    function map(f, xs) {
+        var arr = [];
+        while (xs.ctor !== '[]') {
+            arr.push(f(xs._0));
+            xs = xs._1;
+        }
+        return fromArray(arr);
+    }
+
+    // f defined similarly for both foldl and foldr (NB: different from Haskell)
+    // ie, foldl : (a -> b -> b) -> b -> [a] -> b
+    function foldl(f, b, xs) {
+        var acc = b;
+        while (xs.ctor !== '[]') {
+            acc = A2(f, xs._0, acc);
+            xs = xs._1;
+        }
+        return acc;
+    }
+
+    function foldr(f, b, xs) {
+        var arr = toArray(xs);
+        var acc = b;
+        for (var i = arr.length; i--; ) {
+            acc = A2(f, arr[i], acc);
+        }
+        return acc;
+    }
+
+    function foldl1(f, xs) {
+        return xs.ctor === '[]' ? throwError('foldl1') : foldl(f, xs._0, xs._1);
+    }
+
+    function foldr1(f, xs) {
+        if (xs.ctor === '[]') { throwError('foldr1'); }
+        var arr = toArray(xs);
+        var acc = arr.pop();
+        for (var i = arr.length; i--; ) {
+            acc = A2(f, arr[i], acc);
+        }
+        return acc;
+    }
+
+    function scanl(f, b, xs) {
+        var arr = toArray(xs);
+        arr.unshift(b);
+        var len = arr.length;
+        for (var i = 1; i < len; ++i) {
+            arr[i] = A2(f, arr[i], arr[i-1]);
+        }
+        return fromArray(arr);
+    }
+
+    function scanl1(f, xs) {
+        return xs.ctor === '[]' ? throwError('scanl1') : scanl(f, xs._0, xs._1);
+    }
+
+    function filter(pred, xs) {
+        var arr = [];
+        while (xs.ctor !== '[]') {
+            if (pred(xs._0)) { arr.push(xs._0); }
+            xs = xs._1;
+        }
+        return fromArray(arr);
+    }
+
+    function length(xs) {
+        var out = 0;
+        while (xs.ctor !== '[]') {
+            out += 1;
+            xs = xs._1;
+        }
+        return out;
+    }
+
+    function member(x, xs) {
+        while (xs.ctor !== '[]') {
+            if (Utils.eq(x,xs._0)) return true;
+            xs = xs._1;
+        }
+        return false;
+    }
+
+    function reverse(xs) { return fromArray(toArray(xs).reverse()); }
+
+    function concat(xss) {
+        if (xss.ctor === '[]') return xss;
+        var arr = toArray(xss);
+        var xs = arr[arr.length-1];
+        for (var i = arr.length-1; i--; ) {
+	    xs = append(arr[i], xs);
+        }
+        return xs;
+    }
+
+    function all(pred, xs) {
+        while (xs.ctor !== '[]') {
+            if (!pred(xs._0)) return false;
+            xs = xs._1;
+        }
+        return true;
+    }
+
+    function any(pred, xs) {
+        while (xs.ctor !== '[]') {
+            if (pred(xs._0)) return true;
+            xs = xs._1;
+        }
+        return false;
+    }
+
+    function zip(xs, ys) {
+        var arr = [];
+        while (xs.ctor !== '[]' && ys.ctor !== '[]') {
+            arr.push(Utils.Tuple2(xs._0, ys._0));
+            xs = xs._1;
+            ys = ys._1;
+        }
+        return fromArray(arr);
+    }
+
+    function zipWith(f, xs, ys) {
+        var arr = [];
+        while (xs.ctor !== '[]' && ys.ctor !== '[]') {
+            arr.push(A2(f, xs._0, ys._0));
+            xs = xs._1;
+            ys = ys._1;
+        }
+        return fromArray(arr);
+    }
+
+    function zipWith3(f, xs, ys, zs) {
+        var arr = [];
+        while (xs.ctor !== '[]' && ys.ctor !== '[]' && zs.ctor !== '[]') {
+            arr.push(A3(f, xs._0, ys._0, zs._0));
+            xs = xs._1;
+            ys = ys._1;
+            zs = zs._1;
+        }
+        return fromArray(arr);
+    }
+
+    function zipWith4(f, ws, xs, ys, zs) {
+        var arr = [];
+        while (   ws.ctor !== '[]'
+               && xs.ctor !== '[]'
+               && ys.ctor !== '[]'
+               && zs.ctor !== '[]')
+        {
+            arr.push(A4(f, ws._0, xs._0, ys._0, zs._0));
+            ws = ws._1;
+            xs = xs._1;
+            ys = ys._1;
+            zs = zs._1;
+        }
+        return fromArray(arr);
+    }
+
+    function zipWith5(f, vs, ws, xs, ys, zs) {
+        var arr = [];
+        while (   vs.ctor !== '[]'
+               && ws.ctor !== '[]'
+               && xs.ctor !== '[]'
+               && ys.ctor !== '[]'
+               && zs.ctor !== '[]')
+        {
+            arr.push(A5(f, vs._0, ws._0, xs._0, ys._0, zs._0));
+            vs = vs._1;
+            ws = ws._1;
+            xs = xs._1;
+            ys = ys._1;
+            zs = zs._1;
+        }
+        return fromArray(arr);
+    }
+
+    function sort(xs) {
+        return fromArray(toArray(xs).sort(Utils.cmp));
+    }
+
+    function sortBy(f, xs) {
+        return fromArray(toArray(xs).sort(function(a,b){
+            return Utils.cmp(f(a), f(b));
+        }));
+    }
+
+    function sortWith(f, xs) {
+        return fromArray(toArray(xs).sort(function(a,b){
+            var ord = f(a)(b).ctor;
+            return ord === 'EQ' ? 0 : ord === 'LT' ? -1 : 1;
+        }));
+    }
+
+    function nth(xs, n) {
+        return toArray(xs)[n];
+    }
+
+    function take(n, xs) {
+        var arr = [];
+        while (xs.ctor !== '[]' && n > 0) {
+            arr.push(xs._0);
+            xs = xs._1;
+            --n;
+        }
+        return fromArray(arr);
+    }
+
+    function drop(n, xs) {
+        while (xs.ctor !== '[]' && n > 0) {
+            xs = xs._1;
+            --n;
+        }
+        return xs;
+    }
+
+    function repeat(n, x) {
+        var arr = [];
+        var pattern = [x];
+        while (n > 0) {
+            if (n & 1) arr = arr.concat(pattern);
+            n >>= 1, pattern = pattern.concat(pattern);
+        }
+        return fromArray(arr);
+    }
+
+    function join(sep, xss) {
+        if (sep.text) {
+            sep = Utils.makeText(sep);
+            xss = toArray(xss);
+            for (var i = xss.length; i--; ) {
+                xss[i] = Utils.makeText(xss[i]);
+            }
+            return Utils.txt(xss.join(sep));
+        }
+        if (typeof sep === 'string') return toArray(xss).join(sep);
+        if (xss.ctor === '[]') return Nil;
+        var s = toArray(sep);
+        var out = toArray(xss._0);
+        xss = xss._1;
+        while (xss.ctor !== '[]') {
+            out = out.concat(s, toArray(xss._0));
+            xss = xss._1;
+        }
+        return fromArray(out);
+    }
+
+    /*
+     * Only to be used internally; do some side effects for each elem
+     */
+    function each(action, xs) {
+        while(xs.ctor !== '[]') {
+            action(xs._0);
+            xs = xs._1;
+        }
+    }
+
+    Elm.Native.List.values = {
+        Nil:Nil,
+        Cons:Cons,
+        cons:F2(Cons),
+        toArray:toArray,
+        fromArray:fromArray,
+        range:range,
+        append:append,
+
+        head:head,
+        tail:tail,
+        last:last,
+
+        map:F2(map),
+        foldl:F3(foldl),
+        foldr:F3(foldr),
+
+        foldl1:F2(foldl1),
+        foldr1:F2(foldr1),
+        scanl:F3(scanl),
+        scanl1:F2(scanl1),
+        filter:F2(filter),
+        length:length,
+        member:F2(member),
+        reverse:reverse,
+        concat:concat,
+
+        all:F2(all),
+        any:F2(any),
+        zipWith :F3(zipWith ),
+        zipWith3:F4(zipWith3),
+        zipWith4:F5(zipWith4),
+        zipWith5:F6(zipWith5),
+        zip:F2(zip),
+        sort:sort,
+        sortBy:F2(sortBy),
+        sortWith:F2(sortWith),
+        nth:F2(nth),
+        take:F2(take),
+        drop:F2(drop),
+        repeat:F2(repeat),
+
+        join:F2(join),
+
+        each:each
+    };
+    return elm.Native.List.values = Elm.Native.List.values;
+
+};
+Elm.Native.Ports = {};
+Elm.Native.Ports.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.Ports = elm.Native.Ports || {};
+    if (elm.Native.Ports.values) return elm.Native.Ports.values;
+
+    var Signal = Elm.Signal.make(elm);
+
+    function incomingSignal(converter) {
+        converter.isSignal = true;
+        return converter;
+    }
+
+    function outgoingSignal(converter) {
+        return function(signal) {
+            var subscribers = []
+            function subscribe(handler) {
+                subscribers.push(handler);
+            }
+            function unsubscribe(handler) {
+                subscribers.pop(subscribers.indexOf(handler));
+            }
+            A2( Signal.lift, function(value) {
+                var val = converter(value);
+                var len = subscribers.length;
+                for (var i = 0; i < len; ++i) {
+                    subscribers[i](val);
+                }
+            }, signal);
+            return { subscribe:subscribe, unsubscribe:unsubscribe };
+        }
+    }
+
+    function portIn(name, converter) {
+        var jsValue = elm.ports.incoming[name];
+        if (jsValue === undefined) {
+            throw new Error("Initialization Error: port '" + name +
+                            "' was not given an input!");
+        }
+        elm.ports.uses[name] += 1;
+        try {
+            var elmValue = converter(jsValue);
+        } catch(e) {
+            throw new Error("Initialization Error on port '" + name + "': \n" + e.message);
+        }
+
+        // just return a static value if it is not a signal
+        if (!converter.isSignal) {
+            return elmValue;
+        }
+
+        // create a signal if necessary
+        var signal = Signal.constant(elmValue);
+        function send(jsValue) {
+            try {
+                var elmValue = converter(jsValue);
+            } catch(e) {
+                throw new Error("Error sending to port '" + name + "': \n" + e.message);
+            }
+            setTimeout(function() {
+                elm.notify(signal.id, elmValue);
+            }, 0);
+        }
+        elm.ports.outgoing[name] = { send:send };
+        return signal;
+    }
+
+    function portOut(name, converter, value) {
+        try {
+            elm.ports.outgoing[name] = converter(value);
+        } catch(e) {
+            throw new Error("Initialization Error on port '" + name + "': \n" + e.message);
+        }
+        return value;
+    }
+
+    return elm.Native.Ports.values = {
+        incomingSignal: incomingSignal,
+        outgoingSignal: outgoingSignal,
+        portOut: portOut,
+        portIn: portIn
+    };
+};
+Elm.Native.Regex = {};
+Elm.Native.Regex.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.Regex = elm.Native.Regex || {};
+    if (elm.Native.Regex.values) return elm.Native.Regex.values;
+    if ('values' in Elm.Native.Regex)
+        return elm.Native.Regex.values = Elm.Native.Regex.values;
+
+    var List = Elm.Native.List.make(elm);
+    var Maybe = Elm.Maybe.make(elm);
+
+    function escape(str) {
+        return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
+    }
+    function caseInsensitive(re) {
+        return new RegExp(re.source, 'gi');
+    }
+    function regex(raw) {
+        return new RegExp(raw, 'g');
+    }
+
+    function contains(re, string) {
+        return string.match(re) !== null;
+    }
+
+    function find(n, re, str) {
+        n = n.ctor === "All" ? Infinity : n._0;
+        var out = [];
+        var number = 0;
+        var string = str;
+        var result;
+        while (number++ < n && (result = re.exec(string))) {
+            var i = result.length - 1;
+            var subs = new Array(i);
+            while (i > 0) {
+                var submatch = result[i];
+                subs[--i] = submatch === undefined
+                    ? Maybe.Nothing
+                    : Maybe.Just(submatch);
+            }
+            out.push({
+                _:{},
+                match: result[0],
+                submatches: List.fromArray(subs),
+                index: result.index,
+                number: number
+            });
+        }
+        return List.fromArray(out);
+    }
+
+    function replace(n, re, replacer, string) {
+        n = n.ctor === "All" ? Infinity : n._0;
+        var count = 0;
+        function jsReplacer(match) {
+            if (count++ > n) return match;
+            var i = arguments.length-3;
+            var submatches = new Array(i);
+            while (i > 0) {
+                var submatch = arguments[i];
+                submatches[--i] = submatch === undefined
+                    ? Maybe.Nothing
+                    : Maybe.Just(submatch);
+            }
+            return replacer({
+                _:{},
+                match:match,
+                submatches:List.fromArray(submatches),
+                index:arguments[i-1],
+                number:count
+            });
+        }
+        return string.replace(re, jsReplacer);
+    }
+
+    function split(n, re, str) {
+        if (n === Infinity) {
+            return List.fromArray(string.split(re));
+        }
+        var string = str;
+        var result;
+        var out = [];
+        var start = re.lastIndex;
+        while (n--) {
+            if (!(result = re.exec(string))) break;
+            out.push(string.slice(start, result.index));
+            start = re.lastIndex;
+        }
+        out.push(string.slice(start));
+        return List.fromArray(out);
+    }
+
+    return Elm.Native.Regex.values = {
+        regex: regex,
+        caseInsensitive: caseInsensitive,
+        escape: escape,
+
+        contains: F2(contains),
+        find: F3(find),
+        replace: F4(replace),
+        split: F3(split)
+    };
+};
+Elm.Native.Show = {};
+Elm.Native.Show.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.Show = elm.Native.Show || {};
+    if (elm.Native.Show.values) return elm.Native.Show.values;
+
+    var NList = Elm.Native.List.make(elm);
+    var Array = Elm.Array.make(elm);
+    var List = Elm.List.make(elm);
+    var Dict = Elm.Dict.make(elm);
+    var Tuple2 = Elm.Native.Utils.make(elm).Tuple2;
+
+    var toString = function(v) {
+        var type = typeof v;
+        if (type === "function") {
+            var name = v.func ? v.func.name : v.name;
+            return '<function' + (name === '' ? '' : ': ') + name + '>';
+        }
+        else if (type === "boolean") {
+            return v ? "True" : "False";
+        }
+        else if (type === "number") {
+            return v + "";
+        }
+        else if ((v instanceof String) && v.isChar) {
+            return "'" + addSlashes(v) + "'";
+        }
+        else if (type === "string") {
+            return '"' + addSlashes(v) + '"';
+        }
+        else if (type === "object" && '_' in v && probablyPublic(v)) {
+            var output = [];
+            for (var k in v._) {
+                for (var i = v._[k].length; i--; ) {
+                    output.push(k + " = " + toString(v._[k][i]));
+                }
+            }
+            for (var k in v) {
+                if (k === '_') continue;
+                output.push(k + " = " + toString(v[k]));
+            }
+            if (output.length === 0) {
+                return "{}";
+            }
+            return "{ " + output.join(", ") + " }";
+        }
+        else if (type === "object" && 'ctor' in v) {
+            if (v.ctor.substring(0,6) === "_Tuple") {
+                var output = [];
+                for (var k in v) {
+                    if (k === 'ctor') continue;
+                    output.push(toString(v[k]));
+                }
+                return "(" + output.join(",") + ")";
+            }
+            else if (v.ctor === "_Array") {
+                var list = Array.toList(v);
+                return "Array.fromList " + toString(list);
+            }
+            else if (v.ctor === "::") {
+                var output = '[' + toString(v._0);
+                v = v._1;
+                while (v.ctor === "::") {
+                    output += "," + toString(v._0);
+                    v = v._1;
+                }
+                return output + ']';
+            }
+            else if (v.ctor === "[]") {
+                return "[]";
+            }
+            else if (v.ctor === "RBNode" || v.ctor === "RBEmpty") {
+                var cons = F3(function(k,v,acc){return NList.Cons(Tuple2(k,v),acc)});
+                var list = A3(Dict.foldr, cons, NList.Nil, v);
+                var name = "Dict";
+                if (list.ctor === "::" && list._0._1.ctor === "_Tuple0") {
+                    name = "Set";
+                    list = A2(List.map, function(x){return x._0}, list);
+                }
+                return name + ".fromList " + toString(list);
+            }
+            else {
+                var output = "";
+                for (var i in v) {
+                    if (i === 'ctor') continue;
+                    var str = toString(v[i]);
+                    var parenless = str[0] === '{' || str[0] === '<' || str.indexOf(' ') < 0;
+                    output += ' ' + (parenless ? str : '(' + str + ')');
+                }
+                return v.ctor + output;
+            }
+        }
+        if (type === 'object' && 'recv' in v) {
+            return '<signal>';
+        }
+        return "<internal structure>";
+    };
+
+    function addSlashes(str) {
+        return str.replace(/\\/g, '\\\\')
+                  .replace(/\n/g, '\\n')
+                  .replace(/\t/g, '\\t')
+                  .replace(/\r/g, '\\r')
+                  .replace(/\v/g, '\\v')
+                  .replace(/\0/g, '\\0')
+                  .replace(/\'/g, "\\'")
+                  .replace(/\"/g, '\\"');
+    }
+
+    function probablyPublic(v) {
+        var keys = Object.keys(v);
+        var len = keys.length;
+        if (len === 3
+            && 'props' in v
+            && 'element' in v) return false;
+        if (len === 5
+            && 'horizontal' in v
+            && 'vertical' in v
+            && 'x' in v
+            && 'y' in v) return false;
+        if (len === 7
+            && 'theta' in v
+            && 'scale' in v
+            && 'x' in v
+            && 'y' in v
+            && 'alpha' in v
+            && 'form' in v) return false;
+        return true;
+    }
+
+    return elm.Native.Show.values = { show:toString };
+};
+Elm.Native.String = {};
+Elm.Native.String.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.String = elm.Native.String || {};
+    if (elm.Native.String.values) return elm.Native.String.values;
+    if ('values' in Elm.Native.String)
+        return elm.Native.String.values = Elm.Native.String.values;
+
+    var Char = Elm.Char.make(elm);
+    var Maybe = Elm.Maybe.make(elm);
+    var List = Elm.Native.List.make(elm);
+    var Utils = Elm.Native.Utils.make(elm);
+
+    function isEmpty(str) {
+        return str.length === 0;
+    }
+    function cons(chr,str) {
+        return chr + str;
+    }
+    function uncons(str) {
+        var hd;
+        return (hd = str[0]) ? Maybe.Just(Utils.Tuple2(Utils.chr(hd), str.slice(1)))
+                              : Maybe.Nothing;
+    }
+    function append(a,b) {
+        return a + b;
+    }
+    function concat(strs) {
+        return List.toArray(strs).join('');
+    }
+    function length(str) {
+        return str.length;
+    }
+    function map(f,str) {
+        var out = str.split('');
+        for (var i = out.length; i--; ) {
+            out[i] = f(Utils.chr(out[i]));
+        }
+        return out.join('');
+    }
+    function filter(pred,str) {
+        return str.split('').map(Utils.chr).filter(pred).join('');
+    }
+    function reverse(str) {
+        return str.split('').reverse().join('');
+    }
+    function foldl(f,b,str) {
+        var len = str.length;
+        for (var i = 0; i < len; ++i) {
+            b = A2(f, Utils.chr(str[i]), b);
+        }
+        return b;
+    }
+    function foldr(f,b,str) {
+        for (var i = str.length; i--; ) {
+            b = A2(f, Utils.chr(str[i]), b);
+        }
+        return b;
+    }
+
+    function split(sep, str) {
+        return List.fromArray(str.split(sep));
+    }
+    function join(sep, strs) {
+        return List.toArray(strs).join(sep);
+    }
+    function repeat(n, str) {
+        var result = '';
+        while (n > 0) {
+            if (n & 1) result += str;
+            n >>= 1, str += str;
+        }
+        return result;
+    }
+
+    function slice(start, end, str) {
+        return str.slice(start,end);
+    }
+    function left(n, str) {
+        return n < 1 ? "" : str.slice(0,n);
+    }
+    function right(n, str) {
+        return n < 1 ? "" : str.slice(-n);
+    }
+    function dropLeft(n, str) {
+        return n < 1 ? str : str.slice(n);
+    }
+    function dropRight(n, str) {
+        return n < 1 ? str : str.slice(0,-n);
+    }
+
+    function pad(n,chr,str) {
+        var half = (n - str.length) / 2;
+        return repeat(Math.ceil(half),chr) + str + repeat(half|0,chr);
+    }
+    function padRight(n,chr,str) {
+        return str + repeat(n - str.length, chr);
+    }
+    function padLeft(n,chr,str) {
+        return repeat(n - str.length, chr) + str;
+    }
+
+    function trim(str) {
+        return str.trim();
+    }
+    function trimLeft(str) {
+        return str.trimLeft();
+    }
+    function trimRight(str) {
+        return str.trimRight();
+    }
+
+    function words(str) {
+        return List.fromArray(str.trim().split(/\s+/g));
+    }
+    function lines(str) {
+        return List.fromArray(str.split(/\r\n|\r|\n/g));
+    }
+
+    function toUpper(str) {
+        return str.toUpperCase();
+    }
+    function toLower(str) {
+        return str.toLowerCase();
+    }
+
+    function any(pred, str) {
+        for (var i = str.length; i--; ) {
+            if (pred(Utils.chr(str[i]))) return true;
+        }
+        return false;
+    }
+    function all(pred, str) {
+        for (var i = str.length; i--; ) {
+            if (!pred(Utils.chr(str[i]))) return false;
+        }
+        return true;
+    }
+
+    function contains(sub, str) {
+        return str.indexOf(sub) > -1;
+    }
+    function startsWith(sub, str) {
+        return str.indexOf(sub) === 0;
+    }
+    function endsWith(sub, str) {
+        return str.length >= sub.length &&
+               str.lastIndexOf(sub) === str.length - sub.length;
+    }
+    function indexes(sub, str) {
+        var subLen = sub.length;
+        var i = 0;
+        var is = [];
+        while ((i = str.indexOf(sub, i)) > -1) {
+            is.push(i);
+            i = i + subLen;
+        }
+        return List.fromArray(is);
+    }
+
+    function toInt(s) {
+        var len = s.length;
+        if (len === 0) { return Maybe.Nothing; }
+        var start = 0;
+        if (s[0] == '-') {
+            if (len === 1) { return Maybe.Nothing; }
+            start = 1;
+        }
+        for (var i = start; i < len; ++i) {
+            if (!Char.isDigit(s[i])) { return Maybe.Nothing; }
+        }
+        return Maybe.Just(parseInt(s, 10));
+    }
+
+    function toFloat(s) {
+        var len = s.length;
+        if (len === 0) { return Maybe.Nothing; }
+        var start = 0;
+        if (s[0] == '-') {
+            if (len === 1) { return Maybe.Nothing; }
+            start = 1;
+        }
+        var dotCount = 0;
+        for (var i = start; i < len; ++i) {
+            if (Char.isDigit(s[i])) { continue; }
+            if (s[i] === '.') {
+                dotCount += 1;
+                if (dotCount <= 1) { continue; }
+            }
+            return Maybe.Nothing;
+        }
+        return Maybe.Just(parseFloat(s));
+    }
+
+    function toList(str) {
+        return List.fromArray(str.split('').map(Utils.chr));
+    }
+    function fromList(chars) {
+        return List.toArray(chars).join('');
+    }
+
+    return Elm.Native.String.values = {
+        isEmpty: isEmpty,
+        cons: F2(cons),
+        uncons: uncons,
+        append: F2(append),
+        concat: concat,
+        length: length,
+        map: F2(map),
+        filter: F2(filter),
+        reverse: reverse,
+        foldl: F3(foldl),
+        foldr: F3(foldr),
+
+        split: F2(split),
+        join: F2(join),
+        repeat: F2(repeat),
+
+        slice: F3(slice),
+        left: F2(left),
+        right: F2(right),
+        dropLeft: F2(dropLeft),
+        dropRight: F2(dropRight),
+
+        pad: F3(pad),
+        padLeft: F3(padLeft),
+        padRight: F3(padRight),
+
+        trim: trim,
+        trimLeft: trimLeft,
+        trimRight: trimRight,
+
+        words: words,
+        lines: lines,
+
+        toUpper: toUpper,
+        toLower: toLower,
+
+        any: F2(any),
+        all: F2(all),
+
+        contains: F2(contains),
+        startsWith: F2(startsWith),
+        endsWith: F2(endsWith),
+        indexes: F2(indexes),
+
+        toInt: toInt,
+        toFloat: toFloat,
+        toList: toList,
+        fromList: fromList
+    };
+};
+Elm.Native.Text = {};
+Elm.Native.Text.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.Text = elm.Native.Text || {};
+    if (elm.Native.Text.values) return elm.Native.Text.values;
+
+    var toCss = Elm.Native.Color.make(elm).toCss;
+    var Element = Elm.Graphics.Element.make(elm);
+    var List = Elm.Native.List.make(elm);
+    var Utils = Elm.Native.Utils.make(elm);
+
+    function makeSpaces(s) {
+        if (s.length == 0) { return s; }
+        var arr = s.split('');
+        if (arr[0] == ' ') { arr[0] = "&nbsp;" }      
+        for (var i = arr.length; --i; ) {
+            if (arr[i][0] == ' ' && arr[i-1] == ' ') {
+                arr[i-1] = arr[i-1] + arr[i];
+                arr[i] = '';
+            }
+        }
+        for (var i = arr.length; i--; ) {
+            if (arr[i].length > 1 && arr[i][0] == ' ') {
+                var spaces = arr[i].split('');
+                for (var j = spaces.length - 2; j >= 0; j -= 2) {
+                    spaces[j] = '&nbsp;';
+                }
+                arr[i] = spaces.join('');
+            }
+        }
+        arr = arr.join('');
+        if (arr[arr.length-1] === " ") {
+	    return arr.slice(0,-1) + '&nbsp;';
+        }
+        return arr;
+    }
+
+    function properEscape(str) {
+        if (str.length == 0) return str;
+        str = str //.replace(/&/g,  "&#38;")
+	    .replace(/"/g,  '&#34;')
+	    .replace(/'/g,  "&#39;")
+	    .replace(/</g,  "&#60;")
+	    .replace(/>/g,  "&#62;")
+	    .replace(/\n/g, "<br/>");
+        var arr = str.split('<br/>');
+        for (var i = arr.length; i--; ) {
+	    arr[i] = makeSpaces(arr[i]);
+        }
+        return arr.join('<br/>');
+    }
+
+    function toText(str) { return Utils.txt(properEscape(str)); }
+
+    // conversions from Elm values to CSS
+    function toTypefaces(list) {
+        var typefaces = List.toArray(list);
+        for (var i = typefaces.length; i--; ) {
+            var typeface = typefaces[i];
+            if (typeface.indexOf(' ') > -1) {
+                typefaces[i] = "'" + typeface + "'";
+            }
+        }
+        return typefaces.join(',');
+    }
+    function toLine(line) {
+        var ctor = line.ctor;
+        return ctor === 'Under' ? 'underline' :
+               ctor === 'Over'  ? 'overline'  : 'line-through';
+    }
+
+    // setting styles of Text
+    function style(style, text) {
+        var newText = '<span style="color:' + toCss(style.color) + ';'
+        if (style.typeface.ctor !== '[]') {
+            newText += 'font-family:' + toTypefaces(style.typeface) + ';'
+        }
+        if (style.height.ctor !== "Nothing") {
+            newText += 'font-size:' + style.height._0 + 'px;';
+        }
+        if (style.bold) {
+            newText += 'font-weight:bold;';
+        }
+        if (style.italic) {
+            newText += 'font-style:italic;';
+        }
+        if (style.line.ctor !== 'Nothing') {
+            newText += 'text-decoration:' + toLine(style.line._0) + ';';
+        }
+        newText += '">' + Utils.makeText(text) + '</span>'
+        return Utils.txt(newText);
+    }
+    function height(px, text) {
+        return { style: 'font-size:' + px + 'px;', text:text }
+    }
+    function typeface(names, text) {
+        return { style: 'font-family:' + toTypefaces(names) + ';', text:text }
+    }
+    function monospace(text) {
+        return { style: 'font-family:monospace;', text:text }
+    }
+    function italic(text) {
+        return { style: 'font-style:italic;', text:text }
+    }
+    function bold(text) {
+        return { style: 'font-weight:bold;', text:text }
+    }
+    function link(href, text) {
+        return { href: toText(href), text:text };
+    }
+    function line(line, text) {
+        return { style: 'text-decoration:' + toLine(line) + ';', text:text };
+    }
+
+    function color(color, text) {
+        return { style: 'color:' + toCss(color) + ';', text:text };
+    }
+
+    function block(align) {
+        return function(text) {
+            var raw = {
+                ctor :'RawHtml',
+                html : Utils.makeText(text),
+                align: align,
+                guid : null,
+                args : []
+            };
+            var pos = A2(Utils.htmlHeight, 0, raw);
+            return A3(Element.newElement, pos._0, pos._1, raw);
+        }
+    }
+
+    function markdown(text, guid) {
+        var raw = {
+            ctor:'RawHtml',
+            html: text,
+            align: null,
+            guid: guid,
+            args: []
+        };
+        var pos = A2(Utils.htmlHeight, 0, raw);
+        return A3(Element.newElement, pos._0, pos._1, raw);
+    }
+
+    return elm.Native.Text.values = {
+        toText: toText,
+
+        height : F2(height),
+        italic : italic,
+        bold : bold,
+        line : F2(line),
+        monospace : monospace,
+        typeface : F2(typeface),
+        color : F2(color),
+        link : F2(link),
+        style : F2(style),
+
+        leftAligned  : block('left'),
+        rightAligned : block('right'),
+        centered     : block('center'),
+        justified    : block('justify'),
+        markdown     : markdown,
+
+        toTypefaces:toTypefaces,
+        toLine:toLine
+    };
+};
+Elm.Native.Trampoline = {};
+Elm.Native.Trampoline.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.Trampoline = elm.Native.Trampoline || {};
+    if (elm.Native.Trampoline.values) return elm.Native.Trampoline.values;
+
+    // trampoline : Trampoline a -> a
+    function trampoline(t) {
+        var tramp = t;
+        while(true) {
+            switch(tramp.ctor) {
+            case "Done":
+                return tramp._0;
+            case "Continue":
+                tramp = tramp._0({ctor: "_Tuple0"});
+                continue;
+            }
+        }
+    }
+
+    return elm.Native.Trampoline.values = {
+        trampoline:trampoline
+    };
+};
+Elm.Native.Transform2D = {};
+Elm.Native.Transform2D.make = function(elm) {
+
+ elm.Native = elm.Native || {};
+ elm.Native.Transform2D = elm.Native.Transform2D || {};
+ if (elm.Native.Transform2D.values) return elm.Native.Transform2D.values;
+
+ var A;
+ if (typeof Float32Array === 'undefined') {
+     A = function(arr) {
+         this.length = arr.length;
+         this[0] = arr[0];
+         this[1] = arr[1];
+         this[2] = arr[2];
+         this[3] = arr[3];
+         this[4] = arr[4];
+         this[5] = arr[5];
+     };
+ } else {
+     A = Float32Array;
+ }
+
+ // layout of matrix in an array is
+ //
+ //   | m11 m12 dx |
+ //   | m21 m22 dy |
+ //   |  0   0   1 |
+ //
+ //  new A([ m11, m12, dx, m21, m22, dy ])
+
+ var identity = new A([1,0,0,0,1,0]);
+ function matrix(m11, m12, m21, m22, dx, dy) {
+     return new A([m11, m12, dx, m21, m22, dy]);
+ }
+ function rotation(t) {
+     var c = Math.cos(t);
+     var s = Math.sin(t);
+     return new A([c, -s, 0, s, c, 0]);
+ }
+ function rotate(t,m) {
+     var c = Math.cos(t);
+     var s = Math.sin(t);
+     var m11 = m[0], m12 = m[1], m21 = m[3], m22 = m[4];
+     return new A([m11*c + m12*s, -m11*s + m12*c, m[2],
+                   m21*c + m22*s, -m21*s + m22*c, m[5]]);
+ }
+ /*
+ function move(xy,m) {
+     var x = xy._0;
+     var y = xy._1;
+     var m11 = m[0], m12 = m[1], m21 = m[3], m22 = m[4];
+     return new A([m11, m12, m11*x + m12*y + m[2],
+                   m21, m22, m21*x + m22*y + m[5]]);
+ }
+ function scale(s,m) { return new A([m[0]*s, m[1]*s, m[2], m[3]*s, m[4]*s, m[5]]); }
+ function scaleX(x,m) { return new A([m[0]*x, m[1], m[2], m[3]*x, m[4], m[5]]); }
+ function scaleY(y,m) { return new A([m[0], m[1]*y, m[2], m[3], m[4]*y, m[5]]); }
+ function reflectX(m) { return new A([-m[0], m[1], m[2], -m[3], m[4], m[5]]); }
+ function reflectY(m) { return new A([m[0], -m[1], m[2], m[3], -m[4], m[5]]); }
+
+ function transform(m11, m21, m12, m22, mdx, mdy, n) {
+     var n11 = n[0], n12 = n[1], n21 = n[3], n22 = n[4], ndx = n[2], ndy = n[5];
+     return new A([m11*n11 + m12*n21,
+                   m11*n12 + m12*n22,
+                   m11*ndx + m12*ndy + mdx,
+                   m21*n11 + m22*n21,
+                   m21*n12 + m22*n22,
+                   m21*ndx + m22*ndy + mdy]);
+ }
+ */
+ function multiply(m, n) {
+     var m11 = m[0], m12 = m[1], m21 = m[3], m22 = m[4], mdx = m[2], mdy = m[5];
+     var n11 = n[0], n12 = n[1], n21 = n[3], n22 = n[4], ndx = n[2], ndy = n[5];
+     return new A([m11*n11 + m12*n21,
+                   m11*n12 + m12*n22,
+                   m11*ndx + m12*ndy + mdx,
+                   m21*n11 + m22*n21,
+                   m21*n12 + m22*n22,
+                   m21*ndx + m22*ndy + mdy]);
+ }
+
+ return elm.Native.Transform2D.values = {
+     identity:identity,
+     matrix:F6(matrix),
+     rotation:rotation,
+     multiply:F2(multiply)
+     /*
+     transform:F7(transform),
+     rotate:F2(rotate),
+     move:F2(move),
+     scale:F2(scale),
+     scaleX:F2(scaleX),
+     scaleY:F2(scaleY),
+     reflectX:reflectX,
+     reflectY:reflectY
+     */
+ };
+
+};
+Elm.Native.Utils = {};
+Elm.Native.Utils.make = function(elm) {
+
+    elm.Native = elm.Native || {};
+    elm.Native.Utils = elm.Native.Utils || {};
+    if (elm.Native.Utils.values) return elm.Native.Utils.values;
+
+    function eq(l,r) {
+        var stack = [{'x': l, 'y': r}]
+        while (stack.length > 0) {
+            var front = stack.pop();
+            var x = front.x;
+            var y = front.y;
+            if (x === y) continue;
+            if (typeof x === "object") {
+                var c = 0;
+                for (var i in x) {
+                    ++c;
+                    if (i in y) {
+                        if (i !== 'ctor') {
+                            stack.push({ 'x': x[i], 'y': y[i] });
+                        }
+                    } else {
+                        return false;
+                    }
+                }
+                if ('ctor' in x) {
+                    stack.push({'x': x.ctor, 'y': y.ctor});
+                }
+                if (c !== Object.keys(y).length) {
+                    return false;
+                };
+            } else if (typeof x === 'function') {
+                throw new Error('Equality error: general function equality is ' +
+                                'undecidable, and therefore, unsupported');
+            } else {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    // code in Generate/JavaScript.hs depends on the particular
+    // integer values assigned to LT, EQ, and GT
+    var LT = -1, EQ = 0, GT = 1, ord = ['LT','EQ','GT'];
+    function compare(x,y) { return { ctor: ord[cmp(x,y)+1] } }
+    function cmp(x,y) {
+        var ord;
+        if (typeof x !== 'object'){
+            return x === y ? EQ : x < y ? LT : GT;
+        }
+        else if (x.isChar){
+            var a = x.toString();
+            var b = y.toString();
+            return a === b ? EQ : a < b ? LT : GT;
+        }
+        else if (x.ctor === "::" || x.ctor === "[]") {
+            while (true) {
+                if (x.ctor === "[]" && y.ctor === "[]") return EQ;
+                if (x.ctor !== y.ctor) return x.ctor === '[]' ? LT : GT;
+                ord = cmp(x._0, y._0);
+                if (ord !== EQ) return ord;
+                x = x._1;
+                y = y._1;
+            }
+        }
+        else if (x.ctor.slice(0,6) === '_Tuple') {
+            var n = x.ctor.slice(6) - 0;
+            var err = 'cannot compare tuples with more than 6 elements.';
+            if (n === 0) return EQ;
+            if (n >= 1) { ord = cmp(x._0, y._0); if (ord !== EQ) return ord;
+            if (n >= 2) { ord = cmp(x._1, y._1); if (ord !== EQ) return ord;
+            if (n >= 3) { ord = cmp(x._2, y._2); if (ord !== EQ) return ord;
+            if (n >= 4) { ord = cmp(x._3, y._3); if (ord !== EQ) return ord;
+            if (n >= 5) { ord = cmp(x._4, y._4); if (ord !== EQ) return ord;
+            if (n >= 6) { ord = cmp(x._5, y._5); if (ord !== EQ) return ord;
+            if (n >= 7) throw new Error('Comparison error: ' + err); } } } } } }
+            return EQ;
+        }
+        else {
+            throw new Error('Comparison error: comparison is only defined on ints, ' +
+                            'floats, times, chars, strings, lists of comparable values, ' +
+                            'and tuples of comparable values.');
+        }
+    }
+
+
+    var Tuple0 = { ctor: "_Tuple0" };
+    function Tuple2(x,y) { return { ctor:"_Tuple2", _0:x, _1:y } }
+
+    function chr(c) {
+        var x = new String(c);
+        x.isChar = true;
+        return x;
+    }
+
+    function txt(str) {
+        var t = new String(str);
+        t.text = true;
+        return t;
+    }
+
+    function makeText(text) {
+        var style = '';
+        var href = '';
+        while (true) {
+            if (text.style) {
+                style += text.style;
+                text = text.text;
+                continue;
+            }
+            if (text.href) {
+                href = text.href;
+                text = text.text;
+                continue;
+            }
+            if (href) text = '<a href="' + href + '">' + text + '</a>';
+            if (style) text = '<span style="' + style + '">' + text + '</span>';
+            return text;
+        }
+    }
+
+    var count = 0;
+    function guid(_) { return count++ }
+
+    function copy(oldRecord) {
+        var newRecord = {};
+        for (var key in oldRecord) {
+            var value = key === '_'
+                ? copy(oldRecord._)
+                : oldRecord[key]
+                ;
+            newRecord[key] = value;
+        }
+        return newRecord;
+    }
+
+    function remove(key, oldRecord) {
+        var record = copy(oldRecord);
+        if (key in record._) {
+            record[key] = record._[key][0];
+            record._[key] = record._[key].slice(1);
+            if (record._[key].length === 0) {
+                delete record._[key];
+            }
+        } else {
+            delete record[key];
+        }
+        return record;
+    }
+
+    function replace(keyValuePairs, oldRecord) {
+        var record = copy(oldRecord);
+        for (var i = keyValuePairs.length; i--; ) {
+            var pair = keyValuePairs[i];
+            record[pair[0]] = pair[1];
+        }
+        return record;
+    }
+
+    function insert(key, value, oldRecord) {
+        var newRecord = copy(oldRecord);
+        if (key in newRecord) {
+            var values = newRecord._[key];
+            var copiedValues = values ? values.slice(0) : [];
+            newRecord._[key] = [newRecord[key]].concat(copiedValues);
+        }
+        newRecord[key] = value;
+        return newRecord;
+    }
+
+    function max(a,b) { return a > b ? a : b }
+    function min(a,b) { return a < b ? a : b }
+
+    function mod(a,b) {
+        if (b === 0) {
+            throw new Error("Cannot perform mod 0. Division by zero error.");
+        }
+        var r = a % b;
+        var m = a === 0 ? 0 : (b > 0 ? (a >= 0 ? r : r+b) : -mod(-a,-b));
+
+        return m === b ? 0 : m;
+    }
+
+    function htmlHeight(width, rawHtml) {
+        // create dummy node
+        var html = rawHtml.html;
+        var t = document.createElement('div');
+        t.innerHTML = html;
+        if (width > 0) { t.style.width = width + "px"; }
+        t.style.visibility = "hidden";
+        t.style.styleFloat = "left";
+        t.style.cssFloat   = "left";
+
+        document.body.appendChild(t);
+
+        // insert interpolated values
+        var args = rawHtml.args;
+        var guid = rawHtml.guid;
+        for (var i = args.length; i--; ) {
+            var arg = args[i];
+            var span = document.getElementById('md-' + guid + '-' + i);
+            if (arg.isElement) {
+                span.style.width = arg.props.width + 'px';
+                span.style.height = arg.props.height + 'px';
+            } else {
+                span.innerHTML = arg;
+            }
+        }
+
+        // get dimensions
+        var style = window.getComputedStyle(t, null);
+        var w = Math.ceil(style.getPropertyValue("width").slice(0,-2) - 0);
+        var h = Math.ceil(style.getPropertyValue("height").slice(0,-2) - 0);
+        document.body.removeChild(t);
+        return Tuple2(w,h);
+    }
+
+    function getXY(e) {
+        var posx = 0;
+        var posy = 0;
+        if (e.pageX || e.pageY) {
+            posx = e.pageX;
+            posy = e.pageY;
+        } else if (e.clientX || e.clientY) {
+            posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
+            posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
+        }
+
+        if (elm.display === ElmRuntime.Display.COMPONENT) {
+            var rect = elm.node.getBoundingClientRect();
+            var relx = rect.left + document.body.scrollLeft + document.documentElement.scrollLeft;
+            var rely = rect.top + document.body.scrollTop + document.documentElement.scrollTop;
+            // TODO: figure out if there is a way to avoid rounding here
+            posx = posx - Math.round(relx) - elm.node.clientLeft;
+            posy = posy - Math.round(rely) - elm.node.clientTop;
+        }
+        return Tuple2(posx, posy);
+    }
+
+    function isJSArray(a) {
+        return a instanceof Array;
+    }
+
+    return elm.Native.Utils.values = {
+        eq:eq,
+        cmp:cmp,
+        compare:F2(compare),
+        Tuple0:Tuple0,
+        Tuple2:Tuple2,
+        chr:chr,
+        txt:txt,
+        makeText:makeText,
+        copy: copy,
+        remove: remove,
+        replace: replace,
+        insert: insert,
+        guid: guid,
+        max : F2(max),
+        min : F2(min),
+        mod : F2(mod),
+        htmlHeight: F2(htmlHeight),
+        getXY: getXY,
+        isJSArray: isJSArray,
+        toFloat: function(x) { return +x; }
+    };
+};
+Elm.Native.Graphics.Collage = {};
+Elm.Native.Graphics.Collage.make = function(elm) {
+
+ elm.Native = elm.Native || {};
+ elm.Native.Graphics = elm.Native.Graphics || {};
+ elm.Native.Graphics.Collage = elm.Native.Graphics.Collage || {};
+ if (elm.Native.Graphics.Collage.values) return elm.Native.Graphics.Collage.values;
+
+ var newElement = Elm.Graphics.Element.make(elm).newElement;
+ var C = ElmRuntime.use(ElmRuntime.Render.Collage);
+
+ function collage(w,h,forms) {
+     return A3(newElement, w, h, {
+                 ctor: 'Custom',
+		 type: 'Collage',
+		 render: C.render,
+		 update: C.update,
+		 model: {w:w, h:h, forms:forms}
+	 });
+ }
+ return elm.Native.Graphics.Collage.values = { collage:F3(collage) };
+
+};Elm.Native.Graphics.Input = {};
+Elm.Native.Graphics.Input.make = function(elm) {
+    elm.Native = elm.Native || {};
+    elm.Native.Graphics = elm.Native.Graphics || {};
+    elm.Native.Graphics.Input = elm.Native.Graphics.Input || {};
+    if (elm.Native.Graphics.Input.values) return elm.Native.Graphics.Input.values;
+
+    var Render = ElmRuntime.use(ElmRuntime.Render.Element);
+    var newNode = ElmRuntime.use(ElmRuntime.Render.Utils).newElement;
+
+    var toCss = Elm.Native.Color.make(elm).toCss;
+    var Text = Elm.Native.Text.make(elm);
+    var Signal = Elm.Signal.make(elm);
+    var newElement = Elm.Graphics.Element.make(elm).newElement;
+    var List = Elm.Native.List.make(elm);
+    var Utils = Elm.Native.Utils.make(elm);
+    var Tuple2 = Utils.Tuple2;
+
+    function input(initialValue) {
+        var signal = Signal.constant(initialValue);
+        return { _:{}, signal:signal, handle:signal };
+    }
+
+    function renderDropDown(model) {
+        var drop = newNode('select');
+        drop.style.border = '0 solid';
+        drop.style.pointerEvents = 'auto';
+        drop.style.display = 'block';
+
+        drop.elm_signal = model.signal;
+        drop.elm_values = List.toArray(model.values);
+        var values = drop.elm_values;
+
+        for (var i = 0; i < values.length; ++i) {
+            var option = newNode('option');
+            var name = values[i]._0;
+            option.value = name;
+            option.innerHTML = name;
+            drop.appendChild(option);
+        }
+        drop.addEventListener('change', function() {
+            elm.notify(drop.elm_signal.id, drop.elm_values[drop.selectedIndex]._1);
+        });
+
+        return drop;
+    }
+
+    function updateDropDown(node, oldModel, newModel) {
+        node.elm_signal = newModel.signal;
+        node.elm_values = List.toArray(newModel.values);
+
+        var values = node.elm_values;
+        var kids = node.childNodes;
+        var kidsLength = kids.length;
+
+        var i = 0;
+        for (; i < kidsLength && i < values.length; ++i) {
+            var option = kids[i];
+            var name = values[i]._0;
+            option.value = name;
+            option.innerHTML = name;
+        }
+        for (; i < kidsLength; ++i) {
+            node.removeChild(node.lastChild);
+        }
+        for (; i < values.length; ++i) {
+            var option = newNode('option');
+            var name = values[i]._0;
+            option.value = name;
+            option.innerHTML = name;
+            node.appendChild(option);
+        }
+    }
+
+    function dropDown(signal, values) {
+        return A3(newElement, 100, 24, {
+            ctor: 'Custom',
+            type: 'DropDown',
+            render: renderDropDown,
+            update: updateDropDown,
+            model: {
+                signal: signal,
+                values: values
+            }
+        });
+    }
+
+    function renderButton(model) {
+        var node = newNode('button');
+        node.style.display = 'block';
+        node.style.pointerEvents = 'auto';
+        node.elm_signal = model.signal;
+        node.elm_value = model.value;
+        function click() {
+            elm.notify(node.elm_signal.id, node.elm_value);
+        }
+        node.addEventListener('click', click);
+        node.innerHTML = model.text;
+        return node;
+    }
+
+    function updateButton(node, oldModel, newModel) {
+        node.elm_signal = newModel.signal;
+        node.elm_value = newModel.value;
+        var txt = newModel.text;
+        if (oldModel.text !== txt) node.innerHTML = txt;
+    }
+
+    function button(signal, value, text) {
+        return A3(newElement, 100, 40, {
+            ctor: 'Custom',
+            type: 'Button',
+            render: renderButton,
+            update: updateButton,
+            model: { signal:signal, value:value, text:text }
+        });
+    }
+
+    function renderCustomButton(model) {
+        var btn = newNode('div');
+        btn.style.pointerEvents = 'auto';
+        btn.elm_signal = model.signal;
+        btn.elm_value = model.value;
+
+        btn.elm_up    = Render.render(model.up);
+        btn.elm_hover = Render.render(model.hover);
+        btn.elm_down  = Render.render(model.down);
+
+        btn.elm_up.style.display = 'block';
+        btn.elm_hover.style.display = 'none';
+        btn.elm_down.style.display = 'none';
+  
+        btn.appendChild(btn.elm_up);
+        btn.appendChild(btn.elm_hover);
+        btn.appendChild(btn.elm_down);
+
+        function swap(visibleNode, hiddenNode1, hiddenNode2) {
+            visibleNode.style.display = 'block';
+            hiddenNode1.style.display = 'none';
+            hiddenNode2.style.display = 'none';
+        }
+
+        var overCount = 0;
+        function over(e) {
+            if (overCount++ > 0) return;
+            swap(btn.elm_hover, btn.elm_down, btn.elm_up);
+        }
+        function out(e) {
+            if (btn.contains(e.toElement || e.relatedTarget)) return;
+            overCount = 0;
+            swap(btn.elm_up, btn.elm_down, btn.elm_hover);
+        }
+        function up() {
+            swap(btn.elm_hover, btn.elm_down, btn.elm_up);
+            elm.notify(btn.elm_signal.id, btn.elm_value);
+        }
+        function down() {
+            swap(btn.elm_down, btn.elm_hover, btn.elm_up);
+        }
+
+        btn.addEventListener('mouseover', over);
+        btn.addEventListener('mouseout' , out);
+        btn.addEventListener('mousedown', down);
+        btn.addEventListener('mouseup'  , up);
+
+        return btn;
+    }
+
+    function updateCustomButton(node, oldModel, newModel) {
+        node.elm_signal = newModel.signal;
+        node.elm_value = newModel.value;
+
+        var kids = node.childNodes;
+        var styleUp    = kids[0].style.display;
+        var styleHover = kids[1].style.display;
+        var styleDown  = kids[2].style.display;
+
+        Render.update(kids[0], oldModel.up, newModel.up);
+        Render.update(kids[1], oldModel.hover, newModel.hover);
+        Render.update(kids[2], oldModel.down, newModel.down);
+
+        var kids = node.childNodes;
+        kids[0].style.display = styleUp;
+        kids[1].style.display = styleHover;
+        kids[2].style.display = styleDown;
+    }
+
+    function max3(a,b,c) {
+        var ab = a > b ? a : b;
+        return ab > c ? ab : c;
+    }
+
+    function customButton(signal, value, up, hover, down) {
+        return A3(newElement,
+                  max3(up.props.width, hover.props.width, down.props.width),
+                  max3(up.props.height, hover.props.height, down.props.height),
+                  { ctor: 'Custom',
+                    type: 'CustomButton',
+                    render: renderCustomButton,
+                    update: updateCustomButton,
+                    model: { signal:signal, value:value, up:up, hover:hover, down:down }
+                  });
+    }
+
+    function renderCheckbox(model) {
+        var node = newNode('input');
+        node.type = 'checkbox';
+        node.checked = model.checked;
+        node.style.display = 'block';
+        node.style.pointerEvents = 'auto';
+        node.elm_signal = model.signal;
+        node.elm_handler = model.handler;
+        function change() {
+            elm.notify(node.elm_signal.id, node.elm_handler(node.checked));
+        }
+        node.addEventListener('change', change);
+        return node;
+    }
+
+    function updateCheckbox(node, oldModel, newModel) {
+        node.elm_signal = newModel.signal;
+        node.elm_handler = newModel.handler;
+        node.checked = newModel.checked;
+        return true;
+    }
+
+    function checkbox(signal, handler, checked) {
+        return A3(newElement, 13, 13, {
+            ctor: 'Custom',
+            type: 'CheckBox',
+            render: renderCheckbox,
+            update: updateCheckbox,
+            model: { signal:signal, handler:handler, checked:checked }
+        });
+    }
+
+    function setRange(node, start, end, dir) {
+        if (node.parentNode) {
+            node.setSelectionRange(start, end, dir);
+        } else {
+            setTimeout(function(){node.setSelectionRange(start, end, dir);}, 0);
+        }
+    }
+
+    function updateIfNeeded(css, attribute, latestAttribute) {
+        if (css[attribute] !== latestAttribute) {
+            css[attribute] = latestAttribute;
+        }
+    }
+    function cssDimensions(dimensions) {
+        return dimensions.top    + 'px ' +
+               dimensions.right  + 'px ' +
+               dimensions.bottom + 'px ' +
+               dimensions.left   + 'px';
+    }
+    function updateFieldStyle(css, style) {
+        updateIfNeeded(css, 'padding', cssDimensions(style.padding));
+
+        var outline = style.outline;
+        updateIfNeeded(css, 'border-width', cssDimensions(outline.width));
+        updateIfNeeded(css, 'border-color', toCss(outline.color));
+        updateIfNeeded(css, 'border-radius', outline.radius + 'px');
+
+        var highlight = style.highlight;
+        if (highlight.width === 0) {
+            css.outline = 'none';
+        } else {
+            updateIfNeeded(css, 'outline-width', highlight.width + 'px');
+            updateIfNeeded(css, 'outline-color', toCss(highlight.color));
+        }
+
+        var textStyle = style.style;
+        updateIfNeeded(css, 'color', toCss(textStyle.color));
+        if (textStyle.typeface.ctor !== '[]') {
+            updateIfNeeded(css, 'font-family', Text.toTypefaces(textStyle.typeface));
+        }
+        if (textStyle.height.ctor !== "Nothing") {
+            updateIfNeeded(css, 'font-size', textStyle.height._0 + 'px');
+        }
+        updateIfNeeded(css, 'font-weight', textStyle.bold ? 'bold' : 'normal');
+        updateIfNeeded(css, 'font-style', textStyle.italic ? 'italic' : 'normal');
+        if (textStyle.line.ctor !== 'Nothing') {
+            updateIfNeeded(css, 'text-decoration', Text.toLine(textStyle.line._0));
+        }
+    }
+
+    function renderField(model) {
+        var field = newNode('input');
+        updateFieldStyle(field.style, model.style);
+        field.style.borderStyle = 'solid';
+        field.style.pointerEvents = 'auto';
+
+        field.type = model.type;
+        field.placeholder = model.placeHolder;
+        field.value = model.content.string;
+
+        field.elm_signal = model.signal;
+        field.elm_handler = model.handler;
+        field.elm_old_value = field.value;
+
+        function inputUpdate(event) {
+            var curr = field.elm_old_value;
+            var next = field.value;
+            if (curr === next) {
+                return;
+            }
+
+            var direction = field.selectionDirection === 'forward' ? 'Forward' : 'Backward';
+            var start = field.selectionStart;
+            var end = field.selectionEnd;
+            field.value = field.elm_old_value;
+
+            elm.notify(field.elm_signal.id, field.elm_handler({
+                _:{},
+                string: next,
+                selection: {
+                    _:{},
+                    start: start,
+                    end: end,
+                    direction: { ctor: direction }
+                }
+            }));
+        }
+
+        field.addEventListener('input', inputUpdate);
+        field.addEventListener('focus', function() {
+            field.elm_hasFocus = true;
+        });
+        field.addEventListener('blur', function() {
+            field.elm_hasFocus = false;
+        });
+
+        return field;
+    }
+
+    function updateField(field, oldModel, newModel) {
+        if (oldModel.style !== newModel.style) {
+            updateFieldStyle(field.style, newModel.style);
+        }
+        field.elm_signal = newModel.signal;
+        field.elm_handler = newModel.handler;
+
+        field.type = newModel.type;
+        field.placeholder = newModel.placeHolder;
+        var value = newModel.content.string;
+        field.value = value;
+        field.elm_old_value = value;
+        if (field.elm_hasFocus) {
+            var selection = newModel.content.selection;
+            var direction = selection.direction.ctor === 'Forward' ? 'forward' : 'backward';
+            setRange(field, selection.start, selection.end, direction);
+        }
+    }
+
+    function mkField(type) {
+        function field(style, signal, handler, placeHolder, content) {
+            var padding = style.padding;
+            var outline = style.outline.width;
+            var adjustWidth = padding.left + padding.right + outline.left + outline.right;
+            var adjustHeight = padding.top + padding.bottom + outline.top + outline.bottom;
+            return A3(newElement, 200, 30, {
+                ctor: 'Custom',
+                type: type + 'Field',
+                adjustWidth: adjustWidth,
+                adjustHeight: adjustHeight,
+                render: renderField,
+                update: updateField,
+                model: {
+                    signal:signal,
+                    handler:handler,
+                    placeHolder:placeHolder,
+                    content:content,
+                    style:style,
+                    type:type
+                }
+            });
+        }
+        return F5(field);
+    }
+
+    function hoverable(signal, handler, elem) {
+        function onHover(bool) {
+            elm.notify(signal.id, handler(bool));
+        }
+        var props = Utils.replace([['hover',onHover]], elem.props);
+        return { props:props, element:elem.element };
+    }
+
+    function clickable(signal, value, elem) {
+        function onClick(bool) {
+            elm.notify(signal.id, value);
+        }
+        var props = Utils.replace([['click',onClick]], elem.props);
+        return { props:props, element:elem.element };
+    }
+
+    return elm.Native.Graphics.Input.values = {
+        input:input,
+        button:F3(button),
+        customButton:F5(customButton),
+        checkbox:F3(checkbox),
+        dropDown:F2(dropDown),
+        field:mkField('text'),
+        email:mkField('email'),
+        password:mkField('password'),
+        hoverable:F3(hoverable),
+        clickable:F3(clickable)
+    };
+
+};
+Elm.Native.Http = {};
+Elm.Native.Http.make = function(elm) {
+
+    elm.Native = elm.Native || {};
+    elm.Native.Http = elm.Native.Http || {};
+    if (elm.Native.Http.values) return elm.Native.Http.values;
+
+    var List = Elm.List.make(elm);
+    var Signal = Elm.Signal.make(elm);
+
+    function registerReq(queue,responses) {
+        return function(req) {
+            if (req.url.length > 0) {
+                sendReq(queue,responses,req);
+            }
+        };
+    }
+
+    function updateQueue(queue,responses) {
+        if (queue.length > 0) {
+            elm.notify(responses.id, queue[0].value);
+            if (queue[0].value.ctor !== 'Waiting') {
+                queue.shift();
+                setTimeout(function() { updateQueue(queue,responses); }, 0);
+            }
+        }
+    }
+
+    function sendReq(queue,responses,req) {
+        var response = { value: { ctor:'Waiting' } };
+        queue.push(response);
+
+        var request = (window.ActiveXObject
+                       ? new ActiveXObject("Microsoft.XMLHTTP")
+                       : new XMLHttpRequest());
+
+        request.onreadystatechange = function(e) {
+            if (request.readyState === 4) {
+                response.value = (request.status >= 200 && request.status < 300 ?
+                                  { ctor:'Success', _0:request.responseText } :
+                                  { ctor:'Failure', _0:request.status, _1:request.statusText });
+                setTimeout(function() { updateQueue(queue,responses); }, 0);
+            }
+        };
+        request.open(req.verb, req.url, true);
+        function setHeader(pair) {
+            request.setRequestHeader( pair._0, pair._1 );
+        }
+        A2( List.map, setHeader, req.headers );
+        request.send(req.body);
+    }
+
+    function send(requests) {
+        var responses = Signal.constant(elm.Http.values.Waiting);
+        var sender = A2( Signal.lift, registerReq([],responses), requests );
+        function f(x) { return function(y) { return x; } }
+        return A3( Signal.lift2, f, responses, sender );
+    }
+
+    return elm.Native.Http.values = {
+        send:send
+    };
+};
+Elm.Native.Keyboard = {};
+Elm.Native.Keyboard.make = function(elm) {
+
+    elm.Native = elm.Native || {};
+    elm.Native.Keyboard = elm.Native.Keyboard || {};
+    if (elm.Native.Keyboard.values) return elm.Native.Keyboard.values;
+
+    // Duplicated from Native.Signal
+    function send(node, timestep, changed) {
+        var kids = node.kids;
+        for (var i = kids.length; i--; ) {
+            kids[i].recv(timestep, changed, node.id);
+        }
+    }
+
+    var Signal = Elm.Signal.make(elm);
+    var NList = Elm.Native.List.make(elm);
+    var Utils = Elm.Native.Utils.make(elm);
+
+    var downEvents = Signal.constant(null);
+    var upEvents = Signal.constant(null);
+    var blurEvents = Signal.constant(null);
+
+    elm.addListener([downEvents.id], document, 'keydown', function down(e) {
+        elm.notify(downEvents.id, e);
+    });
+
+    elm.addListener([upEvents.id], document, 'keyup', function up(e) {
+        elm.notify(upEvents.id, e);
+    });
+
+    elm.addListener([blurEvents.id], window, 'blur', function blur(e) {
+        elm.notify(blurEvents.id, null);
+    });
+
+    function state(alt, meta, keyCodes) {
+        return {
+            alt: alt,
+            meta: meta,
+            keyCodes: keyCodes
+        };
+    }
+    var emptyState = state(false, false, NList.Nil);
+
+    function KeyMerge(down, up, blur) {
+        var args = [down,up,blur];
+        this.id = Utils.guid();
+        // Ignore starting values here
+        this.value = emptyState;
+        this.kids = [];
+        
+        var n = args.length;
+        var count = 0;
+        var isChanged = false;
+
+        this.recv = function(timestep, changed, parentID) {
+            ++count;
+            if (changed) { 
+                // We know this a change must only be one of the following cases
+                if (parentID === down.id && !A2(NList.member, down.value.keyCode, this.value.keyCodes)) {
+                    isChanged = true;
+                    var v = down.value;
+                    var newCodes = NList.Cons(v.keyCode, this.value.keyCodes);
+                    this.value = state(v.altKey, v.metaKey, newCodes);
+                }
+                else if (parentID === up.id) {
+                    isChanged = true;
+                    var v = up.value;
+                    var notEq = function(kc) { return kc !== v.keyCode };
+                    var newCodes = A2(NList.filter, notEq, this.value.keyCodes);
+                    this.value = state(v.altKey, v.metaKey, newCodes);
+                }
+                else if (parentID === blur.id) {
+                    isChanged = true;
+                    this.value = emptyState;
+                }
+            }
+            if (count == n) {
+                send(this, timestep, isChanged);
+                isChanged = false;
+                count = 0;
+            }
+        };
+
+        for (var i = n; i--; ) {
+            args[i].kids.push(this);
+            args[i].defaultNumberOfKids += 1;
+        }
+    }
+
+    var keyMerge = new KeyMerge(downEvents,upEvents,blurEvents);
+
+    // select a part of a keyMerge and dropRepeats the result
+    function keySignal(f) {
+        var signal = A2(Signal.lift, f, keyMerge);
+        // must set the default number of kids to make it possible to filter
+        // these signals if they are not actually used.
+        keyMerge.defaultNumberOfKids += 1;
+        signal.defaultNumberOfKids = 1;
+        var filtered = Signal.dropRepeats(signal);
+        filtered.defaultNumberOfKids = 0;
+        return filtered;
+    }
+
+    // break keyMerge into parts
+    var keysDown = keySignal(function getKeyCodes(v) {
+        return v.keyCodes;
+    });
+    var alt = keySignal(function getKeyCodes(v) {
+        return v.alt;
+    });
+    var meta = keySignal(function getKeyCodes(v) {
+        return v.meta;
+    });
+
+    function dir(up, down, left, right) {
+        function toDirections(state) {
+            var keyCodes = state.keyCodes;
+            var x = 0, y = 0;
+            while (keyCodes.ctor === "::") {
+                switch (keyCodes._0) {
+                case left : --x; break;
+                case right: ++x; break;
+                case up   : ++y; break;
+                case down : --y; break;
+                }
+                keyCodes = keyCodes._1;
+            }
+            return { _:{}, x:x, y:y };
+        }
+        return keySignal(toDirections);
+    }
+
+    function is(key) {
+        return keySignal(function(v) {
+            return A2( NList.member, key, v.keyCodes );
+        });
+    }
+
+    var lastPressed = A2(Signal.lift, function(e) {
+        return e ? e.keyCode : 0;
+    }, downEvents);
+    downEvents.defaultNumberOfKids += 1;
+
+    return elm.Native.Keyboard.values = {
+        isDown:is,
+        alt: alt,
+        meta: meta,
+        directions:F4(dir),
+        keysDown:keysDown,
+        lastPressed:lastPressed
+    };
+
+};
+Elm.Native.Mouse = {};
+Elm.Native.Mouse.make = function(elm) {
+
+    elm.Native = elm.Native || {};
+    elm.Native.Mouse = elm.Native.Mouse || {};
+    if (elm.Native.Mouse.values) return elm.Native.Mouse.values;
+
+    var Signal = Elm.Signal.make(elm);
+    var Utils = Elm.Native.Utils.make(elm);
+
+    var position  = Signal.constant(Utils.Tuple2(0,0));
+    position.defaultNumberOfKids = 2;
+
+    // do not move x and y into Elm. By setting their default number
+    // of kids, it is possible to detatch the mouse listeners if
+    // they are not needed.
+    var x = A2( Signal.lift, function(p){return p._0}, position);
+    x.defaultNumberOfKids = 0;
+    var y = A2( Signal.lift, function(p){return p._1}, position);
+    y.defaultNumberOfKids = 0;
+
+    var isDown    = Signal.constant(false);
+    var clicks = Signal.constant(Utils.Tuple0);
+
+    var node = elm.display === ElmRuntime.Display.FULLSCREEN ? document : elm.node;
+
+    elm.addListener([clicks.id], node, 'click', function click() {
+        elm.notify(clicks.id, Utils.Tuple0);
+    });
+    elm.addListener([isDown.id], node, 'mousedown', function down() {
+        elm.notify(isDown.id, true);
+    });
+    elm.addListener([isDown.id], node, 'mouseup', function up() {
+        elm.notify(isDown.id, false);
+    });
+    elm.addListener([position.id], node, 'mousemove', function move(e) {
+        elm.notify(position.id, Utils.getXY(e));
+    });
+
+    return elm.Native.Mouse.values = {
+        position: position,
+        x:x,
+        y:y,
+        isDown: isDown,
+        clicks: clicks
+    };
+};
+Elm.Native.Random = {};
+Elm.Native.Random.make = function(elm) {
+
+    elm.Native = elm.Native || {};
+    elm.Native.Random = elm.Native.Random || {};
+    if (elm.Native.Random.values) return elm.Native.Random.values;
+
+    var Signal = Elm.Signal.make(elm);
+    var List = Elm.Native.List.make(elm);
+
+    function range(min, max, signal) {
+        function f(x) { return Math.floor(Math.random() * (max-min+1)) + min; }
+        return A2( Signal.lift, f, signal );
+    }
+
+    function float_(signal) {
+        function f(x) { return Math.random(); }
+        return A2( Signal.lift, f, signal );
+    }
+
+    function floatList(signal) {
+        function f(n) {
+            if (n < 0) return List.Nil;
+            var arr = new Array(n);
+            for (var i = n; i--; ) {
+                arr[i] = Math.random();
+            }
+            return List.fromArray(arr);
+        }
+        return A2( Signal.lift, f, signal );
+    }
+
+    return elm.Native.Random.values = {
+        range: F3(range),
+        float_: float_,
+        floatList: floatList
+    };
+
+};
+
+Elm.Native.Signal = {};
+Elm.Native.Signal.make = function(elm) {
+
+  elm.Native = elm.Native || {};
+  elm.Native.Signal = elm.Native.Signal || {};
+  if (elm.Native.Signal.values) return elm.Native.Signal.values;
+
+  var Utils = Elm.Native.Utils.make(elm);
+  var foldr1 = Elm.List.make(elm).foldr1;
+
+  function send(node, timestep, changed) {
+    var kids = node.kids;
+    for (var i = kids.length; i--; ) {
+      kids[i].recv(timestep, changed, node.id);
+    }
+  }
+
+  function Input(base) {
+    this.id = Utils.guid();
+    this.value = base;
+    this.kids = [];
+    this.defaultNumberOfKids = 0;
+    this.recv = function(timestep, eid, v) {
+      var changed = eid === this.id;
+      if (changed) { this.value = v; }
+      send(this, timestep, changed);
+      return changed;
+    };
+    elm.inputs.push(this);
+  }
+
+  function LiftN(update, args) {
+    this.id = Utils.guid();
+    this.value = update();
+    this.kids = [];
+
+    var n = args.length;
+    var count = 0;
+    var isChanged = false;
+
+    this.recv = function(timestep, changed, parentID) {
+      ++count;
+      if (changed) { isChanged = true; }
+      if (count == n) {
+        if (isChanged) { this.value = update(); }
+        send(this, timestep, isChanged);
+        isChanged = false;
+        count = 0;
+      }
+    };
+    for (var i = n; i--; ) { args[i].kids.push(this); }
+  }
+
+  function lift(func, a) {
+    function update() { return func(a.value); }
+    return new LiftN(update, [a]);
+  }
+  function lift2(func, a, b) {
+    function update() { return A2( func, a.value, b.value ); }
+    return new LiftN(update, [a,b]);
+  }
+  function lift3(func, a, b, c) {
+    function update() { return A3( func, a.value, b.value, c.value ); }
+    return new LiftN(update, [a,b,c]);
+  }
+  function lift4(func, a, b, c, d) {
+    function update() { return A4( func, a.value, b.value, c.value, d.value ); }
+    return new LiftN(update, [a,b,c,d]);
+  }
+  function lift5(func, a, b, c, d, e) {
+    function update() { return A5( func, a.value, b.value, c.value, d.value, e.value ); }
+    return new LiftN(update, [a,b,c,d,e]);
+  }
+  function lift6(func, a, b, c, d, e, f) {
+    function update() { return A6( func, a.value, b.value, c.value, d.value, e.value, f.value ); }
+    return new LiftN(update, [a,b,c,d,e,f]);
+  }
+  function lift7(func, a, b, c, d, e, f, g) {
+    function update() { return A7( func, a.value, b.value, c.value, d.value, e.value, f.value, g.value ); }
+    return new LiftN(update, [a,b,c,d,e,f,g]);
+  }
+  function lift8(func, a, b, c, d, e, f, g, h) {
+    function update() { return A8( func, a.value, b.value, c.value, d.value, e.value, f.value, g.value, h.value ); }
+    return new LiftN(update, [a,b,c,d,e,f,g,h]);
+  }
+
+  function Foldp(step, state, input) {
+    this.id = Utils.guid();
+    this.value = state;
+    this.kids = [];
+
+    this.recv = function(timestep, changed, parentID) {
+      if (changed) {
+          this.value = A2( step, input.value, this.value );
+      }
+      send(this, timestep, changed);
+    };
+    input.kids.push(this);
+  }
+
+  function foldp(step, state, input) {
+      return new Foldp(step, state, input);
+  }
+
+  function DropIf(pred,base,input) {
+    this.id = Utils.guid();
+    this.value = pred(input.value) ? base : input.value;
+    this.kids = [];
+    this.recv = function(timestep, changed, parentID) {
+      var chng = changed && !pred(input.value);
+      if (chng) { this.value = input.value; }
+      send(this, timestep, chng);
+    };
+    input.kids.push(this);
+  }
+
+  function DropRepeats(input) {
+    this.id = Utils.guid();
+    this.value = input.value;
+    this.kids = [];
+    this.recv = function(timestep, changed, parentID) {
+      var chng = changed && !Utils.eq(this.value,input.value);
+      if (chng) { this.value = input.value; }
+      send(this, timestep, chng);
+    };
+    input.kids.push(this);
+  }
+
+  function timestamp(a) {
+    function update() { return Utils.Tuple2(elm.timer.now(), a.value); }
+    return new LiftN(update, [a]);
+  }
+
+  function SampleOn(s1,s2) {
+    this.id = Utils.guid();
+    this.value = s2.value;
+    this.kids = [];
+
+    var count = 0;
+    var isChanged = false;
+
+    this.recv = function(timestep, changed, parentID) {
+      if (parentID === s1.id) isChanged = changed;
+      ++count;
+      if (count == 2) {
+        if (isChanged) { this.value = s2.value; }
+        send(this, timestep, isChanged);
+        count = 0;
+        isChanged = false;
+      }
+    };
+    s1.kids.push(this);
+    s2.kids.push(this);
+  }
+
+  function sampleOn(s1,s2) { return new SampleOn(s1,s2); }
+
+  function delay(t,s) {
+      var delayed = new Input(s.value);
+      var firstEvent = true;
+      function update(v) {
+        if (firstEvent) { firstEvent = false; return; }
+        setTimeout(function() { elm.notify(delayed.id, v); }, t);
+      }
+      function first(a,b) { return a; }
+      return new SampleOn(delayed, lift2(F2(first), delayed, lift(update,s)));
+  }
+
+  function Merge(s1,s2) {
+      this.id = Utils.guid();
+      this.value = s1.value;
+      this.kids = [];
+
+      var next = null;
+      var count = 0;
+      var isChanged = false;
+
+      this.recv = function(timestep, changed, parentID) {
+        ++count;
+        if (changed) {
+            isChanged = true;
+            if (parentID == s2.id && next === null) { next = s2.value; }
+            if (parentID == s1.id) { next = s1.value; }
+        }
+
+        if (count == 2) {
+            if (isChanged) { this.value = next; next = null; }
+            send(this, timestep, isChanged);
+            isChanged = false;
+            count = 0;
+        }
+      };
+      s1.kids.push(this);
+      s2.kids.push(this);
+  }
+
+  function merge(s1,s2) { return new Merge(s1,s2); }
+  function merges(ss) { return A2(foldr1, F2(merge), ss); }
+
+  return elm.Native.Signal.values = {
+    input: function(v) { return new Input(v); },
+    constant : function(v) { return new Input(v); },
+    lift  : F2(lift ),
+    lift2 : F3(lift2),
+    lift3 : F4(lift3),
+    lift4 : F5(lift4),
+    lift5 : F6(lift5),
+    lift6 : F7(lift6),
+    lift7 : F8(lift7),
+    lift8 : F9(lift8),
+    foldp : F3(foldp),
+    delay : F2(delay),
+    merge : F2(merge),
+    merges : merges,
+    count : function(s) { return foldp(F2(function(_,c) { return c+1; }), 0, s); },
+    countIf : F2(function(pred,s) {
+      return foldp(F2(function(x,c){
+        return pred(x) ? c+1 : c; }), 0, s)}),
+    keepIf : F3(function(pred,base,sig) {
+      return new DropIf(function(x) {return !pred(x);},base,sig); }),
+    dropIf : F3(function(pred,base,sig) { return new DropIf(pred,base,sig); }),
+    dropRepeats : function(s) { return new DropRepeats(s);},
+    sampleOn : F2(sampleOn),
+    timestamp : timestamp
+  };
+};
+Elm.Native.Time = {};
+Elm.Native.Time.make = function(elm) {
+
+  elm.Native = elm.Native || {};
+  elm.Native.Time = elm.Native.Time || {};
+  if (elm.Native.Time.values) return elm.Native.Time.values;
+
+  var Signal = Elm.Signal.make(elm);
+  var NS = Elm.Native.Signal.make(elm);
+  var Maybe = Elm.Maybe.make(elm);
+  var Utils = Elm.Native.Utils.make(elm);
+
+  function fpsWhen(desiredFPS, isOn) {
+    var msPerFrame = 1000 / desiredFPS;
+    var prev = elm.timer.now(), curr = prev, diff = 0, wasOn = true;
+    var ticker = NS.input(diff);
+    function tick(zero) {
+      return function() {
+        curr = elm.timer.now();
+        diff = zero ? 0 : curr - prev;
+        if (prev > curr) {
+          diff = 0;
+        }
+        prev = curr;
+        elm.notify(ticker.id, diff);
+      };
+    }
+    var timeoutID = 0;
+    function f(isOn, t) {
+      if (isOn) {
+        timeoutID = elm.setTimeout(tick(!wasOn && isOn), msPerFrame);
+      } else if (wasOn) {
+        clearTimeout(timeoutID);
+      }
+      wasOn = isOn;
+      return t;
+    }
+    return A3( Signal.lift2, F2(f), isOn, ticker );
+  }
+
+  function every(t) {
+    var clock = NS.input(elm.timer.now());
+    function tellTime() {
+        elm.notify(clock.id, elm.timer.now());
+    }
+    setInterval(tellTime, t);
+    return clock;
+  }
+
+  function since(t, s) {
+    function cmp(a,b) { return !Utils.eq(a,b); }
+    var dcount = Signal.count(A2(NS.delay, t, s));
+    return A3( Signal.lift2, F2(cmp), Signal.count(s), dcount );
+  }
+  function read(s) {
+      var t = Date.parse(s);
+      return isNaN(t) ? Maybe.Nothing : Maybe.Just(t);
+  }
+  return elm.Native.Time.values = {
+      fpsWhen : F2(fpsWhen),
+      fps : function(t) { return fpsWhen(t, Signal.constant(true)); },
+      every : every,
+      delay : NS.delay,
+      timestamp : NS.timestamp,
+      since : F2(since),
+      toDate : function(t) { return new window.Date(t); },
+      read   : read
+  };
+
+};
+Elm.Native.Touch = {};
+Elm.Native.Touch.make = function(elm) {
+
+    elm.Native = elm.Native || {};
+    elm.Native.Touch = elm.Native.Touch || {};
+    if (elm.Native.Touch.values) return elm.Native.Touch.values;
+
+    var Signal = Elm.Signal.make(elm);
+    var List = Elm.Native.List.make(elm);
+    var Utils = Elm.Native.Utils.make(elm);
+
+    function Dict() {
+        this.keys = [];
+        this.values = [];
+
+        this.insert = function(key,value) {
+            this.keys.push(key);
+            this.values.push(value);
+        };
+        this.lookup = function(key) {
+            var i = this.keys.indexOf(key)
+            return i >= 0 ? this.values[i] : {x:0,y:0,t:0};
+        };
+        this.remove = function(key) {
+            var i = this.keys.indexOf(key);
+            if (i < 0) return;
+            var t = this.values[i];
+            this.keys.splice(i,1);
+            this.values.splice(i,1);
+            return t;
+        };
+        this.clear = function() {
+            this.keys = [];
+            this.values = [];
+        };
+    }
+    
+    var root = Signal.constant([]),
+    tapTime = 500,
+    hasTap = false,
+    tap = {_:{},x:0,y:0},
+    dict = new Dict();
+
+    function touch(t) {
+        var r = dict.lookup(t.identifier);
+        var point = Utils.getXY(t);
+        return {_ : {},
+	        id: t.identifier,
+	        x : point._0,
+	        y : point._1,
+	        x0: r.x,
+	        y0: r.y,
+	        t0: r.t
+	       };
+    }
+
+    var node = elm.display === ElmRuntime.Display.FULLSCREEN ? document : elm.node;
+
+    function start(e) {
+        var point = Utils.getXY(e);
+        dict.insert(e.identifier,
+                    {x: point._0,
+                     y: point._1,
+                     t: elm.timer.now()});
+    }
+    function end(e) {
+        var t = dict.remove(e.identifier);
+        if (elm.timer.now() - t.t < tapTime) {
+            hasTap = true;
+            tap = {_:{}, x:t.x, y:t.y};
+        }
+    }
+
+    function listen(name, f) {
+        function update(e) {
+            for (var i = e.changedTouches.length; i--; ) { f(e.changedTouches[i]); }
+            var ts = new Array(e.touches.length);
+            for (var i = e.touches.length; i--; ) { ts[i] = touch(e.touches[i]); }
+            elm.notify(root.id, ts);
+            e.preventDefault();
+        }
+        elm.addListener([root.id], node, name, update);
+    }
+
+    listen("touchstart", start);
+    listen("touchmove", function(_){});
+    listen("touchend", end);
+    listen("touchcancel", end);
+    listen("touchleave", end);
+
+    var mouseID = -1;
+    function move(e) {
+        var point = Utils.getXY(e);
+        for (var i = root.value.length; i--; ) {
+            if (root.value[i].id === mouseID) {
+                root.value[i].x = point._0;
+                root.value[i].y = point._1;
+                elm.notify(root.id, root.value);
+                break;
+            }
+        }
+    }
+    elm.addListener([root.id], node, "mousedown", function down(e) {
+        node.addEventListener("mousemove", move);
+        e.identifier = mouseID;
+        start(e);
+        root.value.push(touch(e));
+        elm.notify(root.id, root.value);
+    });
+    elm.addListener([root.id], document, "mouseup", function up(e) {
+        node.removeEventListener("mousemove", move);
+        e.identifier = mouseID;
+        end(e);
+        for (var i = root.value.length; i--; ) {
+            if (root.value[i].id === mouseID) {
+                root.value.splice(i, 1);
+                --mouseID;
+                break;
+            }
+        }
+        elm.notify(root.id, root.value);
+    });
+    elm.addListener([root.id], node, "blur", function blur(e) {
+        node.removeEventListener("mousemove", move);
+        if (root.value.length > 0) {
+            elm.notify(root.id, []);
+            --mouseID;
+        }
+        dict.clear();
+    });
+
+    function dependency(f) {
+        var sig = A2( Signal.lift, f, root );
+        root.defaultNumberOfKids += 1;
+        sig.defaultNumberOfKids = 0;
+        return sig;
+    }
+
+    var touches = dependency(List.fromArray);
+
+    var taps = function() {
+        var sig = dependency(function(_) { return tap; });
+        sig.defaultNumberOfKids = 1;
+        function pred(_) { var b = hasTap; hasTap = false; return b; }
+        var sig2 = A3( Signal.keepIf, pred, {_:{},x:0,y:0}, sig);
+        sig2.defaultNumberOfKids = 0;
+        return sig2;
+    }();
+
+    return elm.Native.Touch.values = { touches: touches, taps: taps };
+
+};
+Elm.Native.WebSocket = {};
+Elm.Native.WebSocket.make = function(elm) {
+
+  elm.Native = elm.Native || {};
+  elm.Native.WebSocket = elm.Native.WebSocket || {};
+  if (elm.Native.WebSocket.values) return elm.Native.WebSocket.values;
+
+  var Signal = Elm.Signal.make(elm);
+  var List = Elm.Native.List.make(elm);
+
+  function open(url, outgoing) {
+    var incoming = Signal.constant("");
+    var ws = new WebSocket(url);
+
+    var pending = [];
+    var ready = false;
+    
+    ws.onopen = function(e) {
+      var len = pending.length;
+      for (var i = 0; i < len; ++i) { ws.send(pending[i]); }
+      ready = true;
+    };
+    ws.onmessage = function(event) {
+      elm.notify(incoming.id, event.data);
+    };
+    
+    function send(msg) {
+      ready ? ws.send(msg) : pending.push(msg);
+    }
+    
+    function take1(x,y) { return x }
+    return A3(Signal.lift2, F2(take1), incoming, A2(Signal.lift, send, outgoing));
+  }
+
+  return elm.Native.WebSocket.values = { connect: F2(open) };
+};
+Elm.Native.Window = {};
+Elm.Native.Window.make = function(elm) {
+
+  elm.Native = elm.Native || {};
+  elm.Native.Window = elm.Native.Window || {};
+  if (elm.Native.Window.values) return elm.Native.Window.values;
+
+  var Signal = Elm.Signal.make(elm);
+  var NS = Elm.Native.Signal.make(elm);
+  var Tuple2 = Elm.Native.Utils.make(elm).Tuple2;
+
+  function getWidth() { return elm.node.clientWidth; }
+  function getHeight() {
+      if (elm.display === ElmRuntime.Display.FULLSCREEN) {
+          return window.innerHeight;
+      }
+      return elm.node.clientHeight;
+  }
+
+  var dimensions = NS.input(Tuple2(getWidth(), getHeight()));
+  dimensions.defaultNumberOfKids = 2;
+
+  // Do not move width and height into Elm. By setting the default number of kids,
+  // the resize listener can be detached.
+  var width  = A2(Signal.lift, function(p){return p._0;}, dimensions);
+  width.defaultNumberOfKids = 0;
+
+  var height = A2(Signal.lift, function(p){return p._1;}, dimensions);
+  height.defaultNumberOfKids = 0;
+
+  function resizeIfNeeded() {
+      // Do not trigger event if the dimensions have not changed.
+      // This should be most of the time.
+      var w = getWidth();
+      var h = getHeight();
+      if (dimensions.value._0 === w && dimensions.value._1 === h) return;
+
+      setTimeout(function () {
+          // Check again to see if the dimensions have changed.
+          // It is conceivable that the dimensions have changed
+          // again while some other event was being processed.
+          var w = getWidth();
+          var h = getHeight();
+          if (dimensions.value._0 === w && dimensions.value._1 === h) return;
+          elm.notify(dimensions.id, Tuple2(w,h));
+      }, 0);
+  }
+  elm.addListener([dimensions.id], window, 'resize', resizeIfNeeded);
+
+  return elm.Native.Window.values = {
+      dimensions:dimensions,
+      width:width,
+      height:height,
+      resizeIfNeeded:resizeIfNeeded
+  };
+
+};
+Elm.Array = Elm.Array || {};
+Elm.Array.make = function (_elm) {
+   "use strict";
+   _elm.Array = _elm.Array || {};
+   if (_elm.Array.values)
+   return _elm.Array.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Array",
+   $Basics = Elm.Basics.make(_elm),
+   $List = Elm.List.make(_elm),
+   $Maybe = Elm.Maybe.make(_elm),
+   $Native$Array = Elm.Native.Array.make(_elm);
+   var append = $Native$Array.append;
+   var length = $Native$Array.length;
+   var slice = $Native$Array.slice;
+   var set = $Native$Array.set;
+   var getOrElse = F3(function ($default,
+   i,
+   array) {
+      return _U.cmp(0,
+      i) < 1 && _U.cmp(i,
+      $Native$Array.length(array)) < 0 ? A2($Native$Array.get,
+      i,
+      array) : $default;
+   });
+   var get = F2(function (i,
+   array) {
+      return _U.cmp(0,
+      i) < 1 && _U.cmp(i,
+      $Native$Array.length(array)) < 0 ? $Maybe.Just(A2($Native$Array.get,
+      i,
+      array)) : $Maybe.Nothing;
+   });
+   var getOrFail = $Native$Array.get;
+   var push = $Native$Array.push;
+   var empty = $Native$Array.empty;
+   var filter = F2(function (isOkay,
+   arr) {
+      return function () {
+         var update = F2(function (x,
+         xs) {
+            return isOkay(x) ? A2($Native$Array.push,
+            x,
+            xs) : xs;
+         });
+         return A3($Native$Array.foldl,
+         update,
+         $Native$Array.empty,
+         arr);
+      }();
+   });
+   var foldr = $Native$Array.foldr;
+   var foldl = $Native$Array.foldl;
+   var indexedMap = $Native$Array.indexedMap;
+   var map = $Native$Array.map;
+   var toIndexedList = function (array) {
+      return A2($List.zip,
+      _L.range(0,
+      $Native$Array.length(array) - 1),
+      $Native$Array.toList(array));
+   };
+   var toList = $Native$Array.toList;
+   var fromList = $Native$Array.fromList;
+   var initialize = $Native$Array.initialize;
+   var repeat = F2(function (n,e) {
+      return A2(initialize,
+      n,
+      $Basics.always(e));
+   });
+   var Array = {ctor: "Array"};
+   _elm.Array.values = {_op: _op
+                       ,Array: Array
+                       ,initialize: initialize
+                       ,repeat: repeat
+                       ,fromList: fromList
+                       ,toList: toList
+                       ,toIndexedList: toIndexedList
+                       ,map: map
+                       ,indexedMap: indexedMap
+                       ,foldl: foldl
+                       ,foldr: foldr
+                       ,filter: filter
+                       ,empty: empty
+                       ,push: push
+                       ,getOrFail: getOrFail
+                       ,get: get
+                       ,getOrElse: getOrElse
+                       ,set: set
+                       ,slice: slice
+                       ,length: length
+                       ,append: append};
+   return _elm.Array.values;
+};Elm.Basics = Elm.Basics || {};
+Elm.Basics.make = function (_elm) {
+   "use strict";
+   _elm.Basics = _elm.Basics || {};
+   if (_elm.Basics.values)
+   return _elm.Basics.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Basics",
+   $Native$Basics = Elm.Native.Basics.make(_elm);
+   var uncurry = F2(function (f,
+   _v0) {
+      return function () {
+         switch (_v0.ctor)
+         {case "_Tuple2": return A2(f,
+              _v0._0,
+              _v0._1);}
+         _E.Case($moduleName,
+         "on line 419, column 19 to 24");
+      }();
+   });
+   var curry = F3(function (f,
+   a,
+   b) {
+      return f({ctor: "_Tuple2"
+               ,_0: a
+               ,_1: b});
+   });
+   var flip = F3(function (f,b,a) {
+      return A2(f,a,b);
+   });
+   var snd = function (_v4) {
+      return function () {
+         switch (_v4.ctor)
+         {case "_Tuple2": return _v4._1;}
+         _E.Case($moduleName,
+         "on line 403, column 13 to 14");
+      }();
+   };
+   var fst = function (_v8) {
+      return function () {
+         switch (_v8.ctor)
+         {case "_Tuple2": return _v8._0;}
+         _E.Case($moduleName,
+         "on line 399, column 13 to 14");
+      }();
+   };
+   var always = F2(function (a,
+   _v12) {
+      return function () {
+         return a;
+      }();
+   });
+   var identity = function (x) {
+      return x;
+   };
+   _op["<|"] = F2(function (f,x) {
+      return f(x);
+   });
+   _op["|>"] = F2(function (x,f) {
+      return f(x);
+   });
+   _op[">>"] = F3(function (f,
+   g,
+   x) {
+      return g(f(x));
+   });
+   _op["<<"] = F3(function (g,
+   f,
+   x) {
+      return g(f(x));
+   });
+   var isInfinite = $Native$Basics.isInfinite;
+   var isNaN = $Native$Basics.isNaN;
+   var toFloat = $Native$Basics.toFloat;
+   var ceiling = $Native$Basics.ceiling;
+   var floor = $Native$Basics.floor;
+   var truncate = $Native$Basics.truncate;
+   var round = $Native$Basics.round;
+   var otherwise = true;
+   var not = $Native$Basics.not;
+   var xor = $Native$Basics.xor;
+   _op["||"] = $Native$Basics.or;
+   _op["&&"] = $Native$Basics.and;
+   var max = $Native$Basics.max;
+   var min = $Native$Basics.min;
+   var GT = {ctor: "GT"};
+   var EQ = {ctor: "EQ"};
+   var LT = {ctor: "LT"};
+   var compare = $Native$Basics.compare;
+   _op[">="] = $Native$Basics.ge;
+   _op["<="] = $Native$Basics.le;
+   _op[">"] = $Native$Basics.gt;
+   _op["<"] = $Native$Basics.lt;
+   _op["/="] = $Native$Basics.neq;
+   _op["=="] = $Native$Basics.eq;
+   var e = $Native$Basics.e;
+   var pi = $Native$Basics.pi;
+   var clamp = $Native$Basics.clamp;
+   var logBase = $Native$Basics.logBase;
+   var abs = $Native$Basics.abs;
+   var negate = $Native$Basics.negate;
+   var sqrt = $Native$Basics.sqrt;
+   var atan2 = $Native$Basics.atan2;
+   var atan = $Native$Basics.atan;
+   var asin = $Native$Basics.asin;
+   var acos = $Native$Basics.acos;
+   var tan = $Native$Basics.tan;
+   var sin = $Native$Basics.sin;
+   var cos = $Native$Basics.cos;
+   _op["^"] = $Native$Basics.exp;
+   _op["%"] = $Native$Basics.mod;
+   var rem = $Native$Basics.rem;
+   _op["//"] = $Native$Basics.div;
+   _op["/"] = $Native$Basics.floatDiv;
+   _op["*"] = $Native$Basics.mul;
+   _op["-"] = $Native$Basics.sub;
+   _op["+"] = $Native$Basics.add;
+   var toPolar = $Native$Basics.toPolar;
+   var fromPolar = $Native$Basics.fromPolar;
+   var turns = $Native$Basics.turns;
+   var degrees = $Native$Basics.degrees;
+   var radians = function (t) {
+      return t;
+   };
+   _elm.Basics.values = {_op: _op
+                        ,radians: radians
+                        ,degrees: degrees
+                        ,turns: turns
+                        ,fromPolar: fromPolar
+                        ,toPolar: toPolar
+                        ,rem: rem
+                        ,cos: cos
+                        ,sin: sin
+                        ,tan: tan
+                        ,acos: acos
+                        ,asin: asin
+                        ,atan: atan
+                        ,atan2: atan2
+                        ,sqrt: sqrt
+                        ,negate: negate
+                        ,abs: abs
+                        ,logBase: logBase
+                        ,clamp: clamp
+                        ,pi: pi
+                        ,e: e
+                        ,compare: compare
+                        ,LT: LT
+                        ,EQ: EQ
+                        ,GT: GT
+                        ,min: min
+                        ,max: max
+                        ,xor: xor
+                        ,not: not
+                        ,otherwise: otherwise
+                        ,round: round
+                        ,truncate: truncate
+                        ,floor: floor
+                        ,ceiling: ceiling
+                        ,toFloat: toFloat
+                        ,isNaN: isNaN
+                        ,isInfinite: isInfinite
+                        ,identity: identity
+                        ,always: always
+                        ,fst: fst
+                        ,snd: snd
+                        ,flip: flip
+                        ,curry: curry
+                        ,uncurry: uncurry};
+   return _elm.Basics.values;
+};Elm.Bitwise = Elm.Bitwise || {};
+Elm.Bitwise.make = function (_elm) {
+   "use strict";
+   _elm.Bitwise = _elm.Bitwise || {};
+   if (_elm.Bitwise.values)
+   return _elm.Bitwise.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Bitwise",
+   $Native$Bitwise = Elm.Native.Bitwise.make(_elm);
+   var shiftRightLogical = $Native$Bitwise.shiftRightLogical;
+   var shiftRight = $Native$Bitwise.shiftRightArithmatic;
+   var shiftLeft = $Native$Bitwise.shiftLeft;
+   var complement = $Native$Bitwise.complement;
+   var xor = $Native$Bitwise.xor;
+   var or = $Native$Bitwise.or;
+   var and = $Native$Bitwise.and;
+   _elm.Bitwise.values = {_op: _op
+                         ,and: and
+                         ,or: or
+                         ,xor: xor
+                         ,complement: complement
+                         ,shiftLeft: shiftLeft
+                         ,shiftRight: shiftRight
+                         ,shiftRightLogical: shiftRightLogical};
+   return _elm.Bitwise.values;
+};Elm.Char = Elm.Char || {};
+Elm.Char.make = function (_elm) {
+   "use strict";
+   _elm.Char = _elm.Char || {};
+   if (_elm.Char.values)
+   return _elm.Char.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Char",
+   $Native$Char = Elm.Native.Char.make(_elm);
+   var fromCode = $Native$Char.fromCode;
+   var toCode = $Native$Char.toCode;
+   var toLocaleLower = $Native$Char.toLocaleLower;
+   var toLocaleUpper = $Native$Char.toLocaleUpper;
+   var toLower = $Native$Char.toLower;
+   var toUpper = $Native$Char.toUpper;
+   var isHexDigit = $Native$Char.isHexDigit;
+   var isOctDigit = $Native$Char.isOctDigit;
+   var isDigit = $Native$Char.isDigit;
+   var isLower = $Native$Char.isLower;
+   var isUpper = $Native$Char.isUpper;
+   _elm.Char.values = {_op: _op
+                      ,isUpper: isUpper
+                      ,isLower: isLower
+                      ,isDigit: isDigit
+                      ,isOctDigit: isOctDigit
+                      ,isHexDigit: isHexDigit
+                      ,toUpper: toUpper
+                      ,toLower: toLower
+                      ,toLocaleUpper: toLocaleUpper
+                      ,toLocaleLower: toLocaleLower
+                      ,toCode: toCode
+                      ,fromCode: fromCode};
+   return _elm.Char.values;
+};Elm.Color = Elm.Color || {};
+Elm.Color.make = function (_elm) {
+   "use strict";
+   _elm.Color = _elm.Color || {};
+   if (_elm.Color.values)
+   return _elm.Color.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Color",
+   $Basics = Elm.Basics.make(_elm);
+   var Radial = F5(function (a,
+   b,
+   c,
+   d,
+   e) {
+      return {ctor: "Radial"
+             ,_0: a
+             ,_1: b
+             ,_2: c
+             ,_3: d
+             ,_4: e};
+   });
+   var radial = Radial;
+   var Linear = F3(function (a,
+   b,
+   c) {
+      return {ctor: "Linear"
+             ,_0: a
+             ,_1: b
+             ,_2: c};
+   });
+   var linear = Linear;
+   var fmod = F2(function (f,n) {
+      return function () {
+         var integer = $Basics.floor(f);
+         return $Basics.toFloat(A2($Basics._op["%"],
+         integer,
+         n)) + f - $Basics.toFloat(integer);
+      }();
+   });
+   var rgbToHsl = F3(function (red,
+   green,
+   blue) {
+      return function () {
+         var b = $Basics.toFloat(blue) / 255;
+         var g = $Basics.toFloat(green) / 255;
+         var r = $Basics.toFloat(red) / 255;
+         var cMax = A2($Basics.max,
+         A2($Basics.max,r,g),
+         b);
+         var cMin = A2($Basics.min,
+         A2($Basics.min,r,g),
+         b);
+         var c = cMax - cMin;
+         var lightness = (cMax + cMin) / 2;
+         var saturation = _U.eq(lightness,
+         0) ? 0 : c / (1 - $Basics.abs(2 * lightness - 1));
+         var hue = $Basics.degrees(60) * (_U.eq(cMax,
+         r) ? A2(fmod,
+         (g - b) / c,
+         6) : _U.eq(cMax,
+         g) ? (b - r) / c + 2 : _U.eq(cMax,
+         b) ? (r - g) / c + 4 : _E.If($moduleName,
+         "between lines 140 and 142"));
+         return {ctor: "_Tuple3"
+                ,_0: hue
+                ,_1: saturation
+                ,_2: lightness};
+      }();
+   });
+   var hslToRgb = F3(function (hue,
+   saturation,
+   lightness) {
+      return function () {
+         var hue$ = hue / $Basics.degrees(60);
+         var chroma = (1 - $Basics.abs(2 * lightness - 1)) * saturation;
+         var x = chroma * (1 - $Basics.abs(A2(fmod,
+         hue$,
+         2) - 1));
+         var $ = _U.cmp(hue$,
+         0) < 0 ? {ctor: "_Tuple3"
+                  ,_0: 0
+                  ,_1: 0
+                  ,_2: 0} : _U.cmp(hue$,
+         1) < 0 ? {ctor: "_Tuple3"
+                  ,_0: chroma
+                  ,_1: x
+                  ,_2: 0} : _U.cmp(hue$,
+         2) < 0 ? {ctor: "_Tuple3"
+                  ,_0: x
+                  ,_1: chroma
+                  ,_2: 0} : _U.cmp(hue$,
+         3) < 0 ? {ctor: "_Tuple3"
+                  ,_0: 0
+                  ,_1: chroma
+                  ,_2: x} : _U.cmp(hue$,
+         4) < 0 ? {ctor: "_Tuple3"
+                  ,_0: 0
+                  ,_1: x
+                  ,_2: chroma} : _U.cmp(hue$,
+         5) < 0 ? {ctor: "_Tuple3"
+                  ,_0: x
+                  ,_1: 0
+                  ,_2: chroma} : _U.cmp(hue$,
+         6) < 0 ? {ctor: "_Tuple3"
+                  ,_0: chroma
+                  ,_1: 0
+                  ,_2: x} : {ctor: "_Tuple3"
+                            ,_0: 0
+                            ,_1: 0
+                            ,_2: 0},
+         r = $._0,
+         g = $._1,
+         b = $._2;
+         var m = lightness - chroma / 2;
+         return {ctor: "_Tuple3"
+                ,_0: r + m
+                ,_1: g + m
+                ,_2: b + m};
+      }();
+   });
+   var toRgb = function (color) {
+      return function () {
+         switch (color.ctor)
+         {case "HSLA":
+            return function () {
+                 var $ = A3(hslToRgb,
+                 color._0,
+                 color._1,
+                 color._2),
+                 r = $._0,
+                 g = $._1,
+                 b = $._2;
+                 return {_: {}
+                        ,alpha: color._3
+                        ,blue: $Basics.round(255 * b)
+                        ,green: $Basics.round(255 * g)
+                        ,red: $Basics.round(255 * r)};
+              }();
+            case "RGBA": return {_: {}
+                                ,alpha: color._3
+                                ,blue: color._2
+                                ,green: color._1
+                                ,red: color._0};}
+         _E.Case($moduleName,
+         "between lines 114 and 122");
+      }();
+   };
+   var toHsl = function (color) {
+      return function () {
+         switch (color.ctor)
+         {case "HSLA": return {_: {}
+                              ,alpha: color._3
+                              ,hue: color._0
+                              ,lightness: color._2
+                              ,saturation: color._1};
+            case "RGBA":
+            return function () {
+                 var $ = A3(rgbToHsl,
+                 color._0,
+                 color._1,
+                 color._2),
+                 h = $._0,
+                 s = $._1,
+                 l = $._2;
+                 return {_: {}
+                        ,alpha: color._3
+                        ,hue: h
+                        ,lightness: l
+                        ,saturation: s};
+              }();}
+         _E.Case($moduleName,
+         "between lines 104 and 111");
+      }();
+   };
+   var HSLA = F4(function (a,
+   b,
+   c,
+   d) {
+      return {ctor: "HSLA"
+             ,_0: a
+             ,_1: b
+             ,_2: c
+             ,_3: d};
+   });
+   var hsla = F4(function (hue,
+   saturation,
+   lightness,
+   alpha) {
+      return A4(HSLA,
+      hue - $Basics.turns($Basics.toFloat($Basics.floor(hue / (2 * $Basics.pi)))),
+      saturation,
+      lightness,
+      alpha);
+   });
+   var hsl = F3(function (hue,
+   saturation,
+   lightness) {
+      return A4(hsla,
+      hue,
+      saturation,
+      lightness,
+      1);
+   });
+   var complement = function (color) {
+      return function () {
+         switch (color.ctor)
+         {case "HSLA": return A4(hsla,
+              color._0 + $Basics.degrees(180),
+              color._1,
+              color._2,
+              color._3);
+            case "RGBA":
+            return function () {
+                 var $ = A3(rgbToHsl,
+                 color._0,
+                 color._1,
+                 color._2),
+                 h = $._0,
+                 s = $._1,
+                 l = $._2;
+                 return A4(hsla,
+                 h + $Basics.degrees(180),
+                 s,
+                 l,
+                 color._3);
+              }();}
+         _E.Case($moduleName,
+         "between lines 95 and 101");
+      }();
+   };
+   var grayscale = function (p) {
+      return A4(HSLA,0,0,1 - p,1);
+   };
+   var greyscale = function (p) {
+      return A4(HSLA,0,0,1 - p,1);
+   };
+   var RGBA = F4(function (a,
+   b,
+   c,
+   d) {
+      return {ctor: "RGBA"
+             ,_0: a
+             ,_1: b
+             ,_2: c
+             ,_3: d};
+   });
+   var rgba = RGBA;
+   var rgb = F3(function (r,g,b) {
+      return A4(RGBA,r,g,b,1);
+   });
+   var lightRed = A4(RGBA,
+   239,
+   41,
+   41,
+   1);
+   var red = A4(RGBA,204,0,0,1);
+   var darkRed = A4(RGBA,
+   164,
+   0,
+   0,
+   1);
+   var lightOrange = A4(RGBA,
+   252,
+   175,
+   62,
+   1);
+   var orange = A4(RGBA,
+   245,
+   121,
+   0,
+   1);
+   var darkOrange = A4(RGBA,
+   206,
+   92,
+   0,
+   1);
+   var lightYellow = A4(RGBA,
+   255,
+   233,
+   79,
+   1);
+   var yellow = A4(RGBA,
+   237,
+   212,
+   0,
+   1);
+   var darkYellow = A4(RGBA,
+   196,
+   160,
+   0,
+   1);
+   var lightGreen = A4(RGBA,
+   138,
+   226,
+   52,
+   1);
+   var green = A4(RGBA,
+   115,
+   210,
+   22,
+   1);
+   var darkGreen = A4(RGBA,
+   78,
+   154,
+   6,
+   1);
+   var lightBlue = A4(RGBA,
+   114,
+   159,
+   207,
+   1);
+   var blue = A4(RGBA,
+   52,
+   101,
+   164,
+   1);
+   var darkBlue = A4(RGBA,
+   32,
+   74,
+   135,
+   1);
+   var lightPurple = A4(RGBA,
+   173,
+   127,
+   168,
+   1);
+   var purple = A4(RGBA,
+   117,
+   80,
+   123,
+   1);
+   var darkPurple = A4(RGBA,
+   92,
+   53,
+   102,
+   1);
+   var lightBrown = A4(RGBA,
+   233,
+   185,
+   110,
+   1);
+   var brown = A4(RGBA,
+   193,
+   125,
+   17,
+   1);
+   var darkBrown = A4(RGBA,
+   143,
+   89,
+   2,
+   1);
+   var black = A4(RGBA,0,0,0,1);
+   var white = A4(RGBA,
+   255,
+   255,
+   255,
+   1);
+   var lightGrey = A4(RGBA,
+   238,
+   238,
+   236,
+   1);
+   var grey = A4(RGBA,
+   211,
+   215,
+   207,
+   1);
+   var darkGrey = A4(RGBA,
+   186,
+   189,
+   182,
+   1);
+   var lightGray = A4(RGBA,
+   238,
+   238,
+   236,
+   1);
+   var gray = A4(RGBA,
+   211,
+   215,
+   207,
+   1);
+   var darkGray = A4(RGBA,
+   186,
+   189,
+   182,
+   1);
+   var lightCharcoal = A4(RGBA,
+   136,
+   138,
+   133,
+   1);
+   var charcoal = A4(RGBA,
+   85,
+   87,
+   83,
+   1);
+   var darkCharcoal = A4(RGBA,
+   46,
+   52,
+   54,
+   1);
+   _elm.Color.values = {_op: _op
+                       ,RGBA: RGBA
+                       ,HSLA: HSLA
+                       ,rgba: rgba
+                       ,rgb: rgb
+                       ,hsla: hsla
+                       ,hsl: hsl
+                       ,grayscale: grayscale
+                       ,greyscale: greyscale
+                       ,complement: complement
+                       ,toHsl: toHsl
+                       ,toRgb: toRgb
+                       ,fmod: fmod
+                       ,rgbToHsl: rgbToHsl
+                       ,hslToRgb: hslToRgb
+                       ,Linear: Linear
+                       ,Radial: Radial
+                       ,linear: linear
+                       ,radial: radial
+                       ,lightRed: lightRed
+                       ,red: red
+                       ,darkRed: darkRed
+                       ,lightOrange: lightOrange
+                       ,orange: orange
+                       ,darkOrange: darkOrange
+                       ,lightYellow: lightYellow
+                       ,yellow: yellow
+                       ,darkYellow: darkYellow
+                       ,lightGreen: lightGreen
+                       ,green: green
+                       ,darkGreen: darkGreen
+                       ,lightBlue: lightBlue
+                       ,blue: blue
+                       ,darkBlue: darkBlue
+                       ,lightPurple: lightPurple
+                       ,purple: purple
+                       ,darkPurple: darkPurple
+                       ,lightBrown: lightBrown
+                       ,brown: brown
+                       ,darkBrown: darkBrown
+                       ,black: black
+                       ,white: white
+                       ,lightGrey: lightGrey
+                       ,grey: grey
+                       ,darkGrey: darkGrey
+                       ,lightGray: lightGray
+                       ,gray: gray
+                       ,darkGray: darkGray
+                       ,lightCharcoal: lightCharcoal
+                       ,charcoal: charcoal
+                       ,darkCharcoal: darkCharcoal};
+   return _elm.Color.values;
+};Elm.Date = Elm.Date || {};
+Elm.Date.make = function (_elm) {
+   "use strict";
+   _elm.Date = _elm.Date || {};
+   if (_elm.Date.values)
+   return _elm.Date.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Date",
+   $Maybe = Elm.Maybe.make(_elm),
+   $Native$Date = Elm.Native.Date.make(_elm),
+   $Time = Elm.Time.make(_elm);
+   var second = $Native$Date.second;
+   var minute = $Native$Date.minute;
+   var hour = $Native$Date.hour;
+   var dayOfWeek = $Native$Date.dayOfWeek;
+   var day = $Native$Date.day;
+   var month = $Native$Date.month;
+   var year = $Native$Date.year;
+   var fromTime = $Native$Date.fromTime;
+   var toTime = $Native$Date.toTime;
+   var read = $Native$Date.read;
+   var Dec = {ctor: "Dec"};
+   var Nov = {ctor: "Nov"};
+   var Oct = {ctor: "Oct"};
+   var Sep = {ctor: "Sep"};
+   var Aug = {ctor: "Aug"};
+   var Jul = {ctor: "Jul"};
+   var Jun = {ctor: "Jun"};
+   var May = {ctor: "May"};
+   var Apr = {ctor: "Apr"};
+   var Mar = {ctor: "Mar"};
+   var Feb = {ctor: "Feb"};
+   var Jan = {ctor: "Jan"};
+   var Sun = {ctor: "Sun"};
+   var Sat = {ctor: "Sat"};
+   var Fri = {ctor: "Fri"};
+   var Thu = {ctor: "Thu"};
+   var Wed = {ctor: "Wed"};
+   var Tue = {ctor: "Tue"};
+   var Mon = {ctor: "Mon"};
+   var Date = {ctor: "Date"};
+   _elm.Date.values = {_op: _op
+                      ,Date: Date
+                      ,Mon: Mon
+                      ,Tue: Tue
+                      ,Wed: Wed
+                      ,Thu: Thu
+                      ,Fri: Fri
+                      ,Sat: Sat
+                      ,Sun: Sun
+                      ,Jan: Jan
+                      ,Feb: Feb
+                      ,Mar: Mar
+                      ,Apr: Apr
+                      ,May: May
+                      ,Jun: Jun
+                      ,Jul: Jul
+                      ,Aug: Aug
+                      ,Sep: Sep
+                      ,Oct: Oct
+                      ,Nov: Nov
+                      ,Dec: Dec
+                      ,read: read
+                      ,toTime: toTime
+                      ,fromTime: fromTime
+                      ,year: year
+                      ,month: month
+                      ,day: day
+                      ,dayOfWeek: dayOfWeek
+                      ,hour: hour
+                      ,minute: minute
+                      ,second: second};
+   return _elm.Date.values;
+};Elm.Debug = Elm.Debug || {};
+Elm.Debug.make = function (_elm) {
+   "use strict";
+   _elm.Debug = _elm.Debug || {};
+   if (_elm.Debug.values)
+   return _elm.Debug.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Debug",
+   $Graphics$Collage = Elm.Graphics.Collage.make(_elm),
+   $Native$Debug = Elm.Native.Debug.make(_elm),
+   $Native$Error = Elm.Native.Error.make(_elm);
+   var trace = $Native$Debug.tracePath;
+   var watchSummary = $Native$Debug.watchSummary;
+   var watch = $Native$Debug.watch;
+   var crash = $Native$Error.raise;
+   var log = $Native$Debug.log;
+   _elm.Debug.values = {_op: _op
+                       ,log: log
+                       ,crash: crash
+                       ,watch: watch
+                       ,watchSummary: watchSummary
+                       ,trace: trace};
+   return _elm.Debug.values;
+};Elm.Dict = Elm.Dict || {};
+Elm.Dict.make = function (_elm) {
+   "use strict";
+   _elm.Dict = _elm.Dict || {};
+   if (_elm.Dict.values)
+   return _elm.Dict.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Dict",
+   $Basics = Elm.Basics.make(_elm),
+   $List = Elm.List.make(_elm),
+   $Maybe = Elm.Maybe.make(_elm),
+   $Native$Error = Elm.Native.Error.make(_elm),
+   $Native$Utils = Elm.Native.Utils.make(_elm);
+   var foldr = F3(function (f,
+   acc,
+   t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty":
+            switch (t._0.ctor)
+              {case "LBlack": return acc;}
+              break;
+            case "RBNode": return A3(foldr,
+              f,
+              A3(f,
+              t._1,
+              t._2,
+              A3(foldr,f,acc,t._4)),
+              t._3);}
+         _E.Case($moduleName,
+         "between lines 369 and 374");
+      }();
+   });
+   var keys = function (t) {
+      return A3(foldr,
+      F3(function (k,v,acc) {
+         return A2($List._op["::"],
+         k,
+         acc);
+      }),
+      _L.fromArray([]),
+      t);
+   };
+   var values = function (t) {
+      return A3(foldr,
+      F3(function (k,v,acc) {
+         return A2($List._op["::"],
+         v,
+         acc);
+      }),
+      _L.fromArray([]),
+      t);
+   };
+   var toList = function (t) {
+      return A3(foldr,
+      F3(function (k,v,acc) {
+         return A2($List._op["::"],
+         {ctor: "_Tuple2",_0: k,_1: v},
+         acc);
+      }),
+      _L.fromArray([]),
+      t);
+   };
+   var foldl = F3(function (f,
+   acc,
+   t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty":
+            switch (t._0.ctor)
+              {case "LBlack": return acc;}
+              break;
+            case "RBNode": return A3(foldl,
+              f,
+              A3(f,
+              t._1,
+              t._2,
+              A3(foldl,f,acc,t._3)),
+              t._4);}
+         _E.Case($moduleName,
+         "between lines 361 and 366");
+      }();
+   });
+   var isBBlack = function (t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty":
+            switch (t._0.ctor)
+              {case "LBBlack": return true;}
+              break;
+            case "RBNode":
+            switch (t._0.ctor)
+              {case "BBlack": return true;}
+              break;}
+         return false;
+      }();
+   };
+   var showFlag = function (f) {
+      return function () {
+         switch (f.ctor)
+         {case "Insert": return "Insert";
+            case "Remove": return "Remove";
+            case "Same": return "Same";}
+         _E.Case($moduleName,
+         "between lines 187 and 192");
+      }();
+   };
+   var Same = {ctor: "Same"};
+   var Remove = {ctor: "Remove"};
+   var Insert = {ctor: "Insert"};
+   var getOrFail = F2(function (k,
+   t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty":
+            switch (t._0.ctor)
+              {case "LBlack":
+                 return $Native$Error.raise("key not found when using \'getOrFail\'");}
+              break;
+            case "RBNode":
+            return function () {
+                 var _v29 = A2($Native$Utils.compare,
+                 k,
+                 t._1);
+                 switch (_v29.ctor)
+                 {case "EQ": return t._2;
+                    case "GT": return A2(getOrFail,
+                      k,
+                      t._4);
+                    case "LT": return A2(getOrFail,
+                      k,
+                      t._3);}
+                 _E.Case($moduleName,
+                 "between lines 156 and 161");
+              }();}
+         _E.Case($moduleName,
+         "between lines 153 and 161");
+      }();
+   });
+   var getOrElse = F3(function (base,
+   k,
+   t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty":
+            switch (t._0.ctor)
+              {case "LBlack": return base;}
+              break;
+            case "RBNode":
+            return function () {
+                 var _v37 = A2($Native$Utils.compare,
+                 k,
+                 t._1);
+                 switch (_v37.ctor)
+                 {case "EQ": return t._2;
+                    case "GT": return A3(getOrElse,
+                      base,
+                      k,
+                      t._4);
+                    case "LT": return A3(getOrElse,
+                      base,
+                      k,
+                      t._3);}
+                 _E.Case($moduleName,
+                 "between lines 134 and 150");
+              }();}
+         _E.Case($moduleName,
+         "between lines 131 and 150");
+      }();
+   });
+   var get = F2(function (k,t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty":
+            switch (t._0.ctor)
+              {case "LBlack":
+                 return $Maybe.Nothing;}
+              break;
+            case "RBNode":
+            return function () {
+                 var _v45 = A2($Native$Utils.compare,
+                 k,
+                 t._1);
+                 switch (_v45.ctor)
+                 {case "EQ":
+                    return $Maybe.Just(t._2);
+                    case "GT": return A2(get,
+                      k,
+                      t._4);
+                    case "LT": return A2(get,
+                      k,
+                      t._3);}
+                 _E.Case($moduleName,
+                 "between lines 115 and 128");
+              }();}
+         _E.Case($moduleName,
+         "between lines 112 and 128");
+      }();
+   });
+   var member = F2(function (k,t) {
+      return $Maybe.isJust(A2(get,
+      k,
+      t));
+   });
+   var max = function (t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty":
+            return $Native$Error.raise("(max Empty) is not defined");
+            case "RBNode":
+            switch (t._4.ctor)
+              {case "RBEmpty":
+                 return {ctor: "_Tuple2"
+                        ,_0: t._1
+                        ,_1: t._2};}
+              return max(t._4);}
+         _E.Case($moduleName,
+         "between lines 92 and 109");
+      }();
+   };
+   var min = function (t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty":
+            switch (t._0.ctor)
+              {case "LBlack":
+                 return $Native$Error.raise("(min Empty) is not defined");}
+              break;
+            case "RBNode":
+            switch (t._3.ctor)
+              {case "RBEmpty":
+                 switch (t._3._0.ctor)
+                   {case "LBlack":
+                      return {ctor: "_Tuple2"
+                             ,_0: t._1
+                             ,_1: t._2};}
+                   break;}
+              return min(t._3);}
+         _E.Case($moduleName,
+         "between lines 85 and 88");
+      }();
+   };
+   var RBEmpty = function (a) {
+      return {ctor: "RBEmpty"
+             ,_0: a};
+   };
+   var RBNode = F5(function (a,
+   b,
+   c,
+   d,
+   e) {
+      return {ctor: "RBNode"
+             ,_0: a
+             ,_1: b
+             ,_2: c
+             ,_3: d
+             ,_4: e};
+   });
+   var showLColor = function (c) {
+      return function () {
+         switch (c.ctor)
+         {case "LBBlack":
+            return "LBBlack";
+            case "LBlack": return "LBlack";}
+         _E.Case($moduleName,
+         "between lines 71 and 73");
+      }();
+   };
+   var LBBlack = {ctor: "LBBlack"};
+   var LBlack = {ctor: "LBlack"};
+   var empty = RBEmpty(LBlack);
+   var map = F2(function (f,t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty":
+            switch (t._0.ctor)
+              {case "LBlack":
+                 return RBEmpty(LBlack);}
+              break;
+            case "RBNode": return A5(RBNode,
+              t._0,
+              t._1,
+              f(t._2),
+              A2(map,f,t._3),
+              A2(map,f,t._4));}
+         _E.Case($moduleName,
+         "between lines 353 and 358");
+      }();
+   });
+   var showNColor = function (c) {
+      return function () {
+         switch (c.ctor)
+         {case "BBlack": return "BBlack";
+            case "Black": return "Black";
+            case "NBlack": return "NBlack";
+            case "Red": return "Red";}
+         _E.Case($moduleName,
+         "between lines 60 and 64");
+      }();
+   };
+   var reportRemBug = F4(function (msg,
+   c,
+   lgot,
+   rgot) {
+      return $Native$Error.raise($List.concat(_L.fromArray(["Internal red-black tree invariant violated, expected "
+                                                           ,msg
+                                                           ,"and got"
+                                                           ,showNColor(c)
+                                                           ," "
+                                                           ,lgot
+                                                           ," "
+                                                           ,rgot
+                                                           ,"\nPlease report this bug to https://github.com/elm-lang/Elm/issues"])));
+   });
+   var NBlack = {ctor: "NBlack"};
+   var BBlack = {ctor: "BBlack"};
+   var Black = {ctor: "Black"};
+   var ensureBlackRoot = function (t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty":
+            switch (t._0.ctor)
+              {case "LBlack": return t;}
+              break;
+            case "RBNode":
+            switch (t._0.ctor)
+              {case "Black": return t;
+                 case "Red": return A5(RBNode,
+                   Black,
+                   t._1,
+                   t._2,
+                   t._3,
+                   t._4);}
+              break;}
+         _E.Case($moduleName,
+         "between lines 168 and 174");
+      }();
+   };
+   var blackish = function (t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty": return true;
+            case "RBNode":
+            return _U.eq(t._0,
+              Black) || _U.eq(t._0,BBlack);}
+         _E.Case($moduleName,
+         "between lines 304 and 306");
+      }();
+   };
+   var blacken = function (t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty":
+            return RBEmpty(LBlack);
+            case "RBNode": return A5(RBNode,
+              Black,
+              t._1,
+              t._2,
+              t._3,
+              t._4);}
+         _E.Case($moduleName,
+         "between lines 340 and 342");
+      }();
+   };
+   var Red = {ctor: "Red"};
+   var moreBlack = function (c) {
+      return function () {
+         switch (c.ctor)
+         {case "BBlack":
+            return $Native$Error.raise("Can\'t make a double black node more black!");
+            case "Black": return BBlack;
+            case "NBlack": return Red;
+            case "Red": return Black;}
+         _E.Case($moduleName,
+         "between lines 230 and 234");
+      }();
+   };
+   var lessBlack = function (c) {
+      return function () {
+         switch (c.ctor)
+         {case "BBlack": return Black;
+            case "Black": return Red;
+            case "NBlack":
+            return $Native$Error.raise("Can\'t make a negative black node less black!");
+            case "Red": return NBlack;}
+         _E.Case($moduleName,
+         "between lines 237 and 241");
+      }();
+   };
+   var lessBlackTree = function (t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty":
+            switch (t._0.ctor)
+              {case "LBBlack":
+                 return RBEmpty(LBlack);}
+              break;
+            case "RBNode": return A5(RBNode,
+              lessBlack(t._0),
+              t._1,
+              t._2,
+              t._3,
+              t._4);}
+         _E.Case($moduleName,
+         "between lines 244 and 246");
+      }();
+   };
+   var redden = function (t) {
+      return function () {
+         switch (t.ctor)
+         {case "RBEmpty":
+            return $Native$Error.raise("can\'t make a Leaf red");
+            case "RBNode": return A5(RBNode,
+              Red,
+              t._1,
+              t._2,
+              t._3,
+              t._4);}
+         _E.Case($moduleName,
+         "between lines 346 and 350");
+      }();
+   };
+   var balance_node = function (t) {
+      return function () {
+         var assemble = function (col) {
+            return function (xk) {
+               return function (xv) {
+                  return function (yk) {
+                     return function (yv) {
+                        return function (zk) {
+                           return function (zv) {
+                              return function (a) {
+                                 return function (b) {
+                                    return function (c) {
+                                       return function (d) {
+                                          return A5(RBNode,
+                                          lessBlack(col),
+                                          yk,
+                                          yv,
+                                          A5(RBNode,Black,xk,xv,a,b),
+                                          A5(RBNode,Black,zk,zv,c,d));
+                                       };
+                                    };
+                                 };
+                              };
+                           };
+                        };
+                     };
+                  };
+               };
+            };
+         };
+         return blackish(t) ? function () {
+            switch (t.ctor)
+            {case "RBNode":
+               switch (t._3.ctor)
+                 {case "RBNode":
+                    switch (t._3._0.ctor)
+                      {case "Red":
+                         switch (t._3._3.ctor)
+                           {case "RBNode":
+                              switch (t._3._3._0.ctor)
+                                {case "Red":
+                                   return assemble(t._0)(t._3._3._1)(t._3._3._2)(t._3._1)(t._3._2)(t._1)(t._2)(t._3._3._3)(t._3._3._4)(t._3._4)(t._4);}
+                                break;}
+                           switch (t._3._4.ctor)
+                           {case "RBNode":
+                              switch (t._3._4._0.ctor)
+                                {case "Red":
+                                   return assemble(t._0)(t._3._1)(t._3._2)(t._3._4._1)(t._3._4._2)(t._1)(t._2)(t._3._3)(t._3._4._3)(t._3._4._4)(t._4);}
+                                break;}
+                           break;}
+                      break;}
+                 switch (t._4.ctor)
+                 {case "RBNode":
+                    switch (t._4._0.ctor)
+                      {case "Red":
+                         switch (t._4._3.ctor)
+                           {case "RBNode":
+                              switch (t._4._3._0.ctor)
+                                {case "Red":
+                                   return assemble(t._0)(t._1)(t._2)(t._4._3._1)(t._4._3._2)(t._4._1)(t._4._2)(t._3)(t._4._3._3)(t._4._3._4)(t._4._4);}
+                                break;}
+                           switch (t._4._4.ctor)
+                           {case "RBNode":
+                              switch (t._4._4._0.ctor)
+                                {case "Red":
+                                   return assemble(t._0)(t._1)(t._2)(t._4._1)(t._4._2)(t._4._4._1)(t._4._4._2)(t._3)(t._4._3)(t._4._4._3)(t._4._4._4);}
+                                break;}
+                           break;}
+                      break;}
+                 switch (t._0.ctor)
+                 {case "BBlack":
+                    switch (t._4.ctor)
+                      {case "RBNode":
+                         switch (t._4._0.ctor)
+                           {case "NBlack":
+                              switch (t._4._3.ctor)
+                                {case "RBNode":
+                                   switch (t._4._3._0.ctor)
+                                     {case "Black":
+                                        return function () {
+                                             switch (t._4._4.ctor)
+                                             {case "RBNode":
+                                                switch (t._4._4._0.ctor)
+                                                  {case "Black":
+                                                     return A5(RBNode,
+                                                       Black,
+                                                       t._4._3._1,
+                                                       t._4._3._2,
+                                                       A5(RBNode,
+                                                       Black,
+                                                       t._1,
+                                                       t._2,
+                                                       t._3,
+                                                       t._4._3._3),
+                                                       A5(balance,
+                                                       Black,
+                                                       t._4._1,
+                                                       t._4._2,
+                                                       t._4._3._4,
+                                                       redden(t._4._4)));}
+                                                  break;}
+                                             return t;
+                                          }();}
+                                     break;}
+                                break;}
+                           break;}
+                      switch (t._3.ctor)
+                      {case "RBNode":
+                         switch (t._3._0.ctor)
+                           {case "NBlack":
+                              switch (t._3._4.ctor)
+                                {case "RBNode":
+                                   switch (t._3._4._0.ctor)
+                                     {case "Black":
+                                        return function () {
+                                             switch (t._3._3.ctor)
+                                             {case "RBNode":
+                                                switch (t._3._3._0.ctor)
+                                                  {case "Black":
+                                                     return A5(RBNode,
+                                                       Black,
+                                                       t._3._4._1,
+                                                       t._3._4._2,
+                                                       A5(balance,
+                                                       Black,
+                                                       t._3._1,
+                                                       t._3._2,
+                                                       redden(t._3._3),
+                                                       t._3._4._3),
+                                                       A5(RBNode,
+                                                       Black,
+                                                       t._1,
+                                                       t._2,
+                                                       t._3._4._4,
+                                                       t._4));}
+                                                  break;}
+                                             return t;
+                                          }();}
+                                     break;}
+                                break;}
+                           break;}
+                      break;}
+                 break;}
+            return t;
+         }() : t;
+      }();
+   };
+   var balance = F5(function (c,
+   k,
+   v,
+   l,
+   r) {
+      return balance_node(A5(RBNode,
+      c,
+      k,
+      v,
+      l,
+      r));
+   });
+   var bubble = F5(function (c,
+   k,
+   v,
+   l,
+   r) {
+      return isBBlack(l) || isBBlack(r) ? A5(balance,
+      moreBlack(c),
+      k,
+      v,
+      lessBlackTree(l),
+      lessBlackTree(r)) : A5(RBNode,
+      c,
+      k,
+      v,
+      l,
+      r);
+   });
+   var remove_max = F5(function (c,
+   k,
+   v,
+   l,
+   r) {
+      return function () {
+         switch (r.ctor)
+         {case "RBEmpty": return A3(rem,
+              c,
+              l,
+              r);
+            case "RBNode": return A5(bubble,
+              c,
+              k,
+              v,
+              l,
+              A5(remove_max,
+              r._0,
+              r._1,
+              r._2,
+              r._3,
+              r._4));}
+         _E.Case($moduleName,
+         "between lines 292 and 295");
+      }();
+   });
+   var rem = F3(function (c,l,r) {
+      return function () {
+         var _v183 = {ctor: "_Tuple2"
+                     ,_0: l
+                     ,_1: r};
+         switch (_v183.ctor)
+         {case "_Tuple2":
+            switch (_v183._0.ctor)
+              {case "RBEmpty":
+                 switch (_v183._1.ctor)
+                   {case "RBEmpty":
+                      return function () {
+                           switch (c.ctor)
+                           {case "Black":
+                              return RBEmpty(LBBlack);
+                              case "Red":
+                              return RBEmpty(LBlack);}
+                           _E.Case($moduleName,
+                           "between lines 265 and 268");
+                        }();
+                      case "RBNode":
+                      return function () {
+                           var _v205 = {ctor: "_Tuple3"
+                                       ,_0: c
+                                       ,_1: _v183._0._0
+                                       ,_2: _v183._1._0};
+                           switch (_v205.ctor)
+                           {case "_Tuple3":
+                              switch (_v205._0.ctor)
+                                {case "Black":
+                                   switch (_v205._1.ctor)
+                                     {case "LBlack":
+                                        switch (_v205._2.ctor)
+                                          {case "Red": return A5(RBNode,
+                                               Black,
+                                               _v183._1._1,
+                                               _v183._1._2,
+                                               _v183._1._3,
+                                               _v183._1._4);}
+                                          break;}
+                                     break;}
+                                break;}
+                           return A4(reportRemBug,
+                           "Black, LBlack, Red",
+                           c,
+                           showLColor(_v183._0._0),
+                           showNColor(_v183._1._0));
+                        }();}
+                   break;
+                 case "RBNode":
+                 switch (_v183._1.ctor)
+                   {case "RBEmpty":
+                      return function () {
+                           var _v209 = {ctor: "_Tuple3"
+                                       ,_0: c
+                                       ,_1: _v183._0._0
+                                       ,_2: _v183._1._0};
+                           switch (_v209.ctor)
+                           {case "_Tuple3":
+                              switch (_v209._0.ctor)
+                                {case "Black":
+                                   switch (_v209._1.ctor)
+                                     {case "Red":
+                                        switch (_v209._2.ctor)
+                                          {case "LBlack":
+                                             return A5(RBNode,
+                                               Black,
+                                               _v183._0._1,
+                                               _v183._0._2,
+                                               _v183._0._3,
+                                               _v183._0._4);}
+                                          break;}
+                                     break;}
+                                break;}
+                           return A4(reportRemBug,
+                           "Black, Red, LBlack",
+                           c,
+                           showNColor(_v183._0._0),
+                           showLColor(_v183._1._0));
+                        }();
+                      case "RBNode":
+                      return function () {
+                           var l$ = A5(remove_max,
+                           _v183._0._0,
+                           _v183._0._1,
+                           _v183._0._2,
+                           _v183._0._3,
+                           _v183._0._4);
+                           var r = A5(RBNode,
+                           _v183._1._0,
+                           _v183._1._1,
+                           _v183._1._2,
+                           _v183._1._3,
+                           _v183._1._4);
+                           var l = A5(RBNode,
+                           _v183._0._0,
+                           _v183._0._1,
+                           _v183._0._2,
+                           _v183._0._3,
+                           _v183._0._4);
+                           var $ = max(l),
+                           k = $._0,
+                           v = $._1;
+                           return A5(bubble,c,k,v,l$,r);
+                        }();}
+                   break;}
+              break;}
+         _E.Case($moduleName,
+         "between lines 264 and 282");
+      }();
+   });
+   var update = F3(function (k,
+   u,
+   t) {
+      return function () {
+         var up = function (t) {
+            return function () {
+               switch (t.ctor)
+               {case "RBEmpty":
+                  switch (t._0.ctor)
+                    {case "LBlack":
+                       return function () {
+                            var _v220 = u($Maybe.Nothing);
+                            switch (_v220.ctor)
+                            {case "Just":
+                               return {ctor: "_Tuple2"
+                                      ,_0: Insert
+                                      ,_1: A5(RBNode,
+                                      Red,
+                                      k,
+                                      _v220._0,
+                                      empty,
+                                      empty)};
+                               case "Nothing":
+                               return {ctor: "_Tuple2"
+                                      ,_0: Same
+                                      ,_1: empty};}
+                            _E.Case($moduleName,
+                            "between lines 196 and 199");
+                         }();}
+                    break;
+                  case "RBNode":
+                  return function () {
+                       var _v222 = A2($Native$Utils.compare,
+                       k,
+                       t._1);
+                       switch (_v222.ctor)
+                       {case "EQ": return function () {
+                               var _v223 = u($Maybe.Just(t._2));
+                               switch (_v223.ctor)
+                               {case "Just":
+                                  return {ctor: "_Tuple2"
+                                         ,_0: Same
+                                         ,_1: A5(RBNode,
+                                         t._0,
+                                         t._1,
+                                         _v223._0,
+                                         t._3,
+                                         t._4)};
+                                  case "Nothing":
+                                  return {ctor: "_Tuple2"
+                                         ,_0: Remove
+                                         ,_1: A3(rem,t._0,t._3,t._4)};}
+                               _E.Case($moduleName,
+                               "between lines 200 and 203");
+                            }();
+                          case "GT": return function () {
+                               var $ = up(t._4),
+                               fl = $._0,
+                               r$ = $._1;
+                               return function () {
+                                  switch (fl.ctor)
+                                  {case "Insert":
+                                     return {ctor: "_Tuple2"
+                                            ,_0: Insert
+                                            ,_1: A5(balance,
+                                            t._0,
+                                            t._1,
+                                            t._2,
+                                            t._3,
+                                            r$)};
+                                     case "Remove":
+                                     return {ctor: "_Tuple2"
+                                            ,_0: Remove
+                                            ,_1: A5(bubble,
+                                            t._0,
+                                            t._1,
+                                            t._2,
+                                            t._3,
+                                            r$)};
+                                     case "Same":
+                                     return {ctor: "_Tuple2"
+                                            ,_0: Same
+                                            ,_1: A5(RBNode,
+                                            t._0,
+                                            t._1,
+                                            t._2,
+                                            t._3,
+                                            r$)};}
+                                  _E.Case($moduleName,
+                                  "between lines 209 and 213");
+                               }();
+                            }();
+                          case "LT": return function () {
+                               var $ = up(t._3),
+                               fl = $._0,
+                               l$ = $._1;
+                               return function () {
+                                  switch (fl.ctor)
+                                  {case "Insert":
+                                     return {ctor: "_Tuple2"
+                                            ,_0: Insert
+                                            ,_1: A5(balance,
+                                            t._0,
+                                            t._1,
+                                            t._2,
+                                            l$,
+                                            t._4)};
+                                     case "Remove":
+                                     return {ctor: "_Tuple2"
+                                            ,_0: Remove
+                                            ,_1: A5(bubble,
+                                            t._0,
+                                            t._1,
+                                            t._2,
+                                            l$,
+                                            t._4)};
+                                     case "Same":
+                                     return {ctor: "_Tuple2"
+                                            ,_0: Same
+                                            ,_1: A5(RBNode,
+                                            t._0,
+                                            t._1,
+                                            t._2,
+                                            l$,
+                                            t._4)};}
+                                  _E.Case($moduleName,
+                                  "between lines 204 and 208");
+                               }();
+                            }();}
+                       _E.Case($moduleName,
+                       "between lines 199 and 213");
+                    }();}
+               _E.Case($moduleName,
+               "between lines 195 and 213");
+            }();
+         };
+         var $ = up(t),
+         fl = $._0,
+         t$ = $._1;
+         return function () {
+            switch (fl.ctor)
+            {case "Insert":
+               return ensureBlackRoot(t$);
+               case "Remove":
+               return blacken(t$);
+               case "Same": return t$;}
+            _E.Case($moduleName,
+            "between lines 214 and 219");
+         }();
+      }();
+   });
+   var insert = F3(function (k,
+   v,
+   t) {
+      return function () {
+         var u = function (_v228) {
+            return function () {
+               return $Maybe.Just(v);
+            }();
+         };
+         return A3(update,k,u,t);
+      }();
+   });
+   var singleton = F2(function (k,
+   v) {
+      return A3(insert,
+      k,
+      v,
+      RBEmpty(LBlack));
+   });
+   var union = F2(function (t1,
+   t2) {
+      return A3(foldl,
+      insert,
+      t2,
+      t1);
+   });
+   var fromList = function (assocs) {
+      return A3($List.foldl,
+      F2(function (_v230,d) {
+         return function () {
+            switch (_v230.ctor)
+            {case "_Tuple2":
+               return A3(insert,
+                 _v230._0,
+                 _v230._1,
+                 d);}
+            _E.Case($moduleName,
+            "on line 402, column 43 to 55");
+         }();
+      }),
+      empty,
+      assocs);
+   };
+   var filter = F2(function (p,
+   dict) {
+      return function () {
+         var add = F3(function (k,
+         v,
+         t) {
+            return A2(p,k,v) ? A3(insert,
+            k,
+            v,
+            t) : t;
+         });
+         return A3(foldl,add,empty,dict);
+      }();
+   });
+   var intersect = F2(function (t1,
+   t2) {
+      return A2(filter,
+      F2(function (k,_v234) {
+         return function () {
+            return A2(member,k,t2);
+         }();
+      }),
+      t1);
+   });
+   var partition = F2(function (p,
+   dict) {
+      return function () {
+         var add = F3(function (k,
+         v,
+         _v236) {
+            return function () {
+               switch (_v236.ctor)
+               {case "_Tuple2": return A2(p,
+                    k,
+                    v) ? {ctor: "_Tuple2"
+                         ,_0: A3(insert,k,v,_v236._0)
+                         ,_1: _v236._1} : {ctor: "_Tuple2"
+                                          ,_0: _v236._0
+                                          ,_1: A3(insert,k,v,_v236._1)};}
+               _E.Case($moduleName,
+               "between lines 416 and 418");
+            }();
+         });
+         return A3(foldl,
+         add,
+         {ctor: "_Tuple2"
+         ,_0: empty
+         ,_1: empty},
+         dict);
+      }();
+   });
+   var remove = F2(function (k,t) {
+      return function () {
+         var u = function (_v240) {
+            return function () {
+               return $Maybe.Nothing;
+            }();
+         };
+         return A3(update,k,u,t);
+      }();
+   });
+   var diff = F2(function (t1,t2) {
+      return A3(foldl,
+      F3(function (k,v,t) {
+         return A2(remove,k,t);
+      }),
+      t1,
+      t2);
+   });
+   _elm.Dict.values = {_op: _op
+                      ,empty: empty
+                      ,singleton: singleton
+                      ,insert: insert
+                      ,update: update
+                      ,get: get
+                      ,getOrElse: getOrElse
+                      ,getOrFail: getOrFail
+                      ,remove: remove
+                      ,member: member
+                      ,filter: filter
+                      ,partition: partition
+                      ,foldl: foldl
+                      ,foldr: foldr
+                      ,map: map
+                      ,union: union
+                      ,intersect: intersect
+                      ,diff: diff
+                      ,keys: keys
+                      ,values: values
+                      ,toList: toList
+                      ,fromList: fromList};
+   return _elm.Dict.values;
+};Elm.Either = Elm.Either || {};
+Elm.Either.make = function (_elm) {
+   "use strict";
+   _elm.Either = _elm.Either || {};
+   if (_elm.Either.values)
+   return _elm.Either.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Either",
+   $List = Elm.List.make(_elm);
+   var consEither = F2(function (e,
+   _v0) {
+      return function () {
+         switch (_v0.ctor)
+         {case "_Tuple2":
+            return function () {
+                 switch (e.ctor)
+                 {case "Left":
+                    return {ctor: "_Tuple2"
+                           ,_0: A2($List._op["::"],
+                           e._0,
+                           _v0._0)
+                           ,_1: _v0._1};
+                    case "Right":
+                    return {ctor: "_Tuple2"
+                           ,_0: _v0._0
+                           ,_1: A2($List._op["::"],
+                           e._0,
+                           _v0._1)};}
+                 _E.Case($moduleName,
+                 "between lines 89 and 91");
+              }();}
+         _E.Case($moduleName,
+         "between lines 89 and 91");
+      }();
+   });
+   var consRight = F2(function (e,
+   vs) {
+      return function () {
+         switch (e.ctor)
+         {case "Left": return vs;
+            case "Right":
+            return A2($List._op["::"],
+              e._0,
+              vs);}
+         _E.Case($moduleName,
+         "between lines 84 and 86");
+      }();
+   });
+   var consLeft = F2(function (e,
+   vs) {
+      return function () {
+         switch (e.ctor)
+         {case "Left":
+            return A2($List._op["::"],
+              e._0,
+              vs);
+            case "Right": return vs;}
+         _E.Case($moduleName,
+         "between lines 79 and 81");
+      }();
+   });
+   var partition = function (es) {
+      return A3($List.foldr,
+      consEither,
+      {ctor: "_Tuple2"
+      ,_0: _L.fromArray([])
+      ,_1: _L.fromArray([])},
+      es);
+   };
+   var rights = function (es) {
+      return A3($List.foldr,
+      consRight,
+      _L.fromArray([]),
+      es);
+   };
+   var lefts = function (es) {
+      return A3($List.foldr,
+      consLeft,
+      _L.fromArray([]),
+      es);
+   };
+   var isRight = function (e) {
+      return function () {
+         switch (e.ctor)
+         {case "Right": return true;}
+         return false;
+      }();
+   };
+   var isLeft = function (e) {
+      return function () {
+         switch (e.ctor)
+         {case "Left": return true;}
+         return false;
+      }();
+   };
+   var either = F3(function (f,
+   g,
+   e) {
+      return function () {
+         switch (e.ctor)
+         {case "Left": return f(e._0);
+            case "Right": return g(e._0);}
+         _E.Case($moduleName,
+         "on line 38, column 16 to 60");
+      }();
+   });
+   var Right = function (a) {
+      return {ctor: "Right",_0: a};
+   };
+   var Left = function (a) {
+      return {ctor: "Left",_0: a};
+   };
+   _elm.Either.values = {_op: _op
+                        ,Left: Left
+                        ,Right: Right
+                        ,either: either
+                        ,isLeft: isLeft
+                        ,isRight: isRight
+                        ,lefts: lefts
+                        ,rights: rights
+                        ,partition: partition
+                        ,consLeft: consLeft
+                        ,consRight: consRight
+                        ,consEither: consEither};
+   return _elm.Either.values;
+};Elm.Http = Elm.Http || {};
+Elm.Http.make = function (_elm) {
+   "use strict";
+   _elm.Http = _elm.Http || {};
+   if (_elm.Http.values)
+   return _elm.Http.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Http",
+   $Native$Http = Elm.Native.Http.make(_elm),
+   $Signal = Elm.Signal.make(_elm);
+   var send = $Native$Http.send;
+   var Request = F4(function (a,
+   b,
+   c,
+   d) {
+      return {_: {}
+             ,body: c
+             ,headers: d
+             ,url: b
+             ,verb: a};
+   });
+   var request = Request;
+   var get = function (url) {
+      return A4(Request,
+      "GET",
+      url,
+      "",
+      _L.fromArray([]));
+   };
+   var sendGet = function (reqs) {
+      return send(A2($Signal.lift,
+      get,
+      reqs));
+   };
+   var post = F2(function (url,
+   body) {
+      return A4(Request,
+      "POST",
+      url,
+      body,
+      _L.fromArray([]));
+   });
+   var Failure = F2(function (a,
+   b) {
+      return {ctor: "Failure"
+             ,_0: a
+             ,_1: b};
+   });
+   var Waiting = {ctor: "Waiting"};
+   var Success = function (a) {
+      return {ctor: "Success"
+             ,_0: a};
+   };
+   _elm.Http.values = {_op: _op
+                      ,Success: Success
+                      ,Waiting: Waiting
+                      ,Failure: Failure
+                      ,Request: Request
+                      ,request: request
+                      ,get: get
+                      ,post: post
+                      ,send: send
+                      ,sendGet: sendGet};
+   return _elm.Http.values;
+};Elm.Json = Elm.Json || {};
+Elm.Json.make = function (_elm) {
+   "use strict";
+   _elm.Json = _elm.Json || {};
+   if (_elm.Json.values)
+   return _elm.Json.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Json",
+   $Dict = Elm.Dict.make(_elm),
+   $Maybe = Elm.Maybe.make(_elm),
+   $Native$Json = Elm.Native.Json.make(_elm);
+   var fromString = function (str) {
+      return $Native$Json.fromString(str);
+   };
+   var toString = F2(function (sep,
+   value) {
+      return A2($Native$Json.toString,
+      sep,
+      value);
+   });
+   var Object = function (a) {
+      return {ctor: "Object"
+             ,_0: a};
+   };
+   var Array = function (a) {
+      return {ctor: "Array",_0: a};
+   };
+   var Null = {ctor: "Null"};
+   var Boolean = function (a) {
+      return {ctor: "Boolean"
+             ,_0: a};
+   };
+   var Number = function (a) {
+      return {ctor: "Number"
+             ,_0: a};
+   };
+   var String = function (a) {
+      return {ctor: "String"
+             ,_0: a};
+   };
+   _elm.Json.values = {_op: _op
+                      ,String: String
+                      ,Number: Number
+                      ,Boolean: Boolean
+                      ,Null: Null
+                      ,Array: Array
+                      ,Object: Object
+                      ,toString: toString
+                      ,fromString: fromString};
+   return _elm.Json.values;
+};Elm.Keyboard = Elm.Keyboard || {};
+Elm.Keyboard.make = function (_elm) {
+   "use strict";
+   _elm.Keyboard = _elm.Keyboard || {};
+   if (_elm.Keyboard.values)
+   return _elm.Keyboard.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Keyboard",
+   $Native$Keyboard = Elm.Native.Keyboard.make(_elm),
+   $Signal = Elm.Signal.make(_elm);
+   var lastPressed = $Native$Keyboard.lastPressed;
+   var keysDown = $Native$Keyboard.keysDown;
+   var meta = $Native$Keyboard.meta;
+   var alt = $Native$Keyboard.alt;
+   var isDown = $Native$Keyboard.isDown;
+   var ctrl = isDown(17);
+   var shift = isDown(16);
+   var space = isDown(32);
+   var enter = isDown(13);
+   var directions = $Native$Keyboard.directions;
+   var arrows = A4(directions,
+   38,
+   40,
+   37,
+   39);
+   var wasd = A4(directions,
+   87,
+   83,
+   65,
+   68);
+   _elm.Keyboard.values = {_op: _op
+                          ,directions: directions
+                          ,arrows: arrows
+                          ,wasd: wasd
+                          ,isDown: isDown
+                          ,alt: alt
+                          ,ctrl: ctrl
+                          ,meta: meta
+                          ,shift: shift
+                          ,space: space
+                          ,enter: enter
+                          ,keysDown: keysDown
+                          ,lastPressed: lastPressed};
+   return _elm.Keyboard.values;
+};Elm.List = Elm.List || {};
+Elm.List.make = function (_elm) {
+   "use strict";
+   _elm.List = _elm.List || {};
+   if (_elm.List.values)
+   return _elm.List.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "List",
+   $Basics = Elm.Basics.make(_elm),
+   $Maybe = Elm.Maybe.make(_elm),
+   $Native$List = Elm.Native.List.make(_elm);
+   var sortWith = $Native$List.sortWith;
+   var sortBy = $Native$List.sortBy;
+   var sort = $Native$List.sort;
+   var repeat = $Native$List.repeat;
+   var drop = $Native$List.drop;
+   var take = $Native$List.take;
+   var join = $Native$List.join;
+   var zipWith5 = $Native$List.zipWith5;
+   var zipWith4 = $Native$List.zipWith4;
+   var zipWith3 = $Native$List.zipWith3;
+   var zipWith = $Native$List.zipWith;
+   var zip5 = $Native$List.zipWith5(F5(function (v0,
+   v1,
+   v2,
+   v3,
+   v4) {
+      return {ctor: "_Tuple5"
+             ,_0: v0
+             ,_1: v1
+             ,_2: v2
+             ,_3: v3
+             ,_4: v4};
+   }));
+   var zip4 = $Native$List.zipWith4(F4(function (v0,
+   v1,
+   v2,
+   v3) {
+      return {ctor: "_Tuple4"
+             ,_0: v0
+             ,_1: v1
+             ,_2: v2
+             ,_3: v3};
+   }));
+   var zip3 = $Native$List.zipWith3(F3(function (v0,
+   v1,
+   v2) {
+      return {ctor: "_Tuple3"
+             ,_0: v0
+             ,_1: v1
+             ,_2: v2};
+   }));
+   var zip = $Native$List.zip;
+   var concat = $Native$List.concat;
+   var any = $Native$List.any;
+   var all = $Native$List.all;
+   var reverse = $Native$List.reverse;
+   var length = $Native$List.length;
+   var filter = $Native$List.filter;
+   var scanl1 = $Native$List.scanl1;
+   var scanl = $Native$List.scanl;
+   var foldr1 = $Native$List.foldr1;
+   var foldl1 = $Native$List.foldl1;
+   var maximum = foldl1($Basics.max);
+   var minimum = foldl1($Basics.min);
+   var foldr = $Native$List.foldr;
+   var foldl = $Native$List.foldl;
+   var sum = A2(foldl,
+   F2(function (x,y) {
+      return x + y;
+   }),
+   0);
+   var product = A2(foldl,
+   F2(function (x,y) {
+      return x * y;
+   }),
+   1);
+   var indexedMap = F2(function (f,
+   xs) {
+      return A3(zipWith,
+      f,
+      _L.range(0,length(xs) - 1),
+      xs);
+   });
+   var map = $Native$List.map;
+   var concatMap = F2(function (f,
+   list) {
+      return concat(A2(map,
+      f,
+      list));
+   });
+   var isEmpty = function (xs) {
+      return function () {
+         switch (xs.ctor)
+         {case "[]": return true;}
+         return false;
+      }();
+   };
+   var last = $Native$List.last;
+   var tail = $Native$List.tail;
+   var head = $Native$List.head;
+   _op["++"] = $Native$List.append;
+   _op["::"] = $Native$List.cons;
+   var maybeCons = F3(function (f,
+   mx,
+   xs) {
+      return function () {
+         var _v1 = f(mx);
+         switch (_v1.ctor)
+         {case "Just":
+            return A2(_op["::"],_v1._0,xs);
+            case "Nothing": return xs;}
+         _E.Case($moduleName,
+         "between lines 145 and 149");
+      }();
+   });
+   var filterMap = F2(function (f,
+   xs) {
+      return A3(foldr,
+      maybeCons(f),
+      _L.fromArray([]),
+      xs);
+   });
+   var partition = function (pred) {
+      return function () {
+         var step = F2(function (x,
+         _v3) {
+            return function () {
+               switch (_v3.ctor)
+               {case "_Tuple2":
+                  return pred(x) ? {ctor: "_Tuple2"
+                                   ,_0: A2(_op["::"],x,_v3._0)
+                                   ,_1: _v3._1} : {ctor: "_Tuple2"
+                                                  ,_0: _v3._0
+                                                  ,_1: A2(_op["::"],x,_v3._1)};}
+               _E.Case($moduleName,
+               "between lines 205 and 207");
+            }();
+         });
+         return A2(foldr,
+         step,
+         {ctor: "_Tuple2"
+         ,_0: _L.fromArray([])
+         ,_1: _L.fromArray([])});
+      }();
+   };
+   var unzip = function () {
+      var step = F2(function (_v7,
+      _v8) {
+         return function () {
+            switch (_v8.ctor)
+            {case "_Tuple2":
+               return function () {
+                    switch (_v7.ctor)
+                    {case "_Tuple2":
+                       return {ctor: "_Tuple2"
+                              ,_0: A2(_op["::"],_v7._0,_v8._0)
+                              ,_1: A2(_op["::"],
+                              _v7._1,
+                              _v8._1)};}
+                    _E.Case($moduleName,
+                    "on line 251, column 32 to 44");
+                 }();}
+            _E.Case($moduleName,
+            "on line 251, column 32 to 44");
+         }();
+      });
+      return A2(foldr,
+      step,
+      {ctor: "_Tuple2"
+      ,_0: _L.fromArray([])
+      ,_1: _L.fromArray([])});
+   }();
+   var intersperse = F2(function (sep,
+   xs) {
+      return function () {
+         switch (xs.ctor)
+         {case "::": return function () {
+                 var step = F2(function (x,
+                 rest) {
+                    return A2(_op["::"],
+                    sep,
+                    A2(_op["::"],x,rest));
+                 });
+                 var spersed = A3(foldr,
+                 step,
+                 _L.fromArray([]),
+                 xs._1);
+                 return A2(_op["::"],
+                 xs._0,
+                 spersed);
+              }();
+            case "[]":
+            return _L.fromArray([]);}
+         _E.Case($moduleName,
+         "between lines 268 and 275");
+      }();
+   });
+   _elm.List.values = {_op: _op
+                      ,head: head
+                      ,tail: tail
+                      ,last: last
+                      ,isEmpty: isEmpty
+                      ,map: map
+                      ,indexedMap: indexedMap
+                      ,foldl: foldl
+                      ,foldr: foldr
+                      ,foldl1: foldl1
+                      ,foldr1: foldr1
+                      ,scanl: scanl
+                      ,scanl1: scanl1
+                      ,filter: filter
+                      ,filterMap: filterMap
+                      ,maybeCons: maybeCons
+                      ,length: length
+                      ,reverse: reverse
+                      ,all: all
+                      ,any: any
+                      ,concat: concat
+                      ,concatMap: concatMap
+                      ,sum: sum
+                      ,product: product
+                      ,maximum: maximum
+                      ,minimum: minimum
+                      ,partition: partition
+                      ,zip: zip
+                      ,zip3: zip3
+                      ,zip4: zip4
+                      ,zip5: zip5
+                      ,zipWith: zipWith
+                      ,zipWith3: zipWith3
+                      ,zipWith4: zipWith4
+                      ,zipWith5: zipWith5
+                      ,unzip: unzip
+                      ,join: join
+                      ,intersperse: intersperse
+                      ,take: take
+                      ,drop: drop
+                      ,repeat: repeat
+                      ,sort: sort
+                      ,sortBy: sortBy
+                      ,sortWith: sortWith};
+   return _elm.List.values;
+};Elm.Maybe = Elm.Maybe || {};
+Elm.Maybe.make = function (_elm) {
+   "use strict";
+   _elm.Maybe = _elm.Maybe || {};
+   if (_elm.Maybe.values)
+   return _elm.Maybe.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Maybe";
+   var maybe = F3(function (b,
+   f,
+   m) {
+      return function () {
+         switch (m.ctor)
+         {case "Just": return f(m._0);
+            case "Nothing": return b;}
+         _E.Case($moduleName,
+         "between lines 30 and 39");
+      }();
+   });
+   var isJust = A2(maybe,
+   false,
+   function (_v2) {
+      return function () {
+         return true;
+      }();
+   });
+   var isNothing = A2(maybe,
+   true,
+   function (_v4) {
+      return function () {
+         return false;
+      }();
+   });
+   var Nothing = {ctor: "Nothing"};
+   var Just = function (a) {
+      return {ctor: "Just",_0: a};
+   };
+   var map = F2(function (f,
+   maybe) {
+      return function () {
+         switch (maybe.ctor)
+         {case "Just":
+            return Just(f(maybe._0));
+            case "Nothing": return Nothing;}
+         _E.Case($moduleName,
+         "between lines 59 and 61");
+      }();
+   });
+   _elm.Maybe.values = {_op: _op
+                       ,maybe: maybe
+                       ,isJust: isJust
+                       ,isNothing: isNothing
+                       ,map: map
+                       ,Just: Just
+                       ,Nothing: Nothing};
+   return _elm.Maybe.values;
+};Elm.Mouse = Elm.Mouse || {};
+Elm.Mouse.make = function (_elm) {
+   "use strict";
+   _elm.Mouse = _elm.Mouse || {};
+   if (_elm.Mouse.values)
+   return _elm.Mouse.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Mouse",
+   $Native$Mouse = Elm.Native.Mouse.make(_elm),
+   $Signal = Elm.Signal.make(_elm);
+   var clicks = $Native$Mouse.clicks;
+   var isDown = $Native$Mouse.isDown;
+   var y = $Native$Mouse.y;
+   var x = $Native$Mouse.x;
+   var position = $Native$Mouse.position;
+   _elm.Mouse.values = {_op: _op
+                       ,position: position
+                       ,x: x
+                       ,y: y
+                       ,isDown: isDown
+                       ,clicks: clicks};
+   return _elm.Mouse.values;
+};Elm.Random = Elm.Random || {};
+Elm.Random.make = function (_elm) {
+   "use strict";
+   _elm.Random = _elm.Random || {};
+   if (_elm.Random.values)
+   return _elm.Random.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Random",
+   $Native$Random = Elm.Native.Random.make(_elm),
+   $Signal = Elm.Signal.make(_elm);
+   var floatList = $Native$Random.floatList;
+   var $float = $Native$Random.float_;
+   var range = $Native$Random.range;
+   _elm.Random.values = {_op: _op
+                        ,range: range
+                        ,$float: $float
+                        ,floatList: floatList};
+   return _elm.Random.values;
+};Elm.Regex = Elm.Regex || {};
+Elm.Regex.make = function (_elm) {
+   "use strict";
+   _elm.Regex = _elm.Regex || {};
+   if (_elm.Regex.values)
+   return _elm.Regex.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Regex",
+   $Maybe = Elm.Maybe.make(_elm),
+   $Native$Regex = Elm.Native.Regex.make(_elm);
+   var split = $Native$Regex.split;
+   var replace = $Native$Regex.replace;
+   var find = $Native$Regex.find;
+   var AtMost = function (a) {
+      return {ctor: "AtMost"
+             ,_0: a};
+   };
+   var All = {ctor: "All"};
+   var Match = F4(function (a,
+   b,
+   c,
+   d) {
+      return {_: {}
+             ,index: c
+             ,match: a
+             ,number: d
+             ,submatches: b};
+   });
+   var contains = $Native$Regex.contains;
+   var caseInsensitive = $Native$Regex.caseInsensitive;
+   var regex = $Native$Regex.regex;
+   var escape = $Native$Regex.escape;
+   var Regex = {ctor: "Regex"};
+   _elm.Regex.values = {_op: _op
+                       ,Regex: Regex
+                       ,escape: escape
+                       ,regex: regex
+                       ,caseInsensitive: caseInsensitive
+                       ,contains: contains
+                       ,Match: Match
+                       ,All: All
+                       ,AtMost: AtMost
+                       ,find: find
+                       ,replace: replace
+                       ,split: split};
+   return _elm.Regex.values;
+};Elm.Set = Elm.Set || {};
+Elm.Set.make = function (_elm) {
+   "use strict";
+   _elm.Set = _elm.Set || {};
+   if (_elm.Set.values)
+   return _elm.Set.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Set",
+   $Dict = Elm.Dict.make(_elm),
+   $List = Elm.List.make(_elm);
+   var partition = F2(function (p,
+   set) {
+      return A2($Dict.partition,
+      F2(function (k,_v0) {
+         return function () {
+            return p(k);
+         }();
+      }),
+      set);
+   });
+   var filter = F2(function (p,
+   set) {
+      return A2($Dict.filter,
+      F2(function (k,_v2) {
+         return function () {
+            return p(k);
+         }();
+      }),
+      set);
+   });
+   var foldr = F3(function (f,
+   b,
+   s) {
+      return A3($Dict.foldr,
+      F3(function (k,_v4,b) {
+         return function () {
+            return A2(f,k,b);
+         }();
+      }),
+      b,
+      s);
+   });
+   var foldl = F3(function (f,
+   b,
+   s) {
+      return A3($Dict.foldl,
+      F3(function (k,_v6,b) {
+         return function () {
+            return A2(f,k,b);
+         }();
+      }),
+      b,
+      s);
+   });
+   var toList = $Dict.keys;
+   var diff = $Dict.diff;
+   var intersect = $Dict.intersect;
+   var union = $Dict.union;
+   var member = $Dict.member;
+   var remove = $Dict.remove;
+   var insert = function (k) {
+      return A2($Dict.insert,
+      k,
+      {ctor: "_Tuple0"});
+   };
+   var singleton = function (k) {
+      return A2($Dict.singleton,
+      k,
+      {ctor: "_Tuple0"});
+   };
+   var empty = $Dict.empty;
+   var fromList = function (xs) {
+      return A3($List.foldl,
+      insert,
+      empty,
+      xs);
+   };
+   var map = F2(function (f,s) {
+      return fromList(A2($List.map,
+      f,
+      toList(s)));
+   });
+   _elm.Set.values = {_op: _op
+                     ,empty: empty
+                     ,singleton: singleton
+                     ,insert: insert
+                     ,remove: remove
+                     ,member: member
+                     ,foldl: foldl
+                     ,foldr: foldr
+                     ,map: map
+                     ,filter: filter
+                     ,partition: partition
+                     ,union: union
+                     ,intersect: intersect
+                     ,diff: diff
+                     ,toList: toList
+                     ,fromList: fromList};
+   return _elm.Set.values;
+};Elm.Signal = Elm.Signal || {};
+Elm.Signal.make = function (_elm) {
+   "use strict";
+   _elm.Signal = _elm.Signal || {};
+   if (_elm.Signal.values)
+   return _elm.Signal.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Signal",
+   $Basics = Elm.Basics.make(_elm),
+   $List = Elm.List.make(_elm),
+   $Native$Signal = Elm.Native.Signal.make(_elm);
+   _op["~"] = F2(function (sf,s) {
+      return A3($Native$Signal.lift2,
+      F2(function (f,x) {
+         return f(x);
+      }),
+      sf,
+      s);
+   });
+   _op["<~"] = F2(function (f,s) {
+      return A2($Native$Signal.lift,
+      f,
+      s);
+   });
+   var sampleOn = $Native$Signal.sampleOn;
+   var dropRepeats = $Native$Signal.dropRepeats;
+   var dropIf = $Native$Signal.dropIf;
+   var keepIf = $Native$Signal.keepIf;
+   var keepWhen = F3(function (bs,
+   def,
+   sig) {
+      return A2(_op["<~"],
+      $Basics.snd,
+      A3(keepIf,
+      $Basics.fst,
+      {ctor: "_Tuple2"
+      ,_0: false
+      ,_1: def},
+      A2(_op["~"],
+      A2(_op["<~"],
+      F2(function (v0,v1) {
+         return {ctor: "_Tuple2"
+                ,_0: v0
+                ,_1: v1};
+      }),
+      A2(sampleOn,sig,bs)),
+      sig)));
+   });
+   var dropWhen = function (bs) {
+      return keepWhen(A2(_op["<~"],
+      $Basics.not,
+      bs));
+   };
+   var countIf = $Native$Signal.countIf;
+   var count = $Native$Signal.count;
+   var combine = A2($List.foldr,
+   $Native$Signal.lift2(F2(function (x,
+   y) {
+      return A2($List._op["::"],
+      x,
+      y);
+   })),
+   $Native$Signal.constant(_L.fromArray([])));
+   var merges = $Native$Signal.merges;
+   var merge = $Native$Signal.merge;
+   var foldp = $Native$Signal.foldp;
+   var lift8 = $Native$Signal.lift8;
+   var lift7 = $Native$Signal.lift7;
+   var lift6 = $Native$Signal.lift6;
+   var lift5 = $Native$Signal.lift5;
+   var lift4 = $Native$Signal.lift4;
+   var lift3 = $Native$Signal.lift3;
+   var lift2 = $Native$Signal.lift2;
+   var lift = $Native$Signal.lift;
+   var constant = $Native$Signal.constant;
+   var Signal = {ctor: "Signal"};
+   _elm.Signal.values = {_op: _op
+                        ,Signal: Signal
+                        ,constant: constant
+                        ,lift: lift
+                        ,lift2: lift2
+                        ,lift3: lift3
+                        ,lift4: lift4
+                        ,lift5: lift5
+                        ,lift6: lift6
+                        ,lift7: lift7
+                        ,lift8: lift8
+                        ,foldp: foldp
+                        ,merge: merge
+                        ,merges: merges
+                        ,combine: combine
+                        ,count: count
+                        ,countIf: countIf
+                        ,keepIf: keepIf
+                        ,dropIf: dropIf
+                        ,keepWhen: keepWhen
+                        ,dropWhen: dropWhen
+                        ,dropRepeats: dropRepeats
+                        ,sampleOn: sampleOn};
+   return _elm.Signal.values;
+};Elm.String = Elm.String || {};
+Elm.String.make = function (_elm) {
+   "use strict";
+   _elm.String = _elm.String || {};
+   if (_elm.String.values)
+   return _elm.String.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "String",
+   $Maybe = Elm.Maybe.make(_elm),
+   $Native$Show = Elm.Native.Show.make(_elm),
+   $Native$String = Elm.Native.String.make(_elm);
+   var fromList = $Native$String.fromList;
+   var toList = $Native$String.toList;
+   var toFloat = $Native$String.toFloat;
+   var toInt = $Native$String.toInt;
+   var show = $Native$Show.show;
+   var indices = $Native$String.indexes;
+   var indexes = $Native$String.indexes;
+   var endsWith = $Native$String.endsWith;
+   var startsWith = $Native$String.startsWith;
+   var contains = $Native$String.contains;
+   var all = $Native$String.all;
+   var any = $Native$String.any;
+   var toLower = $Native$String.toLower;
+   var toUpper = $Native$String.toUpper;
+   var lines = $Native$String.lines;
+   var words = $Native$String.words;
+   var trimRight = $Native$String.trimRight;
+   var trimLeft = $Native$String.trimLeft;
+   var trim = $Native$String.trim;
+   var padRight = $Native$String.padRight;
+   var padLeft = $Native$String.padLeft;
+   var pad = $Native$String.pad;
+   var dropRight = $Native$String.dropRight;
+   var dropLeft = $Native$String.dropLeft;
+   var right = $Native$String.right;
+   var left = $Native$String.left;
+   var slice = $Native$String.slice;
+   var repeat = $Native$String.repeat;
+   var join = $Native$String.join;
+   var split = $Native$String.split;
+   var foldr = $Native$String.foldr;
+   var foldl = $Native$String.foldl;
+   var reverse = $Native$String.reverse;
+   var filter = $Native$String.filter;
+   var map = $Native$String.map;
+   var length = $Native$String.length;
+   var concat = $Native$String.concat;
+   var append = $Native$String.append;
+   var uncons = $Native$String.uncons;
+   var cons = $Native$String.cons;
+   var isEmpty = $Native$String.isEmpty;
+   _elm.String.values = {_op: _op
+                        ,isEmpty: isEmpty
+                        ,cons: cons
+                        ,uncons: uncons
+                        ,append: append
+                        ,concat: concat
+                        ,length: length
+                        ,map: map
+                        ,filter: filter
+                        ,reverse: reverse
+                        ,foldl: foldl
+                        ,foldr: foldr
+                        ,split: split
+                        ,join: join
+                        ,repeat: repeat
+                        ,slice: slice
+                        ,left: left
+                        ,right: right
+                        ,dropLeft: dropLeft
+                        ,dropRight: dropRight
+                        ,pad: pad
+                        ,padLeft: padLeft
+                        ,padRight: padRight
+                        ,trim: trim
+                        ,trimLeft: trimLeft
+                        ,trimRight: trimRight
+                        ,words: words
+                        ,lines: lines
+                        ,toUpper: toUpper
+                        ,toLower: toLower
+                        ,any: any
+                        ,all: all
+                        ,contains: contains
+                        ,startsWith: startsWith
+                        ,endsWith: endsWith
+                        ,indexes: indexes
+                        ,indices: indices
+                        ,show: show
+                        ,toInt: toInt
+                        ,toFloat: toFloat
+                        ,toList: toList
+                        ,fromList: fromList};
+   return _elm.String.values;
+};Elm.Text = Elm.Text || {};
+Elm.Text.make = function (_elm) {
+   "use strict";
+   _elm.Text = _elm.Text || {};
+   if (_elm.Text.values)
+   return _elm.Text.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Text",
+   $Color = Elm.Color.make(_elm),
+   $Graphics$Element = Elm.Graphics.Element.make(_elm),
+   $Maybe = Elm.Maybe.make(_elm),
+   $Native$Show = Elm.Native.Show.make(_elm),
+   $Native$Text = Elm.Native.Text.make(_elm);
+   var markdown = $Native$Text.markdown;
+   var justified = $Native$Text.justified;
+   var centered = $Native$Text.centered;
+   var rightAligned = $Native$Text.rightAligned;
+   var leftAligned = $Native$Text.leftAligned;
+   var line = $Native$Text.line;
+   var italic = $Native$Text.italic;
+   var bold = $Native$Text.bold;
+   var color = $Native$Text.color;
+   var height = $Native$Text.height;
+   var link = $Native$Text.link;
+   var monospace = $Native$Text.monospace;
+   var typeface = $Native$Text.typeface;
+   var style = $Native$Text.style;
+   var toText = $Native$Text.toText;
+   var plainText = function (str) {
+      return leftAligned(toText(str));
+   };
+   var asText = function (value) {
+      return leftAligned(monospace(toText($Native$Show.show(value))));
+   };
+   var defaultStyle = {_: {}
+                      ,bold: false
+                      ,color: $Color.black
+                      ,height: $Maybe.Nothing
+                      ,italic: false
+                      ,line: $Maybe.Nothing
+                      ,typeface: _L.fromArray([])};
+   var Style = F6(function (a,
+   b,
+   c,
+   d,
+   e,
+   f) {
+      return {_: {}
+             ,bold: d
+             ,color: c
+             ,height: b
+             ,italic: e
+             ,line: f
+             ,typeface: a};
+   });
+   var Through = {ctor: "Through"};
+   var Over = {ctor: "Over"};
+   var Under = {ctor: "Under"};
+   var Text = {ctor: "Text"};
+   _elm.Text.values = {_op: _op
+                      ,Text: Text
+                      ,Under: Under
+                      ,Over: Over
+                      ,Through: Through
+                      ,Style: Style
+                      ,defaultStyle: defaultStyle
+                      ,toText: toText
+                      ,style: style
+                      ,typeface: typeface
+                      ,monospace: monospace
+                      ,link: link
+                      ,height: height
+                      ,color: color
+                      ,bold: bold
+                      ,italic: italic
+                      ,line: line
+                      ,leftAligned: leftAligned
+                      ,rightAligned: rightAligned
+                      ,centered: centered
+                      ,justified: justified
+                      ,plainText: plainText
+                      ,markdown: markdown
+                      ,asText: asText};
+   return _elm.Text.values;
+};Elm.Time = Elm.Time || {};
+Elm.Time.make = function (_elm) {
+   "use strict";
+   _elm.Time = _elm.Time || {};
+   if (_elm.Time.values)
+   return _elm.Time.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Time",
+   $Basics = Elm.Basics.make(_elm),
+   $Native$Time = Elm.Native.Time.make(_elm),
+   $Signal = Elm.Signal.make(_elm);
+   var delay = $Native$Time.delay;
+   var timestamp = $Native$Time.timestamp;
+   var since = $Native$Time.since;
+   var every = $Native$Time.every;
+   var fpsWhen = $Native$Time.fpsWhen;
+   var fps = $Native$Time.fps;
+   var inMilliseconds = function (t) {
+      return t;
+   };
+   var millisecond = 1;
+   var second = 1000 * millisecond;
+   var minute = 60 * second;
+   var hour = 60 * minute;
+   var inHours = function (t) {
+      return t / hour;
+   };
+   var inMinutes = function (t) {
+      return t / minute;
+   };
+   var inSeconds = function (t) {
+      return t / second;
+   };
+   _elm.Time.values = {_op: _op
+                      ,millisecond: millisecond
+                      ,second: second
+                      ,minute: minute
+                      ,hour: hour
+                      ,inMilliseconds: inMilliseconds
+                      ,inSeconds: inSeconds
+                      ,inMinutes: inMinutes
+                      ,inHours: inHours
+                      ,fps: fps
+                      ,fpsWhen: fpsWhen
+                      ,every: every
+                      ,since: since
+                      ,timestamp: timestamp
+                      ,delay: delay};
+   return _elm.Time.values;
+};Elm.Touch = Elm.Touch || {};
+Elm.Touch.make = function (_elm) {
+   "use strict";
+   _elm.Touch = _elm.Touch || {};
+   if (_elm.Touch.values)
+   return _elm.Touch.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Touch",
+   $Native$Touch = Elm.Native.Touch.make(_elm),
+   $Signal = Elm.Signal.make(_elm),
+   $Time = Elm.Time.make(_elm);
+   var taps = $Native$Touch.taps;
+   var touches = $Native$Touch.touches;
+   var Touch = F6(function (a,
+   b,
+   c,
+   d,
+   e,
+   f) {
+      return {_: {}
+             ,id: c
+             ,t0: f
+             ,x: a
+             ,x0: d
+             ,y: b
+             ,y0: e};
+   });
+   _elm.Touch.values = {_op: _op
+                       ,Touch: Touch
+                       ,touches: touches
+                       ,taps: taps};
+   return _elm.Touch.values;
+};Elm.Trampoline = Elm.Trampoline || {};
+Elm.Trampoline.make = function (_elm) {
+   "use strict";
+   _elm.Trampoline = _elm.Trampoline || {};
+   if (_elm.Trampoline.values)
+   return _elm.Trampoline.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Trampoline",
+   $Native$Trampoline = Elm.Native.Trampoline.make(_elm);
+   var trampoline = $Native$Trampoline.trampoline;
+   var Continue = function (a) {
+      return {ctor: "Continue"
+             ,_0: a};
+   };
+   var Done = function (a) {
+      return {ctor: "Done",_0: a};
+   };
+   _elm.Trampoline.values = {_op: _op
+                            ,Done: Done
+                            ,Continue: Continue
+                            ,trampoline: trampoline};
+   return _elm.Trampoline.values;
+};Elm.Transform2D = Elm.Transform2D || {};
+Elm.Transform2D.make = function (_elm) {
+   "use strict";
+   _elm.Transform2D = _elm.Transform2D || {};
+   if (_elm.Transform2D.values)
+   return _elm.Transform2D.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Transform2D",
+   $Native$Transform2D = Elm.Native.Transform2D.make(_elm);
+   var multiply = $Native$Transform2D.multiply;
+   var rotation = $Native$Transform2D.rotation;
+   var matrix = $Native$Transform2D.matrix;
+   var translation = F2(function (x,
+   y) {
+      return A6(matrix,
+      1,
+      0,
+      0,
+      1,
+      x,
+      y);
+   });
+   var scale = function (s) {
+      return A6(matrix,
+      s,
+      0,
+      0,
+      s,
+      0,
+      0);
+   };
+   var scaleX = function (x) {
+      return A6(matrix,
+      x,
+      0,
+      0,
+      1,
+      0,
+      0);
+   };
+   var scaleY = function (y) {
+      return A6(matrix,
+      1,
+      0,
+      0,
+      y,
+      0,
+      0);
+   };
+   var identity = $Native$Transform2D.identity;
+   var Transform2D = {ctor: "Transform2D"};
+   _elm.Transform2D.values = {_op: _op
+                             ,identity: identity
+                             ,matrix: matrix
+                             ,multiply: multiply
+                             ,rotation: rotation
+                             ,translation: translation
+                             ,scale: scale
+                             ,scaleX: scaleX
+                             ,scaleY: scaleY};
+   return _elm.Transform2D.values;
+};Elm.WebSocket = Elm.WebSocket || {};
+Elm.WebSocket.make = function (_elm) {
+   "use strict";
+   _elm.WebSocket = _elm.WebSocket || {};
+   if (_elm.WebSocket.values)
+   return _elm.WebSocket.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "WebSocket",
+   $Native$WebSocket = Elm.Native.WebSocket.make(_elm),
+   $Signal = Elm.Signal.make(_elm);
+   var connect = $Native$WebSocket.connect;
+   _elm.WebSocket.values = {_op: _op
+                           ,connect: connect};
+   return _elm.WebSocket.values;
+};Elm.Window = Elm.Window || {};
+Elm.Window.make = function (_elm) {
+   "use strict";
+   _elm.Window = _elm.Window || {};
+   if (_elm.Window.values)
+   return _elm.Window.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Window",
+   $Native$Window = Elm.Native.Window.make(_elm),
+   $Signal = Elm.Signal.make(_elm);
+   var height = $Native$Window.height;
+   var width = $Native$Window.width;
+   var dimensions = $Native$Window.dimensions;
+   _elm.Window.values = {_op: _op
+                        ,dimensions: dimensions
+                        ,width: width
+                        ,height: height};
+   return _elm.Window.values;
+};Elm.Graphics = Elm.Graphics || {};
+Elm.Graphics.Collage = Elm.Graphics.Collage || {};
+Elm.Graphics.Collage.make = function (_elm) {
+   "use strict";
+   _elm.Graphics = _elm.Graphics || {};
+   _elm.Graphics.Collage = _elm.Graphics.Collage || {};
+   if (_elm.Graphics.Collage.values)
+   return _elm.Graphics.Collage.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Graphics.Collage",
+   $Basics = Elm.Basics.make(_elm),
+   $Color = Elm.Color.make(_elm),
+   $Either = Elm.Either.make(_elm),
+   $Graphics$Element = Elm.Graphics.Element.make(_elm),
+   $List = Elm.List.make(_elm),
+   $Native$Graphics$Collage = Elm.Native.Graphics.Collage.make(_elm),
+   $Transform2D = Elm.Transform2D.make(_elm);
+   var ngon = F2(function (n,r) {
+      return function () {
+         var m = $Basics.toFloat(n);
+         var t = 2 * $Basics.pi / m;
+         var f = function (i) {
+            return {ctor: "_Tuple2"
+                   ,_0: r * $Basics.cos(t * i)
+                   ,_1: r * $Basics.sin(t * i)};
+         };
+         return A2($List.map,
+         f,
+         _L.range(0,m - 1));
+      }();
+   });
+   var oval = F2(function (w,h) {
+      return function () {
+         var hh = h / 2;
+         var hw = w / 2;
+         var n = 50;
+         var t = 2 * $Basics.pi / n;
+         var f = function (i) {
+            return {ctor: "_Tuple2"
+                   ,_0: hw * $Basics.cos(t * i)
+                   ,_1: hh * $Basics.sin(t * i)};
+         };
+         return A2($List.map,
+         f,
+         _L.range(0,n - 1));
+      }();
+   });
+   var circle = function (r) {
+      return A2(oval,2 * r,2 * r);
+   };
+   var rect = F2(function (w,h) {
+      return function () {
+         var hh = h / 2;
+         var hw = w / 2;
+         return _L.fromArray([{ctor: "_Tuple2"
+                              ,_0: 0 - hw
+                              ,_1: 0 - hh}
+                             ,{ctor: "_Tuple2"
+                              ,_0: 0 - hw
+                              ,_1: hh}
+                             ,{ctor: "_Tuple2",_0: hw,_1: hh}
+                             ,{ctor: "_Tuple2"
+                              ,_0: hw
+                              ,_1: 0 - hh}]);
+      }();
+   });
+   var square = function (n) {
+      return A2(rect,n,n);
+   };
+   var polygon = function (points) {
+      return points;
+   };
+   var segment = F2(function (p1,
+   p2) {
+      return _L.fromArray([p1,p2]);
+   });
+   var path = function (ps) {
+      return ps;
+   };
+   var collage = $Native$Graphics$Collage.collage;
+   var alpha = F2(function (a,f) {
+      return _U.replace([["alpha"
+                         ,a]],
+      f);
+   });
+   var rotate = F2(function (t,f) {
+      return _U.replace([["theta"
+                         ,f.theta + t]],
+      f);
+   });
+   var scale = F2(function (s,f) {
+      return _U.replace([["scale"
+                         ,f.scale * s]],
+      f);
+   });
+   var moveY = F2(function (y,f) {
+      return _U.replace([["y"
+                         ,f.y + y]],
+      f);
+   });
+   var moveX = F2(function (x,f) {
+      return _U.replace([["x"
+                         ,f.x + x]],
+      f);
+   });
+   var move = F2(function (_v0,f) {
+      return function () {
+         switch (_v0.ctor)
+         {case "_Tuple2":
+            return _U.replace([["x"
+                               ,f.x + _v0._0]
+                              ,["y",f.y + _v0._1]],
+              f);}
+         _E.Case($moduleName,
+         "on line 170, column 20 to 48");
+      }();
+   });
+   var form = function (f) {
+      return {_: {}
+             ,alpha: 1
+             ,form: f
+             ,scale: 1
+             ,theta: 0
+             ,x: 0
+             ,y: 0};
+   };
+   var FGroup = F2(function (a,b) {
+      return {ctor: "FGroup"
+             ,_0: a
+             ,_1: b};
+   });
+   var group = function (fs) {
+      return form(A2(FGroup,
+      $Transform2D.identity,
+      fs));
+   };
+   var groupTransform = F2(function (matrix,
+   fs) {
+      return form(A2(FGroup,
+      matrix,
+      fs));
+   });
+   var FElement = function (a) {
+      return {ctor: "FElement"
+             ,_0: a};
+   };
+   var toForm = function (e) {
+      return form(FElement(e));
+   };
+   var FImage = F4(function (a,
+   b,
+   c,
+   d) {
+      return {ctor: "FImage"
+             ,_0: a
+             ,_1: b
+             ,_2: c
+             ,_3: d};
+   });
+   var sprite = F4(function (w,
+   h,
+   pos,
+   src) {
+      return form(A4(FImage,
+      w,
+      h,
+      pos,
+      src));
+   });
+   var FShape = F2(function (a,b) {
+      return {ctor: "FShape"
+             ,_0: a
+             ,_1: b};
+   });
+   var fill = F2(function (style,
+   shape) {
+      return form(A2(FShape,
+      $Either.Right(style),
+      shape));
+   });
+   var outlined = F2(function (style,
+   shape) {
+      return form(A2(FShape,
+      $Either.Left(style),
+      shape));
+   });
+   var FPath = F2(function (a,b) {
+      return {ctor: "FPath"
+             ,_0: a
+             ,_1: b};
+   });
+   var traced = F2(function (style,
+   path) {
+      return form(A2(FPath,
+      style,
+      path));
+   });
+   var LineStyle = F6(function (a,
+   b,
+   c,
+   d,
+   e,
+   f) {
+      return {_: {}
+             ,cap: c
+             ,color: a
+             ,dashOffset: f
+             ,dashing: e
+             ,join: d
+             ,width: b};
+   });
+   var Clipped = {ctor: "Clipped"};
+   var Sharp = function (a) {
+      return {ctor: "Sharp",_0: a};
+   };
+   var Smooth = {ctor: "Smooth"};
+   var Padded = {ctor: "Padded"};
+   var Round = {ctor: "Round"};
+   var Flat = {ctor: "Flat"};
+   var defaultLine = {_: {}
+                     ,cap: Flat
+                     ,color: $Color.black
+                     ,dashOffset: 0
+                     ,dashing: _L.fromArray([])
+                     ,join: Sharp(10)
+                     ,width: 1};
+   var solid = function (clr) {
+      return _U.replace([["color"
+                         ,clr]],
+      defaultLine);
+   };
+   var dashed = function (clr) {
+      return _U.replace([["color"
+                         ,clr]
+                        ,["dashing"
+                         ,_L.fromArray([8,4])]],
+      defaultLine);
+   };
+   var dotted = function (clr) {
+      return _U.replace([["color"
+                         ,clr]
+                        ,["dashing"
+                         ,_L.fromArray([3,3])]],
+      defaultLine);
+   };
+   var Grad = function (a) {
+      return {ctor: "Grad",_0: a};
+   };
+   var gradient = F2(function (grad,
+   shape) {
+      return A2(fill,
+      Grad(grad),
+      shape);
+   });
+   var Texture = function (a) {
+      return {ctor: "Texture"
+             ,_0: a};
+   };
+   var textured = F2(function (src,
+   shape) {
+      return A2(fill,
+      Texture(src),
+      shape);
+   });
+   var Solid = function (a) {
+      return {ctor: "Solid",_0: a};
+   };
+   var filled = F2(function (color,
+   shape) {
+      return A2(fill,
+      Solid(color),
+      shape);
+   });
+   var Form = F6(function (a,
+   b,
+   c,
+   d,
+   e,
+   f) {
+      return {_: {}
+             ,alpha: e
+             ,form: f
+             ,scale: b
+             ,theta: a
+             ,x: c
+             ,y: d};
+   });
+   _elm.Graphics.Collage.values = {_op: _op
+                                  ,Form: Form
+                                  ,Solid: Solid
+                                  ,Texture: Texture
+                                  ,Grad: Grad
+                                  ,Flat: Flat
+                                  ,Round: Round
+                                  ,Padded: Padded
+                                  ,Smooth: Smooth
+                                  ,Sharp: Sharp
+                                  ,Clipped: Clipped
+                                  ,LineStyle: LineStyle
+                                  ,defaultLine: defaultLine
+                                  ,solid: solid
+                                  ,dashed: dashed
+                                  ,dotted: dotted
+                                  ,FPath: FPath
+                                  ,FShape: FShape
+                                  ,FImage: FImage
+                                  ,FElement: FElement
+                                  ,FGroup: FGroup
+                                  ,form: form
+                                  ,fill: fill
+                                  ,filled: filled
+                                  ,textured: textured
+                                  ,gradient: gradient
+                                  ,outlined: outlined
+                                  ,traced: traced
+                                  ,sprite: sprite
+                                  ,toForm: toForm
+                                  ,group: group
+                                  ,groupTransform: groupTransform
+                                  ,move: move
+                                  ,moveX: moveX
+                                  ,moveY: moveY
+                                  ,scale: scale
+                                  ,rotate: rotate
+                                  ,alpha: alpha
+                                  ,collage: collage
+                                  ,path: path
+                                  ,segment: segment
+                                  ,polygon: polygon
+                                  ,rect: rect
+                                  ,square: square
+                                  ,oval: oval
+                                  ,circle: circle
+                                  ,ngon: ngon};
+   return _elm.Graphics.Collage.values;
+};Elm.Graphics = Elm.Graphics || {};
+Elm.Graphics.Element = Elm.Graphics.Element || {};
+Elm.Graphics.Element.make = function (_elm) {
+   "use strict";
+   _elm.Graphics = _elm.Graphics || {};
+   _elm.Graphics.Element = _elm.Graphics.Element || {};
+   if (_elm.Graphics.Element.values)
+   return _elm.Graphics.Element.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Graphics.Element",
+   $Basics = Elm.Basics.make(_elm),
+   $Color = Elm.Color.make(_elm),
+   $List = Elm.List.make(_elm),
+   $Maybe = Elm.Maybe.make(_elm),
+   $Native$Utils = Elm.Native.Utils.make(_elm);
+   var DOut = {ctor: "DOut"};
+   var outward = DOut;
+   var DIn = {ctor: "DIn"};
+   var inward = DIn;
+   var DRight = {ctor: "DRight"};
+   var right = DRight;
+   var DLeft = {ctor: "DLeft"};
+   var left = DLeft;
+   var DDown = {ctor: "DDown"};
+   var down = DDown;
+   var DUp = {ctor: "DUp"};
+   var up = DUp;
+   var Position = F4(function (a,
+   b,
+   c,
+   d) {
+      return {_: {}
+             ,horizontal: a
+             ,vertical: b
+             ,x: c
+             ,y: d};
+   });
+   var Relative = function (a) {
+      return {ctor: "Relative"
+             ,_0: a};
+   };
+   var relative = Relative;
+   var Absolute = function (a) {
+      return {ctor: "Absolute"
+             ,_0: a};
+   };
+   var absolute = Absolute;
+   var N = {ctor: "N"};
+   var bottomLeftAt = F2(function (x,
+   y) {
+      return {_: {}
+             ,horizontal: N
+             ,vertical: N
+             ,x: x
+             ,y: y};
+   });
+   var Z = {ctor: "Z"};
+   var middle = {_: {}
+                ,horizontal: Z
+                ,vertical: Z
+                ,x: Relative(0.5)
+                ,y: Relative(0.5)};
+   var midLeft = _U.replace([["horizontal"
+                             ,N]
+                            ,["x",Absolute(0)]],
+   middle);
+   var middleAt = F2(function (x,
+   y) {
+      return {_: {}
+             ,horizontal: Z
+             ,vertical: Z
+             ,x: x
+             ,y: y};
+   });
+   var midLeftAt = F2(function (x,
+   y) {
+      return {_: {}
+             ,horizontal: N
+             ,vertical: Z
+             ,x: x
+             ,y: y};
+   });
+   var midBottomAt = F2(function (x,
+   y) {
+      return {_: {}
+             ,horizontal: Z
+             ,vertical: N
+             ,x: x
+             ,y: y};
+   });
+   var P = {ctor: "P"};
+   var topLeft = {_: {}
+                 ,horizontal: N
+                 ,vertical: P
+                 ,x: Absolute(0)
+                 ,y: Absolute(0)};
+   var bottomLeft = _U.replace([["vertical"
+                                ,N]],
+   topLeft);
+   var topRight = _U.replace([["horizontal"
+                              ,P]],
+   topLeft);
+   var bottomRight = _U.replace([["horizontal"
+                                 ,P]],
+   bottomLeft);
+   var midRight = _U.replace([["horizontal"
+                              ,P]],
+   midLeft);
+   var midTop = _U.replace([["vertical"
+                            ,P]
+                           ,["y",Absolute(0)]],
+   middle);
+   var midBottom = _U.replace([["vertical"
+                               ,N]],
+   midTop);
+   var topLeftAt = F2(function (x,
+   y) {
+      return {_: {}
+             ,horizontal: N
+             ,vertical: P
+             ,x: x
+             ,y: y};
+   });
+   var topRightAt = F2(function (x,
+   y) {
+      return {_: {}
+             ,horizontal: P
+             ,vertical: P
+             ,x: x
+             ,y: y};
+   });
+   var bottomRightAt = F2(function (x,
+   y) {
+      return {_: {}
+             ,horizontal: P
+             ,vertical: N
+             ,x: x
+             ,y: y};
+   });
+   var midRightAt = F2(function (x,
+   y) {
+      return {_: {}
+             ,horizontal: P
+             ,vertical: Z
+             ,x: x
+             ,y: y};
+   });
+   var midTopAt = F2(function (x,
+   y) {
+      return {_: {}
+             ,horizontal: Z
+             ,vertical: P
+             ,x: x
+             ,y: y};
+   });
+   var Tiled = {ctor: "Tiled"};
+   var Cropped = function (a) {
+      return {ctor: "Cropped"
+             ,_0: a};
+   };
+   var Fitted = {ctor: "Fitted"};
+   var Plain = {ctor: "Plain"};
+   var Custom = {ctor: "Custom"};
+   var RawHtml = {ctor: "RawHtml"};
+   var Spacer = {ctor: "Spacer"};
+   var Flow = F2(function (a,b) {
+      return {ctor: "Flow"
+             ,_0: a
+             ,_1: b};
+   });
+   var Container = F2(function (a,
+   b) {
+      return {ctor: "Container"
+             ,_0: a
+             ,_1: b};
+   });
+   var Image = F4(function (a,
+   b,
+   c,
+   d) {
+      return {ctor: "Image"
+             ,_0: a
+             ,_1: b
+             ,_2: c
+             ,_3: d};
+   });
+   var link = F2(function (href,
+   e) {
+      return function () {
+         var p = e.props;
+         return {_: {}
+                ,element: e.element
+                ,props: _U.replace([["href"
+                                    ,href]],
+                p)};
+      }();
+   });
+   var tag = F2(function (name,e) {
+      return function () {
+         var p = e.props;
+         return {_: {}
+                ,element: e.element
+                ,props: _U.replace([["tag"
+                                    ,name]],
+                p)};
+      }();
+   });
+   var color = F2(function (c,e) {
+      return function () {
+         var p = e.props;
+         return {_: {}
+                ,element: e.element
+                ,props: _U.replace([["color"
+                                    ,$Maybe.Just(c)]],
+                p)};
+      }();
+   });
+   var opacity = F2(function (o,
+   e) {
+      return function () {
+         var p = e.props;
+         return {_: {}
+                ,element: e.element
+                ,props: _U.replace([["opacity"
+                                    ,o]],
+                p)};
+      }();
+   });
+   var height = F2(function (nh,
+   e) {
+      return function () {
+         var p = e.props;
+         var props = function () {
+            var _v0 = e.element;
+            switch (_v0.ctor)
+            {case "Image":
+               return _U.replace([["width"
+                                  ,$Basics.round($Basics.toFloat(_v0._1) / $Basics.toFloat(_v0._2) * $Basics.toFloat(nh))]],
+                 p);}
+            return p;
+         }();
+         return {_: {}
+                ,element: e.element
+                ,props: _U.replace([["height"
+                                    ,nh]],
+                p)};
+      }();
+   });
+   var width = F2(function (nw,e) {
+      return function () {
+         var p = e.props;
+         var props = function () {
+            var _v5 = e.element;
+            switch (_v5.ctor)
+            {case "Image":
+               return _U.replace([["height"
+                                  ,$Basics.round($Basics.toFloat(_v5._2) / $Basics.toFloat(_v5._1) * $Basics.toFloat(nw))]],
+                 p);
+               case "RawHtml":
+               return _U.replace([["height"
+                                  ,$Basics.snd(A2($Native$Utils.htmlHeight,
+                                  nw,
+                                  e.element))]],
+                 p);}
+            return p;
+         }();
+         return {_: {}
+                ,element: e.element
+                ,props: _U.replace([["width"
+                                    ,nw]],
+                props)};
+      }();
+   });
+   var size = F3(function (w,h,e) {
+      return A2(height,
+      h,
+      A2(width,w,e));
+   });
+   var sizeOf = function (e) {
+      return {ctor: "_Tuple2"
+             ,_0: e.props.width
+             ,_1: e.props.height};
+   };
+   var heightOf = function (e) {
+      return e.props.height;
+   };
+   var widthOf = function (e) {
+      return e.props.width;
+   };
+   var Element = F2(function (a,
+   b) {
+      return {_: {}
+             ,element: b
+             ,props: a};
+   });
+   var Properties = F9(function (a,
+   b,
+   c,
+   d,
+   e,
+   f,
+   g,
+   h,
+   i) {
+      return {_: {}
+             ,click: i
+             ,color: e
+             ,height: c
+             ,hover: h
+             ,href: f
+             ,id: a
+             ,opacity: d
+             ,tag: g
+             ,width: b};
+   });
+   var newElement = F3(function (w,
+   h,
+   e) {
+      return {_: {}
+             ,element: e
+             ,props: A9(Properties,
+             $Native$Utils.guid({ctor: "_Tuple0"}),
+             w,
+             h,
+             1,
+             $Maybe.Nothing,
+             "",
+             "",
+             {ctor: "_Tuple0"},
+             {ctor: "_Tuple0"})};
+   });
+   var image = F3(function (w,
+   h,
+   src) {
+      return A3(newElement,
+      w,
+      h,
+      A4(Image,Plain,w,h,src));
+   });
+   var fittedImage = F3(function (w,
+   h,
+   src) {
+      return A3(newElement,
+      w,
+      h,
+      A4(Image,Fitted,w,h,src));
+   });
+   var croppedImage = F4(function (pos,
+   w,
+   h,
+   src) {
+      return A3(newElement,
+      w,
+      h,
+      A4(Image,Cropped(pos),w,h,src));
+   });
+   var tiledImage = F3(function (w,
+   h,
+   src) {
+      return A3(newElement,
+      w,
+      h,
+      A4(Image,Tiled,w,h,src));
+   });
+   var container = F4(function (w,
+   h,
+   pos,
+   e) {
+      return A3(newElement,
+      w,
+      h,
+      A2(Container,pos,e));
+   });
+   var spacer = F2(function (w,h) {
+      return A3(newElement,
+      w,
+      h,
+      Spacer);
+   });
+   var empty = A2(spacer,0,0);
+   var flow = F2(function (dir,
+   es) {
+      return function () {
+         var newFlow = F2(function (w,
+         h) {
+            return A3(newElement,
+            w,
+            h,
+            A2(Flow,dir,es));
+         });
+         var hs = A2($List.map,
+         heightOf,
+         es);
+         var ws = A2($List.map,
+         widthOf,
+         es);
+         return _U.eq(es,
+         _L.fromArray([])) ? empty : function () {
+            switch (dir.ctor)
+            {case "DDown":
+               return A2(newFlow,
+                 $List.maximum(ws),
+                 $List.sum(hs));
+               case "DIn": return A2(newFlow,
+                 $List.maximum(ws),
+                 $List.maximum(hs));
+               case "DLeft": return A2(newFlow,
+                 $List.sum(ws),
+                 $List.maximum(hs));
+               case "DOut": return A2(newFlow,
+                 $List.maximum(ws),
+                 $List.maximum(hs));
+               case "DRight":
+               return A2(newFlow,
+                 $List.sum(ws),
+                 $List.maximum(hs));
+               case "DUp": return A2(newFlow,
+                 $List.maximum(ws),
+                 $List.sum(hs));}
+            _E.Case($moduleName,
+            "between lines 206 and 216");
+         }();
+      }();
+   });
+   var above = F2(function (hi,
+   lo) {
+      return A3(newElement,
+      A2($Basics.max,
+      widthOf(hi),
+      widthOf(lo)),
+      heightOf(hi) + heightOf(lo),
+      A2(Flow,
+      DDown,
+      _L.fromArray([hi,lo])));
+   });
+   var below = F2(function (lo,
+   hi) {
+      return A3(newElement,
+      A2($Basics.max,
+      widthOf(hi),
+      widthOf(lo)),
+      heightOf(hi) + heightOf(lo),
+      A2(Flow,
+      DDown,
+      _L.fromArray([hi,lo])));
+   });
+   var beside = F2(function (lft,
+   rht) {
+      return A3(newElement,
+      widthOf(lft) + widthOf(rht),
+      A2($Basics.max,
+      heightOf(lft),
+      heightOf(rht)),
+      A2(Flow,
+      right,
+      _L.fromArray([lft,rht])));
+   });
+   var layers = function (es) {
+      return function () {
+         var hs = A2($List.map,
+         heightOf,
+         es);
+         var ws = A2($List.map,
+         widthOf,
+         es);
+         return A3(newElement,
+         $List.maximum(ws),
+         $List.maximum(hs),
+         A2(Flow,DOut,es));
+      }();
+   };
+   _elm.Graphics.Element.values = {_op: _op
+                                  ,Properties: Properties
+                                  ,Element: Element
+                                  ,empty: empty
+                                  ,widthOf: widthOf
+                                  ,heightOf: heightOf
+                                  ,sizeOf: sizeOf
+                                  ,width: width
+                                  ,height: height
+                                  ,size: size
+                                  ,opacity: opacity
+                                  ,color: color
+                                  ,tag: tag
+                                  ,link: link
+                                  ,newElement: newElement
+                                  ,Image: Image
+                                  ,Container: Container
+                                  ,Flow: Flow
+                                  ,Spacer: Spacer
+                                  ,RawHtml: RawHtml
+                                  ,Custom: Custom
+                                  ,Plain: Plain
+                                  ,Fitted: Fitted
+                                  ,Cropped: Cropped
+                                  ,Tiled: Tiled
+                                  ,image: image
+                                  ,fittedImage: fittedImage
+                                  ,croppedImage: croppedImage
+                                  ,tiledImage: tiledImage
+                                  ,P: P
+                                  ,Z: Z
+                                  ,N: N
+                                  ,Absolute: Absolute
+                                  ,Relative: Relative
+                                  ,Position: Position
+                                  ,container: container
+                                  ,spacer: spacer
+                                  ,DUp: DUp
+                                  ,DDown: DDown
+                                  ,DLeft: DLeft
+                                  ,DRight: DRight
+                                  ,DIn: DIn
+                                  ,DOut: DOut
+                                  ,flow: flow
+                                  ,above: above
+                                  ,below: below
+                                  ,beside: beside
+                                  ,layers: layers
+                                  ,absolute: absolute
+                                  ,relative: relative
+                                  ,middle: middle
+                                  ,topLeft: topLeft
+                                  ,topRight: topRight
+                                  ,bottomLeft: bottomLeft
+                                  ,bottomRight: bottomRight
+                                  ,midLeft: midLeft
+                                  ,midRight: midRight
+                                  ,midTop: midTop
+                                  ,midBottom: midBottom
+                                  ,middleAt: middleAt
+                                  ,topLeftAt: topLeftAt
+                                  ,topRightAt: topRightAt
+                                  ,bottomLeftAt: bottomLeftAt
+                                  ,bottomRightAt: bottomRightAt
+                                  ,midLeftAt: midLeftAt
+                                  ,midRightAt: midRightAt
+                                  ,midTopAt: midTopAt
+                                  ,midBottomAt: midBottomAt
+                                  ,up: up
+                                  ,down: down
+                                  ,left: left
+                                  ,right: right
+                                  ,inward: inward
+                                  ,outward: outward};
+   return _elm.Graphics.Element.values;
+};Elm.Graphics = Elm.Graphics || {};
+Elm.Graphics.Input = Elm.Graphics.Input || {};
+Elm.Graphics.Input.make = function (_elm) {
+   "use strict";
+   _elm.Graphics = _elm.Graphics || {};
+   _elm.Graphics.Input = _elm.Graphics.Input || {};
+   if (_elm.Graphics.Input.values)
+   return _elm.Graphics.Input.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Graphics.Input",
+   $Graphics$Element = Elm.Graphics.Element.make(_elm),
+   $Native$Graphics$Input = Elm.Native.Graphics.Input.make(_elm),
+   $Signal = Elm.Signal.make(_elm);
+   var clickable = $Native$Graphics$Input.clickable;
+   var hoverable = $Native$Graphics$Input.hoverable;
+   var dropDown = $Native$Graphics$Input.dropDown;
+   var checkbox = $Native$Graphics$Input.checkbox;
+   var customButton = $Native$Graphics$Input.customButton;
+   var button = $Native$Graphics$Input.button;
+   var input = $Native$Graphics$Input.input;
+   var Handle = {ctor: "Handle"};
+   var Input = F2(function (a,b) {
+      return {_: {}
+             ,handle: b
+             ,signal: a};
+   });
+   _elm.Graphics.Input.values = {_op: _op
+                                ,Input: Input
+                                ,Handle: Handle
+                                ,input: input
+                                ,button: button
+                                ,customButton: customButton
+                                ,checkbox: checkbox
+                                ,dropDown: dropDown
+                                ,hoverable: hoverable
+                                ,clickable: clickable};
+   return _elm.Graphics.Input.values;
+};Elm.Graphics = Elm.Graphics || {};
+Elm.Graphics.Input = Elm.Graphics.Input || {};
+Elm.Graphics.Input.Field = Elm.Graphics.Input.Field || {};
+Elm.Graphics.Input.Field.make = function (_elm) {
+   "use strict";
+   _elm.Graphics = _elm.Graphics || {};
+   _elm.Graphics.Input = _elm.Graphics.Input || {};
+   _elm.Graphics.Input.Field = _elm.Graphics.Input.Field || {};
+   if (_elm.Graphics.Input.Field.values)
+   return _elm.Graphics.Input.Field.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "Graphics.Input.Field",
+   $Color = Elm.Color.make(_elm),
+   $Graphics$Element = Elm.Graphics.Element.make(_elm),
+   $Graphics$Input = Elm.Graphics.Input.make(_elm),
+   $Native$Graphics$Input = Elm.Native.Graphics.Input.make(_elm),
+   $Text = Elm.Text.make(_elm);
+   var email = $Native$Graphics$Input.email;
+   var password = $Native$Graphics$Input.password;
+   var field = $Native$Graphics$Input.field;
+   var Backward = {ctor: "Backward"};
+   var Forward = {ctor: "Forward"};
+   var Selection = F3(function (a,
+   b,
+   c) {
+      return {_: {}
+             ,direction: c
+             ,end: b
+             ,start: a};
+   });
+   var Content = F2(function (a,
+   b) {
+      return {_: {}
+             ,selection: b
+             ,string: a};
+   });
+   var noContent = A2(Content,
+   "",
+   A3(Selection,0,0,Forward));
+   var Style = F4(function (a,
+   b,
+   c,
+   d) {
+      return {_: {}
+             ,highlight: c
+             ,outline: b
+             ,padding: a
+             ,style: d};
+   });
+   var Highlight = F2(function (a,
+   b) {
+      return {_: {}
+             ,color: a
+             ,width: b};
+   });
+   var noHighlight = A2(Highlight,
+   $Color.blue,
+   0);
+   var Outline = F3(function (a,
+   b,
+   c) {
+      return {_: {}
+             ,color: a
+             ,radius: c
+             ,width: b};
+   });
+   var Dimensions = F4(function (a,
+   b,
+   c,
+   d) {
+      return {_: {}
+             ,bottom: d
+             ,left: a
+             ,right: b
+             ,top: c};
+   });
+   var uniformly = function (n) {
+      return A4(Dimensions,
+      n,
+      n,
+      n,
+      n);
+   };
+   var noOutline = A3(Outline,
+   $Color.grey,
+   uniformly(0),
+   0);
+   var defaultStyle = {_: {}
+                      ,highlight: A2(Highlight,
+                      $Color.blue,
+                      1)
+                      ,outline: A3(Outline,
+                      $Color.grey,
+                      uniformly(1),
+                      2)
+                      ,padding: uniformly(4)
+                      ,style: $Text.defaultStyle};
+   _elm.Graphics.Input.Field.values = {_op: _op
+                                      ,uniformly: uniformly
+                                      ,Dimensions: Dimensions
+                                      ,Outline: Outline
+                                      ,noOutline: noOutline
+                                      ,Highlight: Highlight
+                                      ,noHighlight: noHighlight
+                                      ,Style: Style
+                                      ,defaultStyle: defaultStyle
+                                      ,Content: Content
+                                      ,Selection: Selection
+                                      ,Forward: Forward
+                                      ,Backward: Backward
+                                      ,noContent: noContent
+                                      ,field: field
+                                      ,password: password
+                                      ,email: email};
+   return _elm.Graphics.Input.Field.values;
+};Elm.JavaScript = Elm.JavaScript || {};
+Elm.JavaScript.Experimental = Elm.JavaScript.Experimental || {};
+Elm.JavaScript.Experimental.make = function (_elm) {
+   "use strict";
+   _elm.JavaScript = _elm.JavaScript || {};
+   _elm.JavaScript.Experimental = _elm.JavaScript.Experimental || {};
+   if (_elm.JavaScript.Experimental.values)
+   return _elm.JavaScript.Experimental.values;
+   var _op = {},
+   _N = Elm.Native,
+   _U = _N.Utils.make(_elm),
+   _L = _N.List.make(_elm),
+   _A = _N.Array.make(_elm),
+   _E = _N.Error.make(_elm),
+   $moduleName = "JavaScript.Experimental",
+   $Json = Elm.Json.make(_elm),
+   $Native$JavaScript = Elm.Native.JavaScript.make(_elm),
+   $Native$Json = Elm.Native.Json.make(_elm);
+   var fromJson = $Native$Json.toJS;
+   var toJson = $Native$Json.fromJS;
+   var fromRecord = $Native$JavaScript.fromRecord;
+   var toRecord = $Native$JavaScript.toRecord;
+   var RawObject = {ctor: "RawObject"};
+   _elm.JavaScript.Experimental.values = {_op: _op
+                                         ,RawObject: RawObject
+                                         ,toRecord: toRecord
+                                         ,fromRecord: fromRecord
+                                         ,toJson: toJson
+                                         ,fromJson: fromJson};
+   return _elm.JavaScript.Experimental.values;
+};(function() {
+'use strict';
+
+if (typeof window != 'undefined' && !window.location.origin) {
+  window.location.origin =
+      window.location.protocol + "//" +
+      window.location.hostname +
+      (window.location.port ? (':' + window.location.port) : '');
+}
+
+Elm.fullscreenDebugHooks = function(module, debuggerHistory /* =undefined */) {
+  var exposedDebugger = {};
+  function debuggerAttach(module, debuggerHistory) {
+    return {
+      make: function(runtime) {
+        var wrappedModule = debugModule(module, runtime);
+        exposedDebugger = debuggerInit(wrappedModule, runtime, debuggerHistory);
+        return wrappedModule.debuggedModule;
+      }
+    }
+  }
+  var mainHandle = Elm.fullscreen(debuggerAttach(module, debuggerHistory));
+  mainHandle.debugger = exposedDebugger;
+  return mainHandle;
+};
+
+var EVENTS_PER_SAVE = 100;
+
+function debugModule(module, runtime) {
+  var programPaused = false;
+  var recordedEvents = [];
+  var asyncCallbacks = [];
+  var snapshots = [];
+  var watchTracker = Elm.Native.Debug.make(runtime).watchTracker;
+  var pauseTime = 0;
+  var eventsUntilSnapshot = EVENTS_PER_SAVE;
+  runtime.debuggerStatus = runtime.debuggerStatus || {};
+  runtime.debuggerStatus.eventCounter = runtime.debuggerStatus.eventCounter || 0;
+
+  // runtime is the prototype of wrappedRuntime
+  // so we can access all runtime properties too
+  var wrappedRuntime = Object.create(runtime);
+  wrappedRuntime.notify = notifyWrapper;
+  wrappedRuntime.setTimeout = setTimeoutWrapper;
+
+  // make a copy of the wrappedRuntime
+  var assignedPropTracker = Object.create(wrappedRuntime);
+  var debuggedModule = module.make(assignedPropTracker);
+
+  // make sure the signal graph is actually a signal & extract the visual model
+  if ( !('recv' in debuggedModule.main) ) {
+    debuggedModule.main = Elm.Signal.make(runtime).constant(debuggedModule.main);
+  }
+
+  // The main module stores imported modules onto the runtime.
+  // To ensure only one instance of each module is created,
+  // we assign them back on the original runtime object.
+  Object.keys(assignedPropTracker).forEach(function(key) {
+    runtime[key] = assignedPropTracker[key];
+  });
+
+  var signalGraphNodes = flattenSignalGraph(wrappedRuntime.inputs);
+  var tracePath = tracePathInit(runtime, debuggedModule.main);
+
+  snapshots.push(snapshotSignalGraph(signalGraphNodes));
+
+  function notifyWrapper(id, v) {
+    var timestep = runtime.timer.now();
+
+    if (programPaused) {
+      // ignore async events generated while playing back
+      // or user events while program is paused
+      return false;
+    }
+    else {
+      recordEvent(id, v, timestep);
+      var changed = runtime.notify(id, v, timestep);
+      snapshotOnCheckpoint();
+      if (parent.window) {
+        parent.window.postMessage("elmNotify", window.location.origin);
+      }
+      return changed;
+    }
+  };
+
+  function setTimeoutWrapper(func, delayMs) {
+    if (programPaused) {
+      // Don't push timers and such to the callback stack while we're paused.
+      // It causes too many callbacks to be fired during unpausing.
+      return 0;
+    }
+    var cbObj = { func:func, delayMs:delayMs, timerId:0, executed:false };
+    var timerId = setTimeout(function() {
+        cbObj.executed = true;
+        func();
+      }, delayMs);
+    cbObj.timerId = timerId;
+    asyncCallbacks.push(cbObj);
+    return timerId;
+  }
+
+  function recordEvent(id, v, timestep) {
+    watchTracker.pushFrame();
+    recordedEvents.push({ id:id, value:v, timestep:timestep });
+    runtime.debuggerStatus.eventCounter += 1;
+  }
+
+  function clearAsyncCallbacks() {
+    asyncCallbacks.forEach(function(timer) {
+      if (!timer.executed) {
+        clearTimeout(timer.timerId);
+      }
+    });
+  }
+
+  function clearRecordedEvents() {
+    recordedEvents = [];
+    runtime.debuggerStatus.eventCounter = 0;
+  }
+
+  function getRecordedEventsLength() {
+    return recordedEvents.length;
+  }
+
+  function getRecordedEventAt(i) {
+    return recordedEvents[i];
+  }
+
+  function copyRecordedEvents() {
+    return recordedEvents.slice();
+  }
+
+  function loadRecordedEvents(events) {
+    recordedEvents = events.slice();
+  }
+
+  function clearSnapshots() {
+    snapshots = [snapshotSignalGraph(signalGraphNodes)];
+  }
+
+  function getSnapshotAt(i) {
+    var snapshotEvent = Math.floor(i / EVENTS_PER_SAVE);
+    assert(snapshotEvent < snapshots.length && snapshotEvent >= 0,
+           "Out of bounds index: " + snapshotEvent);
+    return snapshots[snapshotEvent];
+  }
+
+  function snapshotOnCheckpoint() {
+    if (eventsUntilSnapshot === 1) {
+      snapshots.push(snapshotSignalGraph(signalGraphNodes));
+      eventsUntilSnapshot = EVENTS_PER_SAVE;
+    } else {
+      eventsUntilSnapshot -= 1;
+    }
+  }
+
+  function setPaused() {
+    programPaused = true;
+    clearAsyncCallbacks();
+    pauseTime = Date.now();
+    tracePath.stopRecording();
+    preventInputEvents();
+  }
+
+  function setContinue(position) {
+    var pauseDelay = Date.now() - pauseTime;
+    runtime.timer.addDelay(pauseDelay);
+    programPaused = false;
+
+    // we need to dump the events that are ahead of where we're continuing.
+    var lastSnapshotPosition = Math.floor(position / EVENTS_PER_SAVE);
+    eventsUntilSnapshot = EVENTS_PER_SAVE - (position % EVENTS_PER_SAVE);
+    snapshots = snapshots.slice(0, lastSnapshotPosition + 1);
+
+    if (position < getRecordedEventsLength()) {
+      var lastEventTime = recordedEvents[position].timestep;
+      var scrubTime = runtime.timer.now() - lastEventTime;
+      runtime.timer.addDelay(scrubTime);
+    }
+
+    recordedEvents = recordedEvents.slice(0, position);
+    tracePath.clearTracesAfter(position);
+    runtime.debuggerStatus.eventCounter = position;
+    executeCallbacks(asyncCallbacks);
+    permitInputEvents();
+
+    tracePath.startRecording();
+  }
+
+  function getPaused() {
+    return programPaused;
+  }
+
+  function preventInputEvents(){
+    var events =
+      [ "click", "mousemove", "mouseup", "mousedown", "mouseclick"
+      , "keydown", "keypress", "keyup", "touchstart", "touchend"
+      , "touchcancel", "touchleave", "touchmove", "pointermove"
+      , "pointerdown", "pointerup", "pointerover", "pointerout"
+      , "pointerenter", "pointerleave", "pointercancel"
+      ];
+
+    var ignore = function(e) {
+      var evt = e ? e : window.event;
+      if (evt.stopPropagation) {
+        evt.stopPropagation();
+      }
+      if (evt.cancelBubble !== null) {
+        evt.cancelBubble = true;
+      }
+      if (evt.preventDefault) {
+        evt.preventDefault();
+      }
+      return false;
+    };
+
+    var ignoringDiv = document.getElementById("elmEventIgnorer");
+    if (!ignoringDiv) {
+      ignoringDiv = document.createElement("div");
+      ignoringDiv.id = "elmEventIgnorer";
+      ignoringDiv.style.position = "absolute";
+      ignoringDiv.style.top = "0px";
+      ignoringDiv.style.left = "0px";
+      ignoringDiv.style.width = "100%";
+      ignoringDiv.style.height = "100%";
+
+      for (var i = events.length; i-- ;) {
+        ignoringDiv.addEventListener(events[i], ignore, true);
+      }
+      runtime.node.appendChild(ignoringDiv);
+    }
+  }
+
+  function permitInputEvents(){
+    var ignoringDiv = document.getElementById("elmEventIgnorer");
+    ignoringDiv.parentNode.removeChild(ignoringDiv);
+  }
+
+  return {
+    debuggedModule: debuggedModule,
+    signalGraphNodes: signalGraphNodes,
+    initialSnapshot: snapshotSignalGraph(signalGraphNodes),
+    initialAsyncCallbacks: asyncCallbacks.slice(),
+    // API functions
+    clearAsyncCallbacks: clearAsyncCallbacks,
+    clearRecordedEvents: clearRecordedEvents,
+    getRecordedEventsLength: getRecordedEventsLength,
+    getRecordedEventAt: getRecordedEventAt,
+    copyRecordedEvents: copyRecordedEvents,
+    loadRecordedEvents: loadRecordedEvents,
+    clearSnapshots: clearSnapshots,
+    getSnapshotAt: getSnapshotAt,
+    snapshotOnCheckpoint: snapshotOnCheckpoint,
+    getPaused: getPaused,
+    setPaused: setPaused,
+    setContinue: setContinue,
+    tracePath: tracePath,
+    watchTracker: watchTracker
+  };
+}
+
+// The debuggerHistory variable is passed in on swap. It represents
+// the a state of the debugger for it to assume during init. It contains
+// the paused state of the debugger, the recorded events, and the current
+// event being processed.
+function debuggerInit(debugModule, runtime, debuggerHistory /* =undefined */) {
+  var currentEventIndex = 0;
+
+  function resetProgram(position) {
+    var closestSnapshot = debugModule.getSnapshotAt(position);
+    debugModule.clearAsyncCallbacks();
+    restoreSnapshot(debugModule.signalGraphNodes, closestSnapshot);
+    redrawGraphics();
+  }
+
+  function restartProgram() {
+    pauseProgram();
+    resetProgram(0);
+    debugModule.watchTracker.clear();
+    debugModule.tracePath.clearTraces();
+    debugModule.setContinue(0);
+    debugModule.clearRecordedEvents();
+    debugModule.clearSnapshots();
+    executeCallbacks(debugModule.initialAsyncCallbacks);
+  }
+
+  function pauseProgram() {
+    debugModule.setPaused();
+    currentEventIndex = debugModule.getRecordedEventsLength();
+  }
+
+  function continueProgram() {
+    if (debugModule.getPaused())
+    {
+      var closestSnapshotIndex =
+          Math.floor(currentEventIndex / EVENTS_PER_SAVE) * EVENTS_PER_SAVE;
+      resetProgram(currentEventIndex);
+      var continueIndex = currentEventIndex;
+      currentEventIndex = closestSnapshotIndex;
+      stepTo(continueIndex);
+      debugModule.setContinue(currentEventIndex);
+    }
+  }
+
+  function stepTo(index) {
+    if (!debugModule.getPaused()) {
+      debugModule.setPaused();
+      resetProgram();
+    }
+
+    if (index < 0 || index > getMaxSteps()) {
+      throw "Index out of bounds: " + index;
+    }
+
+    if (index < currentEventIndex) {
+      var closestSnapshotIndex = Math.floor(index / EVENTS_PER_SAVE) * EVENTS_PER_SAVE;
+      resetProgram(index);
+      currentEventIndex = closestSnapshotIndex;
+    }
+
+    while (currentEventIndex < index) {
+      var nextEvent = debugModule.getRecordedEventAt(currentEventIndex);
+      runtime.notify(nextEvent.id, nextEvent.value, nextEvent.timestep);
+
+      currentEventIndex += 1;
+    }
+  }
+
+  function getMaxSteps() {
+    return debugModule.getRecordedEventsLength();
+  }
+
+  function redrawGraphics() {
+    var main = debugModule.debuggedModule.main
+    for (var i = main.kids.length ; i-- ; ) {
+      main.kids[i].recv(runtime.timer.now(), true, main.id);
+    }
+  }
+
+  function getSwapState() {
+    var continueIndex = currentEventIndex;
+    if (!debugModule.getPaused()) {
+      continueIndex = getMaxSteps();
+    }
+    return {
+      paused: debugModule.getPaused(),
+      recordedEvents: debugModule.copyRecordedEvents(),
+      currentEventIndex: continueIndex
+    };
+  }
+
+  function dispose() {
+    var parentNode = runtime.node.parentNode;
+    parentNode.removeChild(debugModule.tracePath.canvas);
+    parentNode.removeChild(runtime.node);
+  }
+
+  if (debuggerHistory) {
+    // The problem is that we want to previous paused state. But
+    // by the time JS reaches here, the old code has been swapped out
+    // and the new modules are being generated. So we can ask the
+    // debugging console what it thinks the pause state is and go
+    // from there.
+    var paused = debuggerHistory.paused;
+    debugModule.setPaused();
+    debugModule.loadRecordedEvents(debuggerHistory.recordedEvents);
+    var index = getMaxSteps();
+    runtime.debuggerStatus.eventCounter = 0;
+    debugModule.tracePath.clearTraces();
+
+    // draw new trace path
+    debugModule.tracePath.startRecording();
+    while(currentEventIndex < index) {
+      var nextEvent = debugModule.getRecordedEventAt(currentEventIndex);
+      runtime.debuggerStatus.eventCounter += 1;
+      runtime.notify(nextEvent.id, nextEvent.value, nextEvent.timestep);
+      debugModule.snapshotOnCheckpoint();
+      currentEventIndex += 1;
+    }
+    debugModule.tracePath.stopRecording();
+
+    stepTo(debuggerHistory.currentEventIndex);
+    if (!paused) {
+      debugModule.setContinue(debuggerHistory.currentEventIndex);
+    }
+  }
+
+  runtime.node.parentNode.appendChild(debugModule.tracePath.canvas);
+
+  var elmDebugger = {
+      restart: restartProgram,
+      pause: pauseProgram,
+      kontinue: continueProgram,
+      getMaxSteps: getMaxSteps,
+      stepTo: stepTo,
+      getPaused: debugModule.getPaused,
+      getSwapState: getSwapState,
+      dispose: dispose,
+      allNodes: debugModule.signalGraphNodes,
+      watchTracker: debugModule.watchTracker
+  };
+
+  return elmDebugger;
+}
+
+function Point(x, y) {
+  this.x = x;
+  this.y = y;
+
+  this.translate = function(x, y) {
+    return new Point(this.x + x, this.y + y);
+  }
+
+  this.equals = function(p) {
+    return this.x == p.x && this.y == p.y;
+  }
+}
+
+function tracePathInit(runtime, signalGraphMain) {
+  var List = Elm.List.make(runtime);
+  var Signal = Elm.Signal.make(runtime);
+  var tracePathNode = A2(Signal.lift, graphicsUpdate, signalGraphMain);
+  var tracePathCanvas = createCanvas();
+  var tracePositions = {};
+  var recordingTraces = true;
+
+  function findPositions(currentScene) {
+    var positions = {};
+    function processElement(elem, offset) {
+      if (elem.element.ctor == "Custom" && elem.element.type == "Collage")
+      {
+        List.map(F2(processForm)(offset))(elem.element.model.forms);
+      }
+    }
+
+    function processForm(offset, form) {
+      if (form.form.ctor == "FElement")
+      {
+        processElement(form.form._0, offset.translate(form.x, -form.y));
+      }
+      if (form.form.ctor == "FGroup")
+      {
+        var newOffset = offset.translate(form.x, -form.y);
+        List.map(F2(processForm)(newOffset))(form.form._1);
+      }
+      if (form.debugTracePathId)
+      {
+        positions[form.debugTracePathId] = new Point(form.x + offset.x, -form.y + offset.y);
+      }
+    }
+
+    processElement(currentScene, new Point(0, 0));
+    return positions;
+  }
+
+  function appendPositions(positions) {
+    for (var id in positions) {
+      var pos = positions[id];
+      if (tracePositions.hasOwnProperty(id)) {
+        tracePositions[id].push(pos);
+      }
+      else {
+        tracePositions[id] = [pos];
+      }
+      if (tracePositions[id].length < runtime.debuggerStatus.eventCounter) {
+        var padCount = runtime.debuggerStatus.eventCounter - tracePositions[id].length;
+        var lastTracePosition = tracePositions[id][tracePositions[id].length - 1];
+        for (var i = padCount; i--;) {
+          tracePositions[id].push(lastTracePosition)
+        }
+      }
+      assert(tracePositions[id].length === runtime.debuggerStatus.eventCounter,
+             "We don't have a 1-1 mapping of trace positions to events");
+    }
+  }
+
+  function graphicsUpdate(currentScene) {
+    if (!recordingTraces) {
+      return;
+    }
+
+    var ctx = tracePathCanvas.getContext('2d');
+    ctx.clearRect(0, 0, tracePathCanvas.width, tracePathCanvas.height);
+
+    ctx.save();
+    ctx.translate(ctx.canvas.width/2, ctx.canvas.height/2);
+    appendPositions(findPositions(currentScene));
+    for (var id in tracePositions)
+    {
+      ctx.beginPath();
+      var points = tracePositions[id];
+      for (var i=0; i < points.length; i++)
+      {
+        var p = points[i];
+        if (i == 0) {
+          ctx.moveTo(p.x, p.y);
+        }
+        else {
+          ctx.lineTo(p.x, p.y);
+        }
+      }
+      ctx.lineWidth = 1;
+      ctx.strokeStyle = "rgba(50, 50, 50, 0.4)";
+      ctx.stroke();
+    }
+
+    ctx.restore();
+  }
+
+  function clearTraces() {
+    tracePositions = {};
+  }
+
+  function stopRecording() {
+    recordingTraces = false;
+  }
+
+  function startRecording() {
+    recordingTraces = true;
+  }
+
+  function clearTracesAfter(position) {
+    var newTraces = {};
+    for (var id in tracePositions) {
+      newTraces[id] = tracePositions[id].slice(0,position);
+    }
+    tracePositions = newTraces;
+  }
+
+  return {
+    graphicsUpdate: graphicsUpdate,
+    canvas: tracePathCanvas,
+    clearTraces: clearTraces,
+    clearTracesAfter: clearTracesAfter,
+    stopRecording: stopRecording,
+    startRecording: startRecording
+  }
+}
+
+function executeCallbacks(callbacks) {
+  callbacks.forEach(function(timer) {
+    if (!timer.executed) {
+      var func = timer.func;
+      timer.executed = true;
+      func();
+    }
+  });
+}
+
+function createCanvas() {
+  var c = document.createElement('canvas');
+  c.width = window.innerWidth;
+  c.height = window.innerHeight;
+  c.style.position = "absolute";
+  c.style.top = "0";
+  c.style.left = "0";
+  c.style.pointerEvents = "none";
+  return c;
+}
+
+function assert(bool, msg) {
+  if (!bool) {
+    throw "Assertion error: " + msg;
+  }
+}
+
+function snapshotSignalGraph(signalGraphNodes) {
+  var nodeValues = [];
+
+  signalGraphNodes.forEach(function(node) {
+    nodeValues.push({ value: node.value, id: node.id });
+  });
+
+  return nodeValues;
+};
+
+function restoreSnapshot(signalGraphNodes, snapshot) {
+  assert(signalGraphNodes.length == snapshot.length,
+         "saved program state has wrong length");
+  for (var i=0; i < signalGraphNodes.length; i++) {
+    var node = signalGraphNodes[i];
+    var state = snapshot[i];
+    assert(node.id == state.id, "the nodes moved position");
+
+    node.value = state.value;
+  }
+}
+
+function flattenSignalGraph(nodes) {
+  var nodesById = {};
+
+  function addAllToDict(node) {
+    nodesById[node.id] = node;
+    node.kids.forEach(addAllToDict);
+  }
+  nodes.forEach(addAllToDict);
+
+  var allNodes = Object.keys(nodesById).sort().map(function(key) {
+    return nodesById[key];
+  });
+  return allNodes;
+};
+
+}());
+(function() {
+
+// Returns boolean indicating if the swap was successful.
+// Requires that the two signal graphs have exactly the same
+// structure.
+ElmRuntime.swap = function(from, to) {
+    function similar(nodeOld,nodeNew) {
+        var idOkay = nodeOld.id === nodeNew.id;
+        var lengthOkay = nodeOld.kids.length === nodeNew.kids.length;
+        return idOkay && lengthOkay;
+    }
+    function swap(nodeOld,nodeNew) {
+        nodeNew.value = nodeOld.value;
+        return true;
+    }
+    var canSwap = depthFirstTraversals(similar, from.inputs, to.inputs);
+    if (canSwap) { depthFirstTraversals(swap, from.inputs, to.inputs); }
+    from.node.parentNode.replaceChild(to.node, from.node);
+    return canSwap;
+}
+
+// Returns false if the node operation f ever fails.
+function depthFirstTraversals(f, queueOld, queueNew) {
+    if (queueOld.length !== queueNew.length) return false;
+    queueOld = queueOld.slice(0);
+    queueNew = queueNew.slice(0);
+
+    var seen = [];
+    while (queueOld.length > 0 && queueNew.length > 0) {
+        var nodeOld = queueOld.pop();
+        var nodeNew = queueNew.pop();
+        if (seen.indexOf(nodeOld.id) < 0) {
+            if (!f(nodeOld, nodeNew)) return false;
+            queueOld = queueOld.concat(nodeOld.kids);
+            queueNew = queueNew.concat(nodeNew.kids);
+            seen.push(nodeOld.id);
+        }
+    }
+    return true;
+}
+
+}());
+
+(function() {
+'use strict';
+
+Elm.fullscreen = function(module, ports) {
+    var style = document.createElement('style');
+    style.type = 'text/css';
+    style.innerHTML = "html,head,body { padding:0; margin:0; }" +
+        "body { font-family: calibri, helvetica, arial, sans-serif; }";
+    document.head.appendChild(style);
+    var container = document.createElement('div');
+    document.body.appendChild(container);
+    return init(ElmRuntime.Display.FULLSCREEN, container, module, ports || {});
+};
+
+Elm.embed = function(module, container, ports) {
+    var tag = container.tagName;
+    if (tag !== 'DIV') {
+        throw new Error('Elm.node must be given a DIV, not a ' + tag + '.');
+    } else if (container.hasChildNodes()) {
+        throw new Error('Elm.node must be given an empty DIV. No children allowed!');
+    }
+    return init(ElmRuntime.Display.COMPONENT, container, module, ports || {});
+};
+
+Elm.worker = function(module, ports) {
+    return init(ElmRuntime.Display.NONE, {}, module, ports || {});
+};
+
+function init(display, container, module, ports, moduleToReplace) {
+  // defining state needed for an instance of the Elm RTS
+  var inputs = [];
+
+  /* OFFSET
+   * Elm's time traveling debugger lets you interrupt the smooth flow of time
+   * by pausing and continuing program execution. To ensure the user sees a
+   * program that moves smoothly through the pause/continue time gap,
+   * we need to adjsut the value of Date.now().
+   */
+  var timer = function() {
+    var inducedDelay = 0;
+
+    var now = function() {
+      return Date.now() - inducedDelay;
+    };
+
+    var addDelay = function(d) {
+      inducedDelay += d;
+      return inducedDelay;
+    };
+
+    return { now : now
+           , addDelay : addDelay
+           }
+  }();
+
+  var updateInProgress = false;
+  function notify(id, v) {
+      if (updateInProgress) {
+          throw new Error(
+              'The notify function has been called synchronously!\n' +
+              'This can lead to frames being dropped.\n' +
+              'Definitely report this to <https://github.com/elm-lang/Elm/issues>\n');
+      }
+      updateInProgress = true;
+      var timestep = timer.now();
+      for (var i = inputs.length; i--; ) {
+          inputs[i].recv(timestep, id, v);
+      }
+      updateInProgress = false;
+  }
+  function setTimeout(func, delay) {
+    window.setTimeout(func, delay);
+  }
+
+  var listeners = [];
+  function addListener(relevantInputs, domNode, eventName, func) {
+      domNode.addEventListener(eventName, func);
+      var listener = {
+          relevantInputs: relevantInputs,
+          domNode: domNode,
+          eventName: eventName,
+          func: func
+      };
+      listeners.push(listener);
+  }
+
+  var portUses = {}
+  for (var key in ports) {
+      portUses[key] = 0;
+  }
+  // create the actual RTS. Any impure modules will attach themselves to this
+  // object. This permits many Elm programs to be embedded per document.
+  var elm = {
+      notify:notify,
+      setTimeout:setTimeout,
+      node:container,
+      display:display,
+      id:ElmRuntime.guid(),
+      addListener:addListener,
+      inputs:inputs,
+      timer:timer,
+      ports: { incoming:ports, outgoing:{}, uses:portUses }
+  };
+
+  function swap(newModule) {
+      removeListeners(listeners);
+      var div = document.createElement('div');
+      var newElm = init(display, div, newModule, ports, elm);
+      inputs = [];
+      // elm.swap = newElm.swap;
+      return newElm;
+  }
+
+  function dispose() {
+    removeListeners(listeners);
+    inputs = [];
+  }
+
+  var Module = {};
+  var reportAnyErrors = function() {};
+  try {
+      Module = module.make(elm);
+      checkPorts(elm);
+  } catch(e) {
+      var directions = "<br/>&nbsp; &nbsp; Open the developer console for more details."
+      Module.main = Elm.Text.make(elm).leftAligned('<code>' + e.message + directions + '</code>');
+      reportAnyErrors = function() { throw e; }
+  }
+  inputs = ElmRuntime.filterDeadInputs(inputs);
+  filterListeners(inputs, listeners);
+  addReceivers(elm.ports.outgoing);
+  if (display !== ElmRuntime.Display.NONE) {
+      var graphicsNode = initGraphics(elm, Module);
+  }
+  if (typeof moduleToReplace !== 'undefined') {
+      ElmRuntime.swap(moduleToReplace, elm);
+
+      // rerender scene if graphics are enabled.
+      if (typeof graphicsNode !== 'undefined') {
+          graphicsNode.recv(0, true, 0);
+      }
+  }
+
+  reportAnyErrors();
+  return {
+    swap:swap,
+    ports:elm.ports.outgoing,
+    dispose:dispose
+  };
+};
+
+function checkPorts(elm) {
+    var portUses = elm.ports.uses;
+    for (var key in portUses) {
+        var uses = portUses[key]
+        if (uses === 0) {
+            throw new Error(
+                "Initialization Error: provided port '" + key +
+                "' to a module that does not take it as in input.\n" +
+                "Remove '" + key + "' from the module initialization code.");
+        } else if (uses > 1) {
+            throw new Error(
+                "Initialization Error: port '" + key +
+                "' has been declared multiple times in the Elm code.\n" +
+                "Remove declarations until there is exactly one.");
+        }
+    }
+}
+    
+function filterListeners(inputs, listeners) {
+    loop:
+    for (var i = listeners.length; i--; ) {
+        var listener = listeners[i];
+        for (var j = inputs.length; j--; ) {
+            if (listener.relevantInputs.indexOf(inputs[j].id) >= 0) {
+                continue loop;
+            }
+        }
+        listener.domNode.removeEventListener(listener.eventName, listener.func);
+    }
+}
+
+function removeListeners(listeners) {
+    for (var i = listeners.length; i--; ) {
+        var listener = listeners[i];
+        listener.domNode.removeEventListener(listener.eventName, listener.func);
+    }
+}
+
+// add receivers for built-in ports if they are defined
+function addReceivers(ports) {
+    if ('log' in ports) {
+        ports.log.subscribe(function(v) { console.log(v) });
+    }
+    if ('stdout' in ports) {
+        var process = process || {};
+        var handler = process.stdout
+            ? function(v) { process.stdout.write(v); }
+            : function(v) { console.log(v); };
+        ports.stdout.subscribe(handler);
+    }
+    if ('stderr' in ports) {
+        var process = process || {};
+        var handler = process.stderr
+            ? function(v) { process.stderr.write(v); }
+            : function(v) { console.log('Error:' + v); };
+        ports.stderr.subscribe(handler);
+    }
+    if ('title' in ports) {
+        if (typeof ports.title === 'string') {
+            document.title = ports.title;
+        } else {
+            ports.title.subscribe(function(v) { document.title = v; });
+        }
+    }
+    if ('redirect' in ports) {
+        ports.redirect.subscribe(function(v) {
+            if (v.length > 0) window.location = v;
+        });
+    }
+    if ('favicon' in ports) {
+        if (typeof ports.favicon === 'string') {
+            changeFavicon(ports.favicon);
+        } else {
+            ports.favicon.subscribe(changeFavicon);
+        }
+    }
+    function changeFavicon(src) {
+        var link = document.createElement('link');
+        var oldLink = document.getElementById('elm-favicon');
+        link.id = 'elm-favicon';
+        link.rel = 'shortcut icon';
+        link.href = src;
+        if (oldLink) {
+            document.head.removeChild(oldLink);
+        }
+        document.head.appendChild(link);
+    }
+}
+
+function initGraphics(elm, Module) {
+  if (!('main' in Module)) {
+      throw new Error("'main' is missing! What do I display?!");
+  }
+
+  var signalGraph = Module.main;
+
+  // make sure the signal graph is actually a signal & extract the visual model
+  var Signal = Elm.Signal.make(elm);
+  if (!('recv' in signalGraph)) {
+      signalGraph = Signal.constant(signalGraph);
+  }
+  var currentScene = signalGraph.value;
+
+ // Add the currentScene to the DOM
+  var Render = ElmRuntime.use(ElmRuntime.Render.Element);
+  elm.node.appendChild(Render.render(currentScene));
+
+  // set up updates so that the DOM is adjusted as necessary.
+  var savedScene = currentScene;
+  var previousDrawId = 0;
+  function domUpdate(newScene) {
+      previousDrawId = ElmRuntime.draw(previousDrawId, function(_) {
+          Render.update(elm.node.firstChild, savedScene, newScene);
+          if (elm.Native.Window) elm.Native.Window.values.resizeIfNeeded();
+          savedScene = newScene;
+      });
+  }
+  var renderer = A2(Signal.lift, domUpdate, signalGraph);
+
+  // must check for resize after 'renderer' is created so
+  // that changes show up.
+  if (elm.Native.Window) elm.Native.Window.values.resizeIfNeeded();
+
+  return renderer;
+}
+
+}());
+
+(function() {
+'use strict';
+
+ElmRuntime.Display = { FULLSCREEN: 0, COMPONENT: 1, NONE: 2 };
+
+ElmRuntime.counter = 0;
+ElmRuntime.guid = function() { return ElmRuntime.counter++; }
+
+ElmRuntime.use = function(M) {
+    if (typeof M === 'function') M = M();
+    return M;
+};
+
+function isAlive(input) {
+    if (!('defaultNumberOfKids' in input)) return true;
+    var len = input.kids.length;
+    if (len === 0) return false;
+    if (len > input.defaultNumberOfKids) return true;
+    var alive = false;
+    for (var i = len; i--; ) {
+        alive = alive || isAlive(input.kids[i]);
+    }
+    return alive;
+}
+
+ElmRuntime.filterDeadInputs = function(inputs) {
+    var temp = [];
+    for (var i = inputs.length; i--; ) {
+        if (isAlive(inputs[i])) temp.push(inputs[i]);
+    }
+    return temp;
+};
+
+// define function for drawing efficiently
+//
+//   draw : RequestID -> (() -> ()) -> RequestID
+//
+// Takes a "RequestID" allowing you to cancel old requests if possible.
+// Returns a "RequestID" so you can refer to past requests.
+//
+var vendors = ['ms', 'moz', 'webkit', 'o'];
+var win = typeof window !== 'undefined' ? window : {};
+for (var i = 0; i < vendors.length && !win.requestAnimationFrame; ++i) {
+    win.requestAnimationFrame = win[vendors[i]+'RequestAnimationFrame'];
+    win.cancelAnimationFrame  = win[vendors[i]+'CancelAnimationFrame'] ||
+                                win[vendors[i]+'CancelRequestAnimationFrame'];
+}
+
+if (win.requestAnimationFrame && win.cancelAnimationFrame) {
+    ElmRuntime.draw = function(previousRequestID, callback) {
+        win.cancelAnimationFrame(previousRequestID);
+        return win.requestAnimationFrame(callback);
+    };
+} else {
+    ElmRuntime.draw = function(previousRequestID, callback) {
+        callback();
+        return previousRequestID;
+    };
+}
+
+}());
+
+ElmRuntime.Render.Collage = function() {
+
+var Render = ElmRuntime.use(ElmRuntime.Render.Element);
+var Transform = Elm.Transform2D.make({});
+var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
+var newElement = Utils.newElement,
+    colorToCss = Utils.colorToCss, fromList = Utils.fromList,
+    fromString = Utils.fromString, addTransform = Utils.addTransform;
+
+function trace(ctx, path) {
+    var points = fromList(path);
+    var i = points.length - 1;
+    if (i <= 0) return;
+    ctx.moveTo(points[i]._0, points[i]._1);
+    while (i--) { ctx.lineTo(points[i]._0, points[i]._1); }
+    if (path.closed) {
+        i = points.length - 1;
+        ctx.lineTo(points[i]._0, points[i]._1);
+    }
+}
+
+function line(ctx,style,path) {
+    style.dashing.ctor === '[]' ? trace(ctx, path) : customLineHelp(ctx, style, path);
+    ctx.scale(1,-1);
+    ctx.stroke();
+}
+
+function customLineHelp(ctx, style, path) {
+    var points = fromList(path);
+    if (path.closed) points.push(points[0]);
+    var pattern = fromList(style.dashing);
+    var i = points.length - 1;
+    if (i <= 0) return;
+    var x0 = points[i]._0, y0 = points[i]._1;
+    var x1=0, y1=0, dx=0, dy=0, remaining=0, nx=0, ny=0;
+    var pindex = 0, plen = pattern.length;
+    var draw = true, segmentLength = pattern[0];
+    ctx.moveTo(x0,y0);
+    while (i--) {
+        x1 = points[i]._0; y1 = points[i]._1;
+        dx = x1 - x0; dy = y1 - y0;
+        remaining = Math.sqrt(dx * dx + dy * dy);
+        while (segmentLength <= remaining) {
+            x0 += dx * segmentLength / remaining;
+            y0 += dy * segmentLength / remaining;
+            ctx[draw ? 'lineTo' : 'moveTo'](x0, y0);
+            // update starting position
+            dx = x1 - x0; dy = y1 - y0;
+            remaining = Math.sqrt(dx * dx + dy * dy);
+            // update pattern
+            draw = !draw;
+            pindex = (pindex + 1) % plen;
+            segmentLength = pattern[pindex];
+        }
+        if (remaining > 0) {
+            ctx[draw ? 'lineTo' : 'moveTo'](x1, y1);
+            segmentLength -= remaining;
+        }
+        x0 = x1; y0 = y1;
+    }
+}
+
+function drawLine(ctx, style, path) {
+    ctx.lineWidth = style.width;
+    var cap = style.cap.ctor;
+    ctx.lineCap = cap === 'Flat' ? 'butt' :
+                  cap === 'Round' ? 'round' : 'square';
+    var join = style.join.ctor;
+    ctx.lineJoin = join === 'Smooth' ? 'round' :
+                   join === 'Sharp' ? 'miter' : 'bevel';
+    ctx.miterLimit = style.join._0 || 10;
+    ctx.strokeStyle = colorToCss(style.color);
+    return line(ctx, style, path);
+}
+
+function texture(redo, ctx, src) {
+    var img = new Image();
+    img.src = fromString(src);
+    img.onload = redo;
+    return ctx.createPattern(img, 'repeat');
+}
+
+function gradient(ctx, grad) {
+  var g;
+  var stops = [];
+  if (grad.ctor === 'Linear') {
+    var p0 = grad._0, p1 = grad._1;
+    g = ctx.createLinearGradient(p0._0, -p0._1, p1._0, -p1._1);
+    stops = fromList(grad._2);
+  } else {
+    var p0 = grad._0, p2 = grad._2;
+    g = ctx.createRadialGradient(p0._0, -p0._1, grad._1, p2._0, -p2._1, grad._3);
+    stops = fromList(grad._4);
+  }
+  var len = stops.length;
+  for (var i = 0; i < len; ++i) {
+    var stop = stops[i];
+    g.addColorStop(stop._0, colorToCss(stop._1));
+  }
+  return g;
+}
+
+function drawShape(redo, ctx, style, path) {
+    trace(ctx, path);
+    var sty = style.ctor;
+    ctx.fillStyle =
+        sty === 'Solid' ? colorToCss(style._0) :
+        sty === 'Texture' ? texture(redo, ctx, style._0) : gradient(ctx, style._0);
+    ctx.scale(1,-1);
+    ctx.fill();
+}
+
+function drawImage(redo, ctx, form) {
+    var img = new Image();
+    img.onload = redo;
+    img.src = fromString(form._3);
+    var w = form._0,
+        h = form._1,
+        pos = form._2,
+        srcX = pos._0,
+        srcY = pos._1,
+        srcW = w,
+        srcH = h,
+        destX = -w/2,
+        destY = -h/2,
+        destW = w,
+        destH = h;
+
+    ctx.scale(1,-1);
+    ctx.drawImage(img, srcX, srcY, srcW, srcH, destX, destY, destW, destH);
+}
+
+function renderForm(redo, ctx, form) {
+    ctx.save();
+    var x = form.x, y = form.y, theta = form.theta, scale = form.scale;
+    if (x !== 0 || y !== 0) ctx.translate(x, y);
+    if (theta !== 0) ctx.rotate(theta);
+    if (scale !== 1) ctx.scale(scale,scale);
+    if (form.alpha !== 1) ctx.globalAlpha = ctx.globalAlpha * form.alpha;
+    ctx.beginPath();
+    var f = form.form;
+    switch(f.ctor) {
+    case 'FPath' : drawLine(ctx, f._0, f._1); break;
+    case 'FImage': drawImage(redo, ctx, f); break;
+    case 'FShape':
+      if (f._0.ctor === 'Left') {
+        f._1.closed = true;
+        drawLine(ctx, f._0._0, f._1);
+      } else {
+        drawShape(redo, ctx, f._0._0, f._1);
+      }
+    break;
+    }
+    ctx.restore();
+}
+
+function formToMatrix(form) {
+   var scale = form.scale;
+   var matrix = A6( Transform.matrix, scale, 0, 0, scale, form.x, form.y );
+
+   var theta = form.theta
+   if (theta !== 0)
+       matrix = A2( Transform.multiply, matrix, Transform.rotation(theta) );
+
+   return matrix;
+}
+
+function str(n) {
+    if (n < 0.00001 && n > -0.00001) return 0;
+    return n;
+}
+
+function makeTransform(w, h, form, matrices) {
+    var props = form.form._0.props;
+    var m = A6( Transform.matrix, 1, 0, 0, -1,
+                (w - props.width ) / 2,
+                (h - props.height) / 2 );
+    var len = matrices.length;
+    for (var i = 0; i < len; ++i) { m = A2( Transform.multiply, m, matrices[i] ); }
+    m = A2( Transform.multiply, m, formToMatrix(form) );
+
+    return 'matrix(' + str( m[0]) + ', ' + str( m[3]) + ', ' +
+                       str(-m[1]) + ', ' + str(-m[4]) + ', ' +
+                       str( m[2]) + ', ' + str( m[5]) + ')';
+}
+
+function stepperHelp(list) {
+    var arr = fromList(list);
+    var i = 0;
+    function peekNext() {
+        return i < arr.length ? arr[i].form.ctor : '';
+    }
+    // assumes that there is a next element
+    function next() {
+        var out = arr[i];
+        ++i;
+        return out;
+    }
+    return { peekNext:peekNext, next:next };
+}
+
+function formStepper(forms) {
+    var ps = [stepperHelp(forms)];
+    var matrices = [];
+    var alphas = [];
+    function peekNext() {
+        var len = ps.length;
+        var formType = '';
+        for (var i = 0; i < len; ++i ) {
+            if (formType = ps[i].peekNext()) return formType;
+        }
+        return '';
+    }
+    // assumes that there is a next element
+    function next(ctx) {
+        while (!ps[0].peekNext()) {
+            ps.shift();
+            matrices.pop();
+            alphas.shift();
+            if (ctx) { ctx.restore(); }
+        }
+        var out = ps[0].next();
+        var f = out.form;
+        if (f.ctor === 'FGroup') {
+            ps.unshift(stepperHelp(f._1));
+            var m = A2(Transform.multiply, f._0, formToMatrix(out));
+            ctx.save();
+            ctx.transform(m[0], m[3], m[1], m[4], m[2], m[5]);
+            matrices.push(m);
+
+            var alpha = (alphas[0] || 1) * out.alpha;
+            alphas.unshift(alpha);
+            ctx.globalAlpha = alpha;
+        }
+        return out;
+    }
+    function transforms() { return matrices; }
+    function alpha() { return alphas[0] || 1; }
+    return { peekNext:peekNext, next:next, transforms:transforms, alpha:alpha };
+}
+
+function makeCanvas(w,h) {
+    var canvas = newElement('canvas');
+    canvas.style.width  = w + 'px';
+    canvas.style.height = h + 'px';
+    canvas.style.display = "block";
+    canvas.style.position = "absolute";
+    canvas.width  = w;
+    canvas.height = h;
+    return canvas;
+}
+
+function render(model) {
+    var div = newElement('div');
+    div.style.overflow = 'hidden';
+    div.style.position = 'relative';
+    update(div, model, model);
+    return div;
+}
+
+function nodeStepper(w,h,div) {
+    var kids = div.childNodes;
+    var i = 0;
+    function transform(transforms, ctx) {
+        ctx.translate(w/2, h/2);
+        ctx.scale(1,-1);
+        var len = transforms.length;
+        for (var i = 0; i < len; ++i) {
+            var m = transforms[i];
+            ctx.save();
+            ctx.transform(m[0], m[3], m[1], m[4], m[2], m[5]);
+        }
+        return ctx;
+    }
+    function nextContext(transforms) {
+        while (i < kids.length) {
+            var node = kids[i];
+            if (node.getContext) {
+                node.width = w;
+                node.height = h;
+                node.style.width = w + 'px';
+                node.style.height = h + 'px';
+                ++i;
+                return transform(transforms, node.getContext('2d'));
+            }
+            div.removeChild(node);
+        }
+        var canvas = makeCanvas(w,h);
+        div.appendChild(canvas);
+        // we have added a new node, so we must step our position
+        ++i;
+        return transform(transforms, canvas.getContext('2d'));
+    }
+    function addElement(matrices, alpha, form) {
+        var kid = kids[i];
+        var elem = form.form._0;
+
+        var node = (!kid || kid.getContext)
+            ? Render.render(elem)
+            : (Render.update(kid, kid.oldElement, elem), kids[i]);
+
+        node.style.position = 'absolute';
+        node.style.opacity = alpha * form.alpha * elem.props.opacity;
+        addTransform(node.style, makeTransform(w, h, form, matrices));
+        node.oldElement = elem;
+        ++i;
+        if (!kid) {
+            div.appendChild(node);
+        } else if (kid.getContext) {
+            div.insertBefore(node, kid);
+        }
+    }
+    function clearRest() {
+        while (i < kids.length) {
+            div.removeChild(kids[i]);
+        }
+    }
+    return { nextContext:nextContext, addElement:addElement, clearRest:clearRest };
+}
+
+
+function update(div, _, model) {
+    var w = model.w;
+    var h = model.h;
+
+    var forms = formStepper(model.forms);
+    var nodes = nodeStepper(w,h,div);
+    var ctx = null;
+    var formType = '';
+
+    while (formType = forms.peekNext()) {
+        // make sure we have context if we need it
+        if (ctx === null && formType !== 'FElement') {
+            ctx = nodes.nextContext(forms.transforms());
+            ctx.globalAlpha = forms.alpha();
+        }
+
+        var form = forms.next(ctx);
+        // if it is FGroup, all updates are made within formStepper when next is called.
+        if (formType === 'FElement') {
+            // update or insert an element, get a new context
+            nodes.addElement(forms.transforms(), forms.alpha(), form);
+            ctx = null;
+        } else if (formType !== 'FGroup') {
+            renderForm(function() { update(div, model, model); }, ctx, form);
+        }
+    }
+    nodes.clearRest();
+    return false;
+}
+
+return { render:render, update:update };
+
+};
+
+ElmRuntime.Render.Element = function() {
+'use strict';
+
+var Utils = ElmRuntime.use(ElmRuntime.Render.Utils);
+var newElement = Utils.newElement;
+var colorToCss = Utils.colorToCss;
+var addTransform = Utils.addTransform;
+var removeTransform = Utils.removeTransform;
+var fromList = Utils.fromList;
+var eq = Utils.eq;
+
+function setProps(elem, node) {
+    var props = elem.props;
+
+    var element = elem.element;
+    var width = props.width - (element.adjustWidth || 0);
+    var height = props.height - (element.adjustHeight || 0);
+    node.style.width  = (width |0) + 'px';
+    node.style.height = (height|0) + 'px';
+
+    if (props.opacity !== 1) {
+        node.style.opacity = props.opacity;
+    }
+
+    if (props.color.ctor === 'Just') {
+        node.style.backgroundColor = colorToCss(props.color._0);
+    }
+
+    if (props.tag !== '') {
+        node.id = props.tag;
+    }
+
+    if (props.hover.ctor !== '_Tuple0') {
+        addHover(node, props.hover);
+    }
+
+    if (props.click.ctor !== '_Tuple0') {
+        addClick(node, props.click);
+    }
+
+    if (props.href !== '') {
+        var anchor = newElement('a');
+        anchor.href = props.href;
+        anchor.style.display = 'block';
+        anchor.style.pointerEvents = 'auto';
+        anchor.appendChild(node);
+        node = anchor;
+    }
+
+    return node;
+}
+
+function addClick(e, handler) {
+    e.style.pointerEvents = 'auto';
+    e.elm_click_handler = handler;
+    function trigger(ev) {
+        e.elm_click_handler(Utils.Tuple0);
+        ev.stopPropagation();
+    }
+    e.elm_click_trigger = trigger;
+    e.addEventListener('click', trigger);
+}
+
+function removeClick(e, handler) {
+    if (e.elm_click_trigger) {
+        e.removeEventListener('click', e.elm_click_trigger);
+        e.elm_click_trigger = null;
+        e.elm_click_handler = null;
+    }
+}
+
+function addHover(e, handler) {
+    e.style.pointerEvents = 'auto';
+    e.elm_hover_handler = handler;
+    e.elm_hover_count = 0;
+
+    function over(evt) {
+        if (e.elm_hover_count++ > 0) return;
+        e.elm_hover_handler(true);
+        evt.stopPropagation();
+    }
+    function out(evt) {
+        if (e.contains(evt.toElement || evt.relatedTarget)) return;
+        e.elm_hover_count = 0;
+        e.elm_hover_handler(false);
+        evt.stopPropagation();
+    }
+    e.elm_hover_over = over;
+    e.elm_hover_out = out;
+    e.addEventListener('mouseover', over);
+    e.addEventListener('mouseout', out);
+}
+
+function removeHover(e) {
+    e.elm_hover_handler = null;
+    if (e.elm_hover_over) {
+        e.removeEventListener('mouseover', e.elm_hover_over);
+        e.elm_hover_over = null;
+    }
+    if (e.elm_hover_out) {
+        e.removeEventListener('mouseout', e.elm_hover_out);
+        e.elm_hover_out = null;
+    }
+}
+
+function image(props, img) {
+    switch (img._0.ctor) {
+    case 'Plain':   return plainImage(img._3);
+    case 'Fitted':  return fittedImage(props.width, props.height, img._3);
+    case 'Cropped': return croppedImage(img,props.width,props.height,img._3);
+    case 'Tiled':   return tiledImage(img._3);
+    }
+}
+
+function plainImage(src) {
+    var img = newElement('img');
+    img.src = src;
+    img.name = src;
+    img.style.display = "block";
+    return img;
+}
+
+function tiledImage(src) {
+    var div = newElement('div');
+    div.style.backgroundImage = 'url(' + src + ')';
+    return div;
+}
+
+function fittedImage(w, h, src) {
+    var div = newElement('div');
+    div.style.background = 'url(' + src + ') no-repeat center';
+    div.style.webkitBackgroundSize = 'cover';
+    div.style.MozBackgroundSize = 'cover';
+    div.style.OBackgroundSize = 'cover';
+    div.style.backgroundSize = 'cover';
+    return div;
+}
+
+function croppedImage(elem, w, h, src) {
+    var pos = elem._0._0;
+    var e = newElement('div');
+    e.style.overflow = "hidden";
+
+    var img = newElement('img');
+    img.onload = function() {
+        var sw = w / elem._1, sh = h / elem._2;
+        img.style.width = ((this.width * sw)|0) + 'px';
+        img.style.height = ((this.height * sh)|0) + 'px';
+        img.style.marginLeft = ((- pos._0 * sw)|0) + 'px';
+        img.style.marginTop = ((- pos._1 * sh)|0) + 'px';
+    };
+    img.src = src;
+    img.name = src;
+    e.appendChild(img);
+    return e;
+}
+
+function goOut(e) { e.style.position = 'absolute'; return e; }
+function goDown(e) { return e }
+function goRight(e) { e.style.styleFloat = e.style.cssFloat = "left"; return e; }
+
+var directionTable = {
+    DUp    : goDown,
+    DDown  : goDown,
+    DLeft  : goRight,
+    DRight : goRight,
+    DIn    : goOut,
+    DOut   : goOut
+};
+function needsReversal(dir) {
+    return dir == 'DUp' || dir == 'DLeft' || dir == 'DIn';
+}
+
+function flow(dir,elist) {
+    var array = fromList(elist);
+    var container = newElement('div');
+    var goDir = directionTable[dir];
+    if (goDir == goOut) {
+        container.style.pointerEvents = 'none';
+    }
+    if (needsReversal(dir)) {
+        array.reverse();
+    }
+    var len = array.length;
+    for (var i = 0; i < len; ++i) {
+        container.appendChild(goDir(render(array[i])));
+    }
+    return container;
+}
+
+function toPos(pos) {
+    switch(pos.ctor) {
+    case "Absolute": return  pos._0 + "px";
+    case "Relative": return (pos._0 * 100) + "%";
+    }
+}
+
+// must clear right, left, top, bottom, and transform
+// before calling this function
+function setPos(pos,elem,e) {
+    var element = elem.element;
+    var props = elem.props;
+    var w = props.width + (element.adjustWidth ? element.adjustWidth : 0);
+    var h = props.height + (element.adjustHeight ? element.adjustHeight : 0);
+
+    e.style.position = 'absolute';
+    e.style.margin = 'auto';
+    var transform = '';
+    switch(pos.horizontal.ctor) {
+    case 'P': e.style.right = toPos(pos.x); e.style.removeProperty('left'); break;
+    case 'Z': transform = 'translateX(' + ((-w/2)|0) + 'px) ';
+    case 'N': e.style.left = toPos(pos.x); e.style.removeProperty('right'); break;
+    }
+    switch(pos.vertical.ctor) {
+    case 'N': e.style.bottom = toPos(pos.y); e.style.removeProperty('top'); break;
+    case 'Z': transform += 'translateY(' + ((-h/2)|0) + 'px)';
+    case 'P': e.style.top = toPos(pos.y); e.style.removeProperty('bottom'); break;
+    }
+    if (transform !== '') addTransform(e.style, transform);
+    return e;
+}
+
+function container(pos,elem) {
+    var e = render(elem);
+    setPos(pos, elem, e);
+    var div = newElement('div');
+    div.style.position = 'relative';
+    div.style.overflow = 'hidden';
+    div.appendChild(e);
+    return div;
+}
+
+function rawHtml(elem) {
+    var html = elem.html;
+    var args = elem.args;
+    var guid = elem.guid;
+    var align = elem.align;
+
+    var div = newElement('div');
+    div.innerHTML = html;
+    div.style.visibility = "hidden";
+    if (align) div.style.textAlign = align;
+    document.body.appendChild(div);
+
+    for (var i = args.length; i--; ) {
+        var arg = args[i];
+        var span = document.getElementById('md-' + guid + '-' + i);
+        if (arg.isText) {
+            span.innerHTML = arg;
+        } else {
+            span.style.display = 'block';
+            span.style.width = arg.props.width + 'px';
+            span.style.height = arg.props.height + 'px';
+            span.appendChild(render(arg));
+        }
+    }
+    document.body.removeChild(div);
+    div.style.visibility = 'visible';
+    div.style.pointerEvents = 'auto';
+    return div;
+}
+
+function render(elem) {
+    return setProps(elem, makeElement(elem));
+}
+function makeElement(e) {
+    var elem = e.element;
+    switch(elem.ctor) {
+    case 'Image':     return image(e.props, elem);
+    case 'Flow':      return flow(elem._0.ctor, elem._1);
+    case 'Container': return container(elem._0, elem._1);
+    case 'Spacer':    return newElement('div');
+    case 'RawHtml':   return rawHtml(elem);
+    case 'Custom':    return elem.render(elem.model);
+    }
+}
+
+function update(node, curr, next) {
+    if (node.tagName === 'A') {
+        node = node.firstChild;
+    }
+    if (curr.props.id === next.props.id) {
+        return updateProps(node, curr, next);
+    }
+    if (curr.element.ctor !== next.element.ctor) {
+        node.parentNode.replaceChild(render(next),node);
+        return true;
+    }
+    var nextE = next.element, currE = curr.element;
+    switch(nextE.ctor) {
+    case "Spacer": break;
+    case "RawHtml":
+        // only markdown blocks have guids, so this must be a text block
+        if (nextE.guid === null) {
+            if(currE.html.valueOf() !== nextE.html.valueOf()) {
+                node.innerHTML = nextE.html;
+            }
+            break;
+        }
+        if (nextE.guid !== currE.guid) {
+            node.parentNode.replaceChild(render(next),node);
+            return true;
+        }
+        var nargs = nextE.args;
+        var cargs = currE.args;
+        for (var i = nargs.length; i--; ) {
+            var narg = nargs[i];
+            var carg = cargs[i]
+            if (narg == carg) continue;
+            var span = document.getElementById('md-' + currE.guid + '-' + i);
+            if (narg.isElement) {
+                if (carg.isElement) {
+                    update(span, carg, narg);
+                } else {
+                    span.style.display = 'block';
+                    var e = render(narg);
+                    span.innerHTML = '';
+                    span.appendChild(e);
+                }
+            } else {
+                span.style.display = 'inline';
+                span.innerHTML = narg;
+            }
+        }
+        break;
+    case "Image":
+        if (nextE._0.ctor === 'Plain') {
+            if (nextE._3 !== currE._3) node.src = nextE._3;
+        } else if (!eq(nextE,currE) ||
+                   next.props.width !== curr.props.width ||
+                   next.props.height !== curr.props.height) {
+            node.parentNode.replaceChild(render(next),node);
+            return true;
+        }
+        break;
+    case "Flow":
+        var arr = fromList(nextE._1);
+        for (var i = arr.length; i--; ) { arr[i] = arr[i].element.ctor; }
+        if (nextE._0.ctor !== currE._0.ctor) {
+            node.parentNode.replaceChild(render(next),node);
+            return true;
+        }
+        var nexts = fromList(nextE._1);
+        var kids = node.childNodes;
+        if (nexts.length !== kids.length) {
+            node.parentNode.replaceChild(render(next),node);
+            return true;
+        }
+        var currs = fromList(currE._1);
+        var dir = nextE._0.ctor;
+        var goDir = directionTable[dir];
+        var toReverse = needsReversal(dir);
+        var len = kids.length;
+        for (var i = len; i-- ;) {
+            update(kids[toReverse ? len - i - 1 : i],currs[i],nexts[i]);
+            goDir(kids[i]);
+        }
+        break;
+    case "Container":
+        update(node.firstChild, currE._1, nextE._1);
+        setPos(nextE._0, nextE._1, node.firstChild);
+        break;
+    case "Custom":
+        if (currE.type === nextE.type) {
+            var done = nextE.update(node, currE.model, nextE.model);
+            if (done) return;
+        } else {
+            return node.parentNode.replaceChild(render(next), node);
+        }
+    }
+    updateProps(node, curr, next);
+}
+
+function updateProps(node, curr, next) {
+    var nextProps = next.props;
+    var currProps = curr.props;
+
+    var element = next.element;
+    var width = nextProps.width - (element.adjustWidth || 0);
+    var height = nextProps.height - (element.adjustHeight || 0);
+    if (width !== currProps.width) {
+        node.style.width = (width|0) + 'px';
+    }
+    if (height !== currProps.height) {
+        node.style.height = (height|0) + 'px';
+    }
+
+    if (nextProps.opacity !== currProps.opacity) {
+        node.style.opacity = nextProps.opacity;
+    }
+
+    var nextColor = nextProps.color.ctor === 'Just'
+        ? colorToCss(nextProps.color._0)
+        : 'transparent';
+    if (node.style.backgroundColor !== nextColor) {
+        node.style.backgroundColor = nextColor;
+    }
+
+    if (nextProps.tag !== currProps.tag) {
+        node.id = nextProps.tag;
+    }
+
+    if (nextProps.href !== currProps.href) {
+        if (currProps.href === '') {
+            // add a surrounding href
+            var anchor = newElement('a');
+            anchor.href = nextProps.href;
+            anchor.style.display = 'block';
+            anchor.style.pointerEvents = 'auto';
+
+            node.parentNode.replaceChild(anchor, node);
+            anchor.appendChild(node);
+        } else if (nextProps.href === '') {
+            // remove the surrounding href
+            var anchor = node.parentNode;
+            anchor.parentNode.replaceChild(node, anchor);
+        } else {
+            // just update the link
+            node.parentNode.href = nextProps.href;
+        }
+    }
+
+    // update click and hover handlers
+    var removed = false;
+
+    // update hover handlers
+    if (currProps.hover.ctor === '_Tuple0') {
+        if (nextProps.hover.ctor !== '_Tuple0') {
+            addHover(node, nextProps.hover);
+        }
+    }
+    else {
+        if (nextProps.hover.ctor === '_Tuple0') {
+            removed = true;
+            removeHover(node);
+        }
+        else {
+            node.elm_hover_handler = nextProps.hover;
+        }
+    }
+
+    // update click handlers
+    if (currProps.click.ctor === '_Tuple0') {
+        if (nextProps.click.ctor !== '_Tuple0') {
+            addClick(node, nextProps.click);
+        }
+    }
+    else {
+        if (nextProps.click.ctor === '_Tuple0') {
+            removed = true;
+            removeClick(node);
+        } else {
+            node.elm_click_handler = nextProps.click;
+        }
+    }
+
+    // stop capturing clicks if 
+    if (removed
+        && nextProps.hover.ctor === '_Tuple0'
+        && nextProps.click.ctor === '_Tuple0')
+    {
+        node.style.pointerEvents = 'none';
+    }
+}
+
+return { render:render, update:update };
+
+};
+ElmRuntime.Render.Utils = function() {
+  function newElement(elementType) {
+      var e = document.createElement(elementType);
+      e.style.padding = "0";
+      e.style.margin = "0";
+      return e;
+  }
+
+  function addTo(container, elem) {
+      container.appendChild(elem);
+  }
+
+  function addTransform(style, trans) {
+    style.transform       = trans;
+    style.msTransform     = trans;
+    style.MozTransform    = trans;
+    style.webkitTransform = trans;
+    style.OTransform      = trans;
+  }
+
+  function removeTransform(style) {
+    style.transform       = 'none';
+    style.msTransform     = 'none';
+    style.MozTransform    = 'none';
+    style.webkitTransform = 'none';
+    style.OTransform      = 'none';
+  }
+
+  var List = Elm.Native.List.make({});
+
+  return {addTo:addTo,
+          newElement: newElement,
+          colorToCss: Elm.Native.Color.make({}).toCss,
           fromList: List.toArray,
           fromString: function(s) { return s; },
           toString: function(s) { return s; },
diff --git a/data/interfaces.data b/data/interfaces.data
Binary files a/data/interfaces.data and b/data/interfaces.data differ
diff --git a/tests/Main.hs b/tests/Main.hs
deleted file mode 100644
--- a/tests/Main.hs
+++ /dev/null
@@ -1,11 +0,0 @@
-module Main where
-
-import Test.Framework
-
-import Tests.Compiler
-import Tests.Property
-
-main :: IO () 
-main = defaultMain [ compilerTests
-                   , propertyTests
-                   ]
diff --git a/tests/Tests/Compiler.hs b/tests/Tests/Compiler.hs
deleted file mode 100644
--- a/tests/Tests/Compiler.hs
+++ /dev/null
@@ -1,45 +0,0 @@
-module Tests.Compiler (compilerTests)
-       where
-
-import Data.Functor                   ((<$>))
-import Data.Traversable               (traverse)
-import System.FilePath                ((</>))
-import System.FilePath.Find           (find, (==?), extension)
-import Test.Framework
-import Test.Framework.Providers.HUnit (testCase)
-import Test.HUnit                     (Assertion, assertFailure, assertBool)
-import Text.Parsec                    (ParseError)
-
-import Elm.Internal.Utils as Elm
-
-compilerTests :: Test
-compilerTests = buildTest $ do
-  goods <- mkTests goodCompile  =<< getElms "good"
-  bads  <- mkTests badCompile   =<< getElms "bad"
-  return $ testGroup "Compile Tests"
-    [
-      testGroup "Good Tests" goods
-    , testGroup "Bad Tests"  bads
-    ]
-
-  where getElms :: FilePath -> IO [FilePath]
-        getElms fname = find (return True) (extension ==? ".elm") (testsDir </> fname)
-
-        mkTests :: (Either String String -> Assertion) -> [FilePath] -> IO [Test]
-        mkTests h = traverse setupTest
-          where setupTest f = testCase f . mkCompileTest h <$> readFile f
-
-        testsDir = "tests" </> "test-files"
-
-goodCompile :: Either String String -> Assertion
-goodCompile (Left err) = assertFailure err
-goodCompile (Right _)  = assertBool "" True
-
-badCompile :: Either String String -> Assertion
-badCompile (Left _)  = assertBool "" True
-badCompile (Right _) = assertFailure "Compilation succeeded but should have failed"
-  
-mkCompileTest :: ((Either String String) -> Assertion) -- ^ Handler
-                 -> String -- ^ File Contents
-                 -> Assertion
-mkCompileTest handle = handle . Elm.compile
diff --git a/tests/Tests/Property.hs b/tests/Tests/Property.hs
deleted file mode 100644
--- a/tests/Tests/Property.hs
+++ /dev/null
@@ -1,54 +0,0 @@
-module Tests.Property where
-
-import Control.Applicative ((<*))
-import Test.Framework
-import Test.Framework.Providers.HUnit
-import Test.Framework.Providers.QuickCheck2
-import Test.HUnit (assert)
-import Test.QuickCheck
-import Text.Parsec.Combinator (eof)
-import Text.PrettyPrint as P
-
-import SourceSyntax.Literal as Lit
-import SourceSyntax.Pattern as Pat
-import SourceSyntax.PrettyPrint  (Pretty, pretty)
-import Parse.Helpers             (IParser, iParse)
-import Parse.Literal             (literal)
-import qualified Parse.Pattern as Pat (expr)
-import qualified Parse.Type as Type (expr)
-import Tests.Property.Arbitrary
-
-propertyTests :: Test
-propertyTests =
-  testGroup "Parse/Print Agreement Tests"
-  [
-    testCase "Long Pattern test" $ assert (prop_parse_print Pat.expr longPat)
-  , testProperty "Literal test" $ prop_parse_print literal
-  , testProperty "Pattern test" $ prop_parse_print Pat.expr
-  , testProperty "Type test" $ prop_parse_print Type.expr
-  ]
-
-  where
-    -- This test was autogenerated from the Pattern test and should be
-    -- left in all its ugly glory.
-    longPat = Pat.PData "I" [ Pat.PLiteral (Lit.Chr '+')
-                            , Pat.PRecord [
-                                 "q7yclkcm7k_ikstrczv_"
-                                 , "wQRv6gKsvvkjw4b5F"
-                                 ,"c9'eFfhk9FTvsMnwF_D"
-                                 ,"yqxhEkHvRFwZ"
-                                 ,"o"
-                                 ,"nbUlCn3y3NnkVoxhW"
-                                 ,"iJ0MNy3KZ_lrs"
-                                 ,"ug"
-                                 ,"sHHsX"
-                                 ,"mRKs9d"
-                                 ,"o2KiCX5'ZRzHJfRi8" ]
-                            , Pat.PVar "su'BrrbPUK6I33Eq" ]
-
-prop_parse_print :: (Pretty a, Arbitrary a, Eq a) => IParser a -> a -> Bool
-prop_parse_print p x =
-  either (const False) (== x) . parse_print p $ x
-
-parse_print :: (Pretty a) => IParser a -> a -> Either String a
-parse_print p = either (Left . show) (Right) . iParse (p <* eof) . P.renderStyle P.style {mode=P.LeftMode} . pretty
diff --git a/tests/Tests/Property/Arbitrary.hs b/tests/Tests/Property/Arbitrary.hs
deleted file mode 100644
--- a/tests/Tests/Property/Arbitrary.hs
+++ /dev/null
@@ -1,113 +0,0 @@
-{-# OPTIONS_GHC -W -fno-warn-orphans #-}
-module Tests.Property.Arbitrary where
-
-import Control.Applicative       ((<$>), (<*>), pure)
-import Test.QuickCheck.Arbitrary
-import Test.QuickCheck.Gen
-
-import qualified Data.Set as Set
-import qualified Parse.Helpers (reserveds)
-
-import SourceSyntax.Literal
-import SourceSyntax.Pattern
-import SourceSyntax.Type hiding (listOf)
-
-instance Arbitrary Literal where
-  arbitrary = oneof [ IntNum   <$> arbitrary
-                    , FloatNum <$> (arbitrary `suchThat` noE)
-                    , Chr      <$> arbitrary
-                      -- This is too permissive
-                    , Str      <$> arbitrary
-                      -- Booleans aren't actually source syntax 
-                      -- , Boolean  <$> arbitrary
-                    ]
-  shrink l = case l of
-    IntNum n   -> IntNum   <$> shrink n
-    FloatNum f -> FloatNum <$> (filter noE . shrink $ f)
-    Chr c      -> Chr      <$> shrink c
-    Str s      -> Str      <$> shrink s
-    Boolean b  -> Boolean  <$> shrink b
-
-noE :: Double -> Bool
-noE = notElem 'e' . show
-
-
-instance Arbitrary Pattern where
-  arbitrary = sized pat
-    where pat :: Int -> Gen Pattern
-          pat n = oneof [ pure PAnything
-                        , PVar     <$> lowVar
-                        , PRecord  <$> (listOf1 lowVar)
-                        , PLiteral <$> arbitrary
-                        , PAlias   <$> lowVar    <*> pat (n-1)
-                        , PData    <$> capVar    <*> sizedPats
-                        ]
-            where sizedPats = do
-                    len <- choose (0,n)
-                    let m = n `div` (len + 1)
-                    vectorOf len $ pat m
-
-  shrink pat = case pat of
-    PAnything  -> []
-    PVar v     -> PVar     <$> shrinkWHead v
-    PRecord fs -> PRecord  <$> (filter (all $ not . null) . filter (not . null) $ shrink fs)
-    PLiteral l -> PLiteral <$> shrink l
-    PAlias s p -> p : (PAlias <$> shrinkWHead s <*> shrink p)
-    PData s ps -> ps ++ (PData <$> shrinkWHead s <*> shrink ps)
-
-shrinkWHead :: Arbitrary a => [a] -> [[a]]
-shrinkWHead [] = error "Should be nonempty"
-shrinkWHead (x:xs) = (x:) <$> shrink xs
-
-instance Arbitrary Type where
-  arbitrary = sized tipe
-    where tipe :: Int -> Gen Type
-          tipe n = oneof [ Lambda <$> depthTipe <*> depthTipe
-                         , Var    <$> lowVar
-                         , Data   <$> capVar <*> depthTipes
-                         , Record <$> fields <*> pure Nothing
-                         , Record <$> fields1 <*> (Just <$> lowVar)
-                         ]
-            where depthTipe = choose (0,n) >>= tipe
-                  depthTipes = do
-                    len <- choose (0,n) 
-                    let m = n `div` (len + 1)
-                    vectorOf len $ tipe m
-
-                  field = (,) <$> lowVar <*> depthTipe
-                  fields = do
-                    len <- choose (0,n)
-                    let m = n `div` (len + 1)
-                    vectorOf len $ (,) <$> lowVar <*> tipe m
-                  fields1 = (:) <$> field <*> fields
-
-  shrink tipe = case tipe of
-    Lambda s t    -> s : t : (Lambda <$> shrink s <*> shrink t)
-    Var _         -> []
-    Data n ts     -> ts ++ (Data <$> shrinkWHead n <*> shrink ts)
-    Record fs t   -> map snd fs ++ case t of
-      Nothing -> Record <$> shrinkList shrinkField fs <*> pure Nothing
-      Just _ ->
-        do
-          fields <- filter (not . null) $ shrinkList shrinkField fs
-          return $ Record fields t
-      where shrinkField (n,t) = (,) <$> shrinkWHead n <*> shrink t
-
-lowVar :: Gen String
-lowVar = notReserved $ (:) <$> lower <*> listOf varLetter
-  where lower = elements ['a'..'z']
-
-capVar :: Gen String
-capVar = notReserved $ (:) <$> upper <*> listOf varLetter
-  where upper = elements ['A'..'Z']
-
-varLetter :: Gen Char
-varLetter = elements $ ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9'] ++ ['\'', '_']
-
-notReserved :: Gen String -> Gen String
-notReserved = flip exceptFor Parse.Helpers.reserveds
-
-exceptFor :: (Ord a) => Gen a -> [a] -> Gen a
-exceptFor g xs = g `suchThat` notAnX
-  where notAnX = flip Set.notMember xset
-        xset = Set.fromList xs
diff --git a/tests/compiler/CompilerTest.hs b/tests/compiler/CompilerTest.hs
new file mode 100644
--- /dev/null
+++ b/tests/compiler/CompilerTest.hs
@@ -0,0 +1,11 @@
+module Main where
+
+import Test.Framework
+
+import Tests.Compiler
+import Tests.Property
+
+main :: IO () 
+main = defaultMain [ compilerTests
+                   , propertyTests
+                   ]
diff --git a/tests/compiler/Tests/Compiler.hs b/tests/compiler/Tests/Compiler.hs
new file mode 100644
--- /dev/null
+++ b/tests/compiler/Tests/Compiler.hs
@@ -0,0 +1,62 @@
+{-# OPTIONS_GHC -W #-}
+module Tests.Compiler (compilerTests) where
+
+import Data.Traversable (traverse)
+
+import System.Exit
+import System.FilePath ((</>))
+import System.FilePath.Find (find, (==?), extension)
+import System.Process (readProcessWithExitCode)
+
+import Test.Framework
+import Test.Framework.Providers.HUnit (testCase)
+import Test.HUnit (Assertion, assertFailure, assertBool)
+
+compilerTests :: Test
+compilerTests =
+  buildTest $ do
+    goods <- testIf isSuccess =<< getElms "good"
+    bads  <- testIf isFailure =<< getElms "bad"
+    return $ testGroup "Compile Tests"
+             [ testGroup "Good Tests" goods
+             , testGroup "Bad Tests"  bads
+             ]
+
+-- COLLECT FILES
+
+getElms :: FilePath -> IO [FilePath]
+getElms filePath =
+    find (return True) (extension ==? ".elm") (testsDir </> filePath)
+
+testsDir :: FilePath
+testsDir = "tests" </> "compiler" </> "test-files"
+
+
+-- RUN COMPILER
+
+testIf :: (ExitCode -> String -> Assertion) -> [FilePath] -> IO [Test]
+testIf handler filePaths =
+    traverse setupTest filePaths
+  where
+    setupTest filePath = do
+      let args = [ "--make", "--src-dir=" ++ testsDir, filePath ]
+      (exitCode, stdout, stderr) <- readProcessWithExitCode compiler args ""
+      return (testCase filePath (handler exitCode (stdout ++ stderr)))
+
+compiler :: FilePath
+compiler = "dist" </> "build" </> "elm" </> "elm"
+
+
+-- CHECK RESULTS
+
+isSuccess :: ExitCode -> String -> Assertion
+isSuccess exitCode stderr =
+    case exitCode of
+      ExitSuccess -> assertBool "" True
+      ExitFailure _ -> assertFailure stderr
+
+isFailure :: ExitCode -> String -> Assertion
+isFailure exitCode _stderr =
+    case exitCode of
+      ExitSuccess -> assertFailure "Compilation succeeded but should have failed"
+      ExitFailure _ -> assertBool "" True
diff --git a/tests/compiler/Tests/Property.hs b/tests/compiler/Tests/Property.hs
new file mode 100644
--- /dev/null
+++ b/tests/compiler/Tests/Property.hs
@@ -0,0 +1,56 @@
+module Tests.Property where
+
+import Control.Applicative ((<*))
+import Test.Framework
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2
+import Test.HUnit (assert)
+import Test.QuickCheck
+import Text.Parsec.Combinator (eof)
+import Text.PrettyPrint as P
+
+import AST.Literal as Lit
+import qualified AST.Pattern as P
+import qualified AST.Variable as V
+import AST.PrettyPrint (Pretty, pretty)
+import Parse.Helpers (IParser, iParse)
+import Parse.Literal (literal)
+import qualified Parse.Pattern as Pat (expr)
+import qualified Parse.Type as Type (expr)
+import Tests.Property.Arbitrary
+
+propertyTests :: Test
+propertyTests =
+  testGroup "Parse/Print Agreement Tests"
+  [ testCase "Long Pattern test" $ assert (prop_parse_print Pat.expr longPat)
+  , testProperty "Literal test" $ prop_parse_print literal
+  , testProperty "Pattern test" $ prop_parse_print Pat.expr
+  , testProperty "Type test" $ prop_parse_print Type.expr
+  ]
+
+  where
+    -- This test was autogenerated from the Pattern test and should be
+    -- left in all its ugly glory.
+    longPat = P.Data (V.Raw "I")
+              [ P.Literal (Lit.Chr '+')
+              , P.Record
+                [ "q7yclkcm7k_ikstrczv_"
+                , "wQRv6gKsvvkjw4b5F"
+                ,"c9'eFfhk9FTvsMnwF_D"
+                ,"yqxhEkHvRFwZ"
+                ,"o"
+                ,"nbUlCn3y3NnkVoxhW"
+                ,"iJ0MNy3KZ_lrs"
+                ,"ug"
+                ,"sHHsX"
+                ,"mRKs9d"
+                ,"o2KiCX5'ZRzHJfRi8" ]
+              , P.Var "su'BrrbPUK6I33Eq"
+              ]
+
+prop_parse_print :: (Pretty a, Arbitrary a, Eq a) => IParser a -> a -> Bool
+prop_parse_print p x =
+  either (const False) (== x) . parse_print p $ x
+
+parse_print :: (Pretty a) => IParser a -> a -> Either String a
+parse_print p = either (Left . show) Right . iParse (p <* eof) . P.renderStyle P.style {mode=P.LeftMode} . pretty
diff --git a/tests/compiler/Tests/Property/Arbitrary.hs b/tests/compiler/Tests/Property/Arbitrary.hs
new file mode 100644
--- /dev/null
+++ b/tests/compiler/Tests/Property/Arbitrary.hs
@@ -0,0 +1,137 @@
+{-# OPTIONS_GHC -W -fno-warn-orphans #-}
+module Tests.Property.Arbitrary where
+
+import Control.Applicative       ((<$>), (<*>), pure)
+import Test.QuickCheck.Arbitrary
+import Test.QuickCheck.Gen
+
+import qualified Data.Set as Set
+import qualified Parse.Helpers (reserveds)
+
+import qualified AST.Literal as L
+import qualified AST.Pattern as P
+import qualified AST.Type as T
+import qualified AST.Variable as V
+
+instance Arbitrary V.Raw where
+  arbitrary = V.Raw <$> capVar
+  shrink (V.Raw v) = V.Raw <$> shrink v
+
+instance Arbitrary L.Literal where
+  arbitrary =
+      oneof
+      [ L.IntNum   <$> arbitrary
+      , L.FloatNum <$> (arbitrary `suchThat` noE)
+      , L.Chr      <$> arbitrary
+      -- This is too permissive
+      , L.Str      <$> arbitrary
+      -- Booleans aren't actually source syntax 
+      -- , Boolean  <$> arbitrary
+      ]
+
+  shrink lit =
+    case lit of
+      L.IntNum n   -> L.IntNum   <$> shrink n
+      L.FloatNum f -> L.FloatNum <$> (filter noE . shrink $ f)
+      L.Chr c      -> L.Chr      <$> shrink c
+      L.Str s      -> L.Str      <$> shrink s
+      L.Boolean b  -> L.Boolean  <$> shrink b
+
+noE :: Double -> Bool
+noE = notElem 'e' . show
+
+genVector :: Int -> (Int -> Gen a) -> Gen [a]
+genVector n generator = do
+  len <- choose (0,n)
+  let m = n `div` (len + 1)
+  vectorOf len $ generator m
+
+instance Arbitrary v => Arbitrary (P.Pattern v) where
+  arbitrary = sized pat
+    where
+      pat :: (Arbitrary v) => Int -> Gen (P.Pattern v)
+      pat n =
+          oneof
+          [ pure P.Anything
+          , P.Var     <$> lowVar
+          , P.Record  <$> (listOf1 lowVar)
+          , P.Literal <$> arbitrary
+          , P.Alias   <$> lowVar <*> pat (n-1)
+          , P.Data    <$> arbitrary <*> genVector n pat
+          ]
+
+  shrink pat =
+    case pat of
+      P.Anything  -> []
+      P.Var v     -> P.Var <$> shrinkWHead v
+      P.Literal l -> P.Literal <$> shrink l
+      P.Alias s p -> p : (P.Alias <$> shrinkWHead s <*> shrink p)
+      P.Data s ps -> ps ++ (P.Data <$> shrink s <*> shrink ps)
+      P.Record fs ->
+          P.Record <$> filter (all notNull) (filter notNull (shrink fs))
+          where
+            notNull = not . null
+
+shrinkWHead :: Arbitrary a => [a] -> [[a]]
+shrinkWHead [] = error "Should be nonempty"
+shrinkWHead (x:xs) = (x:) <$> shrink xs
+
+instance Arbitrary v => Arbitrary (T.Type v) where
+  arbitrary = sized tipe
+    where
+      tipe :: Arbitrary v => Int -> Gen (T.Type v)
+      tipe n =
+          let depthTipe = tipe =<< choose (0,n)
+              field = (,) <$> lowVar <*> depthTipe
+              fields = genVector n (\m -> (,) <$> lowVar <*> tipe m)
+              fields1 = (:) <$> field <*> fields
+              depthTipes = (:) <$> depthTipe <*> genVector n tipe
+          in
+              oneof
+              [ T.Lambda <$> depthTipe <*> depthTipe
+              , T.Var    <$> lowVar
+              , T.Type   <$> arbitrary
+              , T.App    <$> (T.Type <$> arbitrary) <*> depthTipes
+              , T.Record <$> fields <*> pure Nothing
+              , T.Record <$> fields1 <*> (Just . T.Var <$> lowVar)
+              ]
+
+  shrink tipe =
+    case tipe of
+      T.Lambda s t  -> s : t : (T.Lambda <$> shrink s <*> shrink t)
+      T.Var _       -> []
+      T.Aliased v t -> t : (T.Aliased v <$> shrink t)
+      T.Type v      -> T.Type <$> shrink v
+      T.App t ts    -> t : ts ++ (T.App <$> shrink t <*> shrink ts)
+      T.Record fs t -> map snd fs ++ record
+          where
+            record =
+                case t of
+                  Nothing -> T.Record <$> shrinkList shrinkField fs <*> pure Nothing
+                  Just _ ->
+                      do fields <- filter (not . null) $ shrinkList shrinkField fs
+                         return $ T.Record fields t
+
+            shrinkField (n,t) = (,) <$> shrinkWHead n <*> shrink t
+
+lowVar :: Gen String
+lowVar = notReserved $ (:) <$> lower <*> listOf varLetter
+  where
+    lower = elements ['a'..'z']
+
+capVar :: Gen String
+capVar = notReserved $ (:) <$> upper <*> listOf varLetter
+  where
+    upper = elements ['A'..'Z']
+
+varLetter :: Gen Char
+varLetter = elements $ ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9'] ++ ['\'', '_']
+
+notReserved :: Gen String -> Gen String
+notReserved = flip exceptFor Parse.Helpers.reserveds
+
+exceptFor :: (Ord a) => Gen a -> [a] -> Gen a
+exceptFor g xs = g `suchThat` notAnX
+  where
+    notAnX = flip Set.notMember xset
+    xset = Set.fromList xs
diff --git a/tests/libraries/LibraryTest.hs b/tests/libraries/LibraryTest.hs
new file mode 100644
--- /dev/null
+++ b/tests/libraries/LibraryTest.hs
@@ -0,0 +1,55 @@
+module Main where
+
+import Control.Monad (unless)
+import Data.List (isInfixOf)
+import System.Directory
+import System.Exit
+import System.FilePath
+import System.Process
+
+import Elm.Internal.Paths as Elm
+
+main :: IO ()
+main = do
+  top <- getCurrentDirectory
+
+  -- setup submodules and npm
+  runCmd "git" ["submodule", "update", "--init"]
+  out <- readProcess "npm" ["ls", "--parseable"] ""
+  unless ("jsdom" `isInfixOf` out) $ runCmd "npm" ["install","jsdom"]
+
+  -- setup actual library tests
+  let localCompiler = joinPath [ "dist", "build", "elm", "elm" ]
+  runCmd localCompiler [ "--make"
+                       , "--only-js"
+                       , "--src-dir=IO"
+                       , "--src-dir=Elm-Test"
+                       , "--src-dir=" ++ "tests" </> "libraries"
+                       , testFile <.> "elm"
+                       ]
+
+  -- run tests
+  let files = [ "IO" </> "share" </> "prescript.js"
+              , Elm.runtime
+              , "build" </> testFile <.> "js"
+              , "IO" </> "share" </> "handler.js"
+              ]
+      testRunner = "build" </> "TestRunner.js"
+  exe <- readProcess "cat" files ""
+  writeFile testRunner exe
+  exitCode <- rawSystem "node" [testRunner]
+  removeDirectoryRecursive "cache"
+  removeDirectoryRecursive "build"
+  exitWith exitCode
+  where
+    testFile = "tests" </> "libraries" </> "Test"
+
+runCmd :: String -> [String] -> IO ()
+runCmd cmd args = do
+  putStrLn (cmd ++ " " ++ unwords args)
+  (exitCode, stdout, stderr) <- readProcessWithExitCode cmd args ""
+  putStr stdout
+  putStr stderr
+  case exitCode of
+    ExitSuccess   -> return ()
+    ExitFailure _ -> exitWith exitCode
