Commits: 7

Update Elm Markup to 2.0.2

Fixe slider length and remove Debug.toString from CartesianCordinates.

index c770fd4..2bb88f6 100644
--- a/elm.json
+++ b/elm.json
@@ -11,21 +11,22 @@
=            "elm/html": "1.0.0",
=            "elm/http": "2.0.0",
=            "elm/json": "1.1.2",
+            "elm/parser": "1.1.0",
=            "elm/svg": "1.0.1",
=            "elm-community/basics-extra": "4.0.0",
=            "elm-community/list-extra": "8.1.0",
=            "elm-community/result-extra": "2.2.1",
=            "elm-explorations/markdown": "1.0.0",
+            "feathericons/elm-feather": "1.2.0",
=            "ianmackenzie/elm-geometry": "1.2.1",
=            "ianmackenzie/elm-geometry-svg": "1.0.2",
-            "mdgriffith/elm-markup": "1.0.0",
+            "mdgriffith/elm-markup": "2.0.2",
=            "mdgriffith/elm-ui": "1.1.0",
=            "turboMaCk/any-dict": "1.0.1"
=        },
=        "indirect": {
=            "elm/bytes": "1.0.7",
=            "elm/file": "1.0.1",
-            "elm/parser": "1.1.0",
=            "elm/time": "1.0.0",
=            "elm/url": "1.0.0",
=            "elm/virtual-dom": "1.0.2",
index 138e422..2afd30d 100644
--- a/index.txt
+++ b/index.txt
@@ -1,19 +1,21 @@
-| title
+| Title
=    Software Garden
=
+| Emphasize
=    ⚘
=
+| Emphasize
=    A functional programming workshop for non-programmers
=
=
=
-| header
+| Header
=    Before the course begins
=
-| header
+| Header
=    Setup
=
-| note
+| Note
=    This setup instructions are based on an assumption that you are using a Mac.
=
=    If you are using Linux or BSD, then you probably know how to install stuff.
@@ -25,114 +27,97 @@
=
=We will need
=
-| list
+| List
=    - a text editor (I use Atom)
=    - and the Elm programming language
=
-
-| header
+| Header
=    Installing Elm
=
=To install the Elm programming language, go to it's website:
=
-| emphasize
-    [elm-lang.org](http://elm-lang.org/)
-
+| Emphasize
+    {Link|elm-lang.org|url=http://elm-lang.org/}
=
=and follow the installation instructions.
=
-
-
-
-
-| header
+| Header
=    To do:
=
=Steps to reproduce the tree:
=
-Make a dot
-
-  Centered (Elm UI, viewBox, cartesian coordinates)
-
-Make a line
-
-  Play with transformations (union types)
-
-Gradients
-
-Multiple lines
-
-  Rosettes (different kinds)
-
-Groups and transformations
-
-  Spiral (recursion)
-
-Tree
-
-
-| header
+| List
+    - Make a dot (Centered (Elm UI, viewBox, cartesian coordinates))
+    - Make a line (Play with transformations (union types))
+    - Gradients
+    - Multiple lines
+    - Rosettes (different kinds)
+    - Groups and transformations
+    - Spiral (recursion)
+    - Tree
+
+| Header
=    Before the course begins
=
=Setup the development environment
=
-| list
+| List
=    - Elm
=    - Node.js
=
=
-| counter
+| Counter
=
=Embedded simplest example:
=
-| simplest
+| Simplest
=
=Embedded fill the screen example:
=
-| fill-the-screen
+| FillTheScreen
=
=Embedded centered dot example:
=
-| centered-dot
+| CenteredDot
=
=Embedded line example:
=
-| line
+| Line
=
=Embedded gradient example:
=
-| gradient
+| Gradient
=
=Embedded cartesian coordinates example:
=
-| cartesian-coordinates
+| CartesianCoordinates
=
=Embedded polar coordinates example:
=
-| polar-coordinates
+| PolarCoordinates
=
=Embeded transformations example:
=
-| transformations
+| Transformations
=
=Embedded nested-transformations example:
=
-| nested-transformations
+| NestedTransformations
=
=Embedded rosette example:
=
-| rosette
+| Rosette
=
=Embedded spiral example:
=
-| spiral
+| Spiral
=
=Embedded tree example:
=
-| tree
+| Tree
=
=Embedded view box example:
=
-| view-box
+| ViewBox
=
=Finito!
index 7441ca2..fc29be3 100644
--- a/src/CartesianCoordinates.elm
+++ b/src/CartesianCoordinates.elm
@@ -91,12 +91,18 @@ ui model =
=                        , fontSize "0.05"
=                        , dominantBaseline "central"
=                        ]
-                        [ text <| Debug.toString ( model.x, model.y ) ]
+                        [ text <|
+                            "("
+                                ++ String.fromFloat model.x
+                                ++ ", "
+                                ++ String.fromFloat model.y
+                                ++ ")"
+                        ]
=                    ]
=        , Input.slider
=            [ Element.behindContent
=                (Element.el
-                    [ Element.width (Element.maximum 600 Element.fill)
+                    [ Element.width Element.fill
=                    , Element.height (Element.px 2)
=                    , Element.centerY
=                    , Background.color <| Element.rgb 0.7 0.7 0.7
index 29bbd46..31f964d 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -1,16 +1,25 @@
=module Main exposing (main)
=
+{-| This program is responsible for rendering the website.
+
+It fetches the Elm Markup file at /index.txt and renders it. There are a number of embeded programs in the markup.
+
+-}
+
+import Basics.Extra exposing (curry)
=import Browser
=import BrowserWindow
=import CartesianCoordinates
=import CenteredDot
=import Counter
+import Dict
=import Element exposing (Element)
=import Element.Background as Background
=import Element.Border as Border
=import Element.Events
=import Element.Font as Font
=import Element.Input as Input
+import FeatherIcons exposing (icons)
=import FillTheScreen
=import Gradient
=import Html exposing (Html)
@@ -18,8 +27,10 @@ import Html.Attributes
=import Http
=import Line
=import Mark
-import Mark.Custom
+import Mark.Default
=import NestedTransformations
+import Parser
+import Parser.Advanced
=import PolarCoordinates
=import Result.Extra as Result
=import RosetteTypedTransformations
@@ -30,6 +41,7 @@ import Tree
=import ViewBox
=
=
+main : Program Flags Model Msg
=main =
=    Browser.element
=        { init = init
@@ -88,6 +100,7 @@ init flags =
=view : Model -> Html Msg
=view model =
=    let
+        content : Element Msg
=        content =
=            case model.markup of
=                Nothing ->
@@ -96,13 +109,14 @@ view model =
=
=                Just markup ->
=                    markup
-                        |> Mark.parseWith options
-                        |> Result.map (\fn -> fn model)
-                        |> Result.extract problemsElement
-
-        problemsElement problems =
-            problems
-                |> List.map problemElement
+                        |> Mark.parse document
+                        |> Result.map (\render -> render model)
+                        |> Result.extract deadEndsElement
+
+        deadEndsElement : List DeadEnd -> Element Msg
+        deadEndsElement deadEnds =
+            deadEnds
+                |> List.map deadEndElement
=                |> Element.column
=                    [ Element.centerX
=                    , Element.centerY
@@ -111,13 +125,117 @@ view model =
=                    , Element.spacing 20
=                    ]
=
-        problemElement { row, col, problem } =
-            Debug.toString problem
-                ++ " at "
-                ++ String.fromInt row
-                ++ ":"
-                ++ String.fromInt col
-                |> Element.text
+        deadEndElement : DeadEnd -> Element Msg
+        deadEndElement { row, col, problem, contextStack } =
+            let
+                message =
+                    case problem of
+                        Mark.ExpectingIndent level ->
+                            "Expecting indentation level "
+                                ++ String.fromInt level
+
+                        Mark.InlineStart ->
+                            "Inline start"
+
+                        Mark.InlineEnd ->
+                            "Inline end"
+
+                        Mark.BlockStart ->
+                            "Block start"
+
+                        Mark.Expecting what ->
+                            "Expecting " ++ what
+
+                        Mark.ExpectingBlockName name ->
+                            "Expecting a block name " ++ name
+
+                        Mark.ExpectingInlineName name ->
+                            "Expecting an inline name" ++ name
+
+                        Mark.ExpectingFieldName name ->
+                            "Expecting a field name" ++ name
+
+                        Mark.NonMatchingFields { expecting, found } ->
+                            "Fields don't match. Expecting one of [ "
+                                ++ String.join ", " expecting
+                                ++ " ], but got [ "
+                                ++ String.join ", " found
+                                ++ " ]"
+
+                        Mark.MissingField name ->
+                            "A field is missing from the record: "
+                                ++ name
+
+                        Mark.RecordError ->
+                            "A record error"
+
+                        Mark.Escape ->
+                            "Escape"
+
+                        Mark.EscapedChar ->
+                            "Escaped character"
+
+                        Mark.Newline ->
+                            "Expecting newline"
+
+                        Mark.Space ->
+                            "Space"
+
+                        Mark.End ->
+                            "End"
+
+                        Mark.Integer ->
+                            "Integer"
+
+                        Mark.FloatingPoint ->
+                            "Floating point"
+
+                        Mark.InvalidNumber ->
+                            "Invalid number"
+
+                        Mark.UnexpectedEnd ->
+                            "Unexpected end"
+
+                        Mark.CantStartTextWithSpace ->
+                            "Can't start text with a space"
+
+                        Mark.UnclosedStyles styles ->
+                            let
+                                styleName : Mark.Style -> String
+                                styleName style =
+                                    case style of
+                                        Mark.Bold ->
+                                            "Bold"
+
+                                        Mark.Italic ->
+                                            "Italic"
+
+                                        Mark.Strike ->
+                                            "Strike"
+                            in
+                            "Unclosed styles: [ "
+                                ++ (styles
+                                        |> List.map styleName
+                                        |> String.join ", "
+                                   )
+                                ++ "]"
+
+                        Mark.UnexpectedField { found, options, recordName } ->
+                            "Unexpected field: "
+                                ++ found
+                                ++ ". Valid fields for "
+                                ++ recordName
+                                ++ " are: [ "
+                                ++ String.join ", " options
+                                ++ " ]"
+            in
+            Element.text
+                (message
+                    ++ " at "
+                    ++ String.fromInt row
+                    ++ ":"
+                    ++ String.fromInt col
+                )
=    in
=    Element.layout
=        [ -- Below is a hack that enables static site generation
@@ -128,7 +246,7 @@ view model =
=
=update : Msg -> Model -> ( Model, Cmd Msg )
=update msg model =
-    case Debug.log "update" msg of
+    case msg of
=        DocumentFetched (Ok markup) ->
=            ( { model | markup = Just markup }
=            , Cmd.none
@@ -195,363 +313,438 @@ subscriptions model =
=                |> Sub.map TreeMsg
=
=
-type alias Styling =
-    Mark.Styling Msg
-
-
-type alias Options =
-    Mark.Options Model Styling Msg
-
-
-colors =
-    { maroon = Element.rgb 0.7 0 0
-    , gray = Element.rgb 0.8 0.8 0.8
-    , pink = Element.rgb 1 0.6 0.6
-    }
+type alias DeadEnd =
+    Parser.Advanced.DeadEnd Mark.Context Mark.Problem
=
=
-options : Options
-options =
+document : Mark.Document (Model -> Element Msg)
+document =
=    let
-        default =
-            Mark.default
-
-        emphasizeBlock : Mark.Custom.Block Model Styling Msg
-        emphasizeBlock =
-            Mark.Custom.section "emphasize" emphasizeView
+        title =
+            Mark.Default.title
+                [ Element.width Element.fill
+                , Element.paddingXY 0 32
+                , Font.center
+                , Font.size 86
+                , Font.extraBold
+                ]
+                text
=
-        emphasizeView : List (Element Msg) -> Styling -> Model -> Element Msg
-        emphasizeView elements style model =
-            elements
-                |> Element.column
-                    [ Element.spacing 30
-                    , Font.bold
-                    , Font.size 30
-                    , Font.center
-                    , Element.paddingXY 0 40
-                    ]
+        header =
+            Mark.Default.header
+                [ Font.size 24
+                , Font.underline
+                , Element.paddingXY 0 24
+                ]
+                text
=
-        titleBlock : Mark.Custom.Block Model Styling Msg
-        titleBlock =
-            Mark.Custom.section "title" titleView
-
-        titleView : List (Element Msg) -> Styling -> Model -> Element Msg
-        titleView elements style model =
-            case elements of
-                title :: subtitles ->
-                    let
-                        titleElement =
-                            Element.el
-                                [ Font.center
-                                , Font.size 60
-                                , Font.extraBold
-                                , Element.width Element.fill
-                                ]
-                                title
-                    in
-                    Element.column
-                        [ Element.spacing 30
-                        , Font.bold
-                        , Font.size 30
-                        , Font.center
-                        , Element.paddingXY 0 80
+        paragraph : Mark.Block (Model -> Element Msg)
+        paragraph =
+            let
+                render content model =
+                    Element.paragraph
+                        [ Element.paddingXY 0 24
=                        ]
-                        (titleElement :: subtitles)
-
-                [] ->
-                    Element.none
-
-        noteBlock : Mark.Custom.Block Model Styling Msg
-        noteBlock =
-            Mark.Custom.section "note" noteView
+                        (content model)
+            in
+            Mark.map
+                render
+                text
=
-        noteView : List (Element Msg) -> Styling -> Model -> Element Msg
-        noteView elements style model =
-            Element.column
+        monospace =
+            Mark.Default.monospace
=                [ Element.padding 20
-                , Element.spacing 10
-                , Border.width 1
+                , Element.width Element.fill
=                , Border.color colors.gray
+                , Border.width 3
=                , Border.rounded 5
-                , Font.italic
+                , Font.family [ Font.monospace ]
+                , Element.scrollbarY
=                ]
-                elements
=
-        counterBlock : Mark.Custom.Block Model Styling Msg
-        counterBlock =
-            Mark.Custom.block "counter" counterView
+        css : String -> String -> Element.Attribute msg
+        css property value =
+            Element.htmlAttribute
+                (Html.Attributes.style
+                    property
+                    value
+                )
=
-        counterView : Styling -> Model -> Element Msg
-        counterView style model =
-            model.counter
-                |> Counter.ui
-                |> Element.el
-                    [ Element.centerX
-                    , Element.centerY
-                    ]
-                |> Element.el
-                    [ Element.height (Element.px 400)
-                    , Element.width Element.fill
-                    ]
-                |> BrowserWindow.window []
-                |> Element.map CounterMsg
-
-        simplestBlock : Mark.Custom.Block Model Styling Msg
-        simplestBlock =
-            Mark.Custom.block "simplest" simplestView
-
-        simplestView : Styling -> Model -> Element Msg
-        simplestView style model =
-            Simplest.main
-                |> Element.html
-                |> Element.el
-                    [ Element.height (Element.px 400)
-                    , Element.width Element.fill
-                    , Element.padding 10
-                    ]
-                |> BrowserWindow.window []
-
-        fillTheScreenBlock : Mark.Custom.Block Model Styling Msg
-        fillTheScreenBlock =
-            Mark.Custom.block "fill-the-screen" fillTheScreenView
-
-        fillTheScreenView : Styling -> Model -> Element Msg
-        fillTheScreenView style model =
-            FillTheScreen.ui
-                |> Element.el
-                    [ Element.height (Element.px 400)
-                    , Element.width Element.fill
-                    ]
-                |> BrowserWindow.window []
-
-        centeredDotBlock : Mark.Custom.Block Model Styling Msg
-        centeredDotBlock =
-            Mark.Custom.block "centered-dot" centeredDotView
-
-        centeredDotView : Styling -> Model -> Element Msg
-        centeredDotView style model =
-            CenteredDot.main
-                |> Element.html
-                |> Element.el
-                    [ Element.height (Element.px 400)
-                    , Element.width Element.fill
-                    , Element.padding 10
-                    ]
-                |> BrowserWindow.window []
-
-        lineBlock : Mark.Custom.Block Model Styling Msg
-        lineBlock =
-            Mark.Custom.block "line" lineView
+        code =
+            let
+                render string model =
+                    string
+                        |> String.split "\n"
+                        |> List.indexedMap
+                            (\n loc ->
+                                Element.row [ Element.spacing 10 ]
+                                    [ Element.el
+                                        [ Font.color colors.gray
+                                        , Font.size 20
+                                        , Element.width (Element.px 40)
+                                        , css "user-select" "none"
+                                        , css "-webkit-user-select" "none"
+                                        , css "-ms-user-select" "none"
+                                        , css "-webkit-touch-callout" "none"
+                                        , css "-o-user-select" "none"
+                                        , css "-moz-user-select" "none"
+                                        ]
+                                        (Element.text (String.fromInt n ++ "."))
+                                    , Element.el
+                                        [ Element.width Element.fill
+                                        ]
+                                        (Element.text loc)
+                                    ]
+                            )
+                        |> Element.column
+                            [ Element.padding 20
+                            , Element.spacing 10
+                            , Element.width Element.fill
+                            , Border.color colors.gray
+                            , Border.width 3
+                            , Border.rounded 5
+                            , Font.family [ Font.monospace ]
+                            , Element.scrollbarY
+                            ]
+            in
+            Mark.block "Code"
+                render
+                Mark.multiline
=
-        lineView : Styling -> Model -> Element Msg
-        lineView style model =
-            Line.ui
-                |> Element.el
-                    [ Element.centerX
+        note : Mark.Block (Model -> Element Msg)
+        note =
+            let
+                render elements model =
+                    elements
+                        |> List.map (\element -> element model)
+                        |> Element.textColumn
+                            [ Element.padding 20
+                            , Element.spacing 10
+                            , Element.width Element.fill
+                            , Border.width 1
+                            , Border.color colors.gray
+                            , Font.color colors.gray
+                            , Border.rounded 5
+                            ]
+            in
+            Mark.block "Note"
+                render
+                (Mark.manyOf
+                    [ paragraph
+                    , header
=                    ]
-                |> BrowserWindow.window []
+                )
=
-        gradientBlock : Mark.Custom.Block Model Styling Msg
-        gradientBlock =
-            Mark.Custom.block "gradient" gradientView
+        emphasize : Mark.Block (Model -> Element Msg)
+        emphasize =
+            let
+                render element model =
+                    model
+                        |> element
+                        |> Element.el
+                            [ Element.spacing 30
+                            , Font.bold
+                            , Font.size 30
+                            , Font.center
+                            , Element.paddingXY 0 40
+                            , Element.width Element.fill
+                            ]
+            in
+            Mark.block "Emphasize"
+                render
+                paragraph
=
-        gradientView : Styling -> Model -> Element Msg
-        gradientView style model =
-            Gradient.ui
-                |> Element.el
-                    [ Element.centerX
-                    ]
-                |> BrowserWindow.window []
-
-        transformationsBlock : Mark.Custom.Block Model Styling Msg
-        transformationsBlock =
-            Mark.Custom.block "transformations" transformationsView
-
-        transformationsView : Styling -> Model -> Element Msg
-        transformationsView style model =
-            model.transformations
-                |> Transformations.ui
-                |> Element.el
-                    [ Element.height Element.fill
-                    , Element.width Element.fill
-                    ]
-                |> Element.el
-                    [ Element.centerX
-                    , Border.color colors.pink
-                    , Border.rounded 5
-                    , Border.width 2
-                    ]
-                |> Element.map TransformationsMsg
+        image =
+            Mark.Default.image
+                [ Element.width Element.fill
+                ]
=
-        nestedTransformationsBlock : Mark.Custom.Block Model Styling Msg
-        nestedTransformationsBlock =
-            Mark.Custom.block "nested-transformations" nestedTransformationsView
+        list =
+            Mark.Default.list
+                { icon = Mark.Default.listIcon
+                , style =
+                    \cursor ->
+                        case List.length cursor of
+                            0 ->
+                                -- top level element
+                                [ Element.spacing 16 ]
+
+                            1 ->
+                                [ Element.spacing 16 ]
+
+                            2 ->
+                                [ Element.spacing 16 ]
+
+                            _ ->
+                                [ Element.spacing 8 ]
+                }
+                text
+
+        text : Mark.Block (Model -> List (Element Msg))
+        text =
+            let
+                defaultTextStyle =
+                    Mark.Default.defaultTextStyle
+            in
+            Mark.Default.textWith
+                { defaultTextStyle
+                    | inlines = defaultTextStyle.inlines ++ [ icon ]
+                }
+
+        icon : Mark.Inline (Model -> Element Msg)
+        icon =
+            Mark.inline "Icon"
+                (\name model ->
+                    icons
+                        |> Dict.get name
+                        |> Maybe.map (FeatherIcons.toHtml [])
+                        |> Maybe.map Element.html
+                        |> Maybe.withDefault
+                            (Element.text
+                                ("Icon not found: '" ++ name ++ "'")
+                            )
+                )
+                |> Mark.inlineString "name"
+
+        -- Embeded programs' blocks
+        counter : Mark.Block (Model -> Element Msg)
+        counter =
+            let
+                render model =
+                    model.counter
+                        |> Counter.ui
+                        |> Element.el
+                            [ Element.centerX
+                            , Element.centerY
+                            ]
+                        |> Element.el
+                            [ Element.height (Element.px 400)
+                            , Element.width Element.fill
+                            ]
+                        |> BrowserWindow.window []
+                        |> Element.map CounterMsg
+            in
+            Mark.stub "Counter" render
=
-        nestedTransformationsView : Styling -> Model -> Element Msg
-        nestedTransformationsView style model =
-            model.nestedTransformations
-                |> NestedTransformations.ui
-                |> Element.el
-                    [ Element.centerX
-                    ]
-                |> Element.el
-                    [ Element.centerX
-                    , Border.color (Element.rgb 1 0.6 0.6)
-                    , Border.rounded 5
-                    , Border.width 2
-                    ]
-                |> Element.map NestedTransformationsMsg
+        simplest : Mark.Block (Model -> Element Msg)
+        simplest =
+            let
+                render model =
+                    Simplest.main
+                        |> Element.html
+                        |> Element.el
+                            [ Element.height (Element.px 400)
+                            , Element.width Element.fill
+                            ]
+                        |> BrowserWindow.window []
+            in
+            Mark.stub "Simplest" render
=
-        cartesianCoordinatesBlock : Mark.Custom.Block Model Styling Msg
-        cartesianCoordinatesBlock =
-            Mark.Custom.block "cartesian-coordinates" cartesianCoordinatesView
+        fillTheScreen : Mark.Block (Model -> Element Msg)
+        fillTheScreen =
+            let
+                render model =
+                    FillTheScreen.ui
+                        |> Element.el
+                            [ Element.height (Element.px 400)
+                            , Element.width Element.fill
+                            ]
+                        |> BrowserWindow.window []
+            in
+            Mark.stub "FillTheScreen" render
=
-        cartesianCoordinatesView : Styling -> Model -> Element Msg
-        cartesianCoordinatesView style model =
-            model.cartesianCoordinates
-                |> CartesianCoordinates.ui
-                |> Element.el
-                    [ Element.centerX
-                    , Element.width Element.fill
-                    ]
-                |> Element.el
-                    [ Element.centerX
-                    , Border.color (Element.rgb 1 0.6 0.6)
-                    , Border.rounded 5
-                    , Border.width 2
-                    ]
-                |> Element.map CartesianCoordinatesMsg
+        centeredDot : Mark.Block (Model -> Element Msg)
+        centeredDot =
+            let
+                render model =
+                    CenteredDot.main
+                        |> Element.html
+                        |> Element.el
+                            [ Element.height (Element.px 400)
+                            , Element.width Element.fill
+                            ]
+                        |> BrowserWindow.window []
+            in
+            Mark.stub "CenteredDot" render
=
-        polarCoordinatesBlock : Mark.Custom.Block Model Styling Msg
-        polarCoordinatesBlock =
-            Mark.Custom.block "polar-coordinates" polarCoordinatesView
+        line : Mark.Block (Model -> Element Msg)
+        line =
+            let
+                render model =
+                    Line.ui
+                        |> Element.el
+                            [ Element.height (Element.px 400)
+                            , Element.width Element.fill
+                            ]
+                        |> BrowserWindow.window []
+            in
+            Mark.stub "Line" render
=
-        polarCoordinatesView : Styling -> Model -> Element Msg
-        polarCoordinatesView style model =
-            model.polarCoordinates
-                |> PolarCoordinates.ui
-                |> Element.el
-                    [ Element.centerX
-                    , Element.width Element.fill
-                    ]
-                |> Element.el
-                    [ Element.centerX
-                    , Border.color (Element.rgb 1 0.6 0.6)
-                    , Border.rounded 5
-                    , Border.width 2
-                    ]
-                |> Element.map PolarCoordinatesMsg
+        gradient : Mark.Block (Model -> Element Msg)
+        gradient =
+            let
+                render model =
+                    Gradient.ui
+                        |> Element.el
+                            [ Element.height (Element.px 400)
+                            , Element.width Element.fill
+                            ]
+                        |> BrowserWindow.window []
+            in
+            Mark.stub "Gradient" render
=
-        rosetteBlock : Mark.Custom.Block Model Styling Msg
-        rosetteBlock =
-            Mark.Custom.block "rosette" rosetteView
+        transformations : Mark.Block (Model -> Element Msg)
+        transformations =
+            let
+                render model =
+                    model.transformations
+                        |> Transformations.ui
+                        |> Element.el
+                            [ Element.width Element.fill
+                            ]
+                        |> BrowserWindow.window []
+                        |> Element.map TransformationsMsg
+            in
+            Mark.stub "Transformations" render
=
-        rosetteView : Styling -> Model -> Element Msg
-        rosetteView style model =
-            RosetteTypedTransformations.ui
-                |> Element.el
-                    [ Element.centerX
-                    ]
-                |> BrowserWindow.window []
+        nestedTransformations : Mark.Block (Model -> Element Msg)
+        nestedTransformations =
+            let
+                render model =
+                    model.nestedTransformations
+                        |> NestedTransformations.ui
+                        |> Element.el
+                            [ Element.width Element.fill
+                            ]
+                        |> BrowserWindow.window []
+                        |> Element.map NestedTransformationsMsg
+            in
+            Mark.stub "NestedTransformations" render
=
-        spiralBlock : Mark.Custom.Block Model Styling Msg
-        spiralBlock =
-            Mark.Custom.block "spiral" spiralView
+        cartesianCoordinates : Mark.Block (Model -> Element Msg)
+        cartesianCoordinates =
+            let
+                render model =
+                    model.cartesianCoordinates
+                        |> CartesianCoordinates.ui
+                        |> Element.el
+                            [ Element.width Element.fill
+                            ]
+                        |> BrowserWindow.window []
+                        |> Element.map CartesianCoordinatesMsg
+            in
+            Mark.stub "CartesianCoordinates" render
=
-        spiralView : Styling -> Model -> Element Msg
-        spiralView style model =
-            Spiral.ui
-                |> Element.el
-                    [ Element.centerX
-                    , Element.width Element.fill
+        polarCoordinates : Mark.Block (Model -> Element Msg)
+        polarCoordinates =
+            let
+                render model =
+                    model.polarCoordinates
+                        |> PolarCoordinates.ui
+                        |> Element.el
+                            [ Element.width Element.fill
+                            ]
+                        |> BrowserWindow.window []
+                        |> Element.map PolarCoordinatesMsg
+            in
+            Mark.stub "PolarCoordinates" render
=
-                    -- , Element.height Element.fill
-                    ]
-                |> BrowserWindow.window []
+        rosette : Mark.Block (Model -> Element Msg)
+        rosette =
+            let
+                render model =
+                    RosetteTypedTransformations.ui
+                        |> Element.el
+                            [ Element.height (Element.px 400)
+                            , Element.width Element.fill
+                            ]
+                        |> BrowserWindow.window []
+            in
+            Mark.stub "Rosette" render
=
-        treeBlock : Mark.Custom.Block Model Styling Msg
-        treeBlock =
-            Mark.Custom.block "tree" treeView
+        spiral : Mark.Block (Model -> Element Msg)
+        spiral =
+            let
+                render model =
+                    Spiral.ui
+                        |> Element.el
+                            [ Element.height (Element.px 400)
+                            , Element.width Element.fill
+                            ]
+                        |> BrowserWindow.window []
+            in
+            Mark.stub "Spiral" render
=
-        treeView : Styling -> Model -> Element Msg
-        treeView style model =
+        tree : Mark.Block (Model -> Element Msg)
+        tree =
=            let
-                height =
-                    500
-
-                content =
-                    case model.tree of
-                        Nothing ->
-                            Element.text "Click Here to Display Tree"
-                                |> List.singleton
-                                |> Element.paragraph
-                                    [ Element.centerY
-                                    ]
-                                |> Element.el
-                                    [ Element.centerX
-                                    , Element.height <|
-                                        Element.minimum height <|
-                                            Element.maximum height <|
-                                                Element.fill
-                                    , Element.Events.onClick
-                                        (Tree.init ()
-                                            |> Tuple.first
-                                            |> Just
-                                            |> ToggleTree
-                                        )
-                                    ]
+                render model =
+                    model.tree
+                        |> Maybe.map Tree.ui
+                        |> Maybe.withDefault Element.none
+                        |> Element.el
+                            [ Element.height (Element.px 600)
+                            , Element.width Element.fill
+                            ]
+                        |> BrowserWindow.window []
+                        |> Element.map TreeMsg
+            in
+            Mark.stub "Tree" render
=
-                        Just tree ->
-                            tree
-                                |> Tree.ui
-                                |> Element.map TreeMsg
-                                |> Element.el
-                                    [ Element.centerX
-                                    , Element.height <|
-                                        Element.minimum height <|
-                                            Element.maximum height <|
-                                                Element.fill
-                                    , Element.width Element.fill
-                                    , Element.Events.onClick (ToggleTree Nothing)
-                                    ]
+        viewBox : Mark.Block (Model -> Element Msg)
+        viewBox =
+            let
+                render model =
+                    model.viewBox
+                        |> ViewBox.ui
+                        |> Element.el
+                            [ Element.width Element.fill
+                            ]
+                        |> Element.map ViewBoxMsg
=            in
-            content
-                |> BrowserWindow.window []
-
-        viewBoxBlock : Mark.Custom.Block Model Styling Msg
-        viewBoxBlock =
-            Mark.Custom.block "view-box" viewBoxView
-
-        viewBoxView : Styling -> Model -> Element Msg
-        viewBoxView style model =
-            model.viewBox
-                |> ViewBox.ui
-                |> Element.el
-                    [ Element.centerX
-                    , Border.color (Element.rgb 1 0.6 0.6)
-                    , Border.rounded 5
-                    , Border.width 2
-                    ]
-                |> Element.map ViewBoxMsg
+            Mark.stub "ViewBox" render
=    in
-    { default
-        | blocks =
-            titleBlock
-                :: emphasizeBlock
-                :: noteBlock
-                :: counterBlock
-                :: simplestBlock
-                :: fillTheScreenBlock
-                :: lineBlock
-                :: gradientBlock
-                :: centeredDotBlock
-                :: transformationsBlock
-                :: nestedTransformationsBlock
-                :: cartesianCoordinatesBlock
-                :: polarCoordinatesBlock
-                :: rosetteBlock
-                :: spiralBlock
-                :: treeBlock
-                :: viewBoxBlock
-                :: Mark.defaultBlocks
+    Mark.document
+        (\children model ->
+            Element.textColumn
+                [ Element.centerX
+                , Element.width (Element.px 800)
+                , Element.spacing 24
+                ]
+                (List.map (\render -> render model) children)
+        )
+        (Mark.manyOf
+            [ title
+            , header
+            , paragraph
+            , monospace
+            , code
+            , note
+            , emphasize
+            , list
+            , image
+
+            -- Embeded programs
+            , counter
+            , simplest
+            , fillTheScreen
+            , centeredDot
+            , line
+            , gradient
+            , transformations
+            , nestedTransformations
+            , cartesianCoordinates
+            , polarCoordinates
+            , rosette
+            , spiral
+            , tree
+            , viewBox
+            ]
+        )
+
+
+colors =
+    { maroon = Element.rgb 0.7 0 0
+    , gray = Element.rgb 0.8 0.8 0.8
+    , pink = Element.rgb 1 0.6 0.6
=    }

Remove calls to Debug functions

This enables the optimized compilation.

index 1f34423..e0aaded 100644
--- a/src/NestedTransformations.elm
+++ b/src/NestedTransformations.elm
@@ -64,7 +64,7 @@ type GroupMsg
=
=init : Model
=init =
-    Dict.empty Debug.toString
+    Dict.empty groupName
=        |> Dict.insert Pink
=            (Array.fromList
=                [ Translate 0 0
@@ -138,7 +138,7 @@ ui model =
=
=                color =
=                    group
-                        |> Debug.toString
+                        |> groupName
=                        |> String.toLower
=            in
=            g [ transform transformation ]
@@ -218,7 +218,7 @@ transformationUI index transformation =
=        controls =
=            case transformation of
=                Identity ->
-                    [ Element.text <| Debug.toString transformation ]
+                    [ Element.text "Identity" ]
=
=                Scale horizontal vertical ->
=                    [ Input.slider
@@ -388,6 +388,16 @@ apply transformations =
=        |> String.join " "
=
=
+groupName : Group -> String
+groupName group =
+    case group of
+        Pink ->
+            "Pink"
+
+        Green ->
+            "Green"
+
+
=toColor : Group -> Element.Color
=toColor group =
=    case group of
index 5da8133..3a476cd 100644
--- a/src/PolarCoordinates.elm
+++ b/src/PolarCoordinates.elm
@@ -93,7 +93,17 @@ ui model =
=                        , Svg.Attributes.fontSize "10pt"
=                        ]
=                        [ text <|
-                            Debug.toString ( round point.x, round point.y )
+                            "( "
+                                ++ (point.x
+                                        |> round
+                                        |> String.fromInt
+                                   )
+                                ++ " , "
+                                ++ (point.x
+                                        |> round
+                                        |> String.fromInt
+                                   )
+                                ++ " )"
=                        ]
=                    ]
=        , Input.slider
index 0bcd917..295c1ef 100644
--- a/src/Transformations.elm
+++ b/src/Transformations.elm
@@ -179,7 +179,7 @@ transformationUI index transformation =
=        controls =
=            case transformation of
=                Identity ->
-                    [ Element.text <| Debug.toString transformation ]
+                    [ Element.text "Identity" ]
=
=                Scale horizontal vertical ->
=                    [ Input.slider
index 44e7a9a..e2925a8 100644
--- a/src/Tree.elm
+++ b/src/Tree.elm
@@ -173,7 +173,7 @@ subscriptions model =
=            Json.Decode.field "key" Json.Decode.string
=                |> Json.Decode.andThen
=                    (\key ->
-                        case Debug.log "Key" key of
+                        case key of
=                            "," ->
=                                Json.Decode.succeed (Regress 10)
=

Remove background color and position of the dot from Simplest

index dee7dbd..9f90116 100644
--- a/src/Simplest.elm
+++ b/src/Simplest.elm
@@ -7,14 +7,11 @@ import Svg.Attributes
=
=main =
=    Svg.svg
-        [ Svg.Attributes.style "background: pink"
-        , Svg.Attributes.width "300"
+        [ Svg.Attributes.width "300"
=        , Svg.Attributes.height "150"
=        ]
=        [ Svg.circle
=            [ Svg.Attributes.r "10"
-            , Svg.Attributes.cx "30"
-            , Svg.Attributes.cy "30"
=            ]
=            []
=        ]

Create DotAtTheCenterOfTheScreen program

It's the same as the FillTheScreen but without background color

new file mode 100644
index 0000000..83f0d1d
--- /dev/null
+++ b/src/DotAtTheCenterOfTheScreen.elm
@@ -0,0 +1,27 @@
+module DotAtTheCenterOfTheScreen exposing (main, ui)
+
+import Element
+import Svg
+import Svg.Attributes
+
+
+main =
+    Element.layout
+        [ Element.width Element.fill
+        , Element.height Element.fill
+        ]
+        ui
+
+
+ui =
+    Svg.svg
+        [ Svg.Attributes.viewBox "-100 -100 200 200"
+        ]
+        [ Svg.circle
+            [ Svg.Attributes.r "10"
+            , Svg.Attributes.cx "0"
+            , Svg.Attributes.cy "0"
+            ]
+            []
+        ]
+        |> Element.html
index 29bbd46..82bc5a7 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -5,6 +5,7 @@ import BrowserWindow
=import CartesianCoordinates
=import CenteredDot
=import Counter
+import DotAtTheCenterOfTheScreen
=import Element exposing (Element)
=import Element.Background as Background
=import Element.Border as Border
@@ -324,6 +325,19 @@ options =
=                    ]
=                |> BrowserWindow.window []
=
+        dotAtTheCenterOfTheScreenBlock : Mark.Custom.Block Model Styling Msg
+        dotAtTheCenterOfTheScreenBlock =
+            Mark.Custom.block "dot-at-the-center-of-the-screen" dotAtTheCenterOfTheScreenView
+
+        dotAtTheCenterOfTheScreenView : Styling -> Model -> Element Msg
+        dotAtTheCenterOfTheScreenView style model =
+            DotAtTheCenterOfTheScreen.ui
+                |> Element.el
+                    [ Element.height (Element.px 400)
+                    , Element.width Element.fill
+                    ]
+                |> BrowserWindow.window []
+
=        centeredDotBlock : Mark.Custom.Block Model Styling Msg
=        centeredDotBlock =
=            Mark.Custom.block "centered-dot" centeredDotView
@@ -542,6 +556,7 @@ options =
=                :: counterBlock
=                :: simplestBlock
=                :: fillTheScreenBlock
+                :: dotAtTheCenterOfTheScreenBlock
=                :: lineBlock
=                :: gradientBlock
=                :: centeredDotBlock

Add the content from paper slides

index e9d30d1..7deafce 100644
--- a/index.txt
+++ b/index.txt
@@ -33,15 +33,18 @@ We will need
=| header
=    Installing Elm
=
+
=To install the Elm programming language, go to it's website:
=
+
=| emphasize
=    [elm-lang.org](http://elm-lang.org/)
=
=
+
=and follow the installation instructions.
-Some of the tools we use with Elm require [Node.js.](https://nodejs.org/en/)
-Go to the [Node.js](https://nodejs.org/en/) website and install the current version (the green button on the right)
+
+Some of the tools we use with Elm require Node.js. Go to the [Node.js](https://nodejs.org/en/) website and install the current version (the green button on the right)
=
=We will need to use the terminal a little bit.
=
@@ -57,6 +60,1021 @@ Don't be scared. It's easy.
=    "Here is a picture of terminal"
=
=
+Mac Terminal app window
+You should see a window like this
+
+
+| image "/assets/mac-terminal-window.png"
+    "A picture of Mac Terminal"
+
+Type the following in the terminal.
+
+
+| monospace
+    elm repl
+
+Inside the REPL type
+
+
+| monospace
+    2+2
+
+And expect to see
+
+
+| monospace
+    ---- Elm 0.19.0 ----------------
+    Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help
+    --------------------------------
+    > 2 + 2
+    4 : number
+    >
+
+Easy, huh?
+We will learn more about REPL later. For now type
+:exit to close it.
+The command line should get back to its initial state.
+
+| header
+    Install Atom Text Editor
+
+Computer Programs are represented as text, so the text editor is the most fundamental tool of a programmer. There is a lot of good text editors, but to get you started, we will use Atom here.
+
+Go to
+[atom.io](https://atom.io)
+and download the editor.
+After installation on Mac, open it and from Atom menu choose Install Shell Commands.
+
+One last thing we need is Elm support for Atom editor.
+You can install it by typing in the terminal:
+
+| monospace
+    apm install language-elm
+
+APM is the Atom Package Manager, but don't pay much attention to it. We won't be using it again.
+We are all set.
+
+| header
+    Day 1 - let's make a dot!
+
+| note
+    Today we are going to learn about
+
+    | list
+        -> Scalable Vector Graphics
+        -> cartesian Coordinates System
+        -> Layouts with ELM UI
+
+
+| header
+    First Program!
+
+As mentioned before, programs are represented as text (called the /source code/).
+The source code is stored in files
+
+| emphasize
+    * icon|name=file *
+
+
+and files are organized in directories
+
+
+| emphasize
+    * icon|name=directory *
+
+
+So the first step is to create a directory for our new program. Lets call it fpart.
+In the terminal type
+
+| monospace
+    mkdir fpart/
+
+and then
+
+| monospace
+    cd fpart/
+
+This creates a new directory and makes it the current one. Again, don't worry about the details.
+
+To easily create a new program, we can type
+
+| monospace
+    elm init
+
+Then to create a file with source code, type
+
+| monospace
+    atom src/Main.elm
+
+This command should open a new Atom window with empty text file.
+
+| header
+    Main.elm
+
+| monospace
+    module Main exposing (main)
+    import Html
+    main=
+       Html.text "Hello, Tree"
+
+Type the above in the editor and save the file.
+To see the program running type the following in the terminal
+
+| monospace
+    elm reactor
+
+This command starts the Elm reactor, which will let you run your program in the web browser. Note that it won't give you the command line back - it will run as long as you don't stop it.
+
+
+| emphasize
+    Voila!
+
+
+Open following address in the web browser
+[localhost](http://localhost:8000/src/Main.elm)
+Note that the same address was printed by Elm reactor
+
+| header
+    The problem
+
+We want to have a dot at the center of the screen, like this
+
+| dot-at-the-center-of-the-screen
+
+We are going to use a technology called SVG (Scalable Vector Graphics)
+Its all about drawing shapes on the screen
+
+* to be filled with the complete code *
+
+Let's install an Elm Package to help us work with SVG. Stop the reactor running in terminal by pressing `CTRL + C`
+and type the following
+
+| monospace
+    elm install elm/svg
+
+Then start the reactor again
+
+| monospace
+    elm reactor
+
+you can press up arrow  *icon up-arrow*  on the keyboard to get to the previous commands
+
+* simplest elm should be displayed here *
+
+| simplest
+
+Why is the dot at the corner?
+
+| simplest
+
+It's because its center is at point (0, 0)
+But what does it mean ?
+
+* a picture of a vase on a table should be here *
+
+Move sliders to change the x and y coordinates of the dot. It's like moving a thing on a table by telling how far left, right, up or down it should go.
+
+| cartesian-coordinates
+
+Note that the command line changes. You should see something like this
+
+| monospace
+    ---- Elm 0.19.0 --------------------------------------------------
+    Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help
+    ---------------------------------------------------------------------
+    >
+
+It's the Elm REPL
+Read-Evaluate-Print Loop
+
+To change where the dot is we can use cx and cy attributes of the circle
+
+* simplest with cx and cy should be here *
+
+* Module main exposing main should be here *
+
+Note that we have a complete program that draws a dot at the center of the screen , lets take a moment to understand it.
+
+Think about this ( * a picture of eggs and a box of eggs should be here * )
+
+| note
+    An egg is a thing.
+    Six eggs are six things.
+    A box of six eggs is a thing.
+
+
+
+Now, let's make the SVG element fill the screen
+
+
+| fill-the-screen
+
+
+For that we will need a package called [mdgriffith](https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/)
+
+Install it using terminal
+
+`CTRL + C` to stop elm-reactor and type `elm install mdgriffith/elm-ui`
+
+Then in `src/Main.elm` add import `import Element` and change `Main` to look like this :
+
+Main = * the code of Element.layout should be here*
+
+Note that our scene fills the screen, it's time to put the dot at the center of the scene.
+
+* a picture of cx and cy with width and height should be here *
+
+If we would know the height and width of the screen , we could calculate its position as
+
+`cx = width/2`
+
+`cy = height/2`
+
+There is a problem though, we don't know the height and width.
+☹️
+
+But we don't need to!
+
+*Scalable icon should be here*
+
+S for Scalable
+
+Instead of moving the dot, we can set the boundaries of the scene so that the dot is at the center using a property called Viewbox.
+
+| view-box
+
+Here is how the viewbox works
+
+* a picture of viewbox should be here*
+
+viewbox = 0 0 100 100 (left, top, width and height respectively)
+
+* a picture of periscope looking table should be here*
+
+The trick is to set the width and height to any arbitrary value (say 1000) and top and left to `- width/2`!
+
+That way point (0,0) will always be right in the middle (the distance to the left and to the right is the same, likewise the distance to the top and bottom).
+
+First, lets see where the SVG boundaries are by giving it a background color
+
+
+| centered-dot
+
+
+`Svg [background "pink"]
+[...
+]`
+
+Give a color to the dot
+
+
+| list
+    - Explain SVG attributes ( svg elements take a list of attributes)
+    - Everyone can pick a color
+
+
+Multiple dots
+
+
+| list
+    -> Introduce a problem: We want to have two dots on the screen
+    -> Explain a list, and show there is already a list there (with one item)
+
+
+| header
+    Do you see any other lists?
+
+
+| list
+    -> Element takes a list of children
+    -> Mention , how can we have a list with one or zero elements? Shopping list with one item. Empty spoon drawer( list of spoons)
+    -> Give your new dot a color and different coordinates
+    -> Show the code for 2 dots
+    -> Exercise: make 3 more dots (5 total)
+
+
+| header
+    Day 2 - Place the dots in a circle
+
+Introduce a problem: We want to place the dots in a circle, show an example on the slides
+
+How we will get there: We will change the cartesian coordinates of the dots, nothing else! But figuring out the right coordinates is a bit tricky
+
+How can we figure out the correct cartesian coordinates?
+
+| note
+    Story about the flowerpot and the table: two ways to measure relative position, one is distance from an x and y axis (cartesian coordinates), the other is angle and distance relative to origin (polar coordinates)
+
+
+What does this have to do with a circle? Do you know the expression 'I did a 180'. Where would you be looking if you did two 180s (a '360'). We see that circles and angles are closely related!
+
+Exercise with compass and 5 objects, place objects evenly along compass. How many degrees apart are they? (observe if we multiply the result by 5, we're back to 360)
+
+We have one part of it (angle), we now need the distance. Notice they are all the same distance from the origin (the center dot) of the compass. Definition of circle: points that are an equal distance from a center. Actually, the distance doesn't matter, so long as they all have the same distance. You can have a big circle or a small circle, they're both circles
+
+Ok great, we're done! Now, does anyone know how to give an angle and distance to svg? Oh... no? We don't either... you can't. You can only give x and y values relative to the origin
+
+So we already know that angle and length are just another way of describing x and y. But we need some way of translating between the two
+
+sing a visual demonstration, if you draw a line from your object to the x axis, you have a triangle. Same if you draw a line to the y axis. You can figure out the point on the axis using sin and cos functions and multiplying the result by the length.
+
+Let's use a chart to figure out the sin and cos of our angles
+
+/It's important to get a chart, otherwise we have to use calculators which work with radians/
+
+Now we are done... we can plug in our x and y values, and presto, our dots are arranged in a circle. But we don't see most of them...
+
+Our origin is in the top left corner. This means any dots with negative x or y values are off the screen.
+
+We can shift the dots so they are on the screen, or shift the screen so that it covers the dots. We will be shifting the screen
+
+Sample viewbox program to demonstrate
+
+Create a viewbox with correct perimeters (must be more than the radius of the circle plus the radius of a dot in each direction, and width and height are circumference)
+
+`svg [viewbox "-100 -100 200 200 " ] []`
+
+| header
+    Day 3 - Let the computer do the math
+
+Introduce the problem: Can we avoid all these repetitive and manual steps?
+
+What is a program made of? (in the REPL):
+
+Values and names
+
+| monospace
+    5
+    10.4
+    "Hello World"
+    [1, 2, 3, 4, 5]
+
+
+| list
+    -> Numbers like 5, 10.4
+    -> Strings like "Hello World"
+    -> and lists containing numbers or strings
+
+
+are all values
+
+They are self-referential. They simply state what they are. There are other kinds of values that we will see later.
+
+You can give (or assign) a name to a value, as shown.
+
+| monospace
+    family = 5
+    price = 10.4
+    morningGreeting = "Hello World"
+    fingers = [1, 2, 3, 4, 5]
+
+Here, `family` is a name and `5` is the value assigned to `family`.
+
+You can get the value back by calling its name.
+
+```
+---- Elm 0.19.0 ----------------------------------------------------------------
+Read <https://elm-lang.org/0.19.0/repl> to learn more: exit, help, imports, etc.
+--------------------------------------------------------------------------------
+> family = 5
+5 : number
+> family
+5 : number
+```
+
+Operators (`+`, `-`, `++`, `::`)
+
+| monospace
+    > 2 + 5
+    7 : number
+
+| monospace
+    > 4 - 6
+    -2 : number
+
+| monospace
+    > "Hello" ++ " world!"
+    "Hello world!" : String
+
+
+| monospace
+    > 1 :: [2, 3, 4, 5]
+    [1,2,3,4,5] : List number
+
+
+Operators take two values and return a new value. We know that names refer to values, so we can use them in place of values:
+
+| monospace
+    > family = 5
+    5 : number
+    > family + 2
+    7 : number
+
+
+You can also give a name to the value returned by an operator:
+
+| monospace
+    > family = 5
+    5 : number
+    > familyAndPets = family + 2
+    7 : number
+    > familyAndPets
+    7 : number
+
+Note that different values have different types.
+
+| monospace
+    5 : number
+    10.4 : Float
+    "Hello World" : String
+    [1,2,3,4,5] : List number
+
+Different operators work on different types. Adding a number and a string doesn't make sense. So if you try, Elm will complain (and give a helpful hint):
+
+| monospace
+    > "Hello " + 5
+    -- TYPE MISMATCH ----------------------------------------------------------- elm
+    I cannot do addition with String values like this one:
+    5|   "Hello " + 5
+         ^^^^^^^^
+    The (+) operator only works with Int and Float values.
+    Hint: Switch to the (++) operator to append strings!
+
+
+(Int and Float are both types representing numbers)
+
+Functions
+
+`fun something = something ++ " is fun."`
+
+Explain: a function is a thing that takes some values (called arguments) and return one value. So it's similar to operators. In fact operators are functions!
+
+| monospace
+    (-) 5 10
+    5 - 10
+
+
+You can think of a function as a machine. You put something in the machine, and it produces something in return. For example think about a machine that produces rubber ducks. You put a bucket of white plastic pellets and a bucket of red paint, and you get a bunch of red rubber ducks!
+
+What you get will depends on what you put. The color of the ducks depends on the paint you put. Quantity of ducks depends on how much plastic you put in.
+
+| monospace
+    makeMeSomeDucks color plastic =
+    String.fromInt plastic ++ " " ++ color ++ " rubber ducks"
+
+
+Once you have a function, you can call it like this:
+
+| monospace
+    > makeMeSomeDucks "blue" 12
+    "12 blue rubber ducks" : String
+
+
+Note: functions help organize code into nice reusable chunks.
+
+How do you get functions? There are three ways.
+
+Some functions are always there for you
+
+`(+)`, `(-)`
+
+Some functions you can import using code like this:
+
+`import Svg`
+
+
+and then
+
+| monospace
+    Svg.circle [ cx "10", cy "10", r "20" ] [ ]
+
+
+To call a function that was imported, you have to prefix it with the name of the module (in this example `Svg`).
+
+
+Finally, you will write some functions, just like we saw in the `fun` and `makeMeSomeDucks` examples.
+
+Finally there is one special thing: the first line of the program is a module declaration. For now it's enough for us to know, that it has to be there and it has to match the name of the file.
+
+Exercise: In our Main.elm, try to identify some values, names and function calls:
+
+Hint: `"darkred"` is a value, `main` is a name, `width` is a function.
+
+Hint: There is nothing else there now, but we will soon introduce our own functions.
+
+* Where can we use some functions?*
+
+As we said before, functions are good when we have some repetitive operation that can be parametrized (like rubber ducks production).
+
+Obviously calculating `x` and `y` coordinates is repetitive and can be parametrized (parameters are `radius` and `angle`).
+
+*Apply to our trigonometry calculations*
+
+Compose and copy and paste the trigonometry functions to calculate cx and cy:
+
+| monospace
+    cx (String.fromFloat (cos (degrees 72) * 100))
+    cy (String.fromFloat (sin (degrees 72) * 100))
+
+*Eliminate the repetition:*
+
+Assign a value of `100` to a name `radius`:
+
+| monospace
+    radius = 100
+
+and plug it to our functions:
+
+| monospace
+    cx (String.fromFloat (cos (degrees 72) * radius))
+    cy (String.fromFloat (sin (degrees 72) * radius))
+
+As you see the names are good for repetitive things too.
+
+Define and reuse
+
+`x : angle -> cx`
+
+| monospace
+    x angle =
+    String.fromFloat (cos (degrees angle) * radius)
+
+`y : angle -> cy`
+
+| monospace
+    y angle =
+    String.fromFloat (sin (degrees angle) * radius)
+
+Then plug it into the code making circles:
+| monospace
+    circle
+    [ cx (x 72)
+    , cy (y 72)
+    , r "10"
+    , fill "darkred"
+    ]
+
+define and reuse `dot : angle -> color -> Svg`
+
+| monospace
+    dot angle color =
+    circle
+    [ cx (x angle)
+    , cy (y angle)
+    , r "10"
+    , fill color
+    ]
+
+and plug it into our SVG picture:
+
+| monospace
+    svg [ viewbox "-100 -100 200 200" ]
+    [ dot 0 "darkred"
+    , dot 72 "fuchsia"
+    , dot 144 "saddlebrown"
+    , dot 216 "deepskyblue"
+    , dot 288 "gold"
+    ]
+
+For more cool colors check out [Color keywords page at Mozilla Developer's Network](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords)
+
+*Make it more general*
+
+| list
+    - Show List and list operations (map and indexedMap)
+    - There are a number of functions that operate on lists, for example `List.length` and `List.map`.
+
+
+Examples of a map: a shopping list, after you find each item and place it in your basket, you are 'mapping' from a list of needed items to a list of items in your basket. Now you have two lists, and they are related. One is your original shopping list, the other the list of items in the basket.
+
+Demonstrate:
+
+| monospace
+    > things = ["Programming", "Swimming", "Dancing", "Saddle brown"]
+    ["Programming","Swimming","Dancing","Saddle brown"]
+    : List String
+
+| monospace
+    > List.length things
+    4 : Int
+
+| monospace
+    > List.map fun things
+    ["Programming is fun!","Swimming is fun!","Dancing is fun!","Saddle brown is fun!"]
+    : List String
+
+| monospace
+    > things
+    ["Programming","Swimming","Dancing","Saddle brown"]
+    : List String
+
+
+Notice our original `things` list is unchanged. This is different from our rubber duck machine. The rubber duck turns the plastic and paint into rubber ducks. A function on the other hand 'creates' the value it gives you. You don't loose the original value given to it.
+
+Make a `palette : List color`
+
+| monospace
+    palette =
+    [ "darkred"
+    , "fuchsia"
+    , "saddlebrown"
+    , "deepskyblue"
+    , "gold"
+    ]
+
+
+Use `List.indexedMap dot palette` to generate the dots
+
+
+Another function that operates on lists is `List.indexedMap`. Let's see it at work:
+
+| monospace
+    dot index color =
+    circle
+    [ cx (x ((360 / (List.length palette)) * index))
+    , cy (y ((360 / (List.length palette)) * index))
+    , r "10"
+    , fill color
+    ]
+
+`List.indexedMap dot palette`
+
+We can introduce a `let` block to make our code more readable and avoid repetition.
+
+| monospace
+    dot index color =
+    let
+    angle =
+    (360 / count) * index
+    count =
+    List.length palette
+    in
+    circle
+    [ cx (x angle)
+    , cy (y angle)
+    , r "10"
+    , fill color
+    ]
+
+
+Take a look at the documentation for [List.indexedMap](https://package.elm-lang.org/packages/elm/core/latest/List#indexedMap).
+
+
+| header
+    Day 4 - Introduce SVG groups
+
+We'll need one group for the dots and one group for the lines
+
+| monospace
+    svg [ viewBox "-100 -100 200 200" ]
+    [ Svg.g [] (List.indexedMap dot pallete)
+    , Svg.g [] [ Svg.line [ x1 "123", y1 "112", x2 "41", y2 "11", stroke "black" ] [] ]
+    ]
+
+
+Exercise: add a few lines with different colors
+
+Now we'll learn how to color a line with a gradient (going from one color to another)
+
+| monospace
+    svg [ width "600", height "600", viewBox "-300 -300 600 600" ]
+    [ Svg.g [] (List.indexedMap dot pallete)
+    , Svg.defs []
+    [ Svg.linearGradient [ Svg.Attributes.id "MyGradient", x1 "0", y1 "0", x2 "1", y2 "0" ]
+    [ Svg.stop [ Svg.Attributes.offset "0", Svg.Attributes.stopColor "saddlebrown" ] []
+    , Svg.stop [ Svg.Attributes.offset "1", Svg.Attributes.stopColor "pink" ] []
+    ]
+    ]
+    , Svg.g []
+    [ Svg.line [ x1 "0", y1 "0", x2 "100", y2 "100", stroke "url(#MyGradient)" ] []
+    , Svg.line [ x1 "0", y1 "0", x2 "-100", y2 "-100", stroke "url(#MyGradient)" ] []
+    ]
+    ]
+
+
+We see a problem here. The gradient always goes from saddlebrown to pink from top left to bottom right. If we want to use the same gradient to connect different points, we'll need to be creative.
+
+| monospace
+    main =
+    svg [ width "600", height "600", viewBox "-300 -300 600 600" ]
+    [ Svg.g [] (List.indexedMap dot pallete)
+    , Svg.defs []
+    [ Svg.linearGradient [ Svg.Attributes.id "MyGradient", x1 "0", y1 "0", x2 "1", y2 "0", gradientUnits "userSpaceOnUse" ]
+    [ Svg.stop [ Svg.Attributes.offset "0", Svg.Attributes.stopColor "saddlebrown" ] []
+    , Svg.stop [ Svg.Attributes.offset "1", Svg.Attributes.stopColor "pink" ] []
+    ]
+    ]
+    , Svg.g []
+    [ Svg.line [ x1 "0", y1 "0", x2 "1", y2 "0", transform "rotate(45),scale(100,1)", stroke "url(#MyGradient)" ] []
+    , Svg.line [ x1 "0", y1 "0", x2 "1", y2 "0", transform "rotate(180),scale(100,1)", stroke "url(#MyGradient)" ] []
+    , Svg.line [ x1 "0", y1 "0", x2 "1", y2 "0", transform "rotate(270),scale(100,1)", stroke "url(#MyGradient)" ] []
+    ]
+    ]
+
+
+*TODO:* We need to fix the viewbox!
+
+
+Here's the trick: we have the lines initially match the gradient. We're using the same x and y values for all the lines and the gradient. Then we transform the lines to position them where we'd like them. We're actually using our old friend polar coordinates here.
+
+If you're interested in what `gradientUnits "userSpaceOnUse"` does, come see me after the lesson.
+
+
+| monospace
+    gradient : Int -> String -> Svg msg
+    gradient index color =
+    Svg.linearGradient
+    [ id ("Gradient-" ++ String.fromInt index)
+    , x1 "0"
+    , y1 "0"
+    , x2 "1"
+    , y2 "0"
+    , gradientUnits "userSpaceOnUse"
+    ]
+    [ Svg.stop
+    [ Svg.Attributes.offset "0"
+    , Svg.Attributes.stopColor "saddlebrown"
+    ]
+    []
+    , Svg.stop
+    [ Svg.Attributes.offset "1"
+    , Svg.Attributes.stopColor color
+    ]
+    []
+    ]
+
+| monospace
+    line : Int -> String -> Svg msg
+    line index color =
+    let
+    count =
+    List.length pallete
+
+    angle =
+    (360 / toFloat count) * toFloat index
+
+    transformation =
+    "rotate("
+    ++ String.fromFloat angle
+    ++ "), scale("
+    ++ String.fromInt radius
+    ++ ", 1)"
+
+| monospace
+    url =
+    "url(#Gradient-" ++ String.fromInt index ++ ")"
+    in
+    Svg.line
+    [ x1 "0"
+    , y1 "0"
+    , x2 "1"
+    , y2 "0"
+    , transform transformation
+    , stroke url
+    ]
+    []
+
+
+| monospace
+    main =
+    svg [ width "600", height "600", viewBox "-300 -300 600 600" ]
+    [ Svg.g [] (List.indexedMap dot pallete)
+    , Svg.defs [] (List.indexedMap gradient pallete)
+    , Svg.g [] (List.indexedMap line pallete)
+    ]
+
+
+This may look like a lot, but our `gradient` and `line` functions are very similar to our `dot` function from earlier. In fact we see an essential principle of good programming design here. We spent a lot of time banging our heads over gradients. Now that we've done that work, we can hide the implementation in our gradient and line functions. Now, if we want to draw a new dot, line, and gradient going from the center to the dot, we only need to add a new item to our palette. Our functions do the rest for us. Our functions conceal our complexity. We can forget about the implementation, so long as we know how to operate them. They're like black boxes, we know what goes in and what comes out, but we don't have to know how they work on the inside.
+
+
+| header
+    Day 5 - Let's make a beautiful tree!
+
+The Problem:
+Describe A tree using data
+
+A tree is a composition of segments. A segment can be either a twig or a branch. Twig is a terminal segment of a tree. When the tree is very young it consists of a single twig. Later this twig will evolve into a branch and will grow it's own twigs, that in turn will evolve into branches. So a branch is a segment of a tree that ends with some other  segments (twigs or branches).
+
+
+Note that a branch can split to several branches that each in turn can split into several branches and so on. This way a tree can be as complex as we want. Note that real trees are like that. It's difficult to say how many generations of branches it can have from the trunk to the smallest little twigs on top of the crown. This kind of structure is called recursive. It repeats the same pattern.
+
+
+Each segment (a twig or a branch) has length, a direction (represented as an angle) and a color (so that it's beautiful despite having no leafs or flowers).
+
+Here is how we can represent it in code:
+
+| monospace
+    type alias Segment =
+    { length : Float
+    , direction : Float
+    , color : Color
+    }
+
+
+Consider  the following
+
+| list
+    - A branch can split into more branches or twigs,
+    - And then that a trunk of a tree is just a first branch or a twig if the tree is very      young, then you can see that each segment separated from the parent branch can be considered a tree.
+
+
+So we can reuse the same structure to represent a tree or any of it's segments!
+
+Look:
+
+| monospace
+    type Tree
+    = Twig Segment
+    | Branch Segment (List Tree)
+
+
+Think about it! A tree is a twig (when it's young) or a branch that splits into __a zero, one or many__ __twigs or branches__.
+
+| list
+    -> zero, one or many: a list
+    -> twig or branch: a tree
+
+
+So a Twig is just a Segment while a branch is a Segment with a list of Trees!
+
+Let's encode a simple tree by hand:
+
+| monospace
+    tree =
+    Branch { length = 10, direction = degrees -90, color = "brown" }
+    [ Branch { length = 6, direction = degrees -45, color = "lightbrown" }
+    [ Twig { length = 2, direction = degrees -30, color = "green" }
+    , Twig { length = 2, direction = degrees -60, color = "green" }
+    ]
+    , Branch { length = 6, direction = degrees -135, color = "lightbrown" }
+    [ Twig { length = 2, direction = degrees -120, color = "green" }
+    , Twig { length = 2, direction = degrees -150, color = "green" }
+    ]
+    ]
+
+
+| header
+    Day 6 - Make the tree grow!
+
+Make a function that given the age of the tree and rules returns a tree
+
+Use time subscription to make the tree grow
+
+Show complete code.
+There is a lot going on here, and it's not obvious how it all works.
+
+Our main value has changed.
+
+| monospace
+    main : Program () State Msg
+    main =
+    Browser.sandbox
+    { init = init
+    , view = view
+    , update = update
+    }
+
+Previously, the value of `main` was an SVG element. Now it contains a call to `Browser.sandbox` function.
+
+A sandbox is a basic interactive program. For a program to be interactive, it need more than just a SVG element.
+
+| monospace
+    type alias State =
+    Color
+    type alias Color =
+    String
+
+
+Here we create something called a type alias. We've already discussed types. A type alias is basically a way to give an alternative name for a type. We give the alias `Color` to `String` and the alias `State` to `Color`. So in the end all three names point to the same type!
+
+
+Why are we doing this? All of these types are strings, and Elm will treat them all as strings. But it will make our code more readable to use these aliases. We are writing an application that allows the user to change the background color. That should explain why our `State` is a `Color`.
+
+
+Our `Browser.sandbox` takes something with the name `init`. This is our initial state. Let's take a look at the value of `init`.
+
+| monospace
+    init : State
+    init =
+    "white"
+
+
+We see that the initial state is `"white"`. We'll see how our application uses this value in a moment.
+
+
+Looking back at our `sandbox`, we see it also takes a `view`. Let's take a look at our view function:
+
+| monospace
+    view : State -> Html Msg
+    view color =
+    svg
+    [ width "600"
+    , height "600"
+    , viewBox "-300 -300 600 600"
+    , Svg.Attributes.style ("background: " ++ color)
+    ]
+    [ Svg.g [] (List.indexedMap dot pallete)
+    , Svg.defs [] (List.indexedMap gradient pallete)
+    , Svg.g [] (List.indexedMap line pallete)
+    ]
+
+
+You'll notice that this `view` function looks very similar to the `main` variable from earlier. Before, our application was only a view. Now the view is only one piece of our interactive application.
+
+
+One important way our `view` function differs from the `main` variable from ealier is that `view` is a function. We see it takes a variable of type `State` (a string), which we have named `color`. In an Elm sandbox project the `view` always takes a variable with the same type as the `init` variable. This is the current state of the application. `view` can use the state to render the application properly, just as Atom uses its state to render text for its user.
+
+
+We see that we've added a line to the svg attributes, `Svg.Attributes.style ("background: " ++ color)`. Here we use the state of the application to set the background color of the svg element.
+
+
+All we need now is some way to update the state (the background color) of the application.
+
+
+Taking a look at our `main` function, we see that it take a third and final function, `update`. Let's look at our update function:
+
+| monospace
+    type Msg
+    = SetBackground Color
+    update : Msg -> State -> State
+    update msg state =
+    case msg of
+    SetBackground color ->
+    color
+
+
+
+We see our `update` function takes two variables, of type `Msg` and `State`. If we think of update as a machine which takes an old state and spits out a new state, this state variable corresponds to the old state.
+
+
+The `msg` variable is something new. Looking above, we see that we have defined a `Msg` variable type. This is similar to our `State` and `Color` union types, in that we have defined a new type that Elm understands. However, unlike the `type alias` constructor, the `type` constructor does not simply give a new name for an existing type. Instead, here we define a completely unique type. We see values with type Msg must have the form `SetBackground Color`. `SetBackground "white"`, `SetBackground "blue"`, `SetBackground "saddlebrown"` are all valid values of the type `Msg`.
+
+
+What is important to understand is that our `msg` variable is used by `update` to determine how it should update the state. We see that update first checks that `msg` has the form `SetBackground color`, and then returns the value of `color`. This will become our new state. Every time update is called, the sandbox will re-render our view with the new state.
+
+
+So now we see how our application changes the background color of the svg element. However, we haven't seen when it will update the background color. Well, we want to change the background color by clicking a dot. So let's take a look at our `dot` function to see if we can find a hint there.
+
+
+*Model*
+The structure of the state of the program
+
+| note
+    *TO DO* /Consistently use Model and model instead of less standard state to make it easier to our participants.
+
+
+
+*Msg*
+What events can there be in the program? Currently have only one possible event- setting the background to a given color.
+
+
+`update`
+
+The instructions of how to change the state when a particular message comes in.
+
+`view`
+
+The instruction of what to display on the screen. It also contains instructions of what messages to send when certain events (like clicks on elements) happen. Every time the state changes the instructions will be applied.
+
+`init`
+
+What is the initial state right after the program is started.
+
+`main`
+
+Glues it all together.
+
+| monospace
+    dot : Int -> String -> Svg Msg
+    dot index color =
+    let
+    angle =
+    (360 / toFloat (List.length pallete)) * toFloat index
+    in
+    circle
+    [ cx (x angle)
+    , cy (y angle)
+    , r "40"
+    , fill color
+    , Svg.Events.onClick (SetBackground color)
+    ]
+    []
+
+
+
+We see there is a new line here:
+
+
+| monospace
+    Svg.Events.onClick (SetBackground color)
+
+
+
+
+`onClick` is an event. It basically tells our svg element to listen for someone to click on it. It will then handle the event by emitting the Msg `SetBackground color`. We know `color` is the color of the dot. We see then that when someone clicks on the dot, the Msg will be emitted, `update` will be called with this Msg and will update our state. Our sandbox will rerender the view with this new state. The user will see the svg element with a new background color.
+
+
+Notice that our `view` function, as well as all the functions that call functions responsible for rendering svg elements, including `gradient`, `line`, and `dot` have return values with type `Svg Msg` or `Html Msg`. This is because svg element can emit Msgs which will be handled by `update`.
=
=| header
=    To do:

Merge remote-tracking branch 'origin/master' into elm-markup-2

Merge branch 'elm-markup-2' into 'master'

Update Elm Markup package to 2.0.2

See merge request software-garden/software-garden.gitlab.io!1