diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 3fa3422d8b32c730268ffd197f3f63d65c98fbd0..549766ef9e6736fd1e6b08f35b27df57db16d952 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -86,8 +86,8 @@ after_deploy_production:
     script:
         - /www/utils/deploycourseweb.sh
     variables:
-        quarter: eg21wi
-        course: egcse340
+        quarter: 21wi
+        course: cse340
         source_path: public
     only:
         refs:
diff --git a/Gemfile.lock b/Gemfile.lock
deleted file mode 100644
index 030c4f4499b5327400f41ab61ccdd420ee0a54d9..0000000000000000000000000000000000000000
--- a/Gemfile.lock
+++ /dev/null
@@ -1,196 +0,0 @@
-PATH
-  remote: .
-  specs:
-    jekyll-theme-cayman (0.1.1)
-      jekyll (~> 3.1)
-      jekyll-seo-tag (~> 2.0)
-
-GEM
-  remote: https://rubygems.org/
-  specs:
-    activesupport (5.2.4.3)
-      concurrent-ruby (~> 1.0, >= 1.0.2)
-      i18n (>= 0.7, < 2)
-      minitest (~> 5.1)
-      tzinfo (~> 1.1)
-    addressable (2.7.0)
-      public_suffix (>= 2.0.2, < 5.0)
-    ast (2.4.1)
-    colorator (1.1.0)
-    concurrent-ruby (1.1.7)
-    em-websocket (0.5.1)
-      eventmachine (>= 0.12.9)
-      http_parser.rb (~> 0.6.0)
-    ethon (0.12.0)
-      ffi (>= 1.3.0)
-    eventmachine (1.2.7)
-    execjs (2.7.0)
-    extras (0.3.0)
-      forwardable-extended (~> 2.5)
-    fastimage (2.2.0)
-    ffi (1.13.1)
-    font-awesome-sass (5.13.0)
-      sassc (>= 1.11)
-    forwardable-extended (2.6.0)
-    hpricot (0.8.6)
-    html-proofer (3.15.3)
-      addressable (~> 2.3)
-      mercenary (~> 0.3)
-      nokogumbo (~> 2.0)
-      parallel (~> 1.3)
-      rainbow (~> 3.0)
-      typhoeus (~> 1.3)
-      yell (~> 2.0)
-    http_parser.rb (0.6.0)
-    i18n (0.9.5)
-      concurrent-ruby (~> 1.0)
-    jekyll (3.9.0)
-      addressable (~> 2.4)
-      colorator (~> 1.0)
-      em-websocket (~> 0.5)
-      i18n (~> 0.7)
-      jekyll-sass-converter (~> 1.0)
-      jekyll-watch (~> 2.0)
-      kramdown (>= 1.17, < 3)
-      liquid (~> 4.0)
-      mercenary (~> 0.3.3)
-      pathutil (~> 0.9)
-      rouge (>= 1.7, < 4)
-      safe_yaml (~> 1.0)
-    jekyll-assets (3.0.12)
-      activesupport (~> 5.0)
-      execjs (~> 2.7)
-      extras (~> 0.2)
-      fastimage (~> 2.0, >= 1.8)
-      jekyll (>= 3.5, < 4.0)
-      jekyll-sanity (~> 1.2)
-      liquid-tag-parser (~> 1.0)
-      nokogiri (~> 1.8)
-      pathutil (~> 0.16)
-      sprockets (>= 3.3, < 4.1.beta)
-    jekyll-contentblocks (1.2.0)
-      jekyll
-    jekyll-feed (0.15.0)
-      jekyll (>= 3.7, < 5.0)
-    jekyll-font-awesome-sass (0.1.1)
-      font-awesome-sass (>= 4)
-      jekyll (>= 2.5, < 4.0)
-    jekyll-mermaid (1.0.0)
-    jekyll-paginate (1.1.0)
-    jekyll-redirect-from (0.16.0)
-      jekyll (>= 3.3, < 5.0)
-    jekyll-sanity (1.6.0)
-      jekyll (>= 3.1, < 5.0)
-      pathutil (~> 0.16)
-    jekyll-sass-converter (1.5.2)
-      sass (~> 3.4)
-    jekyll-seo-tag (2.6.1)
-      jekyll (>= 3.3, < 5.0)
-    jekyll-target-blank (2.0.0)
-      jekyll (>= 3.0, < 5.0)
-      nokogiri (~> 1.10)
-    jekyll-watch (2.2.1)
-      listen (~> 3.0)
-    json (2.3.1)
-    kramdown (2.3.0)
-      rexml
-    kramdown-parser-gfm (1.1.0)
-      kramdown (~> 2.0)
-    libv8 (3.16.14.19-x86_64-darwin-17)
-    liquid (4.0.3)
-    liquid-tag-parser (1.9.0)
-      extras (~> 0.3)
-      liquid (>= 3.0, < 5.0)
-    listen (3.2.1)
-      rb-fsevent (~> 0.10, >= 0.10.3)
-      rb-inotify (~> 0.9, >= 0.9.10)
-    mercenary (0.3.6)
-    mini_portile2 (2.4.0)
-    minitest (5.14.2)
-    nokogiri (1.10.10)
-      mini_portile2 (~> 2.4.0)
-    nokogumbo (2.0.2)
-      nokogiri (~> 1.8, >= 1.8.4)
-    parallel (1.19.2)
-    parser (2.7.1.4)
-      ast (~> 2.4.1)
-    pathutil (0.16.2)
-      forwardable-extended (~> 2.6)
-    public_suffix (4.0.6)
-    rack (2.2.3)
-    rainbow (3.0.0)
-    rb-fsevent (0.10.4)
-    rb-inotify (0.10.1)
-      ffi (~> 1.0)
-    ref (2.0.0)
-    regexp_parser (1.7.1)
-    remark (0.3.2)
-      hpricot (~> 0.8.2)
-    rexml (3.2.4)
-    rouge (3.22.0)
-    rubocop (0.90.0)
-      parallel (~> 1.10)
-      parser (>= 2.7.1.1)
-      rainbow (>= 2.2.2, < 4.0)
-      regexp_parser (>= 1.7)
-      rexml
-      rubocop-ast (>= 0.3.0, < 1.0)
-      ruby-progressbar (~> 1.7)
-      unicode-display_width (>= 1.4.0, < 2.0)
-    rubocop-ast (0.3.0)
-      parser (>= 2.7.1.4)
-    ruby-progressbar (1.10.1)
-    safe_yaml (1.0.5)
-    sass (3.7.4)
-      sass-listen (~> 4.0.0)
-    sass-listen (4.0.0)
-      rb-fsevent (~> 0.9, >= 0.9.4)
-      rb-inotify (~> 0.9, >= 0.9.7)
-    sassc (2.4.0)
-      ffi (~> 1.9)
-    sprockets (3.7.2)
-      concurrent-ruby (~> 1.0)
-      rack (> 1, < 3)
-    therubyracer (0.12.3)
-      libv8 (~> 3.16.14.15)
-      ref
-    thread_safe (0.3.6)
-    typhoeus (1.4.0)
-      ethon (>= 0.9.0)
-    tzinfo (1.2.7)
-      thread_safe (~> 0.1)
-    uglifier (4.2.0)
-      execjs (>= 0.3.0, < 3)
-    unicode-display_width (1.7.0)
-    w3c_validators (1.3.5)
-      json (>= 1.8)
-      nokogiri (~> 1.6)
-    yell (2.2.2)
-
-PLATFORMS
-  ruby
-
-DEPENDENCIES
-  execjs
-  html-proofer (~> 3.0)
-  jekyll (< 4.0)
-  jekyll-assets
-  jekyll-contentblocks
-  jekyll-feed
-  jekyll-font-awesome-sass
-  jekyll-mermaid
-  jekyll-paginate
-  jekyll-redirect-from
-  jekyll-target-blank
-  jekyll-theme-cayman!
-  kramdown-parser-gfm
-  remark
-  rubocop (~> 0.50)
-  sprockets (~> 3.7)
-  therubyracer
-  tzinfo-data
-  uglifier
-  w3c_validators (~> 1.3)
-
-BUNDLED WITH
-   2.1.2
diff --git a/_config.yml b/_config.yml
index 10b4f4266f5f2c6cbb06346045426c132e843f5c..f0582e946561e5a392ee52cb8045b64866f78780 100644
--- a/_config.yml
+++ b/_config.yml
@@ -4,10 +4,10 @@
 # You can create any custom variable you would like, and they will be accessible
 # in the templates via {{ site.myvariable }}.
 
-title: Name and number of your class
-description: Description of your class
+title: Interaction Programming (CSE 340)
+description: Interactive Tech is changing society. Help invent the future!
 
-baseurl: "/courses/csexxx/xxqq"
+baseurl: "/courses/cse340/21wi"
 url: https://courses.cs.washington.edu # the base hostname & protocol for your site, e.g. http://example.com
 twitter_username: username
 git_username:  username
@@ -22,16 +22,16 @@ hcibook: "No HCI Textbook, just readings"
 androidbook: "No Android Textbook, just readings"
 
 paginate:            5
-quarter: "Quarter YYYY"
+quarter: "Winter 2021"
 copydate: "3/30/20"
 status: final
 warning: old     # change this to old to display that it is the past quarter website, anthing else won't display that
 
 author:
-    name: Name
-    url: "https://website"
+    name: Jennifer Mankoff
+    url: "https://make4all.org/jennifer-mankoff/"
 
-email: "email@university.edu"            # Your contact email
+email: "jmankoff@uw.edu"            # Your contact email
   # probably want to update this to be the class teaching staff mailing list
 
 # The Reveal theme
@@ -41,6 +41,9 @@ reveal_theme: black.css
 markdown: kramdown
 theme: jekyll-theme-cayman
 
+gems:
+  - jekyll-font-awesome-sass
+
 plugins:
   - jekyll-feed
   - jekyll-seo-tag
diff --git a/_config_production.yml b/_config_production.yml
index 9b0ce718e87540cae36dfbb145da725b439d46b3..be06d6c26f2bdc4d4a68cf48ff3f111adeeb7a25 100644
--- a/_config_production.yml
+++ b/_config_production.yml
@@ -4,10 +4,10 @@
 # You can create any custom variable you would like, and they will be accessible
 # in the templates via {{ site.myvariable }}.
 
-title: Name and number of your class
-description: Description of your class
+title: Interaction Programming (CSE 340)
+description: Interactive Tech is changing society. Help invent the future!
 
-baseurl: "/courses/csexxx/xxqq"
+baseurl: "/courses/cse340/21wi"
 url: https://courses.cs.washington.edu # the base hostname & protocol for your site, e.g. http://example.com
 twitter_username: username
 git_username:  username
@@ -21,16 +21,16 @@ gradescope: https://www.gradescope.com/courses/250076
 hcibook: "No HCI Textbook, just readings"
 androidbook: "No Android Textbook, just readings"
 paginate:            5
-quarter: "Quarter YYYY"
+quarter: "Winter 2021"
 copydate: "3/30/20"
 status: final
 warning: old
 
 author:
-    name: Name
-    url: "https://website"
+    name: Jennifer Mankoff
+    url: "https://make4all.org/jennifer-mankoff/"
 
-email: "email@university.edu"            # Your contact email
+email: "jmankoff@uw.edu"            # Your contact email
   # probably want to update this to be the class teaching staff mailing list
 
 # The Reveal theme
diff --git a/_submodules/mermaid/.ackrc b/_submodules/mermaid/.ackrc
deleted file mode 100644
index 5390d7b92156fb09773917c6b453ec3cf18d5948..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/.ackrc
+++ /dev/null
@@ -1,4 +0,0 @@
---ignore-dir=dist
---ignore-file=match:/^yarn\.lock$/
---ignore-file=match:/^yarn-error\.log$/
---ignore-dir=coverage
diff --git a/_submodules/mermaid/.babelrc b/_submodules/mermaid/.babelrc
deleted file mode 100644
index b207aefdded3fae007f56bcc2f28d7a6c958fb26..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/.babelrc
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "presets": [
-    "env"
-  ]
-}
diff --git a/_submodules/mermaid/.editorconfig b/_submodules/mermaid/.editorconfig
deleted file mode 100644
index ab70fef5e64a0b2cf3dcb28e5781c98fa7c36679..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/.editorconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-root = true
-
-[*]
-indent_style = space
-indent_size = 2
-charset = utf-8
-trim_trailing_whitespace = true
-insert_final_newline = true
-
-[*.md]
-indent_size = 4
diff --git a/_submodules/mermaid/.gitignore b/_submodules/mermaid/.gitignore
deleted file mode 100644
index f2c5e769955120f6793cbe1b3322a802dda60f47..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-.DS_Store
-
-node_modules/
-coverage/
-
-dist/*.js
-dist/*.map
-
-yarn-error.log
diff --git a/_submodules/mermaid/.travis.yml b/_submodules/mermaid/.travis.yml
deleted file mode 100644
index d28528ef6b5ed96a03761e97e2fec02f1d759b46..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-dist: trusty
-language: node_js
-node_js:
-  - "8"
-script:
-  - yarn test --coverage
-after_success:
-  - cat ./coverage/lcov.info | ./node_modules/.bin/coveralls
diff --git a/_submodules/mermaid/CHANGELOG.md b/_submodules/mermaid/CHANGELOG.md
deleted file mode 100644
index 3bbf313664ce7ec9f3820c9ba2c97c8a4a959e02..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/CHANGELOG.md
+++ /dev/null
@@ -1,386 +0,0 @@
-# Change Log
-
-## [Unreleased](https://github.com/knsv/mermaid/tree/HEAD)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.4.0...HEAD)
-
-**Implemented enhancements:**
-
-- Add a css file, mermaid.css, with default styling [\#122](https://github.com/knsv/mermaid/issues/122)
-
-**Closed issues:**
-
-- Some examples not displayed on Firefox 36.0.1 [\#138](https://github.com/knsv/mermaid/issues/138)
-
-- inoperable in an AMD/requirejs environment: IPython Notebook [\#127](https://github.com/knsv/mermaid/issues/127)
-
-- Add capability for gantt diagrams [\#118](https://github.com/knsv/mermaid/issues/118)
-
-- lower case v causes error in the parser [\#108](https://github.com/knsv/mermaid/issues/108)
-
-- Label's css conflict with boostrap's .label [\#67](https://github.com/knsv/mermaid/issues/67)
-
-**Merged pull requests:**
-
-- Adding init argument to the global API [\#137](https://github.com/knsv/mermaid/pull/137) ([bollwyvl](https://github.com/bollwyvl))
-
-- Add description of manual calling of init [\#136](https://github.com/knsv/mermaid/pull/136) ([bollwyvl](https://github.com/bollwyvl))
-
-- Allow other forms of node selection for init\(\) [\#135](https://github.com/knsv/mermaid/pull/135) ([bollwyvl](https://github.com/bollwyvl))
-
-- Use a library-level variable for assigning ids [\#134](https://github.com/knsv/mermaid/pull/134) ([bollwyvl](https://github.com/bollwyvl))
-
-## [0.4.0](https://github.com/knsv/mermaid/tree/0.4.0) (2015-03-01)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.3.5...0.4.0)
-
-**Implemented enhancements:**
-
-- Assymetric shapes not documented [\#82](https://github.com/knsv/mermaid/issues/82)
-
-- Improve arrows [\#3](https://github.com/knsv/mermaid/issues/3)
-
-**Fixed bugs:**
-
-- NoModificationAllowedError [\#23](https://github.com/knsv/mermaid/issues/23)
-
-**Closed issues:**
-
-- subgraph background is black in rendered flowchart PNG via CLI [\#121](https://github.com/knsv/mermaid/issues/121)
-
-- Integrate editor at https://github.com/naseer/mermaid-webapp [\#110](https://github.com/knsv/mermaid/issues/110)
-
-- Internet Explorer Support [\#99](https://github.com/knsv/mermaid/issues/99)
-
-## [0.3.5](https://github.com/knsv/mermaid/tree/0.3.5) (2015-02-15)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.3.4...0.3.5)
-
-## [0.3.4](https://github.com/knsv/mermaid/tree/0.3.4) (2015-02-15)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.3.3...0.3.4)
-
-**Implemented enhancements:**
-
-- Apply styling from css when using the CLI utility [\#85](https://github.com/knsv/mermaid/issues/85)
-
-- Generated SVG works poorly outside web browsers [\#58](https://github.com/knsv/mermaid/issues/58)
-
-- Generating SVG text blob for use in Node [\#2](https://github.com/knsv/mermaid/issues/2)
-
-**Closed issues:**
-
-- Subgraph syntax bug? [\#120](https://github.com/knsv/mermaid/issues/120)
-
-- Live editor [\#115](https://github.com/knsv/mermaid/issues/115)
-
-- Error in "Basic Syntax" wiki page [\#113](https://github.com/knsv/mermaid/issues/113)
-
-- semicolons, anyone? [\#111](https://github.com/knsv/mermaid/issues/111)
-
-- undefined `sequenceConfig` fails [\#109](https://github.com/knsv/mermaid/issues/109)
-
-- Sequence Diagrams: Show Actors below as well [\#106](https://github.com/knsv/mermaid/issues/106)
-
-- Allow overriding sequence diagram configuration \(SVG properties\) [\#103](https://github.com/knsv/mermaid/issues/103)
-
-- Error when rendering A-- This is the text -- B [\#102](https://github.com/knsv/mermaid/issues/102)
-
-- Clipping in documentation [\#97](https://github.com/knsv/mermaid/issues/97)
-
-- isolate class styling to the svg container [\#92](https://github.com/knsv/mermaid/issues/92)
-
-- Make the new graph declaration more visual [\#40](https://github.com/knsv/mermaid/issues/40)
-
-**Merged pull requests:**
-
-- Add live editor [\#119](https://github.com/knsv/mermaid/pull/119) ([naseer](https://github.com/naseer))
-
-- Adds CSS option to the CLI [\#116](https://github.com/knsv/mermaid/pull/116) ([fardog](https://github.com/fardog))
-
-- Update flowchart.md in response Issue \#113 [\#114](https://github.com/knsv/mermaid/pull/114) ([vijay40](https://github.com/vijay40))
-
-- Ignore all files except the license and dist/ folder when installing with Bower. [\#112](https://github.com/knsv/mermaid/pull/112) ([jasonbellamy](https://github.com/jasonbellamy))
-
-## [0.3.3](https://github.com/knsv/mermaid/tree/0.3.3) (2015-01-25)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.3.2...0.3.3)
-
-**Implemented enhancements:**
-
-- Support for dotted links [\#26](https://github.com/knsv/mermaid/issues/26)
-
-**Closed issues:**
-
-- Missing arrows in sequence diagram [\#98](https://github.com/knsv/mermaid/issues/98)
-
-- Error with \>9 linkStyles [\#95](https://github.com/knsv/mermaid/issues/95)
-
-**Merged pull requests:**
-
-- Require d3 directly to better support Node usage [\#107](https://github.com/knsv/mermaid/pull/107) ([markdalgleish](https://github.com/markdalgleish))
-
-- update doc with -c option [\#105](https://github.com/knsv/mermaid/pull/105) ([jjmr](https://github.com/jjmr))
-
-- Add new parameter to the console client to override the svg configuration in sequence diagrams [\#104](https://github.com/knsv/mermaid/pull/104) ([jjmr](https://github.com/jjmr))
-
-- Text based labels, new shape [\#101](https://github.com/knsv/mermaid/pull/101) ([bjowes](https://github.com/bjowes))
-
-- fix html tags in example usage [\#100](https://github.com/knsv/mermaid/pull/100) ([deiwin](https://github.com/deiwin))
-
-## [0.3.2](https://github.com/knsv/mermaid/tree/0.3.2) (2015-01-11)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.3.1...0.3.2)
-
-**Implemented enhancements:**
-
-- Make link text look like it is on the line [\#53](https://github.com/knsv/mermaid/issues/53)
-
-**Closed issues:**
-
-- disable auto render [\#91](https://github.com/knsv/mermaid/issues/91)
-
-- Tidy breaks mermaid \(linebreaks in <div\>\) [\#87](https://github.com/knsv/mermaid/issues/87)
-
-- Bug: <br\> being rendered as text in node [\#73](https://github.com/knsv/mermaid/issues/73)
-
-- Graph edges appear to render outside of the canvas [\#70](https://github.com/knsv/mermaid/issues/70)
-
-**Merged pull requests:**
-
-- Merge pull request \#1 from knsv/master [\#96](https://github.com/knsv/mermaid/pull/96) ([gkchic](https://github.com/gkchic))
-
-- Removed duplicated section in flowchart docs [\#94](https://github.com/knsv/mermaid/pull/94) ([kaime](https://github.com/kaime))
-
-- Grammar changes to sequence page [\#93](https://github.com/knsv/mermaid/pull/93) ([gkchic](https://github.com/gkchic))
-
-- Grammar changes to development page [\#90](https://github.com/knsv/mermaid/pull/90) ([gkchic](https://github.com/gkchic))
-
-- Github buttons [\#89](https://github.com/knsv/mermaid/pull/89) ([gkchic](https://github.com/gkchic))
-
-- Template change [\#88](https://github.com/knsv/mermaid/pull/88) ([gkchic](https://github.com/gkchic))
-
-- New content template [\#86](https://github.com/knsv/mermaid/pull/86) ([gkchic](https://github.com/gkchic))
-
-## [0.3.1](https://github.com/knsv/mermaid/tree/0.3.1) (2015-01-05)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.3.0...0.3.1)
-
-**Implemented enhancements:**
-
-- Support for sequence diagrams [\#16](https://github.com/knsv/mermaid/issues/16)
-
-- Client utility for mermaid [\#6](https://github.com/knsv/mermaid/issues/6)
-
-**Closed issues:**
-
-- Non ASCII chars in labels [\#84](https://github.com/knsv/mermaid/issues/84)
-
-- 'undefined' titles of Quicklinks on the usage page [\#80](https://github.com/knsv/mermaid/issues/80)
-
-- \[cli\] Enhancement proposal: not fail --version / --help if phantomjs isn't installed [\#71](https://github.com/knsv/mermaid/issues/71)
-
-**Merged pull requests:**
-
-- Formatting of the CONTRIBUTING file [\#83](https://github.com/knsv/mermaid/pull/83) ([Grahack](https://github.com/Grahack))
-
-- Flowchart doc: Text in the circle now in a circle [\#81](https://github.com/knsv/mermaid/pull/81) ([Grahack](https://github.com/Grahack))
-
-- Fix for issue \#73 [\#79](https://github.com/knsv/mermaid/pull/79) ([it0a](https://github.com/it0a))
-
-- Ink template [\#78](https://github.com/knsv/mermaid/pull/78) ([gkchic](https://github.com/gkchic))
-
-- Index template file [\#77](https://github.com/knsv/mermaid/pull/77) ([gkchic](https://github.com/gkchic))
-
-- Index template file [\#76](https://github.com/knsv/mermaid/pull/76) ([gkchic](https://github.com/gkchic))
-
-- Show help and version even if phantom isn't present. Fixes \#71 [\#75](https://github.com/knsv/mermaid/pull/75) ([fardog](https://github.com/fardog))
-
-- Add apostrophe & 'and' [\#72](https://github.com/knsv/mermaid/pull/72) ([sudodoki](https://github.com/sudodoki))
-
-## [0.3.0](https://github.com/knsv/mermaid/tree/0.3.0) (2014-12-22)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.16...0.3.0)
-
-**Implemented enhancements:**
-
-- How do I do comments? [\#47](https://github.com/knsv/mermaid/issues/47)
-
-- Improve readability with new line as terminator and whitespace [\#38](https://github.com/knsv/mermaid/issues/38)
-
-**Fixed bugs:**
-
-- This characters failed the lexical parsing [\#46](https://github.com/knsv/mermaid/issues/46)
-
-**Closed issues:**
-
-- Trailing whitespace at the end of lines is not ignored [\#55](https://github.com/knsv/mermaid/issues/55)
-
-- Use classes instead of inline style for easy styling [\#24](https://github.com/knsv/mermaid/issues/24)
-
-**Merged pull requests:**
-
-- Adds Command Line Interface for generating PNGs from mermaid description files [\#69](https://github.com/knsv/mermaid/pull/69) ([fardog](https://github.com/fardog))
-
-- Allow special symbols for direction along with acronyms [\#66](https://github.com/knsv/mermaid/pull/66) ([vijay40](https://github.com/vijay40))
-
-## [0.2.16](https://github.com/knsv/mermaid/tree/0.2.16) (2014-12-15)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.15...0.2.16)
-
-**Fixed bugs:**
-
-- Lines routed outside visible area [\#19](https://github.com/knsv/mermaid/issues/19)
-
-**Closed issues:**
-
-- Mermaid not rendering properly on Wordpress pages [\#59](https://github.com/knsv/mermaid/issues/59)
-
-- Improve example page with live demo [\#52](https://github.com/knsv/mermaid/issues/52)
-
-- Does not render upon AngularJS Updates [\#45](https://github.com/knsv/mermaid/issues/45)
-
-- Download link in README.MD doesn't work. [\#42](https://github.com/knsv/mermaid/issues/42)
-
-- linkStyle usage is not obvious [\#41](https://github.com/knsv/mermaid/issues/41)
-
-- Move \*.spec.js in src/ to test/ [\#35](https://github.com/knsv/mermaid/issues/35)
-
-**Merged pull requests:**
-
-- New grammar will allow statements ending without semicolon as disccused in Issue \#38 [\#63](https://github.com/knsv/mermaid/pull/63) ([vijay40](https://github.com/vijay40))
-
-- Class based styling [\#62](https://github.com/knsv/mermaid/pull/62) ([bjowes](https://github.com/bjowes))
-
-- Update from master [\#61](https://github.com/knsv/mermaid/pull/61) ([bjowes](https://github.com/bjowes))
-
-- Fix typos [\#60](https://github.com/knsv/mermaid/pull/60) ([sublimino](https://github.com/sublimino))
-
-- Included .DS\_Store in gitignore [\#57](https://github.com/knsv/mermaid/pull/57) ([alvynmcq](https://github.com/alvynmcq))
-
-- Improves readablity discussed in issue \#38 [\#56](https://github.com/knsv/mermaid/pull/56) ([vijay40](https://github.com/vijay40))
-
-- Added a linting task for gulp [\#43](https://github.com/knsv/mermaid/pull/43) ([serv](https://github.com/serv))
-
-## [0.2.15](https://github.com/knsv/mermaid/tree/0.2.15) (2014-12-05)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.14...0.2.15)
-
-**Fixed bugs:**
-
-- Error with some characters [\#25](https://github.com/knsv/mermaid/issues/25)
-
-- Cap-cased words break parser [\#8](https://github.com/knsv/mermaid/issues/8)
-
-**Closed issues:**
-
-- Question marks don't render properly with /dist/mermaid.full.min.js [\#30](https://github.com/knsv/mermaid/issues/30)
-
-- Provide parse function in browser widthout `require`? [\#21](https://github.com/knsv/mermaid/issues/21)
-
-- Better label text support [\#18](https://github.com/knsv/mermaid/issues/18)
-
-**Merged pull requests:**
-
-- Include bower\_components/ to .gitignore [\#33](https://github.com/knsv/mermaid/pull/33) ([serv](https://github.com/serv))
-
-- Fixed reference to Git repo. [\#32](https://github.com/knsv/mermaid/pull/32) ([guyellis](https://github.com/guyellis))
-
-## [0.2.14](https://github.com/knsv/mermaid/tree/0.2.14) (2014-12-03)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.13...0.2.14)
-
-## [0.2.13](https://github.com/knsv/mermaid/tree/0.2.13) (2014-12-03)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.10...0.2.13)
-
-**Implemented enhancements:**
-
-- Publish to NPM [\#7](https://github.com/knsv/mermaid/issues/7)
-
-**Closed issues:**
-
-- modified init to be applied more than once [\#29](https://github.com/knsv/mermaid/issues/29)
-
-- Wanted to know build process for the project. [\#28](https://github.com/knsv/mermaid/issues/28)
-
-- can not support Chinese description [\#20](https://github.com/knsv/mermaid/issues/20)
-
-- Support unicode chars in labels [\#9](https://github.com/knsv/mermaid/issues/9)
-
-**Merged pull requests:**
-
-- initial setup for editor page to generate graph through textarea input [\#14](https://github.com/knsv/mermaid/pull/14) ([ImanimalXI](https://github.com/ImanimalXI))
-
-## [0.2.10](https://github.com/knsv/mermaid/tree/0.2.10) (2014-12-01)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.9...0.2.10)
-
-## [0.2.9](https://github.com/knsv/mermaid/tree/0.2.9) (2014-12-01)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.8...0.2.9)
-
-**Closed issues:**
-
-- Add link to jsbin playground to README [\#11](https://github.com/knsv/mermaid/issues/11)
-
-- What are the requirements ? [\#10](https://github.com/knsv/mermaid/issues/10)
-
-**Merged pull requests:**
-
-- Allow unicode chars in labels [\#13](https://github.com/knsv/mermaid/pull/13) ([codebeige](https://github.com/codebeige))
-
-- Formatting Update [\#12](https://github.com/knsv/mermaid/pull/12) ([darrencauthon](https://github.com/darrencauthon))
-
-## [0.2.8](https://github.com/knsv/mermaid/tree/0.2.8) (2014-12-01)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.7...0.2.8)
-
-## [0.2.7](https://github.com/knsv/mermaid/tree/0.2.7) (2014-12-01)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.6...0.2.7)
-
-**Closed issues:**
-
-- Provide parser as separate module [\#4](https://github.com/knsv/mermaid/issues/4)
-
-## [0.2.6](https://github.com/knsv/mermaid/tree/0.2.6) (2014-11-27)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.5...0.2.6)
-
-## [0.2.5](https://github.com/knsv/mermaid/tree/0.2.5) (2014-11-27)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.4...0.2.5)
-
-**Merged pull requests:**
-
-- Added new shapes! [\#1](https://github.com/knsv/mermaid/pull/1) ([bjowes](https://github.com/bjowes))
-
-## [0.2.4](https://github.com/knsv/mermaid/tree/0.2.4) (2014-11-25)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.3...0.2.4)
-
-## [0.2.3](https://github.com/knsv/mermaid/tree/0.2.3) (2014-11-24)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.2...0.2.3)
-
-## [0.2.2](https://github.com/knsv/mermaid/tree/0.2.2) (2014-11-22)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.1...0.2.2)
-
-## [0.2.1](https://github.com/knsv/mermaid/tree/0.2.1) (2014-11-22)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.2.0...0.2.1)
-
-## [0.2.0](https://github.com/knsv/mermaid/tree/0.2.0) (2014-11-22)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.1.1...0.2.0)
-
-## [0.1.1](https://github.com/knsv/mermaid/tree/0.1.1) (2014-11-17)
-
-[Full Changelog](https://github.com/knsv/mermaid/compare/0.1.0...0.1.1)
-
-## [0.1.0](https://github.com/knsv/mermaid/tree/0.1.0) (2014-11-16)
-
-
-\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
\ No newline at end of file
diff --git a/_submodules/mermaid/LICENSE b/_submodules/mermaid/LICENSE
deleted file mode 100644
index 77b04c3aba988265626d86accec3a33d3979305b..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2014 - 2018 Knut Sveidqvist
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/_submodules/mermaid/README.md b/_submodules/mermaid/README.md
deleted file mode 100644
index 45464c0ea22edc7152814c4d504d80a9e131d5e4..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/README.md
+++ /dev/null
@@ -1,206 +0,0 @@
-# mermaid
-
-[![Build Status](https://travis-ci.org/knsv/mermaid.svg?branch=master)](https://travis-ci.org/knsv/mermaid)
-[![Coverage Status](https://coveralls.io/repos/github/knsv/mermaid/badge.svg?branch=master)](https://coveralls.io/github/knsv/mermaid?branch=master)
-[![Join the chat at https://gitter.im/knsv/mermaid](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/knsv/mermaid?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-![banner](./img/header.png)
-
-Generation of diagrams and flowcharts from text in a similar manner as markdown.
-
-Ever wanted to simplify documentation and avoid heavy tools like Visio when explaining your code?
-
-This is why mermaid was born, a simple markdown-like script language for generating charts from text via javascript.
-
-
-### Flowchart
-
-```
-graph TD;
-    A-->B;
-    A-->C;
-    B-->D;
-    C-->D;
-```
-![Flowchart](./img/flow.png)
-
-
-### Sequence diagram
-
-```
-sequenceDiagram
-    participant Alice
-    participant Bob
-    Alice->>John: Hello John, how are you?
-    loop Healthcheck
-        John->>John: Fight against hypochondria
-    end
-    Note right of John: Rational thoughts <br/>prevail...
-    John-->>Alice: Great!
-    John->>Bob: How about you?
-    Bob-->>John: Jolly good!
-```
-![Sequence diagram](./img/sequence.png)
-
-
-### Gantt diagram
-
-```
-gantt
-dateFormat  YYYY-MM-DD
-title Adding GANTT diagram to mermaid
-
-section A section
-Completed task            :done,    des1, 2014-01-06,2014-01-08
-Active task               :active,  des2, 2014-01-09, 3d
-Future task               :         des3, after des2, 5d
-Future task2               :         des4, after des3, 5d
-```
-![Gantt diagram](./img/gantt.png)
-
-
-### Class diagram - :exclamation: experimental
-
-```
-classDiagram
-Class01 <|-- AveryLongClass : Cool
-Class03 *-- Class04
-Class05 o-- Class06
-Class07 .. Class08
-Class09 --> C2 : Where am i?
-Class09 --* C3
-Class09 --|> Class07
-Class07 : equals()
-Class07 : Object[] elementData
-Class01 : size()
-Class01 : int chimp
-Class01 : int gorilla
-Class08 <--> C2: Cool label
-```
-![Class diagram](./img/class.png)
-
-
-### Git graph - :exclamation: experimental
-
-```
-gitGraph:
-options
-{
-    "nodeSpacing": 150,
-    "nodeRadius": 10
-}
-end
-commit
-branch newbranch
-checkout newbranch
-commit
-commit
-checkout master
-commit
-commit
-merge newbranch
-
-```
-
-![Git graph](./img/git.png)
-
-
-## Installation
-
-### CDN
-
-```
-https://unpkg.com/mermaid@<version>/dist/
-```
-
-Replace `<version>` with expected version number.
-
-Example: https://unpkg.com/mermaid@7.1.0/dist/
-
-### Node.js
-
-```
-yarn add mermaid
-```
-
-
-## Documentation
-
-https://mermaidjs.github.io
-
-
-## Sibling projects
-
-- [mermaid CLI](https://github.com/mermaidjs/mermaid.cli)
-- [mermaid live editor](https://github.com/mermaidjs/mermaid-live-editor)
-- [mermaid webpack demo](https://github.com/mermaidjs/mermaid-webpack-demo)
-- [mermaid Parcel demo](https://github.com/mermaidjs/mermaid-parcel-demo)
-
-
-# Request for assistance
-
-Things are piling up and I have hard time keeping up. To remedy this
-it would be great if we could form a core team of developers to cooperate
-with the future development mermaid.
-
-As part of this team you would get write access to the repository and would
-represent the project when answering questions and issues.
-
-Together we could continue the work with things like:
-* adding more typers of diagrams like mindmaps, ert digrams etc
-* improving existing diagrams
-
-Don't hesitate to contact me if you want to get involved.
-
-
-# For contributors
-
-## Setup
-
-    yarn install
-
-
-## Build
-
-    yarn build:watch
-
-
-## Lint
-
-    yarn lint
-
-We use [JavaScript Standard Style](https://github.com/feross/standard).
-We recommend you installing [editor plugins](https://github.com/feross/standard#are-there-text-editor-plugins) so you can get real time lint result.
-
-
-## Test
-
-    yarn test
-
-Manual test in browser:
-
-    open dist/index.html
-
-
-## Release
-
-For those who have the permission to do so:
-
-Update version number in `package.json`.
-
-    npm publish
-
-Command above generates files into the `dist` folder and publishes them to npmjs.org.
-
-
-# Credits
-
-Many thanks to the [d3](http://d3js.org/) and [dagre-d3](https://github.com/cpettitt/dagre-d3) projects for providing the graphical layout and drawing libraries!
-
-Thanks also to the [js-sequence-diagram](http://bramp.github.io/js-sequence-diagrams) project for usage of the grammar for the sequence diagrams. Thanks to Jessica Peter for inspiration and starting point for gantt rendering.
-
-*Mermaid was created by Knut Sveidqvist for easier documentation.*
-
-*[Tyler Long](https://github.com/tylerlong) has became a collaborator since April 2017.*
-
-Here is the full list of the projects [contributors](https://github.com/knsv/mermaid/graphs/contributors).
diff --git a/_submodules/mermaid/__mocks__/d3.js b/_submodules/mermaid/__mocks__/d3.js
deleted file mode 100644
index 218ed9754f70b895a3e1310c43e3be269b74fd2d..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/__mocks__/d3.js
+++ /dev/null
@@ -1,38 +0,0 @@
-let NewD3 = function () {
-  return {
-    append: function () {
-      return NewD3()
-    },
-    attr: function () {
-      return this
-    },
-    style: function () {
-      return this
-    },
-    text: function () {
-      return this
-    },
-    0: {
-      0: {
-        getBBox: function () {
-          return {
-            height: 10,
-            width: 20
-          }
-        }
-      }
-    }
-  }
-}
-
-export const select = function () {
-  return new NewD3()
-}
-
-export const selectAll = function () {
-  return new NewD3()
-}
-
-export const curveBasis = 'basis'
-export const curveLinear = 'linear'
-export const curveCardinal = 'cardinal'
diff --git a/_submodules/mermaid/gulpfile.js b/_submodules/mermaid/gulpfile.js
deleted file mode 100644
index 613cf83c1430012153d05236eede68bd0ee060a2..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/gulpfile.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import gulp from 'gulp'
-import jison from 'gulp-jison'
-import filelog from 'gulp-filelog'
-
-gulp.task('jison', function () {
-  return gulp.src('./src/**/*.jison')
-    .pipe(filelog('Jison file:'))
-    .pipe(jison({ 'token-stack': true }))
-    .pipe(gulp.dest('./src/'))
-})
diff --git a/_submodules/mermaid/img/class.png b/_submodules/mermaid/img/class.png
deleted file mode 100644
index bf6e379e1abf5db97fcd3d7bb06cad26400b8a7f..0000000000000000000000000000000000000000
Binary files a/_submodules/mermaid/img/class.png and /dev/null differ
diff --git a/_submodules/mermaid/img/flow.png b/_submodules/mermaid/img/flow.png
deleted file mode 100644
index e324299764ef1540b37b891a76484514ce5d6d15..0000000000000000000000000000000000000000
Binary files a/_submodules/mermaid/img/flow.png and /dev/null differ
diff --git a/_submodules/mermaid/img/gantt.png b/_submodules/mermaid/img/gantt.png
deleted file mode 100644
index 64645cb5baf307d7804bf2050ab7f4fb1b2cb312..0000000000000000000000000000000000000000
Binary files a/_submodules/mermaid/img/gantt.png and /dev/null differ
diff --git a/_submodules/mermaid/img/git.png b/_submodules/mermaid/img/git.png
deleted file mode 100644
index 2da331a1eda912e1fb6057726dc8608985b045ac..0000000000000000000000000000000000000000
Binary files a/_submodules/mermaid/img/git.png and /dev/null differ
diff --git a/_submodules/mermaid/img/header.png b/_submodules/mermaid/img/header.png
deleted file mode 100644
index 06159b2c94e22cc09fb507db6c7a1562fe4bdeb7..0000000000000000000000000000000000000000
Binary files a/_submodules/mermaid/img/header.png and /dev/null differ
diff --git a/_submodules/mermaid/img/sequence.png b/_submodules/mermaid/img/sequence.png
deleted file mode 100644
index b35e3b74db9e96de970ec63af9345f0046ec9fcd..0000000000000000000000000000000000000000
Binary files a/_submodules/mermaid/img/sequence.png and /dev/null differ
diff --git a/_submodules/mermaid/package.json b/_submodules/mermaid/package.json
deleted file mode 100644
index 3c2a5b38f7448fa7827728acc36e46f067d61ea2..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/package.json
+++ /dev/null
@@ -1,80 +0,0 @@
-{
-  "name": "mermaid",
-  "version": "8.0.0-rc.8",
-  "description": "Markdownish syntax for generating flowcharts, sequence diagrams, class diagrams, gantt charts and git graphs.",
-  "main": "dist/mermaid.core.js",
-  "keywords": [
-    "diagram",
-    "markdown",
-    "flowchart",
-    "sequence diagram",
-    "gantt",
-    "class diagram",
-    "git graph"
-  ],
-  "scripts": {
-    "build": "webpack --progress --colors",
-    "build:watch": "yarn build --watch",
-    "release": "yarn build -p --config webpack.config.prod.babel.js",
-    "upgrade": "yarn-upgrade-all",
-    "lint": "standard",
-    "test": "yarn lint && jest",
-    "test:watch": "jest --watch",
-    "jison": "node -r babel-register node_modules/.bin/gulp jison",
-    "prepublishOnly": "yarn build && yarn release && yarn test",
-    "prepush": "yarn test"
-  },
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/knsv/mermaid"
-  },
-  "author": "Knut Sveidqvist",
-  "license": "MIT",
-  "standard": {
-    "ignore": [
-      "**/parser/*.js",
-      "dist/**/*.js"
-    ]
-  },
-  "dependencies": {
-    "d3": "^4.13.0",
-    "dagre-d3-renderer": "^0.5.8",
-    "dagre-layout": "^0.8.8",
-    "graphlibrary": "^2.2.0",
-    "he": "^1.1.1",
-    "lodash": "^4.17.5",
-    "moment": "^2.21.0",
-    "scope-css": "^1.0.5"
-  },
-  "devDependencies": {
-    "babel-core": "^6.26.0",
-    "babel-loader": "^7.1.4",
-    "babel-preset-env": "^1.6.1",
-    "coveralls": "^3.0.0",
-    "css-loader": "^0.28.11",
-    "css-to-string-loader": "^0.1.3",
-    "gulp": "^3.9.1",
-    "gulp-filelog": "^0.4.1",
-    "gulp-jison": "^1.2.0",
-    "husky": "^0.14.3",
-    "identity-obj-proxy": "^3.0.0",
-    "jest": "^22.4.2",
-    "jison": "^0.4.18",
-    "node-sass": "^4.7.2",
-    "sass-loader": "^6.0.7",
-    "standard": "^11.0.1",
-    "webpack": "^4.1.1",
-    "webpack-cli": "^2.0.12",
-    "webpack-node-externals": "^1.6.0",
-    "yarn-upgrade-all": "^0.3.0"
-  },
-  "files": [
-    "dist",
-    "src"
-  ],
-  "jest": {
-    "moduleNameMapper": {
-      "\\.(css|scss)$": "identity-obj-proxy"
-    }
-  }
-}
diff --git a/_submodules/mermaid/src/diagrams/class/classDb.js b/_submodules/mermaid/src/diagrams/class/classDb.js
deleted file mode 100644
index 6be4bb7736a1d5a324846d8618f3555d09e7e8c9..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/class/classDb.js
+++ /dev/null
@@ -1,89 +0,0 @@
-
-import { logger } from '../../logger'
-
-let relations = []
-let classes = {}
-
-/**
- * Function called by parser when a node definition has been found.
- * @param id
- * @param text
- * @param type
- * @param style
- */
-export const addClass = function (id) {
-  if (typeof classes[id] === 'undefined') {
-    classes[id] = {
-      id: id,
-      methods: [],
-      members: []
-    }
-  }
-}
-
-export const clear = function () {
-  relations = []
-  classes = {}
-}
-
-export const getClass = function (id) {
-  return classes[id]
-}
-export const getClasses = function () {
-  return classes
-}
-
-export const getRelations = function () {
-  return relations
-}
-
-export const addRelation = function (relation) {
-  logger.debug('Adding relation: ' + JSON.stringify(relation))
-  addClass(relation.id1)
-  addClass(relation.id2)
-  relations.push(relation)
-}
-
-export const addMembers = function (className, MembersArr) {
-  const theClass = classes[className]
-  if (typeof MembersArr === 'string') {
-    if (MembersArr.substr(-1) === ')') {
-      theClass.methods.push(MembersArr)
-    } else {
-      theClass.members.push(MembersArr)
-    }
-  }
-}
-
-export const cleanupLabel = function (label) {
-  if (label.substring(0, 1) === ':') {
-    return label.substr(2).trim()
-  } else {
-    return label.trim()
-  }
-}
-
-export const lineType = {
-  LINE: 0,
-  DOTTED_LINE: 1
-}
-
-export const relationType = {
-  AGGREGATION: 0,
-  EXTENSION: 1,
-  COMPOSITION: 2,
-  DEPENDENCY: 3
-}
-
-export default {
-  addClass,
-  clear,
-  getClass,
-  getClasses,
-  getRelations,
-  addRelation,
-  addMembers,
-  cleanupLabel,
-  lineType,
-  relationType
-}
diff --git a/_submodules/mermaid/src/diagrams/class/classDiagram.spec.js b/_submodules/mermaid/src/diagrams/class/classDiagram.spec.js
deleted file mode 100644
index 38657e11d2d0fa22a72e8c54f503df09acb420c4..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/class/classDiagram.spec.js
+++ /dev/null
@@ -1,208 +0,0 @@
-/* eslint-env jasmine */
-import { parser } from './parser/classDiagram'
-import classDb from './classDb'
-
-describe('class diagram, ', function () {
-  describe('when parsing an info graph it', function () {
-    beforeEach(function () {
-      parser.yy = classDb
-    })
-
-    it('should handle relation definitions', function () {
-      const str = 'classDiagram\n' +
-'Class01 <|-- Class02\n' +
-'Class03 *-- Class04\n' +
-'Class05 o-- Class06\n' +
-'Class07 .. Class08\n' +
-'Class09 -- Class1'
-
-      parser.parse(str)
-    })
-    it('should handle relation definition of different types and directions', function () {
-      const str = 'classDiagram\n' +
-'Class11 <|.. Class12\n' +
-'Class13 --> Class14\n' +
-'Class15 ..> Class16\n' +
-'Class17 ..|> Class18\n' +
-'Class19 <--* Class20'
-
-      parser.parse(str)
-    })
-
-    it('should handle cardinality and labels', function () {
-      const str = 'classDiagram\n' +
-'Class01 "1" *-- "many" Class02 : contains\n' +
-'Class03 o-- Class04 : aggregation\n' +
-'Class05 --> "1" Class06'
-
-      parser.parse(str)
-    })
-    it('should handle class definitions', function () {
-      const str = 'classDiagram\n' +
-'class Car\n' +
-'Driver -- Car : drives >\n' +
-'Car *-- Wheel : have 4 >\n' +
-'Car -- Person : < owns'
-
-      parser.parse(str)
-    })
-
-    it('should handle method statements', function () {
-      const str = 'classDiagram\n' +
-'Object <|-- ArrayList\n' +
-'Object : equals()\n' +
-'ArrayList : Object[] elementData\n' +
-'ArrayList : size()'
-
-      parser.parse(str)
-    })
-    it('should handle parsing of method statements  grouped by brackets', function () {
-      const str = 'classDiagram\n' +
-'class Dummy {\n' +
-'String data\n' +
-'  void methods()\n' +
-'}\n' +
-'\n' +
-'class Flight {\n' +
-'   flightNumber : Integer\n' +
-'   departureTime : Date\n' +
-'}'
-
-      parser.parse(str)
-    })
-
-    it('should handle parsing of separators', function () {
-      const str = 'classDiagram\n' +
-                'class Foo1 {\n' +
-                '  You can use\n' +
-                '  several lines\n' +
-                '..\n' +
-                'as you want\n' +
-                'and group\n' +
-                '==\n' +
-                'things together.\n' +
-                '__\n' +
-                'You can have as many groups\n' +
-                'as you want\n' +
-                '--\n' +
-                'End of class\n' +
-                '}\n' +
-                '\n' +
-                'class User {\n' +
-                '.. Simple Getter ..\n' +
-                '+ getName()\n' +
-                '+ getAddress()\n' +
-                '.. Some setter ..\n' +
-                '+ setName()\n' +
-                '__ private data __\n' +
-                'int age\n' +
-                '-- encrypted --\n' +
-                'String password\n' +
-                '}'
-
-      parser.parse(str)
-    })
-  })
-
-  describe('when fetching data from an classDiagram graph it', function () {
-    beforeEach(function () {
-      parser.yy = classDb
-      parser.yy.clear()
-    })
-    it('should handle relation definitions EXTENSION', function () {
-      const str = 'classDiagram\n' +
-                        'Class01 <|-- Class02'
-
-      parser.parse(str)
-
-      const relations = parser.yy.getRelations()
-
-      expect(parser.yy.getClass('Class01').id).toBe('Class01')
-      expect(parser.yy.getClass('Class02').id).toBe('Class02')
-      expect(relations[0].relation.type1).toBe(classDb.relationType.EXTENSION)
-      expect(relations[0].relation.type2).toBe('none')
-      expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
-    })
-    it('should handle relation definitions AGGREGATION and dotted line', function () {
-      const str = 'classDiagram\n' +
-                        'Class01 o.. Class02'
-
-      parser.parse(str)
-
-      const relations = parser.yy.getRelations()
-
-      expect(parser.yy.getClass('Class01').id).toBe('Class01')
-      expect(parser.yy.getClass('Class02').id).toBe('Class02')
-      expect(relations[0].relation.type1).toBe(classDb.relationType.AGGREGATION)
-      expect(relations[0].relation.type2).toBe('none')
-      expect(relations[0].relation.lineType).toBe(classDb.lineType.DOTTED_LINE)
-    })
-    it('should handle relation definitions COMPOSITION on both sides', function () {
-      const str = 'classDiagram\n' +
-                       'Class01 *--* Class02'
-
-      parser.parse(str)
-
-      const relations = parser.yy.getRelations()
-
-      expect(parser.yy.getClass('Class01').id).toBe('Class01')
-      expect(parser.yy.getClass('Class02').id).toBe('Class02')
-      expect(relations[0].relation.type1).toBe(classDb.relationType.COMPOSITION)
-      expect(relations[0].relation.type2).toBe(classDb.relationType.COMPOSITION)
-      expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
-    })
-    it('should handle relation definitions no types', function () {
-      const str = 'classDiagram\n' +
-                        'Class01 -- Class02'
-
-      parser.parse(str)
-
-      const relations = parser.yy.getRelations()
-
-      expect(parser.yy.getClass('Class01').id).toBe('Class01')
-      expect(parser.yy.getClass('Class02').id).toBe('Class02')
-      expect(relations[0].relation.type1).toBe('none')
-      expect(relations[0].relation.type2).toBe('none')
-      expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
-    })
-    it('should handle relation definitions with type only on right side', function () {
-      const str = 'classDiagram\n' +
-                       'Class01 --|> Class02'
-
-      parser.parse(str)
-
-      const relations = parser.yy.getRelations()
-
-      expect(parser.yy.getClass('Class01').id).toBe('Class01')
-      expect(parser.yy.getClass('Class02').id).toBe('Class02')
-      expect(relations[0].relation.type1).toBe('none')
-      expect(relations[0].relation.type2).toBe(classDb.relationType.EXTENSION)
-      expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
-    })
-
-    it('should handle multiple classes and relation definitions', function () {
-      const str = 'classDiagram\n' +
-                        'Class01 <|-- Class02\n' +
-                        'Class03 *-- Class04\n' +
-                        'Class05 o-- Class06\n' +
-                        'Class07 .. Class08\n' +
-                        'Class09 -- Class10'
-
-      parser.parse(str)
-
-      const relations = parser.yy.getRelations()
-
-      expect(parser.yy.getClass('Class01').id).toBe('Class01')
-      expect(parser.yy.getClass('Class10').id).toBe('Class10')
-
-      expect(relations.length).toBe(5)
-
-      expect(relations[0].relation.type1).toBe(classDb.relationType.EXTENSION)
-      expect(relations[0].relation.type2).toBe('none')
-      expect(relations[0].relation.lineType).toBe(classDb.lineType.LINE)
-      expect(relations[3].relation.type1).toBe('none')
-      expect(relations[3].relation.type2).toBe('none')
-      expect(relations[3].relation.lineType).toBe(classDb.lineType.DOTTED_LINE)
-    })
-  })
-})
diff --git a/_submodules/mermaid/src/diagrams/class/classRenderer.js b/_submodules/mermaid/src/diagrams/class/classRenderer.js
deleted file mode 100644
index 5169fce4bf3db14087082700cd498423855a3a2c..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/class/classRenderer.js
+++ /dev/null
@@ -1,365 +0,0 @@
-import dagre from 'dagre-layout'
-import graphlib from 'graphlibrary'
-import * as d3 from 'd3'
-
-import classDb from './classDb'
-import { logger } from '../../logger'
-import { parser } from './parser/classDiagram'
-
-parser.yy = classDb
-
-const idCache = {}
-
-let classCnt = 0
-const conf = {
-  dividerMargin: 10,
-  padding: 5,
-  textHeight: 10
-}
-
-// Todo optimize
-const getGraphId = function (label) {
-  const keys = Object.keys(idCache)
-
-  for (let i = 0; i < keys.length; i++) {
-    if (idCache[keys[i]].label === label) {
-      return keys[i]
-    }
-  }
-
-  return undefined
-}
-
-/**
- * Setup arrow head and define the marker. The result is appended to the svg.
- */
-const insertMarkers = function (elem) {
-  elem.append('defs').append('marker')
-    .attr('id', 'extensionStart')
-    .attr('class', 'extension')
-    .attr('refX', 0)
-    .attr('refY', 7)
-    .attr('markerWidth', 190)
-    .attr('markerHeight', 240)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 1,7 L18,13 V 1 Z')
-
-  elem.append('defs').append('marker')
-    .attr('id', 'extensionEnd')
-    .attr('refX', 19)
-    .attr('refY', 7)
-    .attr('markerWidth', 20)
-    .attr('markerHeight', 28)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 1,1 V 13 L18,7 Z') // this is actual shape for arrowhead
-
-  elem.append('defs').append('marker')
-    .attr('id', 'compositionStart')
-    .attr('class', 'extension')
-    .attr('refX', 0)
-    .attr('refY', 7)
-    .attr('markerWidth', 190)
-    .attr('markerHeight', 240)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
-
-  elem.append('defs').append('marker')
-    .attr('id', 'compositionEnd')
-    .attr('refX', 19)
-    .attr('refY', 7)
-    .attr('markerWidth', 20)
-    .attr('markerHeight', 28)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
-
-  elem.append('defs').append('marker')
-    .attr('id', 'aggregationStart')
-    .attr('class', 'extension')
-    .attr('refX', 0)
-    .attr('refY', 7)
-    .attr('markerWidth', 190)
-    .attr('markerHeight', 240)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
-
-  elem.append('defs').append('marker')
-    .attr('id', 'aggregationEnd')
-    .attr('refX', 19)
-    .attr('refY', 7)
-    .attr('markerWidth', 20)
-    .attr('markerHeight', 28)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 18,7 L9,13 L1,7 L9,1 Z')
-
-  elem.append('defs').append('marker')
-    .attr('id', 'dependencyStart')
-    .attr('class', 'extension')
-    .attr('refX', 0)
-    .attr('refY', 7)
-    .attr('markerWidth', 190)
-    .attr('markerHeight', 240)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 5,7 L9,13 L1,7 L9,1 Z')
-
-  elem.append('defs').append('marker')
-    .attr('id', 'dependencyEnd')
-    .attr('refX', 19)
-    .attr('refY', 7)
-    .attr('markerWidth', 20)
-    .attr('markerHeight', 28)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 18,7 L9,13 L14,7 L9,1 Z')
-}
-
-let edgeCount = 0
-const drawEdge = function (elem, path, relation) {
-  const getRelationType = function (type) {
-    switch (type) {
-      case classDb.relationType.AGGREGATION:
-        return 'aggregation'
-      case classDb.relationType.EXTENSION:
-        return 'extension'
-      case classDb.relationType.COMPOSITION:
-        return 'composition'
-      case classDb.relationType.DEPENDENCY:
-        return 'dependency'
-    }
-  }
-
-  // The data for our line
-  const lineData = path.points
-
-  // This is the accessor function we talked about above
-  const lineFunction = d3.line()
-    .x(function (d) {
-      return d.x
-    })
-    .y(function (d) {
-      return d.y
-    })
-    .curve(d3.curveBasis)
-
-  const svgPath = elem.append('path')
-    .attr('d', lineFunction(lineData))
-    .attr('id', 'edge' + edgeCount)
-    .attr('class', 'relation')
-  let url = ''
-  if (conf.arrowMarkerAbsolute) {
-    url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search
-    url = url.replace(/\(/g, '\\(')
-    url = url.replace(/\)/g, '\\)')
-  }
-
-  if (relation.relation.type1 !== 'none') {
-    svgPath.attr('marker-start', 'url(' + url + '#' + getRelationType(relation.relation.type1) + 'Start' + ')')
-  }
-  if (relation.relation.type2 !== 'none') {
-    svgPath.attr('marker-end', 'url(' + url + '#' + getRelationType(relation.relation.type2) + 'End' + ')')
-  }
-
-  let x, y
-  const l = path.points.length
-  if ((l % 2) !== 0) {
-    const p1 = path.points[Math.floor(l / 2)]
-    const p2 = path.points[Math.ceil(l / 2)]
-    x = (p1.x + p2.x) / 2
-    y = (p1.y + p2.y) / 2
-  } else {
-    const p = path.points[Math.floor(l / 2)]
-    x = p.x
-    y = p.y
-  }
-
-  if (typeof relation.title !== 'undefined') {
-    const g = elem.append('g')
-      .attr('class', 'classLabel')
-    const label = g.append('text')
-      .attr('class', 'label')
-      .attr('x', x)
-      .attr('y', y)
-      .attr('fill', 'red')
-      .attr('text-anchor', 'middle')
-      .text(relation.title)
-
-    window.label = label
-    const bounds = label.node().getBBox()
-
-    g.insert('rect', ':first-child')
-      .attr('class', 'box')
-      .attr('x', bounds.x - conf.padding / 2)
-      .attr('y', bounds.y - conf.padding / 2)
-      .attr('width', bounds.width + conf.padding)
-      .attr('height', bounds.height + conf.padding)
-  }
-
-  edgeCount++
-}
-
-const drawClass = function (elem, classDef) {
-  logger.info('Rendering class ' + classDef)
-
-  const addTspan = function (textEl, txt, isFirst) {
-    const tSpan = textEl.append('tspan')
-      .attr('x', conf.padding)
-      .text(txt)
-    if (!isFirst) {
-      tSpan.attr('dy', conf.textHeight)
-    }
-  }
-
-  const id = 'classId' + classCnt
-  const classInfo = {
-    id: id,
-    label: classDef.id,
-    width: 0,
-    height: 0
-  }
-
-  const g = elem.append('g')
-    .attr('id', id)
-    .attr('class', 'classGroup')
-  const title = g.append('text')
-    .attr('x', conf.padding)
-    .attr('y', conf.textHeight + conf.padding)
-    .text(classDef.id)
-
-  const titleHeight = title.node().getBBox().height
-
-  const membersLine = g.append('line') // text label for the x axis
-    .attr('x1', 0)
-    .attr('y1', conf.padding + titleHeight + conf.dividerMargin / 2)
-    .attr('y2', conf.padding + titleHeight + conf.dividerMargin / 2)
-
-  const members = g.append('text') // text label for the x axis
-    .attr('x', conf.padding)
-    .attr('y', titleHeight + (conf.dividerMargin) + conf.textHeight)
-    .attr('fill', 'white')
-    .attr('class', 'classText')
-
-  let isFirst = true
-  classDef.members.forEach(function (member) {
-    addTspan(members, member, isFirst)
-    isFirst = false
-  })
-
-  const membersBox = members.node().getBBox()
-
-  const methodsLine = g.append('line') // text label for the x axis
-    .attr('x1', 0)
-    .attr('y1', conf.padding + titleHeight + conf.dividerMargin + membersBox.height)
-    .attr('y2', conf.padding + titleHeight + conf.dividerMargin + membersBox.height)
-
-  const methods = g.append('text') // text label for the x axis
-    .attr('x', conf.padding)
-    .attr('y', titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight)
-    .attr('fill', 'white')
-    .attr('class', 'classText')
-
-  isFirst = true
-
-  classDef.methods.forEach(function (method) {
-    addTspan(methods, method, isFirst)
-    isFirst = false
-  })
-
-  const classBox = g.node().getBBox()
-  g.insert('rect', ':first-child')
-    .attr('x', 0)
-    .attr('y', 0)
-    .attr('width', classBox.width + 2 * conf.padding)
-    .attr('height', classBox.height + conf.padding + 0.5 * conf.dividerMargin)
-
-  membersLine.attr('x2', classBox.width + 2 * conf.padding)
-  methodsLine.attr('x2', classBox.width + 2 * conf.padding)
-
-  classInfo.width = classBox.width + 2 * conf.padding
-  classInfo.height = classBox.height + conf.padding + 0.5 * conf.dividerMargin
-
-  idCache[id] = classInfo
-  classCnt++
-  return classInfo
-}
-
-export const setConf = function (cnf) {
-  const keys = Object.keys(cnf)
-
-  keys.forEach(function (key) {
-    conf[key] = cnf[key]
-  })
-}
-/**
- * Draws a flowchart in the tag with id: id based on the graph definition in text.
- * @param text
- * @param id
- */
-export const draw = function (text, id) {
-  parser.yy.clear()
-  parser.parse(text)
-
-  logger.info('Rendering diagram ' + text)
-
-  /// / Fetch the default direction, use TD if none was found
-  const diagram = d3.select(`[id="${id}"]`)
-  insertMarkers(diagram)
-
-  // Layout graph, Create a new directed graph
-  const g = new graphlib.Graph({
-    multigraph: true
-  })
-
-  // Set an object for the graph label
-  g.setGraph({
-    isMultiGraph: true
-  })
-
-  // Default to assigning a new object as a label for each new edge.
-  g.setDefaultEdgeLabel(function () {
-    return {}
-  })
-
-  const classes = classDb.getClasses()
-  const keys = Object.keys(classes)
-  for (let i = 0; i < keys.length; i++) {
-    const classDef = classes[keys[i]]
-    const node = drawClass(diagram, classDef)
-    // Add nodes to the graph. The first argument is the node id. The second is
-    // metadata about the node. In this case we're going to add labels to each of
-    // our nodes.
-    g.setNode(node.id, node)
-    logger.info('Org height: ' + node.height)
-  }
-
-  const relations = classDb.getRelations()
-  relations.forEach(function (relation) {
-    logger.info('tjoho' + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation))
-    g.setEdge(getGraphId(relation.id1), getGraphId(relation.id2), { relation: relation })
-  })
-  dagre.layout(g)
-  g.nodes().forEach(function (v) {
-    if (typeof v !== 'undefined') {
-      logger.debug('Node ' + v + ': ' + JSON.stringify(g.node(v)))
-      d3.select('#' + v).attr('transform', 'translate(' + (g.node(v).x - (g.node(v).width / 2)) + ',' + (g.node(v).y - (g.node(v).height / 2)) + ' )')
-    }
-  })
-  g.edges().forEach(function (e) {
-    logger.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(g.edge(e)))
-    drawEdge(diagram, g.edge(e), g.edge(e).relation)
-  })
-
-  diagram.attr('height', '100%')
-  diagram.attr('width', '100%')
-  diagram.attr('viewBox', '0 0 ' + (g.graph().width + 20) + ' ' + (g.graph().height + 20))
-}
-
-export default {
-  setConf,
-  draw
-}
diff --git a/_submodules/mermaid/src/diagrams/class/parser/classDiagram.jison b/_submodules/mermaid/src/diagrams/class/parser/classDiagram.jison
deleted file mode 100644
index f633d144cb260a86c0ffaf05fa80bfcc43825751..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/class/parser/classDiagram.jison
+++ /dev/null
@@ -1,196 +0,0 @@
-/** mermaid
- *  https://mermaidjs.github.io/
- *  (c) 2015 Knut Sveidqvist
- *  MIT license.
- */
-
-/* lexical grammar */
-%lex
-%x string struct
-
-%%
-\%\%[^\n]*            /* do nothing */
-\n+                   return 'NEWLINE';
-\s+                     /* skip whitespace */
-"classDiagram"          return 'CLASS_DIAGRAM';
-[\{]                    { this.begin("struct"); /*console.log('Starting struct');*/return 'STRUCT_START';}
-<struct>\}           { /*console.log('Ending struct');*/this.popState(); return 'STRUCT_STOP';}}
-<struct>[\n]              /* nothing */
-<struct>[^\{\}\n]*     { /*console.log('lex-member: ' + yytext);*/  return "MEMBER";}
-
-
-
-"class"               return 'CLASS';
-["]                   this.begin("string");
-<string>["]           this.popState();
-<string>[^"]*         return "STR";
-
-
-\s*\<\|               return 'EXTENSION';
-\s*\|\>               return 'EXTENSION';
-\s*\>                 return 'DEPENDENCY';
-\s*\<                 return 'DEPENDENCY';
-\s*\*                  return 'COMPOSITION';
-\s*o                  return 'AGGREGATION';
-\-\-                  return 'LINE';
-\.\.                  return 'DOTTED_LINE';
-":"[^#\n;]+        return 'LABEL';
-\-                    return 'MINUS';
-"."                   return 'DOT';
-\+                    return 'PLUS';
-\%                    return 'PCT';
-"="                   return 'EQUALS';
-\=                    return 'EQUALS';
-[A-Za-z]+             return 'ALPHA';
-[!"#$%&'*+,-.`?\\_/]  return 'PUNCTUATION';
-[0-9]+                 return 'NUM';
-[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|
-[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|
-[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|
-[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|
-[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|
-[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|
-[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|
-[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|
-[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|
-[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|
-[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|
-[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|
-[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|
-[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|
-[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|
-[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|
-[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|
-[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|
-[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|
-[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|
-[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|
-[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|
-[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|
-[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|
-[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|
-[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|
-[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|
-[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|
-[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|
-[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|
-[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|
-[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|
-[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|
-[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|
-[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|
-[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|
-[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|
-[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|
-[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|
-[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|
-[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|
-[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|
-[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|
-[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|
-[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|
-[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|
-[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|
-[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|
-[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|
-[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|
-[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|
-[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|
-[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|
-[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|
-[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|
-[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|
-[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|
-[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|
-[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|
-[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|
-[\uFFD2-\uFFD7\uFFDA-\uFFDC]
-                      return 'UNICODE_TEXT';
-\s                    return 'SPACE';
-<<EOF>>               return 'EOF';
-
-/lex
-
-/* operator associations and precedence */
-
-%left '^'
-
-%start mermaidDoc
-
-%% /* language grammar */
-
-mermaidDoc: graphConfig;
-
-graphConfig
-    : CLASS_DIAGRAM NEWLINE statements EOF
-    ;
-
-statements
-    : statement
-    | statement NEWLINE statements
-    ;
-
-
-className
-    : alphaNumToken className { $$=$1+$2; }
-    | alphaNumToken { $$=$1; }
-    ;
-
-statement
-    : relationStatement       { yy.addRelation($1); }
-    | relationStatement LABEL { $1.title =  yy.cleanupLabel($2); yy.addRelation($1);        }
-    | classStatement
-    | methodStatement
-    ;
-
-classStatement
-    : CLASS className
-    | CLASS className STRUCT_START members STRUCT_STOP {/*console.log($2,JSON.stringify($4));*/yy.addMembers($2,$4);}
-    ;
-
-members
-    : MEMBER { $$ = [$1]; }
-    | MEMBER members { $2.push($1);$$=$2;}
-    ;
-
-methodStatement
-    : className {/*console.log('Rel found',$1);*/}
-    | className LABEL {yy.addMembers($1,yy.cleanupLabel($2));}
-    | MEMBER {console.warn('Member',$1);}
-    | SEPARATOR {/*console.log('sep found',$1);*/}
-    ;
-
-relationStatement
-    : className relation className          { $$ = {'id1':$1,'id2':$3, relation:$2, relationTitle1:'none', relationTitle2:'none'}; }
-    | className STR relation className      { $$ = {id1:$1, id2:$4, relation:$3, relationTitle1:$2, relationTitle2:'none'}}
-    | className relation STR className      { $$ = {id1:$1, id2:$4, relation:$2, relationTitle1:'none', relationTitle2:$3}; }
-    | className STR relation STR className  { $$ = {id1:$1, id2:$5, relation:$3, relationTitle1:$2, relationTitle2:$4} }
-    ;
-
-relation
-    : relationType lineType relationType { $$={type1:$1,type2:$3,lineType:$2}; }
-    | lineType relationType { $$={type1:'none',type2:$2,lineType:$1}; }
-    | relationType lineType { $$={type1:$1,type2:'none',lineType:$2}; }
-    | lineType { $$={type1:'none',type2:'none',lineType:$1}; }
-    ;
-
-relationType
-    : AGGREGATION { $$=yy.relationType.AGGREGATION;}
-    | EXTENSION   { $$=yy.relationType.EXTENSION;}
-    | COMPOSITION { $$=yy.relationType.COMPOSITION;}
-    | DEPENDENCY  { $$=yy.relationType.DEPENDENCY;}
-    ;
-
-lineType
-    : LINE          {$$=yy.lineType.LINE;}
-    | DOTTED_LINE   {$$=yy.lineType.DOTTED_LINE;}
-    ;
-
-commentToken   : textToken | graphCodeTokens ;
-
-textToken      : textNoTagsToken | TAGSTART | TAGEND | '=='  | '--' | PCT | DEFAULT;
-
-textNoTagsToken: alphaNumToken | SPACE | MINUS | keywords ;
-
-alphaNumToken  : UNICODE_TEXT | NUM | ALPHA;
-%%
diff --git a/_submodules/mermaid/src/diagrams/class/parser/classDiagram.js b/_submodules/mermaid/src/diagrams/class/parser/classDiagram.js
deleted file mode 100644
index 5ff57a54d2a1b6d0baa3c3ce6a50f75381c4e3c9..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/class/parser/classDiagram.js
+++ /dev/null
@@ -1,740 +0,0 @@
-/* parser generated by jison 0.4.18 */
-/*
-  Returns a Parser object of the following structure:
-
-  Parser: {
-    yy: {}
-  }
-
-  Parser.prototype: {
-    yy: {},
-    trace: function(),
-    symbols_: {associative list: name ==> number},
-    terminals_: {associative list: number ==> name},
-    productions_: [...],
-    performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
-    table: [...],
-    defaultActions: {...},
-    parseError: function(str, hash),
-    parse: function(input),
-
-    lexer: {
-        EOF: 1,
-        parseError: function(str, hash),
-        setInput: function(input),
-        input: function(),
-        unput: function(str),
-        more: function(),
-        less: function(n),
-        pastInput: function(),
-        upcomingInput: function(),
-        showPosition: function(),
-        test_match: function(regex_match_array, rule_index),
-        next: function(),
-        lex: function(),
-        begin: function(condition),
-        popState: function(),
-        _currentRules: function(),
-        topState: function(),
-        pushState: function(condition),
-
-        options: {
-            ranges: boolean           (optional: true ==> token location info will include a .range[] member)
-            flex: boolean             (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
-            backtrack_lexer: boolean  (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
-        },
-
-        performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
-        rules: [...],
-        conditions: {associative list: name ==> set},
-    }
-  }
-
-
-  token location info (@$, _$, etc.): {
-    first_line: n,
-    last_line: n,
-    first_column: n,
-    last_column: n,
-    range: [start_number, end_number]       (where the numbers are indexes into the input string, regular zero-based)
-  }
-
-
-  the parseError function receives a 'hash' object with these members for lexer and parser errors: {
-    text:        (matched text)
-    token:       (the produced terminal token, if any)
-    line:        (yylineno)
-  }
-  while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
-    loc:         (yylloc)
-    expected:    (string describing the set of expected tokens)
-    recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
-  }
-*/
-var parser = (function(){
-var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,11],$V1=[1,12],$V2=[1,13],$V3=[1,15],$V4=[1,16],$V5=[1,17],$V6=[6,8],$V7=[1,26],$V8=[1,27],$V9=[1,28],$Va=[1,29],$Vb=[1,30],$Vc=[1,31],$Vd=[6,8,13,17,23,26,27,28,29,30,31],$Ve=[6,8,13,17,23,26,27,28,29,30,31,45,46,47],$Vf=[23,45,46,47],$Vg=[23,30,31,45,46,47],$Vh=[23,26,27,28,29,45,46,47],$Vi=[6,8,13],$Vj=[1,46];
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {"error":2,"mermaidDoc":3,"graphConfig":4,"CLASS_DIAGRAM":5,"NEWLINE":6,"statements":7,"EOF":8,"statement":9,"className":10,"alphaNumToken":11,"relationStatement":12,"LABEL":13,"classStatement":14,"methodStatement":15,"CLASS":16,"STRUCT_START":17,"members":18,"STRUCT_STOP":19,"MEMBER":20,"SEPARATOR":21,"relation":22,"STR":23,"relationType":24,"lineType":25,"AGGREGATION":26,"EXTENSION":27,"COMPOSITION":28,"DEPENDENCY":29,"LINE":30,"DOTTED_LINE":31,"commentToken":32,"textToken":33,"graphCodeTokens":34,"textNoTagsToken":35,"TAGSTART":36,"TAGEND":37,"==":38,"--":39,"PCT":40,"DEFAULT":41,"SPACE":42,"MINUS":43,"keywords":44,"UNICODE_TEXT":45,"NUM":46,"ALPHA":47,"$accept":0,"$end":1},
-terminals_: {2:"error",5:"CLASS_DIAGRAM",6:"NEWLINE",8:"EOF",13:"LABEL",16:"CLASS",17:"STRUCT_START",19:"STRUCT_STOP",20:"MEMBER",21:"SEPARATOR",23:"STR",26:"AGGREGATION",27:"EXTENSION",28:"COMPOSITION",29:"DEPENDENCY",30:"LINE",31:"DOTTED_LINE",34:"graphCodeTokens",36:"TAGSTART",37:"TAGEND",38:"==",39:"--",40:"PCT",41:"DEFAULT",42:"SPACE",43:"MINUS",44:"keywords",45:"UNICODE_TEXT",46:"NUM",47:"ALPHA"},
-productions_: [0,[3,1],[4,4],[7,1],[7,3],[10,2],[10,1],[9,1],[9,2],[9,1],[9,1],[14,2],[14,5],[18,1],[18,2],[15,1],[15,2],[15,1],[15,1],[12,3],[12,4],[12,4],[12,5],[22,3],[22,2],[22,2],[22,1],[24,1],[24,1],[24,1],[24,1],[25,1],[25,1],[32,1],[32,1],[33,1],[33,1],[33,1],[33,1],[33,1],[33,1],[33,1],[35,1],[35,1],[35,1],[35,1],[11,1],[11,1],[11,1]],
-performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
-/* this == yyval */
-
-var $0 = $$.length - 1;
-switch (yystate) {
-case 5:
- this.$=$$[$0-1]+$$[$0]; 
-break;
-case 6:
- this.$=$$[$0]; 
-break;
-case 7:
- yy.addRelation($$[$0]); 
-break;
-case 8:
- $$[$0-1].title =  yy.cleanupLabel($$[$0]); yy.addRelation($$[$0-1]);        
-break;
-case 12:
-/*console.log($$[$0-3],JSON.stringify($$[$0-1]));*/yy.addMembers($$[$0-3],$$[$0-1]);
-break;
-case 13:
- this.$ = [$$[$0]]; 
-break;
-case 14:
- $$[$0].push($$[$0-1]);this.$=$$[$0];
-break;
-case 15:
-/*console.log('Rel found',$$[$0]);*/
-break;
-case 16:
-yy.addMembers($$[$0-1],yy.cleanupLabel($$[$0]));
-break;
-case 17:
-console.warn('Member',$$[$0]);
-break;
-case 18:
-/*console.log('sep found',$$[$0]);*/
-break;
-case 19:
- this.$ = {'id1':$$[$0-2],'id2':$$[$0], relation:$$[$0-1], relationTitle1:'none', relationTitle2:'none'}; 
-break;
-case 20:
- this.$ = {id1:$$[$0-3], id2:$$[$0], relation:$$[$0-1], relationTitle1:$$[$0-2], relationTitle2:'none'}
-break;
-case 21:
- this.$ = {id1:$$[$0-3], id2:$$[$0], relation:$$[$0-2], relationTitle1:'none', relationTitle2:$$[$0-1]}; 
-break;
-case 22:
- this.$ = {id1:$$[$0-4], id2:$$[$0], relation:$$[$0-2], relationTitle1:$$[$0-3], relationTitle2:$$[$0-1]} 
-break;
-case 23:
- this.$={type1:$$[$0-2],type2:$$[$0],lineType:$$[$0-1]}; 
-break;
-case 24:
- this.$={type1:'none',type2:$$[$0],lineType:$$[$0-1]}; 
-break;
-case 25:
- this.$={type1:$$[$0-1],type2:'none',lineType:$$[$0]}; 
-break;
-case 26:
- this.$={type1:'none',type2:'none',lineType:$$[$0]}; 
-break;
-case 27:
- this.$=yy.relationType.AGGREGATION;
-break;
-case 28:
- this.$=yy.relationType.EXTENSION;
-break;
-case 29:
- this.$=yy.relationType.COMPOSITION;
-break;
-case 30:
- this.$=yy.relationType.DEPENDENCY;
-break;
-case 31:
-this.$=yy.lineType.LINE;
-break;
-case 32:
-this.$=yy.lineType.DOTTED_LINE;
-break;
-}
-},
-table: [{3:1,4:2,5:[1,3]},{1:[3]},{1:[2,1]},{6:[1,4]},{7:5,9:6,10:10,11:14,12:7,14:8,15:9,16:$V0,20:$V1,21:$V2,45:$V3,46:$V4,47:$V5},{8:[1,18]},{6:[1,19],8:[2,3]},o($V6,[2,7],{13:[1,20]}),o($V6,[2,9]),o($V6,[2,10]),o($V6,[2,15],{22:21,24:24,25:25,13:[1,23],23:[1,22],26:$V7,27:$V8,28:$V9,29:$Va,30:$Vb,31:$Vc}),{10:32,11:14,45:$V3,46:$V4,47:$V5},o($V6,[2,17]),o($V6,[2,18]),o($Vd,[2,6],{11:14,10:33,45:$V3,46:$V4,47:$V5}),o($Ve,[2,46]),o($Ve,[2,47]),o($Ve,[2,48]),{1:[2,2]},{7:34,9:6,10:10,11:14,12:7,14:8,15:9,16:$V0,20:$V1,21:$V2,45:$V3,46:$V4,47:$V5},o($V6,[2,8]),{10:35,11:14,23:[1,36],45:$V3,46:$V4,47:$V5},{22:37,24:24,25:25,26:$V7,27:$V8,28:$V9,29:$Va,30:$Vb,31:$Vc},o($V6,[2,16]),{25:38,30:$Vb,31:$Vc},o($Vf,[2,26],{24:39,26:$V7,27:$V8,28:$V9,29:$Va}),o($Vg,[2,27]),o($Vg,[2,28]),o($Vg,[2,29]),o($Vg,[2,30]),o($Vh,[2,31]),o($Vh,[2,32]),o($V6,[2,11],{17:[1,40]}),o($Vd,[2,5]),{8:[2,4]},o($Vi,[2,19]),{10:41,11:14,45:$V3,46:$V4,47:$V5},{10:42,11:14,23:[1,43],45:$V3,46:$V4,47:$V5},o($Vf,[2,25],{24:44,26:$V7,27:$V8,28:$V9,29:$Va}),o($Vf,[2,24]),{18:45,20:$Vj},o($Vi,[2,21]),o($Vi,[2,20]),{10:47,11:14,45:$V3,46:$V4,47:$V5},o($Vf,[2,23]),{19:[1,48]},{18:49,19:[2,13],20:$Vj},o($Vi,[2,22]),o($V6,[2,12]),{19:[2,14]}],
-defaultActions: {2:[2,1],18:[2,2],34:[2,4],49:[2,14]},
-parseError: function parseError(str, hash) {
-    if (hash.recoverable) {
-        this.trace(str);
-    } else {
-        var error = new Error(str);
-        error.hash = hash;
-        throw error;
-    }
-},
-parse: function parse(input) {
-    var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
-    var args = lstack.slice.call(arguments, 1);
-    var lexer = Object.create(this.lexer);
-    var sharedState = { yy: {} };
-    for (var k in this.yy) {
-        if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
-            sharedState.yy[k] = this.yy[k];
-        }
-    }
-    lexer.setInput(input, sharedState.yy);
-    sharedState.yy.lexer = lexer;
-    sharedState.yy.parser = this;
-    if (typeof lexer.yylloc == 'undefined') {
-        lexer.yylloc = {};
-    }
-    var yyloc = lexer.yylloc;
-    lstack.push(yyloc);
-    var ranges = lexer.options && lexer.options.ranges;
-    if (typeof sharedState.yy.parseError === 'function') {
-        this.parseError = sharedState.yy.parseError;
-    } else {
-        this.parseError = Object.getPrototypeOf(this).parseError;
-    }
-    function popStack(n) {
-        stack.length = stack.length - 2 * n;
-        vstack.length = vstack.length - n;
-        lstack.length = lstack.length - n;
-    }
-            function lex() {
-            var token;
-            token = tstack.pop() || lexer.lex() || EOF;
-            if (typeof token !== 'number') {
-                if (token instanceof Array) {
-                    tstack = token;
-                    token = tstack.pop();
-                }
-                token = self.symbols_[token] || token;
-            }
-            return token;
-        }
-    var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
-    while (true) {
-        state = stack[stack.length - 1];
-        if (this.defaultActions[state]) {
-            action = this.defaultActions[state];
-        } else {
-            if (symbol === null || typeof symbol == 'undefined') {
-                symbol = lex();
-            }
-            action = table[state] && table[state][symbol];
-        }
-        if (typeof action === 'undefined' || !action.length || !action[0]) {
-            var errStr = '';
-            expected = [];
-            for (p in table[state]) {
-                if (this.terminals_[p] && p > TERROR) {
-                    expected.push('\'' + this.terminals_[p] + '\'');
-                }
-            }
-            if (lexer.showPosition) {
-                errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
-            } else {
-                errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
-            }
-            this.parseError(errStr, {
-                text: lexer.match,
-                token: this.terminals_[symbol] || symbol,
-                line: lexer.yylineno,
-                loc: yyloc,
-                expected: expected
-            });
-        }
-        if (action[0] instanceof Array && action.length > 1) {
-            throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
-        }
-        switch (action[0]) {
-        case 1:
-            stack.push(symbol);
-            vstack.push(lexer.yytext);
-            lstack.push(lexer.yylloc);
-            stack.push(action[1]);
-            symbol = null;
-            if (!preErrorSymbol) {
-                yyleng = lexer.yyleng;
-                yytext = lexer.yytext;
-                yylineno = lexer.yylineno;
-                yyloc = lexer.yylloc;
-                if (recovering > 0) {
-                    recovering--;
-                }
-            } else {
-                symbol = preErrorSymbol;
-                preErrorSymbol = null;
-            }
-            break;
-        case 2:
-            len = this.productions_[action[1]][1];
-            yyval.$ = vstack[vstack.length - len];
-            yyval._$ = {
-                first_line: lstack[lstack.length - (len || 1)].first_line,
-                last_line: lstack[lstack.length - 1].last_line,
-                first_column: lstack[lstack.length - (len || 1)].first_column,
-                last_column: lstack[lstack.length - 1].last_column
-            };
-            if (ranges) {
-                yyval._$.range = [
-                    lstack[lstack.length - (len || 1)].range[0],
-                    lstack[lstack.length - 1].range[1]
-                ];
-            }
-            r = this.performAction.apply(yyval, [
-                yytext,
-                yyleng,
-                yylineno,
-                sharedState.yy,
-                action[1],
-                vstack,
-                lstack
-            ].concat(args));
-            if (typeof r !== 'undefined') {
-                return r;
-            }
-            if (len) {
-                stack = stack.slice(0, -1 * len * 2);
-                vstack = vstack.slice(0, -1 * len);
-                lstack = lstack.slice(0, -1 * len);
-            }
-            stack.push(this.productions_[action[1]][0]);
-            vstack.push(yyval.$);
-            lstack.push(yyval._$);
-            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
-            stack.push(newState);
-            break;
-        case 3:
-            return true;
-        }
-    }
-    return true;
-}};
-
-/* generated by jison-lex 0.3.4 */
-var lexer = (function(){
-var lexer = ({
-
-EOF:1,
-
-parseError:function parseError(str, hash) {
-        if (this.yy.parser) {
-            this.yy.parser.parseError(str, hash);
-        } else {
-            throw new Error(str);
-        }
-    },
-
-// resets the lexer, sets new input
-setInput:function (input, yy) {
-        this.yy = yy || this.yy || {};
-        this._input = input;
-        this._more = this._backtrack = this.done = false;
-        this.yylineno = this.yyleng = 0;
-        this.yytext = this.matched = this.match = '';
-        this.conditionStack = ['INITIAL'];
-        this.yylloc = {
-            first_line: 1,
-            first_column: 0,
-            last_line: 1,
-            last_column: 0
-        };
-        if (this.options.ranges) {
-            this.yylloc.range = [0,0];
-        }
-        this.offset = 0;
-        return this;
-    },
-
-// consumes and returns one char from the input
-input:function () {
-        var ch = this._input[0];
-        this.yytext += ch;
-        this.yyleng++;
-        this.offset++;
-        this.match += ch;
-        this.matched += ch;
-        var lines = ch.match(/(?:\r\n?|\n).*/g);
-        if (lines) {
-            this.yylineno++;
-            this.yylloc.last_line++;
-        } else {
-            this.yylloc.last_column++;
-        }
-        if (this.options.ranges) {
-            this.yylloc.range[1]++;
-        }
-
-        this._input = this._input.slice(1);
-        return ch;
-    },
-
-// unshifts one char (or a string) into the input
-unput:function (ch) {
-        var len = ch.length;
-        var lines = ch.split(/(?:\r\n?|\n)/g);
-
-        this._input = ch + this._input;
-        this.yytext = this.yytext.substr(0, this.yytext.length - len);
-        //this.yyleng -= len;
-        this.offset -= len;
-        var oldLines = this.match.split(/(?:\r\n?|\n)/g);
-        this.match = this.match.substr(0, this.match.length - 1);
-        this.matched = this.matched.substr(0, this.matched.length - 1);
-
-        if (lines.length - 1) {
-            this.yylineno -= lines.length - 1;
-        }
-        var r = this.yylloc.range;
-
-        this.yylloc = {
-            first_line: this.yylloc.first_line,
-            last_line: this.yylineno + 1,
-            first_column: this.yylloc.first_column,
-            last_column: lines ?
-                (lines.length === oldLines.length ? this.yylloc.first_column : 0)
-                 + oldLines[oldLines.length - lines.length].length - lines[0].length :
-              this.yylloc.first_column - len
-        };
-
-        if (this.options.ranges) {
-            this.yylloc.range = [r[0], r[0] + this.yyleng - len];
-        }
-        this.yyleng = this.yytext.length;
-        return this;
-    },
-
-// When called from action, caches matched text and appends it on next action
-more:function () {
-        this._more = true;
-        return this;
-    },
-
-// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
-reject:function () {
-        if (this.options.backtrack_lexer) {
-            this._backtrack = true;
-        } else {
-            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
-                text: "",
-                token: null,
-                line: this.yylineno
-            });
-
-        }
-        return this;
-    },
-
-// retain first n characters of the match
-less:function (n) {
-        this.unput(this.match.slice(n));
-    },
-
-// displays already matched input, i.e. for error messages
-pastInput:function () {
-        var past = this.matched.substr(0, this.matched.length - this.match.length);
-        return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
-    },
-
-// displays upcoming input, i.e. for error messages
-upcomingInput:function () {
-        var next = this.match;
-        if (next.length < 20) {
-            next += this._input.substr(0, 20-next.length);
-        }
-        return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
-    },
-
-// displays the character position where the lexing error occurred, i.e. for error messages
-showPosition:function () {
-        var pre = this.pastInput();
-        var c = new Array(pre.length + 1).join("-");
-        return pre + this.upcomingInput() + "\n" + c + "^";
-    },
-
-// test the lexed token: return FALSE when not a match, otherwise return token
-test_match:function (match, indexed_rule) {
-        var token,
-            lines,
-            backup;
-
-        if (this.options.backtrack_lexer) {
-            // save context
-            backup = {
-                yylineno: this.yylineno,
-                yylloc: {
-                    first_line: this.yylloc.first_line,
-                    last_line: this.last_line,
-                    first_column: this.yylloc.first_column,
-                    last_column: this.yylloc.last_column
-                },
-                yytext: this.yytext,
-                match: this.match,
-                matches: this.matches,
-                matched: this.matched,
-                yyleng: this.yyleng,
-                offset: this.offset,
-                _more: this._more,
-                _input: this._input,
-                yy: this.yy,
-                conditionStack: this.conditionStack.slice(0),
-                done: this.done
-            };
-            if (this.options.ranges) {
-                backup.yylloc.range = this.yylloc.range.slice(0);
-            }
-        }
-
-        lines = match[0].match(/(?:\r\n?|\n).*/g);
-        if (lines) {
-            this.yylineno += lines.length;
-        }
-        this.yylloc = {
-            first_line: this.yylloc.last_line,
-            last_line: this.yylineno + 1,
-            first_column: this.yylloc.last_column,
-            last_column: lines ?
-                         lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
-                         this.yylloc.last_column + match[0].length
-        };
-        this.yytext += match[0];
-        this.match += match[0];
-        this.matches = match;
-        this.yyleng = this.yytext.length;
-        if (this.options.ranges) {
-            this.yylloc.range = [this.offset, this.offset += this.yyleng];
-        }
-        this._more = false;
-        this._backtrack = false;
-        this._input = this._input.slice(match[0].length);
-        this.matched += match[0];
-        token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
-        if (this.done && this._input) {
-            this.done = false;
-        }
-        if (token) {
-            return token;
-        } else if (this._backtrack) {
-            // recover context
-            for (var k in backup) {
-                this[k] = backup[k];
-            }
-            return false; // rule action called reject() implying the next rule should be tested instead.
-        }
-        return false;
-    },
-
-// return next match in input
-next:function () {
-        if (this.done) {
-            return this.EOF;
-        }
-        if (!this._input) {
-            this.done = true;
-        }
-
-        var token,
-            match,
-            tempMatch,
-            index;
-        if (!this._more) {
-            this.yytext = '';
-            this.match = '';
-        }
-        var rules = this._currentRules();
-        for (var i = 0; i < rules.length; i++) {
-            tempMatch = this._input.match(this.rules[rules[i]]);
-            if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
-                match = tempMatch;
-                index = i;
-                if (this.options.backtrack_lexer) {
-                    token = this.test_match(tempMatch, rules[i]);
-                    if (token !== false) {
-                        return token;
-                    } else if (this._backtrack) {
-                        match = false;
-                        continue; // rule action called reject() implying a rule MISmatch.
-                    } else {
-                        // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
-                        return false;
-                    }
-                } else if (!this.options.flex) {
-                    break;
-                }
-            }
-        }
-        if (match) {
-            token = this.test_match(match, rules[index]);
-            if (token !== false) {
-                return token;
-            }
-            // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
-            return false;
-        }
-        if (this._input === "") {
-            return this.EOF;
-        } else {
-            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
-                text: "",
-                token: null,
-                line: this.yylineno
-            });
-        }
-    },
-
-// return next match that has a token
-lex:function lex() {
-        var r = this.next();
-        if (r) {
-            return r;
-        } else {
-            return this.lex();
-        }
-    },
-
-// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
-begin:function begin(condition) {
-        this.conditionStack.push(condition);
-    },
-
-// pop the previously active lexer condition state off the condition stack
-popState:function popState() {
-        var n = this.conditionStack.length - 1;
-        if (n > 0) {
-            return this.conditionStack.pop();
-        } else {
-            return this.conditionStack[0];
-        }
-    },
-
-// produce the lexer rule set which is active for the currently active lexer condition state
-_currentRules:function _currentRules() {
-        if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
-            return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
-        } else {
-            return this.conditions["INITIAL"].rules;
-        }
-    },
-
-// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
-topState:function topState(n) {
-        n = this.conditionStack.length - 1 - Math.abs(n || 0);
-        if (n >= 0) {
-            return this.conditionStack[n];
-        } else {
-            return "INITIAL";
-        }
-    },
-
-// alias for begin(condition)
-pushState:function pushState(condition) {
-        this.begin(condition);
-    },
-
-// return the number of states currently on the stack
-stateStackSize:function stateStackSize() {
-        return this.conditionStack.length;
-    },
-options: {},
-performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
-var YYSTATE=YY_START;
-switch($avoiding_name_collisions) {
-case 0:/* do nothing */
-break;
-case 1:return 6;
-break;
-case 2:/* skip whitespace */
-break;
-case 3:return 5;
-break;
-case 4: this.begin("struct"); /*console.log('Starting struct');*/return 17;
-break;
-case 5: /*console.log('Ending struct');*/this.popState(); return 19;
-break;
-case 6:/* nothing */
-break;
-case 7: /*console.log('lex-member: ' + yy_.yytext);*/  return "MEMBER";
-break;
-case 8:return 16;
-break;
-case 9:this.begin("string");
-break;
-case 10:this.popState();
-break;
-case 11:return "STR";
-break;
-case 12:return 27;
-break;
-case 13:return 27;
-break;
-case 14:return 29;
-break;
-case 15:return 29;
-break;
-case 16:return 28;
-break;
-case 17:return 26;
-break;
-case 18:return 30;
-break;
-case 19:return 31;
-break;
-case 20:return 13;
-break;
-case 21:return 43;
-break;
-case 22:return 'DOT';
-break;
-case 23:return 'PLUS';
-break;
-case 24:return 40;
-break;
-case 25:return 'EQUALS';
-break;
-case 26:return 'EQUALS';
-break;
-case 27:return 47;
-break;
-case 28:return 'PUNCTUATION';
-break;
-case 29:return 46;
-break;
-case 30:return 45;
-break;
-case 31:return 42;
-break;
-case 32:return 8;
-break;
-}
-},
-rules: [/^(?:%%[^\n]*)/,/^(?:\n+)/,/^(?:\s+)/,/^(?:classDiagram\b)/,/^(?:[\{])/,/^(?:\})/,/^(?:[\n])/,/^(?:[^\{\}\n]*)/,/^(?:class\b)/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:--)/,/^(?:\.\.)/,/^(?::[^#\n;]+)/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:[A-Za-z]+)/,/^(?:[!"#$%&'*+,-.`?\\_\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:$)/],
-conditions: {"string":{"rules":[10,11],"inclusive":false},"struct":{"rules":[5,6,7],"inclusive":false},"INITIAL":{"rules":[0,1,2,3,4,8,9,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"inclusive":true}}
-});
-return lexer;
-})();
-parser.lexer = lexer;
-function Parser () {
-  this.yy = {};
-}
-Parser.prototype = parser;parser.Parser = Parser;
-return new Parser;
-})();
-
-
-if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
-exports.parser = parser;
-exports.Parser = parser.Parser;
-exports.parse = function () { return parser.parse.apply(parser, arguments); };
-exports.main = function commonjsMain(args) {
-    if (!args[1]) {
-        console.log('Usage: '+args[0]+' FILE');
-        process.exit(1);
-    }
-    var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
-    return exports.parser.parse(source);
-};
-if (typeof module !== 'undefined' && require.main === module) {
-  exports.main(process.argv.slice(1));
-}
-}
\ No newline at end of file
diff --git a/_submodules/mermaid/src/diagrams/flowchart/flowDb.js b/_submodules/mermaid/src/diagrams/flowchart/flowDb.js
deleted file mode 100644
index 275e9c39df5c52839455f0adff0af0c4f131115f..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/flowchart/flowDb.js
+++ /dev/null
@@ -1,423 +0,0 @@
-import * as d3 from 'd3'
-
-import { logger } from '../../logger'
-import utils from '../../utils'
-
-let vertices = {}
-let edges = []
-let classes = []
-let subGraphs = []
-let tooltips = {}
-let subCount = 0
-let direction
-// Functions to be run after graph rendering
-let funs = []
-/**
- * Function called by parser when a node definition has been found
- * @param id
- * @param text
- * @param type
- * @param style
- */
-export const addVertex = function (id, text, type, style) {
-  let txt
-
-  if (typeof id === 'undefined') {
-    return
-  }
-  if (id.trim().length === 0) {
-    return
-  }
-
-  if (typeof vertices[id] === 'undefined') {
-    vertices[id] = { id: id, styles: [], classes: [] }
-  }
-  if (typeof text !== 'undefined') {
-    txt = text.trim()
-
-    // strip quotes if string starts and exnds with a quote
-    if (txt[0] === '"' && txt[txt.length - 1] === '"') {
-      txt = txt.substring(1, txt.length - 1)
-    }
-
-    vertices[id].text = txt
-  }
-  if (typeof type !== 'undefined') {
-    vertices[id].type = type
-  }
-  if (typeof type !== 'undefined') {
-    vertices[id].type = type
-  }
-  if (typeof style !== 'undefined') {
-    if (style !== null) {
-      style.forEach(function (s) {
-        vertices[id].styles.push(s)
-      })
-    }
-  }
-}
-
-/**
- * Function called by parser when a link/edge definition has been found
- * @param start
- * @param end
- * @param type
- * @param linktext
- */
-export const addLink = function (start, end, type, linktext) {
-  logger.info('Got edge...', start, end)
-  const edge = { start: start, end: end, type: undefined, text: '' }
-  linktext = type.text
-
-  if (typeof linktext !== 'undefined') {
-    edge.text = linktext.trim()
-
-    // strip quotes if string starts and exnds with a quote
-    if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') {
-      edge.text = edge.text.substring(1, edge.text.length - 1)
-    }
-  }
-
-  if (typeof type !== 'undefined') {
-    edge.type = type.type
-    edge.stroke = type.stroke
-  }
-  edges.push(edge)
-}
-
-/**
- * Updates a link's line interpolation algorithm
- * @param pos
- * @param interpolate
- */
-export const updateLinkInterpolate = function (pos, interp) {
-  if (pos === 'default') {
-    edges.defaultInterpolate = interp
-  } else {
-    edges[pos].interpolate = interp
-  }
-}
-
-/**
- * Updates a link with a style
- * @param pos
- * @param style
- */
-export const updateLink = function (pos, style) {
-  if (pos === 'default') {
-    edges.defaultStyle = style
-  } else {
-    if (utils.isSubstringInArray('fill', style) === -1) {
-      style.push('fill:none')
-    }
-    edges[pos].style = style
-  }
-}
-
-export const addClass = function (id, style) {
-  if (typeof classes[id] === 'undefined') {
-    classes[id] = { id: id, styles: [] }
-  }
-
-  if (typeof style !== 'undefined') {
-    if (style !== null) {
-      style.forEach(function (s) {
-        classes[id].styles.push(s)
-      })
-    }
-  }
-}
-
-/**
- * Called by parser when a graph definition is found, stores the direction of the chart.
- * @param dir
- */
-export const setDirection = function (dir) {
-  direction = dir
-}
-
-/**
- * Called by parser when a graph definition is found, stores the direction of the chart.
- * @param dir
- */
-export const setClass = function (id, className) {
-  if (id.indexOf(',') > 0) {
-    id.split(',').forEach(function (id2) {
-      if (typeof vertices[id2] !== 'undefined') {
-        vertices[id2].classes.push(className)
-      }
-    })
-  } else {
-    if (typeof vertices[id] !== 'undefined') {
-      vertices[id].classes.push(className)
-    }
-  }
-}
-
-const setTooltip = function (id, tooltip) {
-  if (typeof tooltip !== 'undefined') {
-    tooltips[id] = tooltip
-  }
-}
-
-const setClickFun = function (id, functionName) {
-  if (typeof functionName === 'undefined') {
-    return
-  }
-  if (typeof vertices[id] !== 'undefined') {
-    funs.push(function (element) {
-      const elem = d3.select(element).select(`[id="${id}"]`)
-      if (elem !== null) {
-        elem.on('click', function () {
-          window[functionName](id)
-        })
-      }
-    })
-  }
-}
-
-const setLink = function (id, linkStr) {
-  if (typeof linkStr === 'undefined') {
-    return
-  }
-  if (typeof vertices[id] !== 'undefined') {
-    funs.push(function (element) {
-      const elem = d3.select(element).select(`[id="${id}"]`)
-      if (elem !== null) {
-        elem.on('click', function () {
-          window.open(linkStr, 'newTab')
-        })
-      }
-    })
-  }
-}
-export const getTooltip = function (id) {
-  return tooltips[id]
-}
-
-/**
- * Called by parser when a graph definition is found, stores the direction of the chart.
- * @param dir
- */
-export const setClickEvent = function (id, functionName, link, tooltip) {
-  if (id.indexOf(',') > 0) {
-    id.split(',').forEach(function (id2) {
-      setTooltip(id2, tooltip)
-      setClickFun(id2, functionName)
-      setLink(id2, link)
-      setClass(id, 'clickable')
-    })
-  } else {
-    setTooltip(id, tooltip)
-    setClickFun(id, functionName)
-    setLink(id, link)
-    setClass(id, 'clickable')
-  }
-}
-
-export const bindFunctions = function (element) {
-  funs.forEach(function (fun) {
-    fun(element)
-  })
-}
-export const getDirection = function () {
-  return direction
-}
-/**
- * Retrieval function for fetching the found nodes after parsing has completed.
- * @returns {{}|*|vertices}
- */
-export const getVertices = function () {
-  return vertices
-}
-
-/**
- * Retrieval function for fetching the found links after parsing has completed.
- * @returns {{}|*|edges}
- */
-export const getEdges = function () {
-  return edges
-}
-
-/**
- * Retrieval function for fetching the found class definitions after parsing has completed.
- * @returns {{}|*|classes}
- */
-export const getClasses = function () {
-  return classes
-}
-
-const setupToolTips = function (element) {
-  let tooltipElem = d3.select('.mermaidTooltip')
-  if ((tooltipElem._groups || tooltipElem)[0][0] === null) {
-    tooltipElem = d3.select('body')
-      .append('div')
-      .attr('class', 'mermaidTooltip')
-      .style('opacity', 0)
-  }
-
-  const svg = d3.select(element).select('svg')
-
-  const nodes = svg.selectAll('g.node')
-  nodes
-    .on('mouseover', function () {
-      const el = d3.select(this)
-      const title = el.attr('title')
-      // Dont try to draw a tooltip if no data is provided
-      if (title === null) {
-        return
-      }
-      const rect = this.getBoundingClientRect()
-
-      tooltipElem.transition()
-        .duration(200)
-        .style('opacity', '.9')
-      tooltipElem.html(el.attr('title'))
-        .style('left', (rect.left + (rect.right - rect.left) / 2) + 'px')
-        .style('top', (rect.top - 14 + document.body.scrollTop) + 'px')
-      el.classed('hover', true)
-    })
-    .on('mouseout', function () {
-      tooltipElem.transition()
-        .duration(500)
-        .style('opacity', 0)
-      const el = d3.select(this)
-      el.classed('hover', false)
-    })
-}
-funs.push(setupToolTips)
-
-/**
- * Clears the internal graph db so that a new graph can be parsed.
- */
-export const clear = function () {
-  vertices = {}
-  classes = {}
-  edges = []
-  funs = []
-  funs.push(setupToolTips)
-  subGraphs = []
-  subCount = 0
-  tooltips = []
-}
-/**
- *
- * @returns {string}
- */
-export const defaultStyle = function () {
-  return 'fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;'
-}
-
-/**
- * Clears the internal graph db so that a new graph can be parsed.
- */
-export const addSubGraph = function (list, title) {
-  function uniq (a) {
-    const prims = { 'boolean': {}, 'number': {}, 'string': {} }
-    const objs = []
-
-    return a.filter(function (item) {
-      const type = typeof item
-      if (item.trim() === '') {
-        return false
-      }
-      if (type in prims) { return prims[type].hasOwnProperty(item) ? false : (prims[type][item] = true) } else { return objs.indexOf(item) >= 0 ? false : objs.push(item) }
-    })
-  }
-
-  let nodeList = []
-
-  nodeList = uniq(nodeList.concat.apply(nodeList, list))
-
-  const subGraph = { id: 'subGraph' + subCount, nodes: nodeList, title: title.trim() }
-  subGraphs.push(subGraph)
-  subCount = subCount + 1
-  return subGraph.id
-}
-
-const getPosForId = function (id) {
-  for (let i = 0; i < subGraphs.length; i++) {
-    if (subGraphs[i].id === id) {
-      return i
-    }
-  }
-  return -1
-}
-let secCount = -1
-const posCrossRef = []
-const indexNodes2 = function (id, pos) {
-  const nodes = subGraphs[pos].nodes
-  secCount = secCount + 1
-  if (secCount > 2000) {
-    return
-  }
-  posCrossRef[secCount] = pos
-  // Check if match
-  if (subGraphs[pos].id === id) {
-    return {
-      result: true,
-      count: 0
-    }
-  }
-
-  let count = 0
-  let posCount = 1
-  while (count < nodes.length) {
-    const childPos = getPosForId(nodes[count])
-    // Ignore regular nodes (pos will be -1)
-    if (childPos >= 0) {
-      const res = indexNodes2(id, childPos)
-      if (res.result) {
-        return {
-          result: true,
-          count: posCount + res.count
-        }
-      } else {
-        posCount = posCount + res.count
-      }
-    }
-    count = count + 1
-  }
-
-  return {
-    result: false,
-    count: posCount
-  }
-}
-
-export const getDepthFirstPos = function (pos) {
-  return posCrossRef[pos]
-}
-export const indexNodes = function () {
-  secCount = -1
-  if (subGraphs.length > 0) {
-    indexNodes2('none', subGraphs.length - 1, 0)
-  }
-}
-
-export const getSubGraphs = function () {
-  return subGraphs
-}
-
-export default {
-  addVertex,
-  addLink,
-  updateLinkInterpolate,
-  updateLink,
-  addClass,
-  setDirection,
-  setClass,
-  getTooltip,
-  setClickEvent,
-  bindFunctions,
-  getDirection,
-  getVertices,
-  getEdges,
-  getClasses,
-  clear,
-  defaultStyle,
-  addSubGraph,
-  getDepthFirstPos,
-  indexNodes,
-  getSubGraphs
-}
diff --git a/_submodules/mermaid/src/diagrams/flowchart/flowRenderer.js b/_submodules/mermaid/src/diagrams/flowchart/flowRenderer.js
deleted file mode 100644
index 2375265055373bbbc2a609e7717fe0a3eadd8069..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/flowchart/flowRenderer.js
+++ /dev/null
@@ -1,473 +0,0 @@
-import graphlib from 'graphlibrary'
-import * as d3 from 'd3'
-
-import flowDb from './flowDb'
-import flow from './parser/flow'
-import dagreD3 from 'dagre-d3-renderer'
-import { logger } from '../../logger'
-import { interpolateToCurve } from '../../utils'
-
-const conf = {
-}
-export const setConf = function (cnf) {
-  const keys = Object.keys(cnf)
-  for (let i = 0; i < keys.length; i++) {
-    conf[keys[i]] = cnf[keys[i]]
-  }
-}
-
-/**
- * Function that adds the vertices found in the graph definition to the graph to be rendered.
- * @param vert Object containing the vertices.
- * @param g The graph that is to be drawn.
- */
-export const addVertices = function (vert, g) {
-  const keys = Object.keys(vert)
-
-  const styleFromStyleArr = function (styleStr, arr) {
-    // Create a compound style definition from the style definitions found for the node in the graph definition
-    for (let i = 0; i < arr.length; i++) {
-      if (typeof arr[i] !== 'undefined') {
-        styleStr = styleStr + arr[i] + ';'
-      }
-    }
-
-    return styleStr
-  }
-
-  // Iterate through each item in the vertice object (containing all the vertices found) in the graph definition
-  keys.forEach(function (id) {
-    const vertice = vert[id]
-    let verticeText
-
-    /**
-     * Variable for storing the classes for the vertice
-     * @type {string}
-     */
-    let classStr = ''
-    if (vertice.classes.length > 0) {
-      classStr = vertice.classes.join(' ')
-    }
-
-    /**
-     * Variable for storing the extracted style for the vertice
-     * @type {string}
-     */
-    let style = ''
-    // Create a compound style definition from the style definitions found for the node in the graph definition
-    style = styleFromStyleArr(style, vertice.styles)
-
-    // Use vertice id as text in the box if no text is provided by the graph definition
-    if (typeof vertice.text === 'undefined') {
-      verticeText = vertice.id
-    } else {
-      verticeText = vertice.text
-    }
-
-    let labelTypeStr = ''
-    if (conf.htmlLabels) {
-      labelTypeStr = 'html'
-      verticeText = verticeText.replace(/fa:fa[\w-]+/g, function (s) {
-        return '<i class="fa ' + s.substring(3) + '"></i>'
-      })
-    } else {
-      const svgLabel = document.createElementNS('http://www.w3.org/2000/svg', 'text')
-
-      const rows = verticeText.split(/<br>/)
-
-      for (let j = 0; j < rows.length; j++) {
-        const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan')
-        tspan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve')
-        tspan.setAttribute('dy', '1em')
-        tspan.setAttribute('x', '1')
-        tspan.textContent = rows[j]
-        svgLabel.appendChild(tspan)
-      }
-
-      labelTypeStr = 'svg'
-      verticeText = svgLabel
-    }
-
-    let radious = 0
-    let _shape = ''
-    // Set the shape based parameters
-    switch (vertice.type) {
-      case 'round':
-        radious = 5
-        _shape = 'rect'
-        break
-      case 'square':
-        _shape = 'rect'
-        break
-      case 'diamond':
-        _shape = 'question'
-        break
-      case 'odd':
-        _shape = 'rect_left_inv_arrow'
-        break
-      case 'odd_right':
-        _shape = 'rect_left_inv_arrow'
-        break
-      case 'circle':
-        _shape = 'circle'
-        break
-      case 'ellipse':
-        _shape = 'ellipse'
-        break
-      case 'group':
-        _shape = 'rect'
-        // Need to create a text node if using svg labels, see #367
-        verticeText = conf.htmlLabels ? '' : document.createElementNS('http://www.w3.org/2000/svg', 'text')
-        break
-      default:
-        _shape = 'rect'
-    }
-    // Add the node
-    g.setNode(vertice.id, { labelType: labelTypeStr, shape: _shape, label: verticeText, rx: radious, ry: radious, 'class': classStr, style: style, id: vertice.id })
-  })
-}
-
-/**
- * Add edges to graph based on parsed graph defninition
- * @param {Object} edges The edges to add to the graph
- * @param {Object} g The graph object
- */
-export const addEdges = function (edges, g) {
-  let cnt = 0
-
-  let defaultStyle
-  if (typeof edges.defaultStyle !== 'undefined') {
-    defaultStyle = edges.defaultStyle.toString().replace(/,/g, ';')
-  }
-
-  edges.forEach(function (edge) {
-    cnt++
-    const edgeData = {}
-
-    // Set link type for rendering
-    if (edge.type === 'arrow_open') {
-      edgeData.arrowhead = 'none'
-    } else {
-      edgeData.arrowhead = 'normal'
-    }
-
-    let style = ''
-    if (typeof edge.style !== 'undefined') {
-      edge.style.forEach(function (s) {
-        style = style + s + ';'
-      })
-    } else {
-      switch (edge.stroke) {
-        case 'normal':
-          style = 'fill:none'
-          if (typeof defaultStyle !== 'undefined') {
-            style = defaultStyle
-          }
-          break
-        case 'dotted':
-          style = 'stroke: #333; fill:none;stroke-width:2px;stroke-dasharray:3;'
-          break
-        case 'thick':
-          style = 'stroke: #333; stroke-width: 3.5px;fill:none'
-          break
-      }
-    }
-    edgeData.style = style
-
-    if (typeof edge.interpolate !== 'undefined') {
-      edgeData.curve = interpolateToCurve(edge.interpolate, d3.curveLinear)
-    } else if (typeof edges.defaultInterpolate !== 'undefined') {
-      edgeData.curve = interpolateToCurve(edges.defaultInterpolate, d3.curveLinear)
-    } else {
-      edgeData.curve = interpolateToCurve(conf.curve, d3.curveLinear)
-    }
-
-    if (typeof edge.text === 'undefined') {
-      if (typeof edge.style !== 'undefined') {
-        edgeData.arrowheadStyle = 'fill: #333'
-      }
-    } else {
-      edgeData.arrowheadStyle = 'fill: #333'
-      if (typeof edge.style === 'undefined') {
-        edgeData.labelpos = 'c'
-        if (conf.htmlLabels) {
-          edgeData.labelType = 'html'
-          edgeData.label = '<span class="edgeLabel">' + edge.text + '</span>'
-        } else {
-          edgeData.labelType = 'text'
-          edgeData.style = 'stroke: #333; stroke-width: 1.5px;fill:none'
-          edgeData.label = edge.text.replace(/<br>/g, '\n')
-        }
-      } else {
-        edgeData.label = edge.text.replace(/<br>/g, '\n')
-      }
-    }
-    // Add the edge to the graph
-    g.setEdge(edge.start, edge.end, edgeData, cnt)
-  })
-}
-
-/**
- * Returns the all the styles from classDef statements in the graph definition.
- * @returns {object} classDef styles
- */
-export const getClasses = function (text) {
-  flowDb.clear()
-  const parser = flow.parser
-  parser.yy = flowDb
-
-  // Parse the graph definition
-  parser.parse(text)
-  return flowDb.getClasses()
-}
-
-/**
- * Draws a flowchart in the tag with id: id based on the graph definition in text.
- * @param text
- * @param id
- */
-export const draw = function (text, id) {
-  logger.debug('Drawing flowchart')
-  flowDb.clear()
-  const parser = flow.parser
-  parser.yy = flowDb
-
-  // Parse the graph definition
-  try {
-    parser.parse(text)
-  } catch (err) {
-    logger.debug('Parsing failed')
-  }
-
-  // Fetch the default direction, use TD if none was found
-  let dir = flowDb.getDirection()
-  if (typeof dir === 'undefined') {
-    dir = 'TD'
-  }
-
-  // Create the input mermaid.graph
-  const g = new graphlib.Graph({
-    multigraph: true,
-    compound: true
-  })
-    .setGraph({
-      rankdir: dir,
-      marginx: 20,
-      marginy: 20
-
-    })
-    .setDefaultEdgeLabel(function () {
-      return {}
-    })
-
-  let subG
-  const subGraphs = flowDb.getSubGraphs()
-  for (let i = subGraphs.length - 1; i >= 0; i--) {
-    subG = subGraphs[i]
-    flowDb.addVertex(subG.id, subG.title, 'group', undefined)
-  }
-
-  // Fetch the verices/nodes and edges/links from the parsed graph definition
-  const vert = flowDb.getVertices()
-
-  const edges = flowDb.getEdges()
-
-  let i = 0
-  for (i = subGraphs.length - 1; i >= 0; i--) {
-    subG = subGraphs[i]
-
-    d3.selectAll('cluster').append('text')
-
-    for (let j = 0; j < subG.nodes.length; j++) {
-      g.setParent(subG.nodes[j], subG.id)
-    }
-  }
-  addVertices(vert, g)
-  addEdges(edges, g)
-
-  // Create the renderer
-  const Render = dagreD3.render
-  const render = new Render()
-
-  // Add custom shape for rhombus type of boc (decision)
-  render.shapes().question = function (parent, bbox, node) {
-    const w = bbox.width
-    const h = bbox.height
-    const s = (w + h) * 0.9
-    const points = [
-      { x: s / 2, y: 0 },
-      { x: s, y: -s / 2 },
-      { x: s / 2, y: -s },
-      { x: 0, y: -s / 2 }
-    ]
-    const shapeSvg = parent.insert('polygon', ':first-child')
-      .attr('points', points.map(function (d) {
-        return d.x + ',' + d.y
-      }).join(' '))
-      .attr('rx', 5)
-      .attr('ry', 5)
-      .attr('transform', 'translate(' + (-s / 2) + ',' + (s * 2 / 4) + ')')
-    node.intersect = function (point) {
-      return dagreD3.intersect.polygon(node, points, point)
-    }
-    return shapeSvg
-  }
-
-  // Add custom shape for box with inverted arrow on left side
-  render.shapes().rect_left_inv_arrow = function (parent, bbox, node) {
-    const w = bbox.width
-    const h = bbox.height
-    const points = [
-      { x: -h / 2, y: 0 },
-      { x: w, y: 0 },
-      { x: w, y: -h },
-      { x: -h / 2, y: -h },
-      { x: 0, y: -h / 2 }
-    ]
-    const shapeSvg = parent.insert('polygon', ':first-child')
-      .attr('points', points.map(function (d) {
-        return d.x + ',' + d.y
-      }).join(' '))
-      .attr('transform', 'translate(' + (-w / 2) + ',' + (h * 2 / 4) + ')')
-    node.intersect = function (point) {
-      return dagreD3.intersect.polygon(node, points, point)
-    }
-    return shapeSvg
-  }
-
-  // Add custom shape for box with inverted arrow on right side
-  render.shapes().rect_right_inv_arrow = function (parent, bbox, node) {
-    const w = bbox.width
-    const h = bbox.height
-    const points = [
-      { x: 0, y: 0 },
-      { x: w + h / 2, y: 0 },
-      { x: w, y: -h / 2 },
-      { x: w + h / 2, y: -h },
-      { x: 0, y: -h }
-    ]
-    const shapeSvg = parent.insert('polygon', ':first-child')
-      .attr('points', points.map(function (d) {
-        return d.x + ',' + d.y
-      }).join(' '))
-      .attr('transform', 'translate(' + (-w / 2) + ',' + (h * 2 / 4) + ')')
-    node.intersect = function (point) {
-      return dagreD3.intersect.polygon(node, points, point)
-    }
-    return shapeSvg
-  }
-
-  // Add our custom arrow - an empty arrowhead
-  render.arrows().none = function normal (parent, id, edge, type) {
-    const marker = parent.append('marker')
-      .attr('id', id)
-      .attr('viewBox', '0 0 10 10')
-      .attr('refX', 9)
-      .attr('refY', 5)
-      .attr('markerUnits', 'strokeWidth')
-      .attr('markerWidth', 8)
-      .attr('markerHeight', 6)
-      .attr('orient', 'auto')
-
-    const path = marker.append('path')
-      .attr('d', 'M 0 0 L 0 0 L 0 0 z')
-    dagreD3.util.applyStyle(path, edge[type + 'Style'])
-  }
-
-  // Override normal arrowhead defined in d3. Remove style & add class to allow css styling.
-  render.arrows().normal = function normal (parent, id, edge, type) {
-    const marker = parent.append('marker')
-      .attr('id', id)
-      .attr('viewBox', '0 0 10 10')
-      .attr('refX', 9)
-      .attr('refY', 5)
-      .attr('markerUnits', 'strokeWidth')
-      .attr('markerWidth', 8)
-      .attr('markerHeight', 6)
-      .attr('orient', 'auto')
-
-    marker.append('path')
-      .attr('d', 'M 0 0 L 10 5 L 0 10 z')
-      .attr('class', 'arrowheadPath')
-      .style('stroke-width', 1)
-      .style('stroke-dasharray', '1,0')
-  }
-
-  // Set up an SVG group so that we can translate the final graph.
-  const svg = d3.select(`[id="${id}"]`)
-
-  // Run the renderer. This is what draws the final graph.
-  const element = d3.select('#' + id + ' g')
-  render(element, g)
-
-  element.selectAll('g.node')
-    .attr('title', function () {
-      return flowDb.getTooltip(this.id)
-    })
-
-  const padding = 8
-  const width = g.maxX - g.minX + padding * 2
-  const height = g.maxY - g.minY + padding * 2
-  svg.attr('width', '100%')
-  svg.attr('style', `max-width: ${width}px;`)
-  svg.attr('viewBox', `0 0 ${width} ${height}`)
-  svg.select('g').attr('transform', `translate(${padding - g.minX}, ${padding - g.minY})`)
-
-  // Index nodes
-  flowDb.indexNodes('subGraph' + i)
-
-  for (i = 0; i < subGraphs.length; i++) {
-    subG = subGraphs[i]
-
-    if (subG.title !== 'undefined') {
-      const clusterRects = document.querySelectorAll('#' + id + ' #' + subG.id + ' rect')
-      const clusterEl = document.querySelectorAll('#' + id + ' #' + subG.id)
-
-      const xPos = clusterRects[0].x.baseVal.value
-      const yPos = clusterRects[0].y.baseVal.value
-      const width = clusterRects[0].width.baseVal.value
-      const cluster = d3.select(clusterEl[0])
-      const te = cluster.append('text')
-      te.attr('x', xPos + width / 2)
-      te.attr('y', yPos + 14)
-      te.attr('fill', 'black')
-      te.attr('stroke', 'none')
-      te.attr('id', id + 'Text')
-      te.style('text-anchor', 'middle')
-
-      if (typeof subG.title === 'undefined') {
-        te.text('Undef')
-      } else {
-        te.text(subG.title)
-      }
-    }
-  }
-
-  // Add label rects for non html labels
-  if (!conf.htmlLabels) {
-    const labels = document.querySelectorAll('#' + id + ' .edgeLabel .label')
-    for (let k = 0; k < labels.length; k++) {
-      const label = labels[k]
-
-      // Get dimensions of label
-      const dim = label.getBBox()
-
-      const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
-      rect.setAttribute('rx', 0)
-      rect.setAttribute('ry', 0)
-      rect.setAttribute('width', dim.width)
-      rect.setAttribute('height', dim.height)
-      rect.setAttribute('style', 'fill:#e8e8e8;')
-
-      label.insertBefore(rect, label.firstChild)
-    }
-  }
-}
-
-export default {
-  setConf,
-  addVertices,
-  addEdges,
-  getClasses,
-  draw
-}
diff --git a/_submodules/mermaid/src/diagrams/flowchart/parser/flow.jison b/_submodules/mermaid/src/diagrams/flowchart/parser/flow.jison
deleted file mode 100644
index 0bbb4281eafe0d5cf53a1b1f842e11d9acd455b1..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/flowchart/parser/flow.jison
+++ /dev/null
@@ -1,452 +0,0 @@
-/** mermaid
- *  https://mermaidjs.github.io/
- *  (c) 2015 Knut Sveidqvist
- *  MIT license.
- */
-
-/* lexical grammar */
-%lex
-%x string
-
-%%
-\%\%[^\n]*            /* do nothing */
-["]                     this.begin("string");
-<string>["]             this.popState();
-<string>[^"]*           return "STR";
-"style"               return 'STYLE';
-"default"             return 'DEFAULT';
-"linkStyle"           return 'LINKSTYLE';
-"interpolate"         return 'INTERPOLATE';
-"classDef"            return 'CLASSDEF';
-"class"               return 'CLASS';
-"click"               return 'CLICK';
-"graph"               return 'GRAPH';
-"subgraph"            return 'subgraph';
-"end"\b\s*            return 'end';
-"LR"                  return 'DIR';
-"RL"                  return 'DIR';
-"TB"                  return 'DIR';
-"BT"                  return 'DIR';
-"TD"                  return 'DIR';
-"BR"                  return 'DIR';
-[0-9]+                 return 'NUM';
-\#                    return 'BRKT';
-":"                   return 'COLON';
-";"                   return 'SEMI';
-","                   return 'COMMA';
-"*"                   return 'MULT';
-"<"                   return 'TAGSTART';
-">"                   return 'TAGEND';
-"^"                   return 'UP';
-"v"                   return 'DOWN';
-\s*\-\-[x]\s*            return 'ARROW_CROSS';
-\s*\-\-\>\s*             return 'ARROW_POINT';
-\s*\-\-[o]\s*            return 'ARROW_CIRCLE';
-\s*\-\-\-\s*             return 'ARROW_OPEN';
-\s*\-\.\-[x]\s*          return 'DOTTED_ARROW_CROSS';
-\s*\-\.\-\>\s*           return 'DOTTED_ARROW_POINT';
-\s*\-\.\-[o]\s*          return 'DOTTED_ARROW_CIRCLE';
-\s*\-\.\-\s*             return 'DOTTED_ARROW_OPEN';
-\s*.\-[x]\s*             return 'DOTTED_ARROW_CROSS';
-\s*\.\-\>\s*             return 'DOTTED_ARROW_POINT';
-\s*\.\-[o]\s*            return 'DOTTED_ARROW_CIRCLE';
-\s*\.\-\s*               return 'DOTTED_ARROW_OPEN';
-\s*\=\=[x]\s*            return 'THICK_ARROW_CROSS';
-\s*\=\=\>\s*             return 'THICK_ARROW_POINT';
-\s*\=\=[o]\s*            return 'THICK_ARROW_CIRCLE';
-\s*\=\=[\=]\s*           return 'THICK_ARROW_OPEN';
-\s*\-\-\s*               return '--';
-\s*\-\.\s*               return '-.';
-\s*\=\=\s*               return '==';
-"(-"                  return '(-';
-"-)"                  return '-)';
-\-                    return 'MINUS';
-"."                   return 'DOT';
-\+                    return 'PLUS';
-\%                    return 'PCT';
-"="                   return 'EQUALS';
-\=                    return 'EQUALS';
-[A-Za-z]+             return 'ALPHA';
-[!"#$%&'*+,-.`?\\_/]  return 'PUNCTUATION';
-[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|
-[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|
-[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|
-[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|
-[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|
-[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|
-[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|
-[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|
-[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|
-[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|
-[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|
-[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|
-[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|
-[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|
-[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|
-[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|
-[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|
-[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|
-[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|
-[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|
-[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|
-[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|
-[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|
-[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|
-[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|
-[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|
-[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|
-[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|
-[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|
-[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|
-[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|
-[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|
-[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|
-[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|
-[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|
-[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|
-[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|
-[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|
-[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|
-[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|
-[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|
-[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|
-[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|
-[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|
-[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|
-[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|
-[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|
-[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|
-[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|
-[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|
-[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|
-[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|
-[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|
-[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|
-[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|
-[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|
-[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|
-[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|
-[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|
-[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|
-[\uFFD2-\uFFD7\uFFDA-\uFFDC]
-                      return 'UNICODE_TEXT';
-"|"                   return 'PIPE';
-"("                   return 'PS';
-")"                   return 'PE';
-"["                   return 'SQS';
-"]"                   return 'SQE';
-"{"                   return 'DIAMOND_START'
-"}"                   return 'DIAMOND_STOP'
-"\""                  return 'QUOTE';
-\n+                   return 'NEWLINE';
-\s                    return 'SPACE';
-<<EOF>>               return 'EOF';
-
-/lex
-
-/* operator associations and precedence */
-
-%left '^'
-
-%start mermaidDoc
-
-%% /* language grammar */
-
-mermaidDoc: graphConfig document;
-
-document
-	: /* empty */
-	{ $$ = [];}
-	| document line
-	{
-	    if($2 !== []){
-	        $1.push($2);
-	    }
-	    $$=$1;}
-	;
-
-line
-	: statement
-	{$$=$1;}
-	| SEMI
-	| NEWLINE
-	| SPACE
-	| EOF
-	;
-
-graphConfig
-    : SPACE graphConfig
-    | NEWLINE graphConfig
-    | GRAPH SPACE DIR FirstStmtSeperator
-        { yy.setDirection($3);$$ = $3;}
-    | GRAPH SPACE TAGEND FirstStmtSeperator
-        { yy.setDirection("LR");$$ = $3;}
-    | GRAPH SPACE TAGSTART FirstStmtSeperator
-        { yy.setDirection("RL");$$ = $3;}
-    | GRAPH SPACE UP FirstStmtSeperator
-        { yy.setDirection("BT");$$ = $3;}
-    | GRAPH SPACE DOWN FirstStmtSeperator
-        { yy.setDirection("TB");$$ = $3;}
-    ;
-
-ending: endToken ending
-      | endToken
-      ;
-
-endToken: NEWLINE | SPACE | EOF;
-
-FirstStmtSeperator
-    : SEMI | NEWLINE | spaceList NEWLINE ;
-
-
-spaceListNewline
-    : SPACE spaceListNewline
-    | NEWLINE spaceListNewline
-    | NEWLINE
-    | SPACE
-    ;
-
-
-spaceList
-    : SPACE spaceList
-    | SPACE
-    ;
-
-statement
-    : verticeStatement separator
-    {$$=$1}
-    | styleStatement separator
-    {$$=[];}
-    | linkStyleStatement separator
-    {$$=[];}
-    | classDefStatement separator
-    {$$=[];}
-    | classStatement separator
-    {$$=[];}
-    | clickStatement separator
-    {$$=[];}
-    | subgraph text separator document end
-    {$$=yy.addSubGraph($4,$2);}
-    | subgraph separator document end
-    {$$=yy.addSubGraph($3,undefined);}
-    ;
-
-separator: NEWLINE | SEMI | EOF ;
-
-verticeStatement:
-     vertex link vertex
-        { yy.addLink($1,$3,$2);$$ = [$1,$3];}
-     | vertex
-        {$$ = [$1];}
-    ;
-
-vertex:  alphaNum SQS text SQE
-        {$$ = $1;yy.addVertex($1,$3,'square');}
-    |  alphaNum SQS text SQE spaceList
-        {$$ = $1;yy.addVertex($1,$3,'square');}
-    | alphaNum PS PS text PE PE
-        {$$ = $1;yy.addVertex($1,$4,'circle');}
-    | alphaNum PS PS text PE PE spaceList
-        {$$ = $1;yy.addVertex($1,$4,'circle');}
-    | alphaNum '(-' text '-)'
-        {$$ = $1;yy.addVertex($1,$3,'ellipse');}
-    | alphaNum '(-' text '-)' spaceList
-        {$$ = $1;yy.addVertex($1,$3,'ellipse');}
-    | alphaNum PS text PE
-        {$$ = $1;yy.addVertex($1,$3,'round');}
-    | alphaNum PS text PE spaceList
-        {$$ = $1;yy.addVertex($1,$3,'round');}
-    | alphaNum DIAMOND_START text DIAMOND_STOP
-        {$$ = $1;yy.addVertex($1,$3,'diamond');}
-    | alphaNum DIAMOND_START text DIAMOND_STOP spaceList
-        {$$ = $1;yy.addVertex($1,$3,'diamond');}
-    | alphaNum TAGEND text SQE
-        {$$ = $1;yy.addVertex($1,$3,'odd');}
-    | alphaNum TAGEND text SQE spaceList
-        {$$ = $1;yy.addVertex($1,$3,'odd');}
-/*  | alphaNum SQS text TAGSTART
-        {$$ = $1;yy.addVertex($1,$3,'odd_right');}
-    | alphaNum SQS text TAGSTART spaceList
-        {$$ = $1;yy.addVertex($1,$3,'odd_right');} */
-    | alphaNum
-        {$$ = $1;yy.addVertex($1);}
-    | alphaNum spaceList
-        {$$ = $1;yy.addVertex($1);}
-    ;
-
-alphaNum
-    : alphaNumStatement
-    {$$=$1;}
-    | alphaNum alphaNumStatement
-    {$$=$1+''+$2;}
-    ;
-
-alphaNumStatement
-    : DIR
-        {$$=$1;}
-    | alphaNumToken
-        {$$=$1;}
-    | DOWN
-        {$$='v';}
-    | MINUS
-        {$$='-';}
-    ;
-
-link: linkStatement arrowText
-    {$1.text = $2;$$ = $1;}
-    | linkStatement TESTSTR SPACE
-    {$1.text = $2;$$ = $1;}
-    | linkStatement arrowText SPACE
-    {$1.text = $2;$$ = $1;}
-    | linkStatement
-    {$$ = $1;}
-    | '--' text ARROW_POINT
-        {$$ = {"type":"arrow","stroke":"normal","text":$2};}
-    | '--' text ARROW_CIRCLE
-        {$$ = {"type":"arrow_circle","stroke":"normal","text":$2};}
-    | '--' text ARROW_CROSS
-        {$$ = {"type":"arrow_cross","stroke":"normal","text":$2};}
-    | '--' text ARROW_OPEN
-        {$$ = {"type":"arrow_open","stroke":"normal","text":$2};}
-    | '-.' text DOTTED_ARROW_POINT
-        {$$ = {"type":"arrow","stroke":"dotted","text":$2};}
-    | '-.' text DOTTED_ARROW_CIRCLE
-        {$$ = {"type":"arrow_circle","stroke":"dotted","text":$2};}
-    | '-.' text DOTTED_ARROW_CROSS
-        {$$ = {"type":"arrow_cross","stroke":"dotted","text":$2};}
-    | '-.' text DOTTED_ARROW_OPEN
-        {$$ = {"type":"arrow_open","stroke":"dotted","text":$2};}
-    | '==' text THICK_ARROW_POINT
-        {$$ = {"type":"arrow","stroke":"thick","text":$2};}
-    | '==' text THICK_ARROW_CIRCLE
-        {$$ = {"type":"arrow_circle","stroke":"thick","text":$2};}
-    | '==' text THICK_ARROW_CROSS
-        {$$ = {"type":"arrow_cross","stroke":"thick","text":$2};}
-    | '==' text THICK_ARROW_OPEN
-        {$$ = {"type":"arrow_open","stroke":"thick","text":$2};}
-    ;
-
-linkStatement: ARROW_POINT
-        {$$ = {"type":"arrow","stroke":"normal"};}
-    | ARROW_CIRCLE
-        {$$ = {"type":"arrow_circle","stroke":"normal"};}
-    | ARROW_CROSS
-        {$$ = {"type":"arrow_cross","stroke":"normal"};}
-    | ARROW_OPEN
-        {$$ = {"type":"arrow_open","stroke":"normal"};}
-    | DOTTED_ARROW_POINT
-        {$$ = {"type":"arrow","stroke":"dotted"};}
-    | DOTTED_ARROW_CIRCLE
-        {$$ = {"type":"arrow_circle","stroke":"dotted"};}
-    | DOTTED_ARROW_CROSS
-        {$$ = {"type":"arrow_cross","stroke":"dotted"};}
-    | DOTTED_ARROW_OPEN
-        {$$ = {"type":"arrow_open","stroke":"dotted"};}
-    | THICK_ARROW_POINT
-        {$$ = {"type":"arrow","stroke":"thick"};}
-    | THICK_ARROW_CIRCLE
-        {$$ = {"type":"arrow_circle","stroke":"thick"};}
-    | THICK_ARROW_CROSS
-        {$$ = {"type":"arrow_cross","stroke":"thick"};}
-    | THICK_ARROW_OPEN
-        {$$ = {"type":"arrow_open","stroke":"thick"};}
-        ;
-
-arrowText:
-    PIPE text PIPE
-    {$$ = $2;}
-    ;
-
-text: textToken
-    {$$=$1;}
-    | text textToken
-    {$$=$1+''+$2;}
-    | STR
-    {$$=$1;}
-    ;
-
-
-
-commentText: commentToken
-    {$$=$1;}
-    | commentText commentToken
-    {$$=$1+''+$2;}
-    ;
-
-
-keywords
-    : STYLE | LINKSTYLE | CLASSDEF | CLASS | CLICK | GRAPH | DIR | subgraph | end | DOWN | UP;
-
-
-textNoTags: textNoTagsToken
-    {$$=$1;}
-    | textNoTags textNoTagsToken
-    {$$=$1+''+$2;}
-    ;
-
-
-classDefStatement:CLASSDEF SPACE DEFAULT SPACE stylesOpt
-    {$$ = $1;yy.addClass($3,$5);}
-    | CLASSDEF SPACE alphaNum SPACE stylesOpt
-          {$$ = $1;yy.addClass($3,$5);}
-    ;
-
-classStatement:CLASS SPACE alphaNum SPACE alphaNum
-    {$$ = $1;yy.setClass($3, $5);}
-    ;
-
-clickStatement
-    : CLICK SPACE alphaNum SPACE alphaNum           {$$ = $1;yy.setClickEvent($3,        $5, undefined, undefined);}
-    | CLICK SPACE alphaNum SPACE alphaNum SPACE STR {$$ = $1;yy.setClickEvent($3,        $5, undefined, $7)       ;}
-    | CLICK SPACE alphaNum SPACE STR                {$$ = $1;yy.setClickEvent($3, undefined,        $5, undefined);}
-    | CLICK SPACE alphaNum SPACE STR SPACE STR      {$$ = $1;yy.setClickEvent($3, undefined,        $5, $7       );}
-    ;
-
-styleStatement:STYLE SPACE alphaNum SPACE stylesOpt
-    {$$ = $1;yy.addVertex($3,undefined,undefined,$5);}
-    | STYLE SPACE HEX SPACE stylesOpt
-          {$$ = $1;yy.updateLink($3,$5);}
-    ;
-
-linkStyleStatement
-    : LINKSTYLE SPACE DEFAULT SPACE stylesOpt
-          {$$ = $1;yy.updateLink($3,$5);}
-    | LINKSTYLE SPACE NUM SPACE stylesOpt
-          {$$ = $1;yy.updateLink($3,$5);}
-    | LINKSTYLE SPACE DEFAULT SPACE INTERPOLATE SPACE alphaNum SPACE stylesOpt
-          {$$ = $1;yy.updateLinkInterpolate($3,$7);yy.updateLink($3,$9);}
-    | LINKSTYLE SPACE NUM SPACE INTERPOLATE SPACE alphaNum SPACE stylesOpt
-          {$$ = $1;yy.updateLinkInterpolate($3,$7);yy.updateLink($3,$9);}
-    | LINKSTYLE SPACE DEFAULT SPACE INTERPOLATE SPACE alphaNum
-          {$$ = $1;yy.updateLinkInterpolate($3,$7);}
-    | LINKSTYLE SPACE NUM SPACE INTERPOLATE SPACE alphaNum
-          {$$ = $1;yy.updateLinkInterpolate($3,$7);}
-    ;
-
-commentStatement: PCT PCT commentText;
-
-stylesOpt: style
-        {$$ = [$1]}
-    | stylesOpt COMMA style
-        {$1.push($3);$$ = $1;}
-    ;
-
-style: styleComponent
-    |style styleComponent
-    {$$ = $1 + $2;}
-    ;
-
-styleComponent: ALPHA | COLON | MINUS | NUM | UNIT | SPACE | HEX | BRKT | DOT | STYLE | PCT ;
-
-/* Token lists */
-
-commentToken   : textToken | graphCodeTokens ;
-
-textToken      : textNoTagsToken | TAGSTART | TAGEND | '=='  | '--' | PCT | DEFAULT;
-
-textNoTagsToken: alphaNumToken | SPACE | MINUS | keywords ;
-
-alphaNumToken  : ALPHA | PUNCTUATION | UNICODE_TEXT | NUM | COLON | COMMA | PLUS | EQUALS | MULT | DOT | BRKT ;
-
-graphCodeTokens:  PIPE | PS | PE | SQS | SQE | DIAMOND_START | DIAMOND_STOP | TAG_START | TAG_END | ARROW_CROSS | ARROW_POINT | ARROW_CIRCLE | ARROW_OPEN | QUOTE | SEMI ;
-%%
diff --git a/_submodules/mermaid/src/diagrams/flowchart/parser/flow.js b/_submodules/mermaid/src/diagrams/flowchart/parser/flow.js
deleted file mode 100644
index f45c6fd71d64f1a4567f1f0c4ffd65c44331166f..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/flowchart/parser/flow.js
+++ /dev/null
@@ -1,961 +0,0 @@
-/* parser generated by jison 0.4.18 */
-/*
-  Returns a Parser object of the following structure:
-
-  Parser: {
-    yy: {}
-  }
-
-  Parser.prototype: {
-    yy: {},
-    trace: function(),
-    symbols_: {associative list: name ==> number},
-    terminals_: {associative list: number ==> name},
-    productions_: [...],
-    performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
-    table: [...],
-    defaultActions: {...},
-    parseError: function(str, hash),
-    parse: function(input),
-
-    lexer: {
-        EOF: 1,
-        parseError: function(str, hash),
-        setInput: function(input),
-        input: function(),
-        unput: function(str),
-        more: function(),
-        less: function(n),
-        pastInput: function(),
-        upcomingInput: function(),
-        showPosition: function(),
-        test_match: function(regex_match_array, rule_index),
-        next: function(),
-        lex: function(),
-        begin: function(condition),
-        popState: function(),
-        _currentRules: function(),
-        topState: function(),
-        pushState: function(condition),
-
-        options: {
-            ranges: boolean           (optional: true ==> token location info will include a .range[] member)
-            flex: boolean             (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
-            backtrack_lexer: boolean  (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
-        },
-
-        performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
-        rules: [...],
-        conditions: {associative list: name ==> set},
-    }
-  }
-
-
-  token location info (@$, _$, etc.): {
-    first_line: n,
-    last_line: n,
-    first_column: n,
-    last_column: n,
-    range: [start_number, end_number]       (where the numbers are indexes into the input string, regular zero-based)
-  }
-
-
-  the parseError function receives a 'hash' object with these members for lexer and parser errors: {
-    text:        (matched text)
-    token:       (the produced terminal token, if any)
-    line:        (yylineno)
-  }
-  while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
-    loc:         (yylloc)
-    expected:    (string describing the set of expected tokens)
-    recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
-  }
-*/
-var parser = (function(){
-var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,4],$V1=[1,3],$V2=[1,5],$V3=[1,8,9,10,11,13,18,30,46,71,72,73,74,75,81,86,88,89,91,92,94,95,96,97,98],$V4=[2,2],$V5=[1,12],$V6=[1,13],$V7=[1,14],$V8=[1,15],$V9=[1,31],$Va=[1,33],$Vb=[1,22],$Vc=[1,34],$Vd=[1,24],$Ve=[1,25],$Vf=[1,26],$Vg=[1,27],$Vh=[1,28],$Vi=[1,38],$Vj=[1,40],$Vk=[1,35],$Vl=[1,39],$Vm=[1,45],$Vn=[1,44],$Vo=[1,36],$Vp=[1,37],$Vq=[1,41],$Vr=[1,42],$Vs=[1,43],$Vt=[1,8,9,10,11,13,18,30,32,46,71,72,73,74,75,81,86,88,89,91,92,94,95,96,97,98],$Vu=[1,53],$Vv=[1,52],$Vw=[1,54],$Vx=[1,72],$Vy=[1,80],$Vz=[1,81],$VA=[1,66],$VB=[1,65],$VC=[1,85],$VD=[1,84],$VE=[1,82],$VF=[1,83],$VG=[1,73],$VH=[1,68],$VI=[1,67],$VJ=[1,63],$VK=[1,75],$VL=[1,76],$VM=[1,77],$VN=[1,78],$VO=[1,79],$VP=[1,70],$VQ=[1,69],$VR=[8,9,11],$VS=[8,9,11,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64],$VT=[1,115],$VU=[8,9,10,11,13,15,18,36,38,40,42,46,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,81,86,88,89,91,92,94,95,96,97,98],$VV=[8,9,10,11,12,13,15,16,17,18,30,32,36,37,38,39,40,41,42,43,46,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,71,72,73,74,75,78,81,84,86,88,89,91,92,94,95,96,97,98],$VW=[1,117],$VX=[1,118],$VY=[8,9,10,11,13,18,30,32,46,71,72,73,74,75,81,86,88,89,91,92,94,95,96,97,98],$VZ=[8,9,10,11,12,13,15,16,17,18,30,32,37,39,41,43,46,50,51,52,53,54,56,57,58,59,60,61,62,63,64,65,71,72,73,74,75,78,81,84,86,88,89,91,92,94,95,96,97,98],$V_=[13,18,46,81,86,88,89,91,92,94,95,96,97,98],$V$=[13,18,46,49,65,81,86,88,89,91,92,94,95,96,97,98],$V01=[1,191],$V11=[1,188],$V21=[1,195],$V31=[1,192],$V41=[1,189],$V51=[1,196],$V61=[1,186],$V71=[1,187],$V81=[1,190],$V91=[1,193],$Va1=[1,194],$Vb1=[1,213],$Vc1=[8,9,11,86],$Vd1=[8,9,10,11,46,71,80,81,84,86,88,89,90,91,92];
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {"error":2,"mermaidDoc":3,"graphConfig":4,"document":5,"line":6,"statement":7,"SEMI":8,"NEWLINE":9,"SPACE":10,"EOF":11,"GRAPH":12,"DIR":13,"FirstStmtSeperator":14,"TAGEND":15,"TAGSTART":16,"UP":17,"DOWN":18,"ending":19,"endToken":20,"spaceList":21,"spaceListNewline":22,"verticeStatement":23,"separator":24,"styleStatement":25,"linkStyleStatement":26,"classDefStatement":27,"classStatement":28,"clickStatement":29,"subgraph":30,"text":31,"end":32,"vertex":33,"link":34,"alphaNum":35,"SQS":36,"SQE":37,"PS":38,"PE":39,"(-":40,"-)":41,"DIAMOND_START":42,"DIAMOND_STOP":43,"alphaNumStatement":44,"alphaNumToken":45,"MINUS":46,"linkStatement":47,"arrowText":48,"TESTSTR":49,"--":50,"ARROW_POINT":51,"ARROW_CIRCLE":52,"ARROW_CROSS":53,"ARROW_OPEN":54,"-.":55,"DOTTED_ARROW_POINT":56,"DOTTED_ARROW_CIRCLE":57,"DOTTED_ARROW_CROSS":58,"DOTTED_ARROW_OPEN":59,"==":60,"THICK_ARROW_POINT":61,"THICK_ARROW_CIRCLE":62,"THICK_ARROW_CROSS":63,"THICK_ARROW_OPEN":64,"PIPE":65,"textToken":66,"STR":67,"commentText":68,"commentToken":69,"keywords":70,"STYLE":71,"LINKSTYLE":72,"CLASSDEF":73,"CLASS":74,"CLICK":75,"textNoTags":76,"textNoTagsToken":77,"DEFAULT":78,"stylesOpt":79,"HEX":80,"NUM":81,"INTERPOLATE":82,"commentStatement":83,"PCT":84,"style":85,"COMMA":86,"styleComponent":87,"ALPHA":88,"COLON":89,"UNIT":90,"BRKT":91,"DOT":92,"graphCodeTokens":93,"PUNCTUATION":94,"UNICODE_TEXT":95,"PLUS":96,"EQUALS":97,"MULT":98,"TAG_START":99,"TAG_END":100,"QUOTE":101,"$accept":0,"$end":1},
-terminals_: {2:"error",8:"SEMI",9:"NEWLINE",10:"SPACE",11:"EOF",12:"GRAPH",13:"DIR",15:"TAGEND",16:"TAGSTART",17:"UP",18:"DOWN",30:"subgraph",32:"end",36:"SQS",37:"SQE",38:"PS",39:"PE",40:"(-",41:"-)",42:"DIAMOND_START",43:"DIAMOND_STOP",46:"MINUS",49:"TESTSTR",50:"--",51:"ARROW_POINT",52:"ARROW_CIRCLE",53:"ARROW_CROSS",54:"ARROW_OPEN",55:"-.",56:"DOTTED_ARROW_POINT",57:"DOTTED_ARROW_CIRCLE",58:"DOTTED_ARROW_CROSS",59:"DOTTED_ARROW_OPEN",60:"==",61:"THICK_ARROW_POINT",62:"THICK_ARROW_CIRCLE",63:"THICK_ARROW_CROSS",64:"THICK_ARROW_OPEN",65:"PIPE",67:"STR",71:"STYLE",72:"LINKSTYLE",73:"CLASSDEF",74:"CLASS",75:"CLICK",78:"DEFAULT",80:"HEX",81:"NUM",82:"INTERPOLATE",84:"PCT",86:"COMMA",88:"ALPHA",89:"COLON",90:"UNIT",91:"BRKT",92:"DOT",94:"PUNCTUATION",95:"UNICODE_TEXT",96:"PLUS",97:"EQUALS",98:"MULT",99:"TAG_START",100:"TAG_END",101:"QUOTE"},
-productions_: [0,[3,2],[5,0],[5,2],[6,1],[6,1],[6,1],[6,1],[6,1],[4,2],[4,2],[4,4],[4,4],[4,4],[4,4],[4,4],[19,2],[19,1],[20,1],[20,1],[20,1],[14,1],[14,1],[14,2],[22,2],[22,2],[22,1],[22,1],[21,2],[21,1],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,5],[7,4],[24,1],[24,1],[24,1],[23,3],[23,1],[33,4],[33,5],[33,6],[33,7],[33,4],[33,5],[33,4],[33,5],[33,4],[33,5],[33,4],[33,5],[33,1],[33,2],[35,1],[35,2],[44,1],[44,1],[44,1],[44,1],[34,2],[34,3],[34,3],[34,1],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[34,3],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[47,1],[48,3],[31,1],[31,2],[31,1],[68,1],[68,2],[70,1],[70,1],[70,1],[70,1],[70,1],[70,1],[70,1],[70,1],[70,1],[70,1],[70,1],[76,1],[76,2],[27,5],[27,5],[28,5],[29,5],[29,7],[29,5],[29,7],[25,5],[25,5],[26,5],[26,5],[26,9],[26,9],[26,7],[26,7],[83,3],[79,1],[79,3],[85,1],[85,2],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[69,1],[69,1],[66,1],[66,1],[66,1],[66,1],[66,1],[66,1],[66,1],[77,1],[77,1],[77,1],[77,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1],[93,1]],
-performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
-/* this == yyval */
-
-var $0 = $$.length - 1;
-switch (yystate) {
-case 2:
- this.$ = [];
-break;
-case 3:
-
-	    if($$[$0] !== []){
-	        $$[$0-1].push($$[$0]);
-	    }
-	    this.$=$$[$0-1];
-break;
-case 4: case 57: case 59: case 60: case 92: case 94: case 95: case 108:
-this.$=$$[$0];
-break;
-case 11:
- yy.setDirection($$[$0-1]);this.$ = $$[$0-1];
-break;
-case 12:
- yy.setDirection("LR");this.$ = $$[$0-1];
-break;
-case 13:
- yy.setDirection("RL");this.$ = $$[$0-1];
-break;
-case 14:
- yy.setDirection("BT");this.$ = $$[$0-1];
-break;
-case 15:
- yy.setDirection("TB");this.$ = $$[$0-1];
-break;
-case 30:
-this.$=$$[$0-1]
-break;
-case 31: case 32: case 33: case 34: case 35:
-this.$=[];
-break;
-case 36:
-this.$=yy.addSubGraph($$[$0-1],$$[$0-3]);
-break;
-case 37:
-this.$=yy.addSubGraph($$[$0-1],undefined);
-break;
-case 41:
- yy.addLink($$[$0-2],$$[$0],$$[$0-1]);this.$ = [$$[$0-2],$$[$0]];
-break;
-case 42:
-this.$ = [$$[$0]];
-break;
-case 43:
-this.$ = $$[$0-3];yy.addVertex($$[$0-3],$$[$0-1],'square');
-break;
-case 44:
-this.$ = $$[$0-4];yy.addVertex($$[$0-4],$$[$0-2],'square');
-break;
-case 45:
-this.$ = $$[$0-5];yy.addVertex($$[$0-5],$$[$0-2],'circle');
-break;
-case 46:
-this.$ = $$[$0-6];yy.addVertex($$[$0-6],$$[$0-3],'circle');
-break;
-case 47:
-this.$ = $$[$0-3];yy.addVertex($$[$0-3],$$[$0-1],'ellipse');
-break;
-case 48:
-this.$ = $$[$0-4];yy.addVertex($$[$0-4],$$[$0-2],'ellipse');
-break;
-case 49:
-this.$ = $$[$0-3];yy.addVertex($$[$0-3],$$[$0-1],'round');
-break;
-case 50:
-this.$ = $$[$0-4];yy.addVertex($$[$0-4],$$[$0-2],'round');
-break;
-case 51:
-this.$ = $$[$0-3];yy.addVertex($$[$0-3],$$[$0-1],'diamond');
-break;
-case 52:
-this.$ = $$[$0-4];yy.addVertex($$[$0-4],$$[$0-2],'diamond');
-break;
-case 53:
-this.$ = $$[$0-3];yy.addVertex($$[$0-3],$$[$0-1],'odd');
-break;
-case 54:
-this.$ = $$[$0-4];yy.addVertex($$[$0-4],$$[$0-2],'odd');
-break;
-case 55:
-this.$ = $$[$0];yy.addVertex($$[$0]);
-break;
-case 56:
-this.$ = $$[$0-1];yy.addVertex($$[$0-1]);
-break;
-case 58: case 93: case 96: case 109:
-this.$=$$[$0-1]+''+$$[$0];
-break;
-case 61:
-this.$='v';
-break;
-case 62:
-this.$='-';
-break;
-case 63:
-$$[$0-1].text = $$[$0];this.$ = $$[$0-1];
-break;
-case 64: case 65:
-$$[$0-2].text = $$[$0-1];this.$ = $$[$0-2];
-break;
-case 66:
-this.$ = $$[$0];
-break;
-case 67:
-this.$ = {"type":"arrow","stroke":"normal","text":$$[$0-1]};
-break;
-case 68:
-this.$ = {"type":"arrow_circle","stroke":"normal","text":$$[$0-1]};
-break;
-case 69:
-this.$ = {"type":"arrow_cross","stroke":"normal","text":$$[$0-1]};
-break;
-case 70:
-this.$ = {"type":"arrow_open","stroke":"normal","text":$$[$0-1]};
-break;
-case 71:
-this.$ = {"type":"arrow","stroke":"dotted","text":$$[$0-1]};
-break;
-case 72:
-this.$ = {"type":"arrow_circle","stroke":"dotted","text":$$[$0-1]};
-break;
-case 73:
-this.$ = {"type":"arrow_cross","stroke":"dotted","text":$$[$0-1]};
-break;
-case 74:
-this.$ = {"type":"arrow_open","stroke":"dotted","text":$$[$0-1]};
-break;
-case 75:
-this.$ = {"type":"arrow","stroke":"thick","text":$$[$0-1]};
-break;
-case 76:
-this.$ = {"type":"arrow_circle","stroke":"thick","text":$$[$0-1]};
-break;
-case 77:
-this.$ = {"type":"arrow_cross","stroke":"thick","text":$$[$0-1]};
-break;
-case 78:
-this.$ = {"type":"arrow_open","stroke":"thick","text":$$[$0-1]};
-break;
-case 79:
-this.$ = {"type":"arrow","stroke":"normal"};
-break;
-case 80:
-this.$ = {"type":"arrow_circle","stroke":"normal"};
-break;
-case 81:
-this.$ = {"type":"arrow_cross","stroke":"normal"};
-break;
-case 82:
-this.$ = {"type":"arrow_open","stroke":"normal"};
-break;
-case 83:
-this.$ = {"type":"arrow","stroke":"dotted"};
-break;
-case 84:
-this.$ = {"type":"arrow_circle","stroke":"dotted"};
-break;
-case 85:
-this.$ = {"type":"arrow_cross","stroke":"dotted"};
-break;
-case 86:
-this.$ = {"type":"arrow_open","stroke":"dotted"};
-break;
-case 87:
-this.$ = {"type":"arrow","stroke":"thick"};
-break;
-case 88:
-this.$ = {"type":"arrow_circle","stroke":"thick"};
-break;
-case 89:
-this.$ = {"type":"arrow_cross","stroke":"thick"};
-break;
-case 90:
-this.$ = {"type":"arrow_open","stroke":"thick"};
-break;
-case 91:
-this.$ = $$[$0-1];
-break;
-case 110: case 111:
-this.$ = $$[$0-4];yy.addClass($$[$0-2],$$[$0]);
-break;
-case 112:
-this.$ = $$[$0-4];yy.setClass($$[$0-2], $$[$0]);
-break;
-case 113:
-this.$ = $$[$0-4];yy.setClickEvent($$[$0-2],        $$[$0], undefined, undefined);
-break;
-case 114:
-this.$ = $$[$0-6];yy.setClickEvent($$[$0-4],        $$[$0-2], undefined, $$[$0])       ;
-break;
-case 115:
-this.$ = $$[$0-4];yy.setClickEvent($$[$0-2], undefined,        $$[$0], undefined);
-break;
-case 116:
-this.$ = $$[$0-6];yy.setClickEvent($$[$0-4], undefined,        $$[$0-2], $$[$0]       );
-break;
-case 117:
-this.$ = $$[$0-4];yy.addVertex($$[$0-2],undefined,undefined,$$[$0]);
-break;
-case 118: case 119: case 120:
-this.$ = $$[$0-4];yy.updateLink($$[$0-2],$$[$0]);
-break;
-case 121: case 122:
-this.$ = $$[$0-8];yy.updateLinkInterpolate($$[$0-6],$$[$0-2]);yy.updateLink($$[$0-6],$$[$0]);
-break;
-case 123: case 124:
-this.$ = $$[$0-6];yy.updateLinkInterpolate($$[$0-4],$$[$0]);
-break;
-case 126:
-this.$ = [$$[$0]]
-break;
-case 127:
-$$[$0-2].push($$[$0]);this.$ = $$[$0-2];
-break;
-case 129:
-this.$ = $$[$0-1] + $$[$0];
-break;
-}
-},
-table: [{3:1,4:2,9:$V0,10:$V1,12:$V2},{1:[3]},o($V3,$V4,{5:6}),{4:7,9:$V0,10:$V1,12:$V2},{4:8,9:$V0,10:$V1,12:$V2},{10:[1,9]},{1:[2,1],6:10,7:11,8:$V5,9:$V6,10:$V7,11:$V8,13:$V9,18:$Va,23:16,25:17,26:18,27:19,28:20,29:21,30:$Vb,33:23,35:29,44:30,45:32,46:$Vc,71:$Vd,72:$Ve,73:$Vf,74:$Vg,75:$Vh,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($V3,[2,9]),o($V3,[2,10]),{13:[1,46],15:[1,47],16:[1,48],17:[1,49],18:[1,50]},o($Vt,[2,3]),o($Vt,[2,4]),o($Vt,[2,5]),o($Vt,[2,6]),o($Vt,[2,7]),o($Vt,[2,8]),{8:$Vu,9:$Vv,11:$Vw,24:51},{8:$Vu,9:$Vv,11:$Vw,24:55},{8:$Vu,9:$Vv,11:$Vw,24:56},{8:$Vu,9:$Vv,11:$Vw,24:57},{8:$Vu,9:$Vv,11:$Vw,24:58},{8:$Vu,9:$Vv,11:$Vw,24:59},{8:$Vu,9:$Vv,10:$Vx,11:$Vw,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,24:61,30:$VE,31:60,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VR,[2,42],{34:86,47:87,50:[1,88],51:[1,91],52:[1,92],53:[1,93],54:[1,94],55:[1,89],56:[1,95],57:[1,96],58:[1,97],59:[1,98],60:[1,90],61:[1,99],62:[1,100],63:[1,101],64:[1,102]}),{10:[1,103]},{10:[1,104]},{10:[1,105]},{10:[1,106]},{10:[1,107]},o($VS,[2,55],{45:32,21:113,44:114,10:$VT,13:$V9,15:[1,112],18:$Va,36:[1,108],38:[1,109],40:[1,110],42:[1,111],46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs}),o($VU,[2,57]),o($VU,[2,59]),o($VU,[2,60]),o($VU,[2,61]),o($VU,[2,62]),o($VV,[2,154]),o($VV,[2,155]),o($VV,[2,156]),o($VV,[2,157]),o($VV,[2,158]),o($VV,[2,159]),o($VV,[2,160]),o($VV,[2,161]),o($VV,[2,162]),o($VV,[2,163]),o($VV,[2,164]),{8:$VW,9:$VX,10:$VT,14:116,21:119},{8:$VW,9:$VX,10:$VT,14:120,21:119},{8:$VW,9:$VX,10:$VT,14:121,21:119},{8:$VW,9:$VX,10:$VT,14:122,21:119},{8:$VW,9:$VX,10:$VT,14:123,21:119},o($Vt,[2,30]),o($Vt,[2,38]),o($Vt,[2,39]),o($Vt,[2,40]),o($Vt,[2,31]),o($Vt,[2,32]),o($Vt,[2,33]),o($Vt,[2,34]),o($Vt,[2,35]),{8:$Vu,9:$Vv,10:$Vx,11:$Vw,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,24:124,30:$VE,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VY,$V4,{5:126}),o($VZ,[2,92]),o($VZ,[2,94]),o($VZ,[2,143]),o($VZ,[2,144]),o($VZ,[2,145]),o($VZ,[2,146]),o($VZ,[2,147]),o($VZ,[2,148]),o($VZ,[2,149]),o($VZ,[2,150]),o($VZ,[2,151]),o($VZ,[2,152]),o($VZ,[2,153]),o($VZ,[2,97]),o($VZ,[2,98]),o($VZ,[2,99]),o($VZ,[2,100]),o($VZ,[2,101]),o($VZ,[2,102]),o($VZ,[2,103]),o($VZ,[2,104]),o($VZ,[2,105]),o($VZ,[2,106]),o($VZ,[2,107]),{13:$V9,18:$Va,33:127,35:29,44:30,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($V_,[2,66],{48:128,49:[1,129],65:[1,130]}),{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:131,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:132,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:133,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($V$,[2,79]),o($V$,[2,80]),o($V$,[2,81]),o($V$,[2,82]),o($V$,[2,83]),o($V$,[2,84]),o($V$,[2,85]),o($V$,[2,86]),o($V$,[2,87]),o($V$,[2,88]),o($V$,[2,89]),o($V$,[2,90]),{13:$V9,18:$Va,35:134,44:30,45:32,46:$Vc,80:[1,135],81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{78:[1,136],81:[1,137]},{13:$V9,18:$Va,35:139,44:30,45:32,46:$Vc,78:[1,138],81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{13:$V9,18:$Va,35:140,44:30,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{13:$V9,18:$Va,35:141,44:30,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:142,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:144,32:$VF,38:[1,143],45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:145,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:146,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:147,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VS,[2,56]),o($VU,[2,58]),o($VS,[2,29],{21:148,10:$VT}),o($V3,[2,11]),o($V3,[2,21]),o($V3,[2,22]),{9:[1,149]},o($V3,[2,12]),o($V3,[2,13]),o($V3,[2,14]),o($V3,[2,15]),o($VY,$V4,{5:150}),o($VZ,[2,93]),{6:10,7:11,8:$V5,9:$V6,10:$V7,11:$V8,13:$V9,18:$Va,23:16,25:17,26:18,27:19,28:20,29:21,30:$Vb,32:[1,151],33:23,35:29,44:30,45:32,46:$Vc,71:$Vd,72:$Ve,73:$Vf,74:$Vg,75:$Vh,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VR,[2,41]),o($V_,[2,63],{10:[1,152]}),{10:[1,153]},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:154,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,45:71,46:$VG,50:$VH,51:[1,155],52:[1,156],53:[1,157],54:[1,158],60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,45:71,46:$VG,50:$VH,56:[1,159],57:[1,160],58:[1,161],59:[1,162],60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,45:71,46:$VG,50:$VH,60:$VI,61:[1,163],62:[1,164],63:[1,165],64:[1,166],66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:[1,167],13:$V9,18:$Va,44:114,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:[1,168]},{10:[1,169]},{10:[1,170]},{10:[1,171]},{10:[1,172],13:$V9,18:$Va,44:114,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:[1,173],13:$V9,18:$Va,44:114,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:[1,174],13:$V9,18:$Va,44:114,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,37:[1,175],45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,31:176,32:$VF,45:71,46:$VG,50:$VH,60:$VI,66:62,67:$VJ,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,39:[1,177],45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,41:[1,178],45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,43:[1,179],45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,37:[1,180],45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VS,[2,28]),o($V3,[2,23]),{6:10,7:11,8:$V5,9:$V6,10:$V7,11:$V8,13:$V9,18:$Va,23:16,25:17,26:18,27:19,28:20,29:21,30:$Vb,32:[1,181],33:23,35:29,44:30,45:32,46:$Vc,71:$Vd,72:$Ve,73:$Vf,74:$Vg,75:$Vh,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($Vt,[2,37]),o($V_,[2,65]),o($V_,[2,64]),{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,45:71,46:$VG,50:$VH,60:$VI,65:[1,182],66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($V_,[2,67]),o($V_,[2,68]),o($V_,[2,69]),o($V_,[2,70]),o($V_,[2,71]),o($V_,[2,72]),o($V_,[2,73]),o($V_,[2,74]),o($V_,[2,75]),o($V_,[2,76]),o($V_,[2,77]),o($V_,[2,78]),{10:$V01,46:$V11,71:$V21,79:183,80:$V31,81:$V41,84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{10:$V01,46:$V11,71:$V21,79:197,80:$V31,81:$V41,84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{10:$V01,46:$V11,71:$V21,79:198,80:$V31,81:$V41,82:[1,199],84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{10:$V01,46:$V11,71:$V21,79:200,80:$V31,81:$V41,82:[1,201],84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{10:$V01,46:$V11,71:$V21,79:202,80:$V31,81:$V41,84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{10:$V01,46:$V11,71:$V21,79:203,80:$V31,81:$V41,84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{13:$V9,18:$Va,35:204,44:30,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{13:$V9,18:$Va,35:205,44:30,45:32,46:$Vc,67:[1,206],81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VS,[2,43],{21:207,10:$VT}),{10:$Vx,12:$Vy,13:$Vz,15:$VA,16:$VB,17:$VC,18:$VD,30:$VE,32:$VF,39:[1,208],45:71,46:$VG,50:$VH,60:$VI,66:125,70:74,71:$VK,72:$VL,73:$VM,74:$VN,75:$VO,77:64,78:$VP,81:$Vi,84:$VQ,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},o($VS,[2,49],{21:209,10:$VT}),o($VS,[2,47],{21:210,10:$VT}),o($VS,[2,51],{21:211,10:$VT}),o($VS,[2,53],{21:212,10:$VT}),o($Vt,[2,36]),o([10,13,18,46,81,86,88,89,91,92,94,95,96,97,98],[2,91]),o($VR,[2,117],{86:$Vb1}),o($Vc1,[2,126],{87:214,10:$V01,46:$V11,71:$V21,80:$V31,81:$V41,84:$V51,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1}),o($Vd1,[2,128]),o($Vd1,[2,130]),o($Vd1,[2,131]),o($Vd1,[2,132]),o($Vd1,[2,133]),o($Vd1,[2,134]),o($Vd1,[2,135]),o($Vd1,[2,136]),o($Vd1,[2,137]),o($Vd1,[2,138]),o($Vd1,[2,139]),o($Vd1,[2,140]),o($VR,[2,118],{86:$Vb1}),o($VR,[2,119],{86:$Vb1}),{10:[1,215]},o($VR,[2,120],{86:$Vb1}),{10:[1,216]},o($VR,[2,110],{86:$Vb1}),o($VR,[2,111],{86:$Vb1}),o($VR,[2,112],{45:32,44:114,13:$V9,18:$Va,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs}),o($VR,[2,113],{45:32,44:114,10:[1,217],13:$V9,18:$Va,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs}),o($VR,[2,115],{10:[1,218]}),o($VS,[2,44]),{39:[1,219]},o($VS,[2,50]),o($VS,[2,48]),o($VS,[2,52]),o($VS,[2,54]),{10:$V01,46:$V11,71:$V21,80:$V31,81:$V41,84:$V51,85:220,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},o($Vd1,[2,129]),{13:$V9,18:$Va,35:221,44:30,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{13:$V9,18:$Va,35:222,44:30,45:32,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs},{67:[1,223]},{67:[1,224]},o($VS,[2,45],{21:225,10:$VT}),o($Vc1,[2,127],{87:214,10:$V01,46:$V11,71:$V21,80:$V31,81:$V41,84:$V51,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1}),o($VR,[2,123],{45:32,44:114,10:[1,226],13:$V9,18:$Va,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs}),o($VR,[2,124],{45:32,44:114,10:[1,227],13:$V9,18:$Va,46:$Vc,81:$Vi,86:$Vj,88:$Vk,89:$Vl,91:$Vm,92:$Vn,94:$Vo,95:$Vp,96:$Vq,97:$Vr,98:$Vs}),o($VR,[2,114]),o($VR,[2,116]),o($VS,[2,46]),{10:$V01,46:$V11,71:$V21,79:228,80:$V31,81:$V41,84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},{10:$V01,46:$V11,71:$V21,79:229,80:$V31,81:$V41,84:$V51,85:184,87:185,88:$V61,89:$V71,90:$V81,91:$V91,92:$Va1},o($VR,[2,121],{86:$Vb1}),o($VR,[2,122],{86:$Vb1})],
-defaultActions: {},
-parseError: function parseError(str, hash) {
-    if (hash.recoverable) {
-        this.trace(str);
-    } else {
-        var error = new Error(str);
-        error.hash = hash;
-        throw error;
-    }
-},
-parse: function parse(input) {
-    var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
-    var args = lstack.slice.call(arguments, 1);
-    var lexer = Object.create(this.lexer);
-    var sharedState = { yy: {} };
-    for (var k in this.yy) {
-        if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
-            sharedState.yy[k] = this.yy[k];
-        }
-    }
-    lexer.setInput(input, sharedState.yy);
-    sharedState.yy.lexer = lexer;
-    sharedState.yy.parser = this;
-    if (typeof lexer.yylloc == 'undefined') {
-        lexer.yylloc = {};
-    }
-    var yyloc = lexer.yylloc;
-    lstack.push(yyloc);
-    var ranges = lexer.options && lexer.options.ranges;
-    if (typeof sharedState.yy.parseError === 'function') {
-        this.parseError = sharedState.yy.parseError;
-    } else {
-        this.parseError = Object.getPrototypeOf(this).parseError;
-    }
-    function popStack(n) {
-        stack.length = stack.length - 2 * n;
-        vstack.length = vstack.length - n;
-        lstack.length = lstack.length - n;
-    }
-            function lex() {
-            var token;
-            token = tstack.pop() || lexer.lex() || EOF;
-            if (typeof token !== 'number') {
-                if (token instanceof Array) {
-                    tstack = token;
-                    token = tstack.pop();
-                }
-                token = self.symbols_[token] || token;
-            }
-            return token;
-        }
-    var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
-    while (true) {
-        state = stack[stack.length - 1];
-        if (this.defaultActions[state]) {
-            action = this.defaultActions[state];
-        } else {
-            if (symbol === null || typeof symbol == 'undefined') {
-                symbol = lex();
-            }
-            action = table[state] && table[state][symbol];
-        }
-        if (typeof action === 'undefined' || !action.length || !action[0]) {
-            var errStr = '';
-            expected = [];
-            for (p in table[state]) {
-                if (this.terminals_[p] && p > TERROR) {
-                    expected.push('\'' + this.terminals_[p] + '\'');
-                }
-            }
-            if (lexer.showPosition) {
-                errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
-            } else {
-                errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
-            }
-            this.parseError(errStr, {
-                text: lexer.match,
-                token: this.terminals_[symbol] || symbol,
-                line: lexer.yylineno,
-                loc: yyloc,
-                expected: expected
-            });
-        }
-        if (action[0] instanceof Array && action.length > 1) {
-            throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
-        }
-        switch (action[0]) {
-        case 1:
-            stack.push(symbol);
-            vstack.push(lexer.yytext);
-            lstack.push(lexer.yylloc);
-            stack.push(action[1]);
-            symbol = null;
-            if (!preErrorSymbol) {
-                yyleng = lexer.yyleng;
-                yytext = lexer.yytext;
-                yylineno = lexer.yylineno;
-                yyloc = lexer.yylloc;
-                if (recovering > 0) {
-                    recovering--;
-                }
-            } else {
-                symbol = preErrorSymbol;
-                preErrorSymbol = null;
-            }
-            break;
-        case 2:
-            len = this.productions_[action[1]][1];
-            yyval.$ = vstack[vstack.length - len];
-            yyval._$ = {
-                first_line: lstack[lstack.length - (len || 1)].first_line,
-                last_line: lstack[lstack.length - 1].last_line,
-                first_column: lstack[lstack.length - (len || 1)].first_column,
-                last_column: lstack[lstack.length - 1].last_column
-            };
-            if (ranges) {
-                yyval._$.range = [
-                    lstack[lstack.length - (len || 1)].range[0],
-                    lstack[lstack.length - 1].range[1]
-                ];
-            }
-            r = this.performAction.apply(yyval, [
-                yytext,
-                yyleng,
-                yylineno,
-                sharedState.yy,
-                action[1],
-                vstack,
-                lstack
-            ].concat(args));
-            if (typeof r !== 'undefined') {
-                return r;
-            }
-            if (len) {
-                stack = stack.slice(0, -1 * len * 2);
-                vstack = vstack.slice(0, -1 * len);
-                lstack = lstack.slice(0, -1 * len);
-            }
-            stack.push(this.productions_[action[1]][0]);
-            vstack.push(yyval.$);
-            lstack.push(yyval._$);
-            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
-            stack.push(newState);
-            break;
-        case 3:
-            return true;
-        }
-    }
-    return true;
-}};
-
-/* generated by jison-lex 0.3.4 */
-var lexer = (function(){
-var lexer = ({
-
-EOF:1,
-
-parseError:function parseError(str, hash) {
-        if (this.yy.parser) {
-            this.yy.parser.parseError(str, hash);
-        } else {
-            throw new Error(str);
-        }
-    },
-
-// resets the lexer, sets new input
-setInput:function (input, yy) {
-        this.yy = yy || this.yy || {};
-        this._input = input;
-        this._more = this._backtrack = this.done = false;
-        this.yylineno = this.yyleng = 0;
-        this.yytext = this.matched = this.match = '';
-        this.conditionStack = ['INITIAL'];
-        this.yylloc = {
-            first_line: 1,
-            first_column: 0,
-            last_line: 1,
-            last_column: 0
-        };
-        if (this.options.ranges) {
-            this.yylloc.range = [0,0];
-        }
-        this.offset = 0;
-        return this;
-    },
-
-// consumes and returns one char from the input
-input:function () {
-        var ch = this._input[0];
-        this.yytext += ch;
-        this.yyleng++;
-        this.offset++;
-        this.match += ch;
-        this.matched += ch;
-        var lines = ch.match(/(?:\r\n?|\n).*/g);
-        if (lines) {
-            this.yylineno++;
-            this.yylloc.last_line++;
-        } else {
-            this.yylloc.last_column++;
-        }
-        if (this.options.ranges) {
-            this.yylloc.range[1]++;
-        }
-
-        this._input = this._input.slice(1);
-        return ch;
-    },
-
-// unshifts one char (or a string) into the input
-unput:function (ch) {
-        var len = ch.length;
-        var lines = ch.split(/(?:\r\n?|\n)/g);
-
-        this._input = ch + this._input;
-        this.yytext = this.yytext.substr(0, this.yytext.length - len);
-        //this.yyleng -= len;
-        this.offset -= len;
-        var oldLines = this.match.split(/(?:\r\n?|\n)/g);
-        this.match = this.match.substr(0, this.match.length - 1);
-        this.matched = this.matched.substr(0, this.matched.length - 1);
-
-        if (lines.length - 1) {
-            this.yylineno -= lines.length - 1;
-        }
-        var r = this.yylloc.range;
-
-        this.yylloc = {
-            first_line: this.yylloc.first_line,
-            last_line: this.yylineno + 1,
-            first_column: this.yylloc.first_column,
-            last_column: lines ?
-                (lines.length === oldLines.length ? this.yylloc.first_column : 0)
-                 + oldLines[oldLines.length - lines.length].length - lines[0].length :
-              this.yylloc.first_column - len
-        };
-
-        if (this.options.ranges) {
-            this.yylloc.range = [r[0], r[0] + this.yyleng - len];
-        }
-        this.yyleng = this.yytext.length;
-        return this;
-    },
-
-// When called from action, caches matched text and appends it on next action
-more:function () {
-        this._more = true;
-        return this;
-    },
-
-// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
-reject:function () {
-        if (this.options.backtrack_lexer) {
-            this._backtrack = true;
-        } else {
-            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
-                text: "",
-                token: null,
-                line: this.yylineno
-            });
-
-        }
-        return this;
-    },
-
-// retain first n characters of the match
-less:function (n) {
-        this.unput(this.match.slice(n));
-    },
-
-// displays already matched input, i.e. for error messages
-pastInput:function () {
-        var past = this.matched.substr(0, this.matched.length - this.match.length);
-        return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
-    },
-
-// displays upcoming input, i.e. for error messages
-upcomingInput:function () {
-        var next = this.match;
-        if (next.length < 20) {
-            next += this._input.substr(0, 20-next.length);
-        }
-        return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
-    },
-
-// displays the character position where the lexing error occurred, i.e. for error messages
-showPosition:function () {
-        var pre = this.pastInput();
-        var c = new Array(pre.length + 1).join("-");
-        return pre + this.upcomingInput() + "\n" + c + "^";
-    },
-
-// test the lexed token: return FALSE when not a match, otherwise return token
-test_match:function (match, indexed_rule) {
-        var token,
-            lines,
-            backup;
-
-        if (this.options.backtrack_lexer) {
-            // save context
-            backup = {
-                yylineno: this.yylineno,
-                yylloc: {
-                    first_line: this.yylloc.first_line,
-                    last_line: this.last_line,
-                    first_column: this.yylloc.first_column,
-                    last_column: this.yylloc.last_column
-                },
-                yytext: this.yytext,
-                match: this.match,
-                matches: this.matches,
-                matched: this.matched,
-                yyleng: this.yyleng,
-                offset: this.offset,
-                _more: this._more,
-                _input: this._input,
-                yy: this.yy,
-                conditionStack: this.conditionStack.slice(0),
-                done: this.done
-            };
-            if (this.options.ranges) {
-                backup.yylloc.range = this.yylloc.range.slice(0);
-            }
-        }
-
-        lines = match[0].match(/(?:\r\n?|\n).*/g);
-        if (lines) {
-            this.yylineno += lines.length;
-        }
-        this.yylloc = {
-            first_line: this.yylloc.last_line,
-            last_line: this.yylineno + 1,
-            first_column: this.yylloc.last_column,
-            last_column: lines ?
-                         lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
-                         this.yylloc.last_column + match[0].length
-        };
-        this.yytext += match[0];
-        this.match += match[0];
-        this.matches = match;
-        this.yyleng = this.yytext.length;
-        if (this.options.ranges) {
-            this.yylloc.range = [this.offset, this.offset += this.yyleng];
-        }
-        this._more = false;
-        this._backtrack = false;
-        this._input = this._input.slice(match[0].length);
-        this.matched += match[0];
-        token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
-        if (this.done && this._input) {
-            this.done = false;
-        }
-        if (token) {
-            return token;
-        } else if (this._backtrack) {
-            // recover context
-            for (var k in backup) {
-                this[k] = backup[k];
-            }
-            return false; // rule action called reject() implying the next rule should be tested instead.
-        }
-        return false;
-    },
-
-// return next match in input
-next:function () {
-        if (this.done) {
-            return this.EOF;
-        }
-        if (!this._input) {
-            this.done = true;
-        }
-
-        var token,
-            match,
-            tempMatch,
-            index;
-        if (!this._more) {
-            this.yytext = '';
-            this.match = '';
-        }
-        var rules = this._currentRules();
-        for (var i = 0; i < rules.length; i++) {
-            tempMatch = this._input.match(this.rules[rules[i]]);
-            if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
-                match = tempMatch;
-                index = i;
-                if (this.options.backtrack_lexer) {
-                    token = this.test_match(tempMatch, rules[i]);
-                    if (token !== false) {
-                        return token;
-                    } else if (this._backtrack) {
-                        match = false;
-                        continue; // rule action called reject() implying a rule MISmatch.
-                    } else {
-                        // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
-                        return false;
-                    }
-                } else if (!this.options.flex) {
-                    break;
-                }
-            }
-        }
-        if (match) {
-            token = this.test_match(match, rules[index]);
-            if (token !== false) {
-                return token;
-            }
-            // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
-            return false;
-        }
-        if (this._input === "") {
-            return this.EOF;
-        } else {
-            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
-                text: "",
-                token: null,
-                line: this.yylineno
-            });
-        }
-    },
-
-// return next match that has a token
-lex:function lex() {
-        var r = this.next();
-        if (r) {
-            return r;
-        } else {
-            return this.lex();
-        }
-    },
-
-// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
-begin:function begin(condition) {
-        this.conditionStack.push(condition);
-    },
-
-// pop the previously active lexer condition state off the condition stack
-popState:function popState() {
-        var n = this.conditionStack.length - 1;
-        if (n > 0) {
-            return this.conditionStack.pop();
-        } else {
-            return this.conditionStack[0];
-        }
-    },
-
-// produce the lexer rule set which is active for the currently active lexer condition state
-_currentRules:function _currentRules() {
-        if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
-            return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
-        } else {
-            return this.conditions["INITIAL"].rules;
-        }
-    },
-
-// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
-topState:function topState(n) {
-        n = this.conditionStack.length - 1 - Math.abs(n || 0);
-        if (n >= 0) {
-            return this.conditionStack[n];
-        } else {
-            return "INITIAL";
-        }
-    },
-
-// alias for begin(condition)
-pushState:function pushState(condition) {
-        this.begin(condition);
-    },
-
-// return the number of states currently on the stack
-stateStackSize:function stateStackSize() {
-        return this.conditionStack.length;
-    },
-options: {},
-performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
-var YYSTATE=YY_START;
-switch($avoiding_name_collisions) {
-case 0:/* do nothing */
-break;
-case 1:this.begin("string");
-break;
-case 2:this.popState();
-break;
-case 3:return "STR";
-break;
-case 4:return 71;
-break;
-case 5:return 78;
-break;
-case 6:return 72;
-break;
-case 7:return 82;
-break;
-case 8:return 73;
-break;
-case 9:return 74;
-break;
-case 10:return 75;
-break;
-case 11:return 12;
-break;
-case 12:return 30;
-break;
-case 13:return 32;
-break;
-case 14:return 13;
-break;
-case 15:return 13;
-break;
-case 16:return 13;
-break;
-case 17:return 13;
-break;
-case 18:return 13;
-break;
-case 19:return 13;
-break;
-case 20:return 81;
-break;
-case 21:return 91;
-break;
-case 22:return 89;
-break;
-case 23:return 8;
-break;
-case 24:return 86;
-break;
-case 25:return 98;
-break;
-case 26:return 16;
-break;
-case 27:return 15;
-break;
-case 28:return 17;
-break;
-case 29:return 18;
-break;
-case 30:return 53;
-break;
-case 31:return 51;
-break;
-case 32:return 52;
-break;
-case 33:return 54;
-break;
-case 34:return 58;
-break;
-case 35:return 56;
-break;
-case 36:return 57;
-break;
-case 37:return 59;
-break;
-case 38:return 58;
-break;
-case 39:return 56;
-break;
-case 40:return 57;
-break;
-case 41:return 59;
-break;
-case 42:return 63;
-break;
-case 43:return 61;
-break;
-case 44:return 62;
-break;
-case 45:return 64;
-break;
-case 46:return 50;
-break;
-case 47:return 55;
-break;
-case 48:return 60;
-break;
-case 49:return 40;
-break;
-case 50:return 41;
-break;
-case 51:return 46;
-break;
-case 52:return 92;
-break;
-case 53:return 96;
-break;
-case 54:return 84;
-break;
-case 55:return 97;
-break;
-case 56:return 97;
-break;
-case 57:return 88;
-break;
-case 58:return 94;
-break;
-case 59:return 95;
-break;
-case 60:return 65;
-break;
-case 61:return 38;
-break;
-case 62:return 39;
-break;
-case 63:return 36;
-break;
-case 64:return 37;
-break;
-case 65:return 42
-break;
-case 66:return 43
-break;
-case 67:return 101;
-break;
-case 68:return 9;
-break;
-case 69:return 10;
-break;
-case 70:return 11;
-break;
-}
-},
-rules: [/^(?:%%[^\n]*)/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:click\b)/,/^(?:graph\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:LR\b)/,/^(?:RL\b)/,/^(?:TB\b)/,/^(?:BT\b)/,/^(?:TD\b)/,/^(?:BR\b)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:v\b)/,/^(?:\s*--[x]\s*)/,/^(?:\s*-->\s*)/,/^(?:\s*--[o]\s*)/,/^(?:\s*---\s*)/,/^(?:\s*-\.-[x]\s*)/,/^(?:\s*-\.->\s*)/,/^(?:\s*-\.-[o]\s*)/,/^(?:\s*-\.-\s*)/,/^(?:\s*.-[x]\s*)/,/^(?:\s*\.->\s*)/,/^(?:\s*\.-[o]\s*)/,/^(?:\s*\.-\s*)/,/^(?:\s*==[x]\s*)/,/^(?:\s*==>\s*)/,/^(?:\s*==[o]\s*)/,/^(?:\s*==[\=]\s*)/,/^(?:\s*--\s*)/,/^(?:\s*-\.\s*)/,/^(?:\s*==\s*)/,/^(?:\(-)/,/^(?:-\))/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:[A-Za-z]+)/,/^(?:[!"#$%&'*+,-.`?\\_\/])/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:")/,/^(?:\n+)/,/^(?:\s)/,/^(?:$)/],
-conditions: {"string":{"rules":[2,3],"inclusive":false},"INITIAL":{"rules":[0,1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70],"inclusive":true}}
-});
-return lexer;
-})();
-parser.lexer = lexer;
-function Parser () {
-  this.yy = {};
-}
-Parser.prototype = parser;parser.Parser = Parser;
-return new Parser;
-})();
-
-
-if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
-exports.parser = parser;
-exports.Parser = parser.Parser;
-exports.parse = function () { return parser.parse.apply(parser, arguments); };
-exports.main = function commonjsMain(args) {
-    if (!args[1]) {
-        console.log('Usage: '+args[0]+' FILE');
-        process.exit(1);
-    }
-    var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
-    return exports.parser.parse(source);
-};
-if (typeof module !== 'undefined' && require.main === module) {
-  exports.main(process.argv.slice(1));
-}
-}
\ No newline at end of file
diff --git a/_submodules/mermaid/src/diagrams/flowchart/parser/flow.spec.js b/_submodules/mermaid/src/diagrams/flowchart/parser/flow.spec.js
deleted file mode 100644
index 28d273bafe26097bf32323451349027b0decd928..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/flowchart/parser/flow.spec.js
+++ /dev/null
@@ -1,1346 +0,0 @@
-import flowDb from '../flowDb'
-import flow from './flow'
-
-describe('when parsing ', function () {
-  beforeEach(function () {
-    flow.parser.yy = flowDb
-    flow.parser.yy.clear()
-  })
-
-  it('should handle a nodes and edges', function () {
-    const res = flow.parser.parse('graph TD;\nA-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle subgraph with tab indentation', function () {
-    const res = flow.parser.parse('graph TB\nsubgraph One\n\ta1-->a2\nend')
-    const subgraphs = flow.parser.yy.getSubGraphs()
-    expect(subgraphs.length).toBe(1)
-    const subgraph = subgraphs[0]
-    expect(subgraph.nodes.length).toBe(2)
-    expect(subgraph.nodes[0]).toBe('a1')
-    expect(subgraph.nodes[1]).toBe('a2')
-    expect(subgraph.title).toBe('One')
-  })
-
-  it('should handle angle bracket ' > ' as direction LR', function () {
-    const res = flow.parser.parse('graph >;A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-    const direction = flow.parser.yy.getDirection()
-
-    expect(direction).toBe('LR')
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle angle bracket ' < ' as direction RL', function () {
-    const res = flow.parser.parse('graph <;A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-    const direction = flow.parser.yy.getDirection()
-
-    expect(direction).toBe('RL')
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle caret ' ^ ' as direction BT', function () {
-    const res = flow.parser.parse('graph ^;A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-    const direction = flow.parser.yy.getDirection()
-
-    expect(direction).toBe('BT')
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle lower-case \'v\' as direction TB', function () {
-    const res = flow.parser.parse('graph v;A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-    const direction = flow.parser.yy.getDirection()
-
-    expect(direction).toBe('TB')
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle a nodes and edges and a space between link and node', function () {
-    const res = flow.parser.parse('graph TD;A --> B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle a nodes and edges, a space between link and node and each line ending without semicolon', function () {
-    const res = flow.parser.parse('graph TD\nA --> B\n style e red')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle statements ending without semicolon', function () {
-    const res = flow.parser.parse('graph TD\nA-->B\nB-->C')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(2)
-    expect(edges[1].start).toBe('B')
-    expect(edges[1].end).toBe('C')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle a comments', function () {
-    const res = flow.parser.parse('graph TD;\n%% CComment\n A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle comments a at the start', function () {
-    const res = flow.parser.parse('%% Comment\ngraph TD;\n A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle comments at the end', function () {
-    const res = flow.parser.parse('graph TD;\n A-->B\n %% Comment at the find\n')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle comments at the end no trailing newline', function () {
-    const res = flow.parser.parse('graph TD;\n A-->B\n%% Commento')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle comments at the end many trailing newlines', function () {
-    const res = flow.parser.parse('graph TD;\n A-->B\n%% Commento\n\n\n')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle no trailing newlines', function () {
-    const res = flow.parser.parse('graph TD;\n A-->B')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle many trailing newlines', function () {
-    const res = flow.parser.parse('graph TD;\n A-->B\n\n')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-  it('should handle a comments with blank rows in-between', function () {
-    const res = flow.parser.parse('graph TD;\n\n\n %% Comment\n A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle a comments mermaid flowchart code in them', function () {
-    const res = flow.parser.parse('graph TD;\n\n\n %% Test od>Odd shape]-->|Two line<br>edge comment|ro;\n A-->B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(1)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('it should handle a trailing whitespaces after statememnts', function () {
-    const res = flow.parser.parse('graph TD;\n\n\n %% Comment\n A-->B; \n B-->C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(2)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].type).toBe('arrow')
-    expect(edges[0].text).toBe('')
-  })
-
-  it('should handle node names with "end" substring', function () {
-    const res = flow.parser.parse('graph TD\nendpoint --> sender')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['endpoint'].id).toBe('endpoint')
-    expect(vert['sender'].id).toBe('sender')
-    expect(edges[0].start).toBe('endpoint')
-    expect(edges[0].end).toBe('sender')
-  })
-
-  it('should handle node names ending with keywords', function () {
-    const res = flow.parser.parse('graph TD\nblend --> monograph')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['blend'].id).toBe('blend')
-    expect(vert['monograph'].id).toBe('monograph')
-    expect(edges[0].start).toBe('blend')
-    expect(edges[0].end).toBe('monograph')
-  })
-
-  it('should handle open ended edges', function () {
-    const res = flow.parser.parse('graph TD;A---B;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow_open')
-  })
-
-  it('should handle cross ended edges', function () {
-    const res = flow.parser.parse('graph TD;A--xB;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow_cross')
-  })
-
-  it('should handle open ended edges', function () {
-    const res = flow.parser.parse('graph TD;A--oB;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow_circle')
-  })
-  it('should handle subgraphs', function () {
-    const res = flow.parser.parse('graph TD;A-->B;subgraph myTitle;c-->d;end;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle subgraphs', function () {
-    const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\n\n c-->d \nend\n')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle nested subgraphs', function () {
-    const str = 'graph TD\n' +
-            'A-->B\n' +
-            'subgraph myTitle\n\n' +
-            ' c-->d \n\n' +
-            ' subgraph inner\n\n   e-->f \n end \n\n' +
-            ' subgraph inner\n\n   h-->i \n end \n\n' +
-            'end\n'
-    const res = flow.parser.parse(str)
-  })
-
-  it('should handle subgraphs', function () {
-    const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-->d\nend;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle subgraphs', function () {
-    const res = flow.parser.parse('graph TD\nA-->B\nsubgraph myTitle\nc-- text -->d\nd-->e\n end;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle classDefs with style in classes', function () {
-    const res = flow.parser.parse('graph TD\nA-->B\nclassDef exClass font-style:bold;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle classDefs with % in classes', function () {
-    const res = flow.parser.parse('graph TD\nA-->B\nclassDef exClass fill:#f96,stroke:#333,stroke-width:4px,font-size:50%,font-style:bold;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle style definitons with more then 1 digit in a row', function () {
-    const res = flow.parser.parse('graph TD\n' +
-        'A-->B1\n' +
-        'A-->B2\n' +
-        'A-->B3\n' +
-        'A-->B4\n' +
-        'A-->B5\n' +
-        'A-->B6\n' +
-        'A-->B7\n' +
-        'A-->B8\n' +
-        'A-->B9\n' +
-        'A-->B10\n' +
-        'A-->B11\n' +
-        'linkStyle 10 stroke-width:1px;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow')
-  })
-
-  it('should handle line interpolation default definitions', function () {
-    const res = flow.parser.parse('graph TD\n' +
-        'A-->B\n' +
-        'linkStyle default interpolate basis')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.defaultInterpolate).toBe('basis')
-  })
-
-  it('should handle line interpolation numbered definitions', function () {
-    const res = flow.parser.parse('graph TD\n' +
-        'A-->B\n' +
-        'A-->C\n' +
-        'linkStyle 0 interpolate basis\n' +
-        'linkStyle 1 interpolate cardinal')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].interpolate).toBe('basis')
-    expect(edges[1].interpolate).toBe('cardinal')
-  })
-
-  it('should handle line interpolation default with style', function () {
-    const res = flow.parser.parse('graph TD\n' +
-        'A-->B\n' +
-        'linkStyle default interpolate basis stroke-width:1px;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.defaultInterpolate).toBe('basis')
-  })
-
-  it('should handle line interpolation numbered with style', function () {
-    const res = flow.parser.parse('graph TD\n' +
-        'A-->B\n' +
-        'A-->C\n' +
-        'linkStyle 0 interpolate basis stroke-width:1px;\n' +
-        'linkStyle 1 interpolate cardinal stroke-width:1px;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].interpolate).toBe('basis')
-    expect(edges[1].interpolate).toBe('cardinal')
-  })
-
-  describe('it should handle interaction, ', function () {
-    it('it should be possible to use click to a callback', function () {
-      spyOn(flowDb, 'setClickEvent')
-      const res = flow.parser.parse('graph TD\nA-->B\nclick A callback')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback', undefined, undefined)
-    })
-
-    it('it should be possible to use click to a callback with toolip', function () {
-      spyOn(flowDb, 'setClickEvent')
-      const res = flow.parser.parse('graph TD\nA-->B\nclick A callback "tooltip"')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', 'callback', undefined, 'tooltip')
-    })
-
-    it('should handle interaction - click to a link', function () {
-      spyOn(flowDb, 'setClickEvent')
-      const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html"')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', undefined, 'click.html', undefined)
-    })
-    it('should handle interaction - click to a link with tooltip', function () {
-      spyOn(flowDb, 'setClickEvent')
-      const res = flow.parser.parse('graph TD\nA-->B\nclick A "click.html" "tooltip"')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(flowDb.setClickEvent).toHaveBeenCalledWith('A', undefined, 'click.html', 'tooltip')
-    })
-  })
-
-  describe('it should handle text on edges', function () {
-    it('it should handle text without space', function () {
-      const res = flow.parser.parse('graph TD;A--x|textNoSpace|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('should handle  with space', function () {
-      const res = flow.parser.parse('graph TD;A--x|text including space|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('it should handle text with /', function () {
-      const res = flow.parser.parse('graph TD;A--x|text with / should work|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].text).toBe('text with / should work')
-    })
-
-    it('it should handle space and space between vertices and link', function () {
-      const res = flow.parser.parse('graph TD;A --x|textNoSpace| B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('should handle space and CAPS', function () {
-      const res = flow.parser.parse('graph TD;A--x|text including CAPS space|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('should handle space and dir', function () {
-      const res = flow.parser.parse('graph TD;A--x|text including URL space|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(edges[0].text).toBe('text including URL space')
-    })
-
-    it('should handle space and send', function () {
-      const res = flow.parser.parse('graph TD;A--text including URL space and send-->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow')
-      expect(edges[0].text).toBe('text including URL space and send')
-    })
-    it('should handle space and send', function () {
-      const res = flow.parser.parse('graph TD;A-- text including URL space and send -->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow')
-      expect(edges[0].text).toBe('text including URL space and send')
-    })
-
-    it('should handle space and dir (TD)', function () {
-      const res = flow.parser.parse('graph TD;A--x|text including R TD space|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(edges[0].text).toBe('text including R TD space')
-    })
-    it('should handle `', function () {
-      const res = flow.parser.parse('graph TD;A--x|text including `|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(edges[0].text).toBe('text including `')
-    })
-    it('should handle v in node ids only v', function () {
-            // only v
-      const res = flow.parser.parse('graph TD;A--xv(my text);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(vert['v'].text).toBe('my text')
-    })
-    it('should handle v in node ids v at end', function () {
-            // v at end
-      const res = flow.parser.parse('graph TD;A--xcsv(my text);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(vert['csv'].text).toBe('my text')
-    })
-    it('should handle v in node ids v in middle', function () {
-            // v in middle
-      const res = flow.parser.parse('graph TD;A--xava(my text);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(vert['ava'].text).toBe('my text')
-    })
-    it('should handle v in node ids, v at start', function () {
-            // v at start
-      const res = flow.parser.parse('graph TD;A--xva(my text);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(vert['va'].text).toBe('my text')
-    })
-    it('should handle keywords', function () {
-      const res = flow.parser.parse('graph TD;A--x|text including graph space|B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].text).toBe('text including graph space')
-    })
-    it('should handle keywords', function () {
-      const res = flow.parser.parse('graph TD;V-->a[v]')
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-      expect(vert['a'].text).toBe('v')
-    })
-    it('should handle keywords', function () {
-      const res = flow.parser.parse('graph TD;V-->a[v]')
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-      expect(vert['a'].text).toBe('v')
-    })
-    it('should handle quoted text', function () {
-      const res = flow.parser.parse('graph TD;V-- "test string()" -->a[v]')
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-      expect(edges[0].text).toBe('test string()')
-    })
-  })
-
-  describe('it should handle new line type notation', function () {
-    it('it should handle regular lines', function () {
-      const res = flow.parser.parse('graph TD;A-->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].stroke).toBe('normal')
-    })
-    it('it should handle dotted lines', function () {
-      const res = flow.parser.parse('graph TD;A-.->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].stroke).toBe('dotted')
-    })
-    it('it should handle dotted lines', function () {
-      const res = flow.parser.parse('graph TD;A==>B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].stroke).toBe('thick')
-    })
-    it('it should handle text on lines', function () {
-      const res = flow.parser.parse('graph TD;A-- test text with == -->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].stroke).toBe('normal')
-    })
-    it('it should handle text on lines', function () {
-      const res = flow.parser.parse('graph TD;A-. test text with == .->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].stroke).toBe('dotted')
-    })
-    it('it should handle text on lines', function () {
-      const res = flow.parser.parse('graph TD;A== test text with - ==>B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].stroke).toBe('thick')
-    })
-  })
-
-  describe('it should handle text on edges using the new notation', function () {
-    it('it should handle text without space', function () {
-      const res = flow.parser.parse('graph TD;A-- textNoSpace --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('it should handle text with multiple leading space', function () {
-      const res = flow.parser.parse('graph TD;A--    textNoSpace --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('should handle  with space', function () {
-      const res = flow.parser.parse('graph TD;A-- text including space --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('it should handle text with /', function () {
-      const res = flow.parser.parse('graph TD;A -- text with / should work --x B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].text).toBe('text with / should work')
-    })
-
-    it('it should handle space and space between vertices and link', function () {
-      const res = flow.parser.parse('graph TD;A -- textNoSpace --x B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('should handle space and CAPS', function () {
-      const res = flow.parser.parse('graph TD;A-- text including CAPS space --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-    })
-
-    it('should handle space and dir', function () {
-      const res = flow.parser.parse('graph TD;A-- text including URL space --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(edges[0].text).toBe('text including URL space')
-    })
-
-    it('should handle space and dir (TD)', function () {
-      const res = flow.parser.parse('graph TD;A-- text including R TD space --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].type).toBe('arrow_cross')
-      expect(edges[0].text).toBe('text including R TD space')
-    })
-    it('should handle keywords', function () {
-      const res = flow.parser.parse('graph TD;A-- text including graph space and v --xB;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].text).toBe('text including graph space and v')
-    })
-    it('should handle keywords', function () {
-      const res = flow.parser.parse('graph TD;A-- text including graph space and v --xB[blav]')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(edges[0].text).toBe('text including graph space and v')
-    })
-        // xit('should handle text on open links',function(){
-        //    const res = flow.parser.parse('graph TD;A-- text including graph space --B');
-        //
-        //    const vert = flow.parser.yy.getVertices();
-        //    const edges = flow.parser.yy.getEdges();
-        //
-        //    expect(edges[0].text).toBe('text including graph space');
-        //
-        // });
-  })
-
-  it('should handle multi-line text', function () {
-    const res = flow.parser.parse('graph TD;A--o|text space|B;\n B-->|more text with space|C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges[0].type).toBe('arrow_circle')
-    expect(edges[1].type).toBe('arrow')
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(vert['C'].id).toBe('C')
-    expect(edges.length).toBe(2)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-        // expect(edges[0].text).toBe('text space');
-    expect(edges[1].start).toBe('B')
-    expect(edges[1].end).toBe('C')
-    expect(edges[1].text).toBe('more text with space')
-  })
-
-  it('should handle multiple edges', function () {
-    const res = flow.parser.parse('graph TD;A---|This is the 123 s text|B;\nA---|This is the second edge|B;')
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].id).toBe('A')
-    expect(vert['B'].id).toBe('B')
-    expect(edges.length).toBe(2)
-    expect(edges[0].start).toBe('A')
-    expect(edges[0].end).toBe('B')
-    expect(edges[0].text).toBe('This is the 123 s text')
-    expect(edges[1].start).toBe('A')
-    expect(edges[1].end).toBe('B')
-    expect(edges[1].text).toBe('This is the second edge')
-  })
-
-  it('should handle text in vertices with space', function () {
-    const res = flow.parser.parse('graph TD;A[chimpansen hoppar]-->C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].type).toBe('square')
-    expect(vert['A'].text).toBe('chimpansen hoppar')
-  })
-
-  it('should handle text in vertices with space with spaces between vertices and link', function () {
-    const res = flow.parser.parse('graph TD;A[chimpansen hoppar] --> C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].type).toBe('square')
-    expect(vert['A'].text).toBe('chimpansen hoppar')
-  })
-
-  it('should handle quoted text in vertices ', function () {
-    const res = flow.parser.parse('graph TD;A["chimpansen hoppar ()[]"] --> C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].type).toBe('square')
-    expect(vert['A'].text).toBe('chimpansen hoppar ()[]')
-  })
-
-  it('should handle text in circle vertices with space', function () {
-    const res = flow.parser.parse('graph TD;A((chimpansen hoppar))-->C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].type).toBe('circle')
-    expect(vert['A'].text).toBe('chimpansen hoppar')
-  })
-
-  it('should handle text in ellipse vertices', function () {
-    const res = flow.parser.parse('graph TD\nA(-this is an ellipse-)-->B')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].type).toBe('ellipse')
-    expect(vert['A'].text).toBe('this is an ellipse')
-  })
-
-  it('should handle text in diamond vertices with space', function () {
-    const res = flow.parser.parse('graph TD;A(chimpansen hoppar)-->C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].type).toBe('round')
-    expect(vert['A'].text).toBe('chimpansen hoppar')
-  })
-
-  it('should handle text in with ?', function () {
-    const res = flow.parser.parse('graph TD;A(?)-->|?|C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].text).toBe('?')
-    expect(edges[0].text).toBe('?')
-  })
-  it('should handle text in with éèêàçô', function () {
-    const res = flow.parser.parse('graph TD;A(éèêàçô)-->|éèêàçô|C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].text).toBe('éèêàçô')
-    expect(edges[0].text).toBe('éèêàçô')
-  })
-
-  it('should handle text in with ,.?!+-*', function () {
-    const res = flow.parser.parse('graph TD;A(,.?!+-*)-->|,.?!+-*|C;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['A'].text).toBe(',.?!+-*')
-    expect(edges[0].text).toBe(',.?!+-*')
-  })
-
-  describe('it should handle text in vertices, ', function () {
-    it('it should handle space', function () {
-      const res = flow.parser.parse('graph TD;A-->C(Chimpansen hoppar);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(vert['C'].type).toBe('round')
-      expect(vert['C'].text).toBe('Chimpansen hoppar')
-    })
-    it('it should handle åäö and minus', function () {
-      const res = flow.parser.parse('graph TD;A-->C{Chimpansen hoppar åäö-ÅÄÖ};')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(vert['C'].type).toBe('diamond')
-      expect(vert['C'].text).toBe('Chimpansen hoppar åäö-ÅÄÖ')
-    })
-
-    it('it should handle with åäö, minus and space and br', function () {
-      const res = flow.parser.parse('graph TD;A-->C(Chimpansen hoppar åäö  <br> -  ÅÄÖ);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(vert['C'].type).toBe('round')
-      expect(vert['C'].text).toBe('Chimpansen hoppar åäö  <br> -  ÅÄÖ')
-    })
-        // xit('it should handle åäö, minus and space and br',function(){
-        //    const res = flow.parser.parse('graph TD; A[Object&#40;foo,bar&#41;]-->B(Thing);');
-        //
-        //    const vert = flow.parser.yy.getVertices();
-        //    const edges = flow.parser.yy.getEdges();
-        //
-        //    expect(vert['C'].type).toBe('round');
-        //    expect(vert['C'].text).toBe(' A[Object&#40;foo,bar&#41;]-->B(Thing);');
-        // });
-    it('it should handle unicode chars', function () {
-      const res = flow.parser.parse('graph TD;A-->C(Начало);')
-
-      const vert = flow.parser.yy.getVertices()
-
-      expect(vert['C'].text).toBe('Начало')
-    })
-    it('it should handle backslask', function () {
-      const res = flow.parser.parse('graph TD;A-->C(c:\\windows);')
-
-      const vert = flow.parser.yy.getVertices()
-
-      expect(vert['C'].text).toBe('c:\\windows')
-    })
-    it('it should handle CAPS', function () {
-      const res = flow.parser.parse('graph TD;A-->C(some CAPS);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(vert['C'].type).toBe('round')
-      expect(vert['C'].text).toBe('some CAPS')
-    })
-    it('it should handle directions', function () {
-      const res = flow.parser.parse('graph TD;A-->C(some URL);')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(vert['C'].type).toBe('round')
-      expect(vert['C'].text).toBe('some URL')
-    })
-  })
-
-  it('should handle a single node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;A;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['A'].styles.length).toBe(0)
-  })
-
-  it('should handle a single square node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a[A];')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].styles.length).toBe(0)
-    expect(vert['a'].type).toBe('square')
-  })
-  it('should handle a single round square node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a[A];')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].styles.length).toBe(0)
-    expect(vert['a'].type).toBe('square')
-  })
-  it('should handle a single circle node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a((A));')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].type).toBe('circle')
-  })
-  it('should handle a single round node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a(A);')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].type).toBe('round')
-  })
-  it('should handle a single odd node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a>A];')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].type).toBe('odd')
-  })
-  it('should handle a single diamond node', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a{A};')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].type).toBe('diamond')
-  })
-  it('should handle a single diamond node with html in it', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a{A <br> end};')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].type).toBe('diamond')
-    expect(vert['a'].text).toBe('A <br> end')
-  })
-  it('should handle a single round node with html in it', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;a(A <br> end);')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['a'].type).toBe('round')
-    expect(vert['a'].text).toBe('A <br> end')
-  })
-  it('should handle a single node with alphanumerics starting on a char', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;id1;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['id1'].styles.length).toBe(0)
-  })
-  it('should handle a single node with alphanumerics starting on a num', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;1id;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['1id'].styles.length).toBe(0)
-  })
-  it('should handle a single node with alphanumerics containing a minus sign', function () {
-        // Silly but syntactically correct
-    const res = flow.parser.parse('graph TD;i-d;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(0)
-    expect(vert['i-d'].styles.length).toBe(0)
-  })
-    // log.debug(flow.parser.parse('graph TD;style Q background:#fff;'));
-  it('should handle styles for vertices', function () {
-    const res = flow.parser.parse('graph TD;style Q background:#fff;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    const style = vert['Q'].styles[0]
-
-    expect(vert['Q'].styles.length).toBe(1)
-    expect(vert['Q'].styles[0]).toBe('background:#fff')
-  })
-
-    // log.debug(flow.parser.parse('graph TD;style Q background:#fff;'));
-  it('should handle styles for edges', function () {
-    const res = flow.parser.parse('graph TD;a-->b;\nstyle #0 stroke: #f66;')
-
-    const edges = flow.parser.yy.getEdges()
-
-    expect(edges.length).toBe(1)
-  })
-
-  it('should handle multiple styles for a vortex', function () {
-    const res = flow.parser.parse('graph TD;style R background:#fff,border:1px solid red;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['R'].styles.length).toBe(2)
-    expect(vert['R'].styles[0]).toBe('background:#fff')
-    expect(vert['R'].styles[1]).toBe('border:1px solid red')
-  })
-
-  it('should handle multiple styles in a graph', function () {
-    const res = flow.parser.parse('graph TD;style S background:#aaa;\nstyle T background:#bbb,border:1px solid red;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['S'].styles.length).toBe(1)
-    expect(vert['T'].styles.length).toBe(2)
-    expect(vert['S'].styles[0]).toBe('background:#aaa')
-    expect(vert['T'].styles[0]).toBe('background:#bbb')
-    expect(vert['T'].styles[1]).toBe('border:1px solid red')
-  })
-
-  it('should handle styles and graph definitons in a graph', function () {
-    const res = flow.parser.parse('graph TD;S-->T;\nstyle S background:#aaa;\nstyle T background:#bbb,border:1px solid red;')
-
-    const vert = flow.parser.yy.getVertices()
-    const edges = flow.parser.yy.getEdges()
-
-    expect(vert['S'].styles.length).toBe(1)
-    expect(vert['T'].styles.length).toBe(2)
-    expect(vert['S'].styles[0]).toBe('background:#aaa')
-    expect(vert['T'].styles[0]).toBe('background:#bbb')
-    expect(vert['T'].styles[1]).toBe('border:1px solid red')
-  })
-  it('should handle styles and graph definitons in a graph', function () {
-    const res = flow.parser.parse('graph TD;style T background:#bbb,border:1px solid red;')
-        // const res = flow.parser.parse('graph TD;style T background: #bbb;');
-
-    const vert = flow.parser.yy.getVertices()
-
-    expect(vert['T'].styles.length).toBe(2)
-    expect(vert['T'].styles[0]).toBe('background:#bbb')
-    expect(vert['T'].styles[1]).toBe('border:1px solid red')
-  })
-
-  describe('special characters should be be handled.', function () {
-    const charTest = function (char) {
-      const res = flow.parser.parse('graph TD;A(' + char + ')-->B;')
-
-      const vert = flow.parser.yy.getVertices()
-      const edges = flow.parser.yy.getEdges()
-
-      expect(vert['A'].id).toBe('A')
-      expect(vert['B'].id).toBe('B')
-      expect(vert['A'].text).toBe(char)
-    }
-
-    it('it should be able to parse a \'.\'', function () {
-      charTest('.')
-      charTest('Start 103a.a1')
-    })
-
-    it('it should be able to parse text containing \'_\'', function () {
-      charTest('_')
-    })
-
-    it('it should be able to parse a \':\'', function () {
-      charTest(':')
-    })
-
-    it('it should be able to parse a \',\'', function () {
-      charTest(',')
-    })
-
-    it('it should be able to parse text containing \'-\'', function () {
-      charTest('a-b')
-    })
-
-    it('it should be able to parse a \'+\'', function () {
-      charTest('+')
-    })
-
-    it('it should be able to parse a \'*\'', function () {
-      charTest('*')
-    })
-
-    it('it should be able to parse a \'<\'', function () {
-      charTest('<')
-    })
-
-    it('it should be able to parse a \'>\'', function () {
-      charTest('>')
-    })
-
-    it('it should be able to parse a \'=\'', function () {
-      charTest('=')
-    })
-  })
-
-  it('should be possible to declare a class', function () {
-    const res = flow.parser.parse('graph TD;classDef exClass background:#bbb,border:1px solid red;')
-        // const res = flow.parser.parse('graph TD;style T background: #bbb;');
-
-    const classes = flow.parser.yy.getClasses()
-
-    expect(classes['exClass'].styles.length).toBe(2)
-    expect(classes['exClass'].styles[0]).toBe('background:#bbb')
-    expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
-  })
-
-  it('should be possible to declare a class with a dot in the style', function () {
-    const res = flow.parser.parse('graph TD;classDef exClass background:#bbb,border:1.5px solid red;')
-        // const res = flow.parser.parse('graph TD;style T background: #bbb;');
-
-    const classes = flow.parser.yy.getClasses()
-
-    expect(classes['exClass'].styles.length).toBe(2)
-    expect(classes['exClass'].styles[0]).toBe('background:#bbb')
-    expect(classes['exClass'].styles[1]).toBe('border:1.5px solid red')
-  })
-  it('should be possible to declare a class with a space in the style', function () {
-    const res = flow.parser.parse('graph TD;classDef exClass background:  #bbb,border:1.5px solid red;')
-        // const res = flow.parser.parse('graph TD;style T background  :  #bbb;');
-
-    const classes = flow.parser.yy.getClasses()
-
-    expect(classes['exClass'].styles.length).toBe(2)
-    expect(classes['exClass'].styles[0]).toBe('background:  #bbb')
-    expect(classes['exClass'].styles[1]).toBe('border:1.5px solid red')
-  })
-  it('should be possible to apply a class to a vertex', function () {
-    let statement = ''
-
-    statement = statement + 'graph TD;' + '\n'
-    statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n'
-    statement = statement + 'a-->b;' + '\n'
-    statement = statement + 'class a exClass;'
-
-    const res = flow.parser.parse(statement)
-
-    const classes = flow.parser.yy.getClasses()
-
-    expect(classes['exClass'].styles.length).toBe(2)
-    expect(classes['exClass'].styles[0]).toBe('background:#bbb')
-    expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
-  })
-  it('should be possible to apply a class to a comma separated list of vertices', function () {
-    let statement = ''
-
-    statement = statement + 'graph TD;' + '\n'
-    statement = statement + 'classDef exClass background:#bbb,border:1px solid red;' + '\n'
-    statement = statement + 'a-->b;' + '\n'
-    statement = statement + 'class a,b exClass;'
-
-    const res = flow.parser.parse(statement)
-
-    const classes = flow.parser.yy.getClasses()
-    const vertices = flow.parser.yy.getVertices()
-
-    expect(classes['exClass'].styles.length).toBe(2)
-    expect(classes['exClass'].styles[0]).toBe('background:#bbb')
-    expect(classes['exClass'].styles[1]).toBe('border:1px solid red')
-    expect(vertices['a'].classes[0]).toBe('exClass')
-    expect(vertices['b'].classes[0]).toBe('exClass')
-  })
-})
diff --git a/_submodules/mermaid/src/diagrams/gantt/gantt.spec.js b/_submodules/mermaid/src/diagrams/gantt/gantt.spec.js
deleted file mode 100644
index a170be6e1ffc4ba4dcf4a5366e5ed5c2d9e6a97b..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/gantt/gantt.spec.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/* eslint-env jasmine */
-import { parser } from './parser/gantt'
-import ganttDb from './ganttDb'
-
-describe('when parsing a gantt diagram it', function () {
-  beforeEach(function () {
-    parser.yy = ganttDb
-  })
-
-  it('should handle a dateFormat definition', function () {
-    const str = 'gantt\ndateFormat yyyy-mm-dd'
-
-    parser.parse(str)
-  })
-  it('should handle a title definition', function () {
-    const str = 'gantt\ndateFormat yyyy-mm-dd\ntitle Adding gantt diagram functionality to mermaid'
-
-    parser.parse(str)
-  })
-  it('should handle a section definition', function () {
-    const str = 'gantt\n' +
-      'dateFormat yyyy-mm-dd\n' +
-      'title Adding gantt diagram functionality to mermaid\n' +
-      'section Documentation'
-
-    parser.parse(str)
-  })
-  /**
-   * Beslutsflöde inligt nedan. Obs bla bla bla
-   * ```
-   * graph TD
-   * A[Hard pledge] -- text on link -->B(Round edge)
-   * B --> C{to do or not to do}
-   * C -->|Too| D[Result one]
-   * C -->|Doo| E[Result two]
-   ```
-   * params bapa - a unique bapap
-   */
-  it('should handle a task definition', function () {
-    const str = 'gantt\n' +
-      'dateFormat yyyy-mm-dd\n' +
-      'title Adding gantt diagram functionality to mermaid\n' +
-      'section Documentation\n' +
-      'Design jison grammar:des1, 2014-01-01, 2014-01-04'
-
-    parser.parse(str)
-  })
-})
diff --git a/_submodules/mermaid/src/diagrams/gantt/ganttDb.js b/_submodules/mermaid/src/diagrams/gantt/ganttDb.js
deleted file mode 100644
index b4e4fda763a9305d5d7b3fb5065d8aacc6e213a2..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/gantt/ganttDb.js
+++ /dev/null
@@ -1,363 +0,0 @@
-import moment from 'moment'
-import { logger } from '../../logger'
-
-let dateFormat = ''
-let axisFormat = ''
-let title = ''
-let sections = []
-let tasks = []
-let currentSection = ''
-
-export const clear = function () {
-  sections = []
-  tasks = []
-  currentSection = ''
-  title = ''
-  taskCnt = 0
-  lastTask = undefined
-  lastTaskID = undefined
-  rawTasks = []
-}
-
-export const setAxisFormat = function (txt) {
-  axisFormat = txt
-}
-
-export const getAxisFormat = function () {
-  return axisFormat
-}
-
-export const setDateFormat = function (txt) {
-  dateFormat = txt
-}
-
-export const setTitle = function (txt) {
-  title = txt
-}
-
-export const getTitle = function () {
-  return title
-}
-
-export const addSection = function (txt) {
-  currentSection = txt
-  sections.push(txt)
-}
-
-export const getTasks = function () {
-  let allItemsPricessed = compileTasks()
-  const maxDepth = 10
-  let iterationCount = 0
-  while (!allItemsPricessed && (iterationCount < maxDepth)) {
-    allItemsPricessed = compileTasks()
-    iterationCount++
-  }
-
-  tasks = rawTasks
-
-  return tasks
-}
-
-const getStartDate = function (prevTime, dateFormat, str) {
-  str = str.trim()
-
-  // Test for after
-  const re = /^after\s+([\d\w-]+)/
-  const afterStatement = re.exec(str.trim())
-
-  if (afterStatement !== null) {
-    const task = findTaskById(afterStatement[1])
-
-    if (typeof task === 'undefined') {
-      const dt = new Date()
-      dt.setHours(0, 0, 0, 0)
-      return dt
-    }
-    return task.endTime
-  }
-
-  // Check for actual date set
-  if (moment(str, dateFormat.trim(), true).isValid()) {
-    return moment(str, dateFormat.trim(), true).toDate()
-  } else {
-    logger.debug('Invalid date:' + str)
-    logger.debug('With date format:' + dateFormat.trim())
-  }
-
-  // Default date - now
-  return new Date()
-}
-
-const getEndDate = function (prevTime, dateFormat, str) {
-  str = str.trim()
-
-  // Check for actual date
-  if (moment(str, dateFormat.trim(), true).isValid()) {
-    return moment(str, dateFormat.trim()).toDate()
-  }
-
-  const d = moment(prevTime)
-  // Check for length
-  const re = /^([\d]+)([wdhms])/
-  const durationStatement = re.exec(str.trim())
-
-  if (durationStatement !== null) {
-    switch (durationStatement[2]) {
-      case 's':
-        d.add(durationStatement[1], 'seconds')
-        break
-      case 'm':
-        d.add(durationStatement[1], 'minutes')
-        break
-      case 'h':
-        d.add(durationStatement[1], 'hours')
-        break
-      case 'd':
-        d.add(durationStatement[1], 'days')
-        break
-      case 'w':
-        d.add(durationStatement[1], 'weeks')
-        break
-    }
-    return d.toDate()
-  }
-  // Default date - now
-  return d.toDate()
-}
-
-let taskCnt = 0
-const parseId = function (idStr) {
-  if (typeof idStr === 'undefined') {
-    taskCnt = taskCnt + 1
-    return 'task' + taskCnt
-  }
-  return idStr
-}
-// id, startDate, endDate
-// id, startDate, length
-// id, after x, endDate
-// id, after x, length
-// startDate, endDate
-// startDate, length
-// after x, endDate
-// after x, length
-// endDate
-// length
-
-const compileData = function (prevTask, dataStr) {
-  let ds
-
-  if (dataStr.substr(0, 1) === ':') {
-    ds = dataStr.substr(1, dataStr.length)
-  } else {
-    ds = dataStr
-  }
-
-  const data = ds.split(',')
-
-  const task = {}
-
-  // Get tags like active, done cand crit
-  let matchFound = true
-  while (matchFound) {
-    matchFound = false
-    if (data[0].match(/^\s*active\s*$/)) {
-      task.active = true
-      data.shift(1)
-      matchFound = true
-    }
-    if (data[0].match(/^\s*done\s*$/)) {
-      task.done = true
-      data.shift(1)
-      matchFound = true
-    }
-    if (data[0].match(/^\s*crit\s*$/)) {
-      task.crit = true
-      data.shift(1)
-      matchFound = true
-    }
-  }
-  for (let i = 0; i < data.length; i++) {
-    data[i] = data[i].trim()
-  }
-
-  switch (data.length) {
-    case 1:
-      task.id = parseId()
-      task.startTime = prevTask.endTime
-      task.endTime = getEndDate(task.startTime, dateFormat, data[0])
-      break
-    case 2:
-      task.id = parseId()
-      task.startTime = getStartDate(undefined, dateFormat, data[0])
-      task.endTime = getEndDate(task.startTime, dateFormat, data[1])
-      break
-    case 3:
-      task.id = parseId(data[0])
-      task.startTime = getStartDate(undefined, dateFormat, data[1])
-      task.endTime = getEndDate(task.startTime, dateFormat, data[2])
-      break
-    default:
-  }
-
-  return task
-}
-
-const parseData = function (prevTaskId, dataStr) {
-  let ds
-  if (dataStr.substr(0, 1) === ':') {
-    ds = dataStr.substr(1, dataStr.length)
-  } else {
-    ds = dataStr
-  }
-
-  const data = ds.split(',')
-
-  const task = {}
-
-  // Get tags like active, done cand crit
-  let matchFound = true
-  while (matchFound) {
-    matchFound = false
-    if (data[0].match(/^\s*active\s*$/)) {
-      task.active = true
-      data.shift(1)
-      matchFound = true
-    }
-    if (data[0].match(/^\s*done\s*$/)) {
-      task.done = true
-      data.shift(1)
-      matchFound = true
-    }
-    if (data[0].match(/^\s*crit\s*$/)) {
-      task.crit = true
-      data.shift(1)
-      matchFound = true
-    }
-  }
-  for (let i = 0; i < data.length; i++) {
-    data[i] = data[i].trim()
-  }
-
-  switch (data.length) {
-    case 1:
-      task.id = parseId()
-      task.startTime = { type: 'prevTaskEnd', id: prevTaskId }
-      task.endTime = { data: data[0] }
-      break
-    case 2:
-      task.id = parseId()
-      task.startTime = { type: 'getStartDate', startData: data[0] }
-      task.endTime = { data: data[1] }
-      break
-    case 3:
-      task.id = parseId(data[0])
-      task.startTime = { type: 'getStartDate', startData: data[1] }
-      task.endTime = { data: data[2] }
-      break
-    default:
-  }
-
-  return task
-}
-
-let lastTask
-let lastTaskID
-let rawTasks = []
-const taskDb = {}
-export const addTask = function (descr, data) {
-  const rawTask = {
-    section: currentSection,
-    type: currentSection,
-    processed: false,
-    raw: { data: data },
-    task: descr
-  }
-  const taskInfo = parseData(lastTaskID, data)
-  rawTask.raw.startTime = taskInfo.startTime
-  rawTask.raw.endTime = taskInfo.endTime
-  rawTask.id = taskInfo.id
-  rawTask.prevTaskId = lastTaskID
-  rawTask.active = taskInfo.active
-  rawTask.done = taskInfo.done
-  rawTask.crit = taskInfo.crit
-
-  const pos = rawTasks.push(rawTask)
-
-  lastTaskID = rawTask.id
-  // Store cross ref
-  taskDb[rawTask.id] = pos - 1
-}
-
-export const findTaskById = function (id) {
-  const pos = taskDb[id]
-  return rawTasks[pos]
-}
-
-export const addTaskOrg = function (descr, data) {
-  const newTask = {
-    section: currentSection,
-    type: currentSection,
-    description: descr,
-    task: descr
-  }
-  const taskInfo = compileData(lastTask, data)
-  newTask.startTime = taskInfo.startTime
-  newTask.endTime = taskInfo.endTime
-  newTask.id = taskInfo.id
-  newTask.active = taskInfo.active
-  newTask.done = taskInfo.done
-  newTask.crit = taskInfo.crit
-  lastTask = newTask
-  tasks.push(newTask)
-}
-
-const compileTasks = function () {
-  const compileTask = function (pos) {
-    const task = rawTasks[pos]
-    let startTime = ''
-    switch (rawTasks[pos].raw.startTime.type) {
-      case 'prevTaskEnd':
-        const prevTask = findTaskById(task.prevTaskId)
-        task.startTime = prevTask.endTime
-        break
-      case 'getStartDate':
-        startTime = getStartDate(undefined, dateFormat, rawTasks[pos].raw.startTime.startData)
-        if (startTime) {
-          rawTasks[pos].startTime = startTime
-        }
-        break
-    }
-
-    if (rawTasks[pos].startTime) {
-      rawTasks[pos].endTime = getEndDate(rawTasks[pos].startTime, dateFormat, rawTasks[pos].raw.endTime.data)
-      if (rawTasks[pos].endTime) {
-        rawTasks[pos].processed = true
-      }
-    }
-
-    return rawTasks[pos].processed
-  }
-
-  let allProcessed = true
-  for (let i = 0; i < rawTasks.length; i++) {
-    compileTask(i)
-
-    allProcessed = allProcessed && rawTasks[i].processed
-  }
-  return allProcessed
-}
-
-export default {
-  clear,
-  setDateFormat,
-  setAxisFormat,
-  getAxisFormat,
-  setTitle,
-  getTitle,
-  addSection,
-  getTasks,
-  addTask,
-  findTaskById,
-  addTaskOrg
-}
diff --git a/_submodules/mermaid/src/diagrams/gantt/ganttDb.spec.js b/_submodules/mermaid/src/diagrams/gantt/ganttDb.spec.js
deleted file mode 100644
index a956e3605324b0bf9b671071856444f03c6b262e..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/gantt/ganttDb.spec.js
+++ /dev/null
@@ -1,175 +0,0 @@
-/* eslint-env jasmine */
-import moment from 'moment'
-import ganttDb from './ganttDb'
-
-describe('when using the ganttDb', function () {
-  beforeEach(function () {
-    ganttDb.clear()
-  })
-
-  it('should handle an fixed dates', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2013-01-12')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-12', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].id).toEqual('id1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-  it('should handle duration (days) instead of fixed date to determine end date', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2d')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-03', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].id).toEqual('id1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-  it('should handle duration (hours) instead of fixed date to determine end date', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2h')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-01 2:00', 'YYYY-MM-DD hh:mm').toDate())
-    expect(tasks[0].id).toEqual('id1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-  it('should handle duration (minutes) instead of fixed date to determine end date', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2m')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-01 00:02', 'YYYY-MM-DD hh:mm').toDate())
-    expect(tasks[0].id).toEqual('id1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-  it('should handle duration (seconds) instead of fixed date to determine end date', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2s')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-01 00:00:02', 'YYYY-MM-DD hh:mm:ss').toDate())
-    expect(tasks[0].id).toEqual('id1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-  it('should handle duration (weeks) instead of fixed date to determine end date', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-15', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].id).toEqual('id1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-
-  it('should handle relative start date based on id', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    ganttDb.addTask('test2', 'id2,after id1,1d')
-
-    const tasks = ganttDb.getTasks()
-
-    expect(tasks[1].startTime).toEqual(moment('2013-01-15', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].id).toEqual('id2')
-    expect(tasks[1].task).toEqual('test2')
-  })
-
-  it('should handle relative start date based on id when id is invalid', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    ganttDb.addTask('test2', 'id2,after id3,1d')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[1].startTime).toEqual(new Date((new Date()).setHours(0, 0, 0, 0)))
-    expect(tasks[1].id).toEqual('id2')
-    expect(tasks[1].task).toEqual('test2')
-  })
-
-  it('should handle fixed dates without id', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', '2013-01-01,2013-01-12')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-12', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].id).toEqual('task1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-
-  it('should handle duration instead of a fixed date to determine end date without id', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', '2013-01-01,4d')
-    const tasks = ganttDb.getTasks()
-    expect(tasks[0].startTime).toEqual(moment('2013-01-01', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].endTime).toEqual(moment('2013-01-05', 'YYYY-MM-DD').toDate())
-    expect(tasks[0].id).toEqual('task1')
-    expect(tasks[0].task).toEqual('test1')
-  })
-
-  it('should handle relative start date of a fixed date to determine end date without id', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    ganttDb.addTask('test2', 'after id1,1d')
-
-    const tasks = ganttDb.getTasks()
-
-    expect(tasks[1].startTime).toEqual(moment('2013-01-15', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].id).toEqual('task1')
-    expect(tasks[1].task).toEqual('test2')
-  })
-  it('should handle a new task with only an end date as definition', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    ganttDb.addTask('test2', '2013-01-26')
-
-    const tasks = ganttDb.getTasks()
-
-    expect(tasks[1].startTime).toEqual(moment('2013-01-15', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].endTime).toEqual(moment('2013-01-26', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].id).toEqual('task1')
-    expect(tasks[1].task).toEqual('test2')
-  })
-  it('should handle a new task with only an end date as definition', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    ganttDb.addTask('test2', '2d')
-
-    const tasks = ganttDb.getTasks()
-
-    expect(tasks[1].startTime).toEqual(moment('2013-01-15', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].endTime).toEqual(moment('2013-01-17', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].id).toEqual('task1')
-    expect(tasks[1].task).toEqual('test2')
-  })
-  it('should handle relative start date based on id regardless of sections', function () {
-    ganttDb.setDateFormat('YYYY-MM-DD')
-    ganttDb.addSection('testa1')
-    ganttDb.addTask('test1', 'id1,2013-01-01,2w')
-    ganttDb.addTask('test2', 'id2,after id3,1d')
-    ganttDb.addSection('testa2')
-    ganttDb.addTask('test3', 'id3,after id1,2d')
-
-    const tasks = ganttDb.getTasks()
-
-    expect(tasks[1].startTime).toEqual(moment('2013-01-17', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].endTime).toEqual(moment('2013-01-18', 'YYYY-MM-DD').toDate())
-    expect(tasks[1].id).toEqual('id2')
-    expect(tasks[1].task).toEqual('test2')
-
-    expect(tasks[2].id).toEqual('id3')
-    expect(tasks[2].task).toEqual('test3')
-    expect(tasks[2].startTime).toEqual(moment('2013-01-15', 'YYYY-MM-DD').toDate())
-    expect(tasks[2].endTime).toEqual(moment('2013-01-17', 'YYYY-MM-DD').toDate())
-  })
-})
diff --git a/_submodules/mermaid/src/diagrams/gantt/ganttRenderer.js b/_submodules/mermaid/src/diagrams/gantt/ganttRenderer.js
deleted file mode 100644
index 7d24df2a4c4defa0cd12be30e28a0bbd478f0063..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/gantt/ganttRenderer.js
+++ /dev/null
@@ -1,344 +0,0 @@
-import * as d3 from 'd3'
-
-import { parser } from './parser/gantt'
-import ganttDb from './ganttDb'
-
-parser.yy = ganttDb
-
-const conf = {
-  titleTopMargin: 25,
-  barHeight: 20,
-  barGap: 4,
-  topPadding: 50,
-  rightPadding: 75,
-  leftPadding: 75,
-  gridLineStartPadding: 35,
-  fontSize: 11,
-  fontFamily: '"Open-Sans", "sans-serif"'
-}
-export const setConf = function (cnf) {
-  const keys = Object.keys(cnf)
-
-  keys.forEach(function (key) {
-    conf[key] = cnf[key]
-  })
-}
-let w
-export const draw = function (text, id) {
-  parser.yy.clear()
-  parser.parse(text)
-
-  const elem = document.getElementById(id)
-  w = elem.parentElement.offsetWidth
-
-  if (typeof w === 'undefined') {
-    w = 1200
-  }
-
-  if (typeof conf.useWidth !== 'undefined') {
-    w = conf.useWidth
-  }
-
-  const taskArray = parser.yy.getTasks()
-
-  // Set height based on number of tasks
-  const h = taskArray.length * (conf.barHeight + conf.barGap) + 2 * conf.topPadding
-
-  elem.setAttribute('height', '100%')
-  // Set viewBox
-  elem.setAttribute('viewBox', '0 0 ' + w + ' ' + h)
-  const svg = d3.select(`[id="${id}"]`)
-
-  // Set timescale
-  const timeScale = d3.scaleTime()
-    .domain([d3.min(taskArray, function (d) {
-      return d.startTime
-    }),
-    d3.max(taskArray, function (d) {
-      return d.endTime
-    })])
-    .rangeRound([0, w - conf.leftPadding - conf.rightPadding])
-
-  let categories = []
-
-  for (let i = 0; i < taskArray.length; i++) {
-    categories.push(taskArray[i].type)
-  }
-
-  const catsUnfiltered = categories // for vert labels
-
-  categories = checkUnique(categories)
-
-  makeGant(taskArray, w, h)
-  if (typeof conf.useWidth !== 'undefined') {
-    elem.setAttribute('width', w)
-  }
-
-  svg.append('text')
-    .text(parser.yy.getTitle())
-    .attr('x', w / 2)
-    .attr('y', conf.titleTopMargin)
-    .attr('class', 'titleText')
-
-  function makeGant (tasks, pageWidth, pageHeight) {
-    const barHeight = conf.barHeight
-    const gap = barHeight + conf.barGap
-    const topPadding = conf.topPadding
-    const leftPadding = conf.leftPadding
-
-    const colorScale = d3.scaleLinear()
-      .domain([0, categories.length])
-      .range(['#00B9FA', '#F95002'])
-      .interpolate(d3.interpolateHcl)
-
-    makeGrid(leftPadding, topPadding, pageWidth, pageHeight)
-    drawRects(tasks, gap, topPadding, leftPadding, barHeight, colorScale, pageWidth, pageHeight)
-    vertLabels(gap, topPadding, leftPadding, barHeight, colorScale)
-    drawToday(leftPadding, topPadding, pageWidth, pageHeight)
-  }
-
-  function drawRects (theArray, theGap, theTopPad, theSidePad, theBarHeight, theColorScale, w, h) {
-    svg.append('g')
-      .selectAll('rect')
-      .data(theArray)
-      .enter()
-      .append('rect')
-      .attr('x', 0)
-      .attr('y', function (d, i) {
-        return i * theGap + theTopPad - 2
-      })
-      .attr('width', function () {
-        return w - conf.rightPadding / 2
-      })
-      .attr('height', theGap)
-      .attr('class', function (d) {
-        for (let i = 0; i < categories.length; i++) {
-          if (d.type === categories[i]) {
-            return 'section section' + (i % conf.numberSectionStyles)
-          }
-        }
-        return 'section section0'
-      })
-
-    const rectangles = svg.append('g')
-      .selectAll('rect')
-      .data(theArray)
-      .enter()
-
-    rectangles.append('rect')
-      .attr('rx', 3)
-      .attr('ry', 3)
-      .attr('x', function (d) {
-        return timeScale(d.startTime) + theSidePad
-      })
-      .attr('y', function (d, i) {
-        return i * theGap + theTopPad
-      })
-      .attr('width', function (d) {
-        return (timeScale(d.endTime) - timeScale(d.startTime))
-      })
-      .attr('height', theBarHeight)
-      .attr('class', function (d) {
-        const res = 'task '
-
-        let secNum = 0
-        for (let i = 0; i < categories.length; i++) {
-          if (d.type === categories[i]) {
-            secNum = (i % conf.numberSectionStyles)
-          }
-        }
-
-        if (d.active) {
-          if (d.crit) {
-            return res + ' activeCrit' + secNum
-          } else {
-            return res + ' active' + secNum
-          }
-        }
-
-        if (d.done) {
-          if (d.crit) {
-            return res + ' doneCrit' + secNum
-          } else {
-            return res + ' done' + secNum
-          }
-        }
-
-        if (d.crit) {
-          return res + ' crit' + secNum
-        }
-
-        return res + ' task' + secNum
-      })
-
-    rectangles.append('text')
-      .text(function (d) {
-        return d.task
-      })
-      .attr('font-size', conf.fontSize)
-      .attr('x', function (d) {
-        const startX = timeScale(d.startTime)
-        const endX = timeScale(d.endTime)
-        const textWidth = this.getBBox().width
-
-        // Check id text width > width of rectangle
-        if (textWidth > (endX - startX)) {
-          if (endX + textWidth + 1.5 * conf.leftPadding > w) {
-            return startX + theSidePad - 5
-          } else {
-            return endX + theSidePad + 5
-          }
-        } else {
-          return (endX - startX) / 2 + startX + theSidePad
-        }
-      })
-      .attr('y', function (d, i) {
-        return i * theGap + (conf.barHeight / 2) + (conf.fontSize / 2 - 2) + theTopPad
-      })
-      .attr('text-height', theBarHeight)
-      .attr('class', function (d) {
-        const startX = timeScale(d.startTime)
-        const endX = timeScale(d.endTime)
-        const textWidth = this.getBBox().width
-        let secNum = 0
-        for (let i = 0; i < categories.length; i++) {
-          if (d.type === categories[i]) {
-            secNum = (i % conf.numberSectionStyles)
-          }
-        }
-
-        let taskType = ''
-        if (d.active) {
-          if (d.crit) {
-            taskType = 'activeCritText' + secNum
-          } else {
-            taskType = 'activeText' + secNum
-          }
-        }
-
-        if (d.done) {
-          if (d.crit) {
-            taskType = taskType + ' doneCritText' + secNum
-          } else {
-            taskType = taskType + ' doneText' + secNum
-          }
-        } else {
-          if (d.crit) {
-            taskType = taskType + ' critText' + secNum
-          }
-        }
-
-        // Check id text width > width of rectangle
-        if (textWidth > (endX - startX)) {
-          if (endX + textWidth + 1.5 * conf.leftPadding > w) {
-            return 'taskTextOutsideLeft taskTextOutside' + secNum + ' ' + taskType
-          } else {
-            return 'taskTextOutsideRight taskTextOutside' + secNum + ' ' + taskType
-          }
-        } else {
-          return 'taskText taskText' + secNum + ' ' + taskType
-        }
-      })
-  }
-
-  function makeGrid (theSidePad, theTopPad, w, h) {
-    let xAxis = d3.axisBottom(timeScale)
-      .tickSize(-h + theTopPad + conf.gridLineStartPadding)
-      .tickFormat(d3.timeFormat(parser.yy.getAxisFormat() || conf.axisFormat || '%Y-%m-%d'))
-
-    svg.append('g')
-      .attr('class', 'grid')
-      .attr('transform', 'translate(' + theSidePad + ', ' + (h - 50) + ')')
-      .call(xAxis)
-      .selectAll('text')
-      .style('text-anchor', 'middle')
-      .attr('fill', '#000')
-      .attr('stroke', 'none')
-      .attr('font-size', 10)
-      .attr('dy', '1em')
-  }
-
-  function vertLabels (theGap, theTopPad) {
-    const numOccurances = []
-    let prevGap = 0
-
-    for (let i = 0; i < categories.length; i++) {
-      numOccurances[i] = [categories[i], getCount(categories[i], catsUnfiltered)]
-    }
-
-    svg.append('g') // without doing this, impossible to put grid lines behind text
-      .selectAll('text')
-      .data(numOccurances)
-      .enter()
-      .append('text')
-      .text(function (d) {
-        return d[0]
-      })
-      .attr('x', 10)
-      .attr('y', function (d, i) {
-        if (i > 0) {
-          for (let j = 0; j < i; j++) {
-            prevGap += numOccurances[i - 1][1]
-            return d[1] * theGap / 2 + prevGap * theGap + theTopPad
-          }
-        } else {
-          return d[1] * theGap / 2 + theTopPad
-        }
-      })
-      .attr('class', function (d) {
-        for (let i = 0; i < categories.length; i++) {
-          if (d[0] === categories[i]) {
-            return 'sectionTitle sectionTitle' + (i % conf.numberSectionStyles)
-          }
-        }
-        return 'sectionTitle'
-      })
-  }
-
-  function drawToday (theSidePad, theTopPad, w, h) {
-    const todayG = svg.append('g')
-      .attr('class', 'today')
-
-    const today = new Date()
-
-    todayG.append('line')
-      .attr('x1', timeScale(today) + theSidePad)
-      .attr('x2', timeScale(today) + theSidePad)
-      .attr('y1', conf.titleTopMargin)
-      .attr('y2', h - conf.titleTopMargin)
-      .attr('class', 'today')
-  }
-
-  // from this stackexchange question: http://stackoverflow.com/questions/1890203/unique-for-arrays-in-javascript
-  function checkUnique (arr) {
-    const hash = {}
-    const result = []
-    for (let i = 0, l = arr.length; i < l; ++i) {
-      if (!hash.hasOwnProperty(arr[i])) { // it works with objects! in FF, at least
-        hash[arr[i]] = true
-        result.push(arr[i])
-      }
-    }
-    return result
-  }
-
-  // from this stackexchange question: http://stackoverflow.com/questions/14227981/count-how-many-strings-in-an-array-have-duplicates-in-the-same-array
-  function getCounts (arr) {
-    let i = arr.length // const to loop over
-    const obj = {} // obj to store results
-    while (i) {
-      obj[arr[--i]] = (obj[arr[i]] || 0) + 1 // count occurrences
-    }
-    return obj
-  }
-
-  // get specific from everything
-  function getCount (word, arr) {
-    return getCounts(arr)[word] || 0
-  }
-}
-
-export default {
-  setConf,
-  draw
-}
diff --git a/_submodules/mermaid/src/diagrams/gantt/parser/gantt.jison b/_submodules/mermaid/src/diagrams/gantt/parser/gantt.jison
deleted file mode 100644
index 49ab3ad477e027544f2ef62de2c709c7caeda6af..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/gantt/parser/gantt.jison
+++ /dev/null
@@ -1,64 +0,0 @@
-/** mermaid
- *  https://mermaidjs.github.io/
- *  (c) 2015 Knut Sveidqvist
- *  MIT license.
- */
-%lex
-
-%options case-insensitive
-
-%{
-	// Pre-lexer code can go here
-%}
-
-%%
-
-[\n]+                   return 'NL';
-\s+                     /* skip whitespace */
-\#[^\n]*                /* skip comments */
-\%%[^\n]*               /* skip comments */
-"gantt"     	        return 'gantt';
-"dateFormat"\s[^#\n;]+  return 'dateFormat';
-"axisFormat"\s[^#\n;]+  return 'axisFormat';
-\d\d\d\d"-"\d\d"-"\d\d  return 'date';
-"title"\s[^#\n;]+       return 'title';
-"section"\s[^#:\n;]+    return 'section';
-[^#:\n;]+               return 'taskTxt';
-":"[^#\n;]+             return 'taskData';
-":"                         return ':';
-<<EOF>>                     return 'EOF';
-.                           return 'INVALID';
-
-/lex
-
-%left '^'
-
-%start start
-
-%% /* language grammar */
-
-start
-	: gantt document 'EOF' { return $2; }
-	;
-
-document
-	: /* empty */ { $$ = [] }
-	| document line {$1.push($2);$$ = $1}
-	;
-
-line
-	: SPACE statement { $$ = $2 }
-	| statement { $$ = $1 }
-	| NL { $$=[];}
-	| EOF { $$=[];}
-	;
-
-statement
-	: 'dateFormat' {yy.setDateFormat($1.substr(11));$$=$1.substr(11);}
-  | 'axisFormat' {yy.setAxisFormat($1.substr(11));$$=$1.substr(11);}
-	| title {yy.setTitle($1.substr(6));$$=$1.substr(6);}
-	| section {yy.addSection($1.substr(8));$$=$1.substr(8);}
-	| taskTxt taskData {yy.addTask($1,$2);$$='task';}
-	;
-
-%%
diff --git a/_submodules/mermaid/src/diagrams/gantt/parser/gantt.js b/_submodules/mermaid/src/diagrams/gantt/parser/gantt.js
deleted file mode 100644
index 38ff324ee092da87330859d58b37870f000f39b8..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/gantt/parser/gantt.js
+++ /dev/null
@@ -1,661 +0,0 @@
-/* parser generated by jison 0.4.18 */
-/*
-  Returns a Parser object of the following structure:
-
-  Parser: {
-    yy: {}
-  }
-
-  Parser.prototype: {
-    yy: {},
-    trace: function(),
-    symbols_: {associative list: name ==> number},
-    terminals_: {associative list: number ==> name},
-    productions_: [...],
-    performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
-    table: [...],
-    defaultActions: {...},
-    parseError: function(str, hash),
-    parse: function(input),
-
-    lexer: {
-        EOF: 1,
-        parseError: function(str, hash),
-        setInput: function(input),
-        input: function(),
-        unput: function(str),
-        more: function(),
-        less: function(n),
-        pastInput: function(),
-        upcomingInput: function(),
-        showPosition: function(),
-        test_match: function(regex_match_array, rule_index),
-        next: function(),
-        lex: function(),
-        begin: function(condition),
-        popState: function(),
-        _currentRules: function(),
-        topState: function(),
-        pushState: function(condition),
-
-        options: {
-            ranges: boolean           (optional: true ==> token location info will include a .range[] member)
-            flex: boolean             (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
-            backtrack_lexer: boolean  (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
-        },
-
-        performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
-        rules: [...],
-        conditions: {associative list: name ==> set},
-    }
-  }
-
-
-  token location info (@$, _$, etc.): {
-    first_line: n,
-    last_line: n,
-    first_column: n,
-    last_column: n,
-    range: [start_number, end_number]       (where the numbers are indexes into the input string, regular zero-based)
-  }
-
-
-  the parseError function receives a 'hash' object with these members for lexer and parser errors: {
-    text:        (matched text)
-    token:       (the produced terminal token, if any)
-    line:        (yylineno)
-  }
-  while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
-    loc:         (yylloc)
-    expected:    (string describing the set of expected tokens)
-    recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
-  }
-*/
-var parser = (function(){
-var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[6,8,10,11,12,13,14,15],$V1=[1,9],$V2=[1,10],$V3=[1,11],$V4=[1,12],$V5=[1,13];
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {"error":2,"start":3,"gantt":4,"document":5,"EOF":6,"line":7,"SPACE":8,"statement":9,"NL":10,"dateFormat":11,"axisFormat":12,"title":13,"section":14,"taskTxt":15,"taskData":16,"$accept":0,"$end":1},
-terminals_: {2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",11:"dateFormat",12:"axisFormat",13:"title",14:"section",15:"taskTxt",16:"taskData"},
-productions_: [0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,1],[9,1],[9,1],[9,2]],
-performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
-/* this == yyval */
-
-var $0 = $$.length - 1;
-switch (yystate) {
-case 1:
- return $$[$0-1]; 
-break;
-case 2:
- this.$ = [] 
-break;
-case 3:
-$$[$0-1].push($$[$0]);this.$ = $$[$0-1]
-break;
-case 4: case 5:
- this.$ = $$[$0] 
-break;
-case 6: case 7:
- this.$=[];
-break;
-case 8:
-yy.setDateFormat($$[$0].substr(11));this.$=$$[$0].substr(11);
-break;
-case 9:
-yy.setAxisFormat($$[$0].substr(11));this.$=$$[$0].substr(11);
-break;
-case 10:
-yy.setTitle($$[$0].substr(6));this.$=$$[$0].substr(6);
-break;
-case 11:
-yy.addSection($$[$0].substr(8));this.$=$$[$0].substr(8);
-break;
-case 12:
-yy.addTask($$[$0-1],$$[$0]);this.$='task';
-break;
-}
-},
-table: [{3:1,4:[1,2]},{1:[3]},o($V0,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:$V1,12:$V2,13:$V3,14:$V4,15:$V5},o($V0,[2,7],{1:[2,1]}),o($V0,[2,3]),{9:14,11:$V1,12:$V2,13:$V3,14:$V4,15:$V5},o($V0,[2,5]),o($V0,[2,6]),o($V0,[2,8]),o($V0,[2,9]),o($V0,[2,10]),o($V0,[2,11]),{16:[1,15]},o($V0,[2,4]),o($V0,[2,12])],
-defaultActions: {},
-parseError: function parseError(str, hash) {
-    if (hash.recoverable) {
-        this.trace(str);
-    } else {
-        var error = new Error(str);
-        error.hash = hash;
-        throw error;
-    }
-},
-parse: function parse(input) {
-    var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
-    var args = lstack.slice.call(arguments, 1);
-    var lexer = Object.create(this.lexer);
-    var sharedState = { yy: {} };
-    for (var k in this.yy) {
-        if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
-            sharedState.yy[k] = this.yy[k];
-        }
-    }
-    lexer.setInput(input, sharedState.yy);
-    sharedState.yy.lexer = lexer;
-    sharedState.yy.parser = this;
-    if (typeof lexer.yylloc == 'undefined') {
-        lexer.yylloc = {};
-    }
-    var yyloc = lexer.yylloc;
-    lstack.push(yyloc);
-    var ranges = lexer.options && lexer.options.ranges;
-    if (typeof sharedState.yy.parseError === 'function') {
-        this.parseError = sharedState.yy.parseError;
-    } else {
-        this.parseError = Object.getPrototypeOf(this).parseError;
-    }
-    function popStack(n) {
-        stack.length = stack.length - 2 * n;
-        vstack.length = vstack.length - n;
-        lstack.length = lstack.length - n;
-    }
-            function lex() {
-            var token;
-            token = tstack.pop() || lexer.lex() || EOF;
-            if (typeof token !== 'number') {
-                if (token instanceof Array) {
-                    tstack = token;
-                    token = tstack.pop();
-                }
-                token = self.symbols_[token] || token;
-            }
-            return token;
-        }
-    var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
-    while (true) {
-        state = stack[stack.length - 1];
-        if (this.defaultActions[state]) {
-            action = this.defaultActions[state];
-        } else {
-            if (symbol === null || typeof symbol == 'undefined') {
-                symbol = lex();
-            }
-            action = table[state] && table[state][symbol];
-        }
-        if (typeof action === 'undefined' || !action.length || !action[0]) {
-            var errStr = '';
-            expected = [];
-            for (p in table[state]) {
-                if (this.terminals_[p] && p > TERROR) {
-                    expected.push('\'' + this.terminals_[p] + '\'');
-                }
-            }
-            if (lexer.showPosition) {
-                errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
-            } else {
-                errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
-            }
-            this.parseError(errStr, {
-                text: lexer.match,
-                token: this.terminals_[symbol] || symbol,
-                line: lexer.yylineno,
-                loc: yyloc,
-                expected: expected
-            });
-        }
-        if (action[0] instanceof Array && action.length > 1) {
-            throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
-        }
-        switch (action[0]) {
-        case 1:
-            stack.push(symbol);
-            vstack.push(lexer.yytext);
-            lstack.push(lexer.yylloc);
-            stack.push(action[1]);
-            symbol = null;
-            if (!preErrorSymbol) {
-                yyleng = lexer.yyleng;
-                yytext = lexer.yytext;
-                yylineno = lexer.yylineno;
-                yyloc = lexer.yylloc;
-                if (recovering > 0) {
-                    recovering--;
-                }
-            } else {
-                symbol = preErrorSymbol;
-                preErrorSymbol = null;
-            }
-            break;
-        case 2:
-            len = this.productions_[action[1]][1];
-            yyval.$ = vstack[vstack.length - len];
-            yyval._$ = {
-                first_line: lstack[lstack.length - (len || 1)].first_line,
-                last_line: lstack[lstack.length - 1].last_line,
-                first_column: lstack[lstack.length - (len || 1)].first_column,
-                last_column: lstack[lstack.length - 1].last_column
-            };
-            if (ranges) {
-                yyval._$.range = [
-                    lstack[lstack.length - (len || 1)].range[0],
-                    lstack[lstack.length - 1].range[1]
-                ];
-            }
-            r = this.performAction.apply(yyval, [
-                yytext,
-                yyleng,
-                yylineno,
-                sharedState.yy,
-                action[1],
-                vstack,
-                lstack
-            ].concat(args));
-            if (typeof r !== 'undefined') {
-                return r;
-            }
-            if (len) {
-                stack = stack.slice(0, -1 * len * 2);
-                vstack = vstack.slice(0, -1 * len);
-                lstack = lstack.slice(0, -1 * len);
-            }
-            stack.push(this.productions_[action[1]][0]);
-            vstack.push(yyval.$);
-            lstack.push(yyval._$);
-            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
-            stack.push(newState);
-            break;
-        case 3:
-            return true;
-        }
-    }
-    return true;
-}};
-
-/* generated by jison-lex 0.3.4 */
-var lexer = (function(){
-var lexer = ({
-
-EOF:1,
-
-parseError:function parseError(str, hash) {
-        if (this.yy.parser) {
-            this.yy.parser.parseError(str, hash);
-        } else {
-            throw new Error(str);
-        }
-    },
-
-// resets the lexer, sets new input
-setInput:function (input, yy) {
-        this.yy = yy || this.yy || {};
-        this._input = input;
-        this._more = this._backtrack = this.done = false;
-        this.yylineno = this.yyleng = 0;
-        this.yytext = this.matched = this.match = '';
-        this.conditionStack = ['INITIAL'];
-        this.yylloc = {
-            first_line: 1,
-            first_column: 0,
-            last_line: 1,
-            last_column: 0
-        };
-        if (this.options.ranges) {
-            this.yylloc.range = [0,0];
-        }
-        this.offset = 0;
-        return this;
-    },
-
-// consumes and returns one char from the input
-input:function () {
-        var ch = this._input[0];
-        this.yytext += ch;
-        this.yyleng++;
-        this.offset++;
-        this.match += ch;
-        this.matched += ch;
-        var lines = ch.match(/(?:\r\n?|\n).*/g);
-        if (lines) {
-            this.yylineno++;
-            this.yylloc.last_line++;
-        } else {
-            this.yylloc.last_column++;
-        }
-        if (this.options.ranges) {
-            this.yylloc.range[1]++;
-        }
-
-        this._input = this._input.slice(1);
-        return ch;
-    },
-
-// unshifts one char (or a string) into the input
-unput:function (ch) {
-        var len = ch.length;
-        var lines = ch.split(/(?:\r\n?|\n)/g);
-
-        this._input = ch + this._input;
-        this.yytext = this.yytext.substr(0, this.yytext.length - len);
-        //this.yyleng -= len;
-        this.offset -= len;
-        var oldLines = this.match.split(/(?:\r\n?|\n)/g);
-        this.match = this.match.substr(0, this.match.length - 1);
-        this.matched = this.matched.substr(0, this.matched.length - 1);
-
-        if (lines.length - 1) {
-            this.yylineno -= lines.length - 1;
-        }
-        var r = this.yylloc.range;
-
-        this.yylloc = {
-            first_line: this.yylloc.first_line,
-            last_line: this.yylineno + 1,
-            first_column: this.yylloc.first_column,
-            last_column: lines ?
-                (lines.length === oldLines.length ? this.yylloc.first_column : 0)
-                 + oldLines[oldLines.length - lines.length].length - lines[0].length :
-              this.yylloc.first_column - len
-        };
-
-        if (this.options.ranges) {
-            this.yylloc.range = [r[0], r[0] + this.yyleng - len];
-        }
-        this.yyleng = this.yytext.length;
-        return this;
-    },
-
-// When called from action, caches matched text and appends it on next action
-more:function () {
-        this._more = true;
-        return this;
-    },
-
-// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
-reject:function () {
-        if (this.options.backtrack_lexer) {
-            this._backtrack = true;
-        } else {
-            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
-                text: "",
-                token: null,
-                line: this.yylineno
-            });
-
-        }
-        return this;
-    },
-
-// retain first n characters of the match
-less:function (n) {
-        this.unput(this.match.slice(n));
-    },
-
-// displays already matched input, i.e. for error messages
-pastInput:function () {
-        var past = this.matched.substr(0, this.matched.length - this.match.length);
-        return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
-    },
-
-// displays upcoming input, i.e. for error messages
-upcomingInput:function () {
-        var next = this.match;
-        if (next.length < 20) {
-            next += this._input.substr(0, 20-next.length);
-        }
-        return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
-    },
-
-// displays the character position where the lexing error occurred, i.e. for error messages
-showPosition:function () {
-        var pre = this.pastInput();
-        var c = new Array(pre.length + 1).join("-");
-        return pre + this.upcomingInput() + "\n" + c + "^";
-    },
-
-// test the lexed token: return FALSE when not a match, otherwise return token
-test_match:function (match, indexed_rule) {
-        var token,
-            lines,
-            backup;
-
-        if (this.options.backtrack_lexer) {
-            // save context
-            backup = {
-                yylineno: this.yylineno,
-                yylloc: {
-                    first_line: this.yylloc.first_line,
-                    last_line: this.last_line,
-                    first_column: this.yylloc.first_column,
-                    last_column: this.yylloc.last_column
-                },
-                yytext: this.yytext,
-                match: this.match,
-                matches: this.matches,
-                matched: this.matched,
-                yyleng: this.yyleng,
-                offset: this.offset,
-                _more: this._more,
-                _input: this._input,
-                yy: this.yy,
-                conditionStack: this.conditionStack.slice(0),
-                done: this.done
-            };
-            if (this.options.ranges) {
-                backup.yylloc.range = this.yylloc.range.slice(0);
-            }
-        }
-
-        lines = match[0].match(/(?:\r\n?|\n).*/g);
-        if (lines) {
-            this.yylineno += lines.length;
-        }
-        this.yylloc = {
-            first_line: this.yylloc.last_line,
-            last_line: this.yylineno + 1,
-            first_column: this.yylloc.last_column,
-            last_column: lines ?
-                         lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
-                         this.yylloc.last_column + match[0].length
-        };
-        this.yytext += match[0];
-        this.match += match[0];
-        this.matches = match;
-        this.yyleng = this.yytext.length;
-        if (this.options.ranges) {
-            this.yylloc.range = [this.offset, this.offset += this.yyleng];
-        }
-        this._more = false;
-        this._backtrack = false;
-        this._input = this._input.slice(match[0].length);
-        this.matched += match[0];
-        token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
-        if (this.done && this._input) {
-            this.done = false;
-        }
-        if (token) {
-            return token;
-        } else if (this._backtrack) {
-            // recover context
-            for (var k in backup) {
-                this[k] = backup[k];
-            }
-            return false; // rule action called reject() implying the next rule should be tested instead.
-        }
-        return false;
-    },
-
-// return next match in input
-next:function () {
-        if (this.done) {
-            return this.EOF;
-        }
-        if (!this._input) {
-            this.done = true;
-        }
-
-        var token,
-            match,
-            tempMatch,
-            index;
-        if (!this._more) {
-            this.yytext = '';
-            this.match = '';
-        }
-        var rules = this._currentRules();
-        for (var i = 0; i < rules.length; i++) {
-            tempMatch = this._input.match(this.rules[rules[i]]);
-            if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
-                match = tempMatch;
-                index = i;
-                if (this.options.backtrack_lexer) {
-                    token = this.test_match(tempMatch, rules[i]);
-                    if (token !== false) {
-                        return token;
-                    } else if (this._backtrack) {
-                        match = false;
-                        continue; // rule action called reject() implying a rule MISmatch.
-                    } else {
-                        // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
-                        return false;
-                    }
-                } else if (!this.options.flex) {
-                    break;
-                }
-            }
-        }
-        if (match) {
-            token = this.test_match(match, rules[index]);
-            if (token !== false) {
-                return token;
-            }
-            // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
-            return false;
-        }
-        if (this._input === "") {
-            return this.EOF;
-        } else {
-            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
-                text: "",
-                token: null,
-                line: this.yylineno
-            });
-        }
-    },
-
-// return next match that has a token
-lex:function lex() {
-        var r = this.next();
-        if (r) {
-            return r;
-        } else {
-            return this.lex();
-        }
-    },
-
-// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
-begin:function begin(condition) {
-        this.conditionStack.push(condition);
-    },
-
-// pop the previously active lexer condition state off the condition stack
-popState:function popState() {
-        var n = this.conditionStack.length - 1;
-        if (n > 0) {
-            return this.conditionStack.pop();
-        } else {
-            return this.conditionStack[0];
-        }
-    },
-
-// produce the lexer rule set which is active for the currently active lexer condition state
-_currentRules:function _currentRules() {
-        if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
-            return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
-        } else {
-            return this.conditions["INITIAL"].rules;
-        }
-    },
-
-// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
-topState:function topState(n) {
-        n = this.conditionStack.length - 1 - Math.abs(n || 0);
-        if (n >= 0) {
-            return this.conditionStack[n];
-        } else {
-            return "INITIAL";
-        }
-    },
-
-// alias for begin(condition)
-pushState:function pushState(condition) {
-        this.begin(condition);
-    },
-
-// return the number of states currently on the stack
-stateStackSize:function stateStackSize() {
-        return this.conditionStack.length;
-    },
-options: {"case-insensitive":true},
-performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
-	// Pre-lexer code can go here
-
-var YYSTATE=YY_START;
-switch($avoiding_name_collisions) {
-case 0:return 10;
-break;
-case 1:/* skip whitespace */
-break;
-case 2:/* skip comments */
-break;
-case 3:/* skip comments */
-break;
-case 4:return 4;
-break;
-case 5:return 11;
-break;
-case 6:return 12;
-break;
-case 7:return 'date';
-break;
-case 8:return 13;
-break;
-case 9:return 14;
-break;
-case 10:return 15;
-break;
-case 11:return 16;
-break;
-case 12:return ':';
-break;
-case 13:return 6;
-break;
-case 14:return 'INVALID';
-break;
-}
-},
-rules: [/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],
-conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14],"inclusive":true}}
-});
-return lexer;
-})();
-parser.lexer = lexer;
-function Parser () {
-  this.yy = {};
-}
-Parser.prototype = parser;parser.Parser = Parser;
-return new Parser;
-})();
-
-
-if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
-exports.parser = parser;
-exports.Parser = parser.Parser;
-exports.parse = function () { return parser.parse.apply(parser, arguments); };
-exports.main = function commonjsMain(args) {
-    if (!args[1]) {
-        console.log('Usage: '+args[0]+' FILE');
-        process.exit(1);
-    }
-    var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
-    return exports.parser.parse(source);
-};
-if (typeof module !== 'undefined' && require.main === module) {
-  exports.main(process.argv.slice(1));
-}
-}
\ No newline at end of file
diff --git a/_submodules/mermaid/src/diagrams/git/gitGraphAst.js b/_submodules/mermaid/src/diagrams/git/gitGraphAst.js
deleted file mode 100644
index e734453b761e66a73d1ab5ef5d668774fb166e83..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/git/gitGraphAst.js
+++ /dev/null
@@ -1,228 +0,0 @@
-import _ from 'lodash'
-
-import { logger } from '../../logger'
-
-let commits = {}
-let head = null
-let branches = { 'master': head }
-let curBranch = 'master'
-let direction = 'LR'
-let seq = 0
-
-function getRandomInt (min, max) {
-  return Math.floor(Math.random() * (max - min)) + min
-}
-
-function getId () {
-  const pool = '0123456789abcdef'
-  let id = ''
-  for (let i = 0; i < 7; i++) {
-    id += pool[getRandomInt(0, 16)]
-  }
-  return id
-}
-
-function isfastforwardable (currentCommit, otherCommit) {
-  logger.debug('Entering isfastforwardable:', currentCommit.id, otherCommit.id)
-  while (currentCommit.seq <= otherCommit.seq && currentCommit !== otherCommit) {
-    // only if other branch has more commits
-    if (otherCommit.parent == null) break
-    if (Array.isArray(otherCommit.parent)) {
-      logger.debug('In merge commit:', otherCommit.parent)
-      return isfastforwardable(currentCommit, commits[otherCommit.parent[0]]) ||
-        isfastforwardable(currentCommit, commits[otherCommit.parent[1]])
-    } else {
-      otherCommit = commits[otherCommit.parent]
-    }
-  }
-  logger.debug(currentCommit.id, otherCommit.id)
-  return currentCommit.id === otherCommit.id
-}
-
-function isReachableFrom (currentCommit, otherCommit) {
-  const currentSeq = currentCommit.seq
-  const otherSeq = otherCommit.seq
-  if (currentSeq > otherSeq) return isfastforwardable(otherCommit, currentCommit)
-  return false
-}
-
-export const setDirection = function (dir) {
-  direction = dir
-}
-let options = {}
-export const setOptions = function (rawOptString) {
-  logger.debug('options str', rawOptString)
-  rawOptString = rawOptString && rawOptString.trim()
-  rawOptString = rawOptString || '{}'
-  try {
-    options = JSON.parse(rawOptString)
-  } catch (e) {
-    logger.error('error while parsing gitGraph options', e.message)
-  }
-}
-
-export const getOptions = function () {
-  return options
-}
-
-export const commit = function (msg) {
-  const commit = {
-    id: getId(),
-    message: msg,
-    seq: seq++,
-    parent: head == null ? null : head.id
-  }
-  head = commit
-  commits[commit.id] = commit
-  branches[curBranch] = commit.id
-  logger.debug('in pushCommit ' + commit.id)
-}
-
-export const branch = function (name) {
-  branches[name] = head != null ? head.id : null
-  logger.debug('in createBranch')
-}
-
-export const merge = function (otherBranch) {
-  const currentCommit = commits[branches[curBranch]]
-  const otherCommit = commits[branches[otherBranch]]
-  if (isReachableFrom(currentCommit, otherCommit)) {
-    logger.debug('Already merged')
-    return
-  }
-  if (isfastforwardable(currentCommit, otherCommit)) {
-    branches[curBranch] = branches[otherBranch]
-    head = commits[branches[curBranch]]
-  } else {
-    // create merge commit
-    const commit = {
-      id: getId(),
-      message: 'merged branch ' + otherBranch + ' into ' + curBranch,
-      seq: seq++,
-      parent: [head == null ? null : head.id, branches[otherBranch]]
-    }
-    head = commit
-    commits[commit.id] = commit
-    branches[curBranch] = commit.id
-  }
-  logger.debug(branches)
-  logger.debug('in mergeBranch')
-}
-
-export const checkout = function (branch) {
-  logger.debug('in checkout')
-  curBranch = branch
-  const id = branches[curBranch]
-  head = commits[id]
-}
-
-export const reset = function (commitRef) {
-  logger.debug('in reset', commitRef)
-  const ref = commitRef.split(':')[0]
-  let parentCount = parseInt(commitRef.split(':')[1])
-  let commit = ref === 'HEAD' ? head : commits[branches[ref]]
-  logger.debug(commit, parentCount)
-  while (parentCount > 0) {
-    commit = commits[commit.parent]
-    parentCount--
-    if (!commit) {
-      const err = 'Critical error - unique parent commit not found during reset'
-      logger.error(err)
-      throw err
-    }
-  }
-  head = commit
-  branches[curBranch] = commit.id
-}
-
-function upsert (arr, key, newval) {
-  const index = arr.indexOf(key)
-  if (index === -1) {
-    arr.push(newval)
-  } else {
-    arr.splice(index, 1, newval)
-  }
-}
-
-function prettyPrintCommitHistory (commitArr) {
-  const commit = _.maxBy(commitArr, 'seq')
-  let line = ''
-  commitArr.forEach(function (c) {
-    if (c === commit) {
-      line += '\t*'
-    } else {
-      line += '\t|'
-    }
-  })
-  const label = [line, commit.id, commit.seq]
-  _.each(branches, function (value, key) {
-    if (value === commit.id) label.push(key)
-  })
-  logger.debug(label.join(' '))
-  if (Array.isArray(commit.parent)) {
-    const newCommit = commits[commit.parent[0]]
-    upsert(commitArr, commit, newCommit)
-    commitArr.push(commits[commit.parent[1]])
-  } else if (commit.parent == null) {
-    return
-  } else {
-    const nextCommit = commits[commit.parent]
-    upsert(commitArr, commit, nextCommit)
-  }
-  commitArr = _.uniqBy(commitArr, 'id')
-  prettyPrintCommitHistory(commitArr)
-}
-
-export const prettyPrint = function () {
-  logger.debug(commits)
-  const node = getCommitsArray()[0]
-  prettyPrintCommitHistory([node])
-}
-
-export const clear = function () {
-  commits = {}
-  head = null
-  branches = { 'master': head }
-  curBranch = 'master'
-  seq = 0
-}
-
-export const getBranchesAsObjArray = function () {
-  const branchArr = _.map(branches, function (value, key) {
-    return { 'name': key, 'commit': commits[value] }
-  })
-  return branchArr
-}
-
-export const getBranches = function () { return branches }
-export const getCommits = function () { return commits }
-export const getCommitsArray = function () {
-  const commitArr = Object.keys(commits).map(function (key) {
-    return commits[key]
-  })
-  commitArr.forEach(function (o) { logger.debug(o.id) })
-  return _.orderBy(commitArr, ['seq'], ['desc'])
-}
-export const getCurrentBranch = function () { return curBranch }
-export const getDirection = function () { return direction }
-export const getHead = function () { return head }
-
-export default {
-  setDirection,
-  setOptions,
-  getOptions,
-  commit,
-  branch,
-  merge,
-  checkout,
-  reset,
-  prettyPrint,
-  clear,
-  getBranchesAsObjArray,
-  getBranches,
-  getCommits,
-  getCommitsArray,
-  getCurrentBranch,
-  getDirection,
-  getHead
-}
diff --git a/_submodules/mermaid/src/diagrams/git/gitGraphParser.spec.js b/_submodules/mermaid/src/diagrams/git/gitGraphParser.spec.js
deleted file mode 100644
index aba2812d99ac3e2166a694de1fb700960ea9b30e..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/git/gitGraphParser.spec.js
+++ /dev/null
@@ -1,241 +0,0 @@
-/* eslint-env jasmine */
-import gitGraphAst from './gitGraphAst'
-import { parser } from './parser/gitGraph'
-
-describe('when parsing a gitGraph', function () {
-  beforeEach(function () {
-    parser.yy = gitGraphAst
-    parser.yy.clear()
-  })
-  it('should handle a gitGraph defintion', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-
-    expect(Object.keys(commits).length).toBe(1)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getDirection()).toBe('LR')
-    expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
-  })
-
-  it('should handle a gitGraph defintion with empty options', function () {
-    const str = 'gitGraph:\n' +
-      'options\n' +
-      'end\n' +
-      'commit\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-
-    expect(parser.yy.getOptions()).toEqual({})
-    expect(Object.keys(commits).length).toBe(1)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getDirection()).toBe('LR')
-    expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
-  })
-
-  it('should handle a gitGraph defintion with valid options', function () {
-    const str = 'gitGraph:\n' +
-      'options\n' +
-      '{"key": "value"}\n' +
-      'end\n' +
-      'commit\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-    expect(parser.yy.getOptions()['key']).toBe('value')
-    expect(Object.keys(commits).length).toBe(1)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getDirection()).toBe('LR')
-    expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
-  })
-
-  it('should not fail on a gitGraph with malformed json', function () {
-    const str = 'gitGraph:\n' +
-      'options\n' +
-      '{"key": "value"\n' +
-      'end\n' +
-      'commit\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(1)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getDirection()).toBe('LR')
-    expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
-  })
-
-  it('should handle set direction', function () {
-    const str = 'gitGraph BT:\n' +
-      'commit\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-
-    expect(Object.keys(commits).length).toBe(1)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getDirection()).toBe('BT')
-    expect(Object.keys(parser.yy.getBranches()).length).toBe(1)
-  })
-
-  it('should checkout a branch', function () {
-    const str = 'gitGraph:\n' +
-      'branch new\n' +
-      'checkout new\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-
-    expect(Object.keys(commits).length).toBe(0)
-    expect(parser.yy.getCurrentBranch()).toBe('new')
-  })
-
-  it('should add commits to checked out branch', function () {
-    const str = 'gitGraph:\n' +
-      'branch new\n' +
-      'checkout new\n' +
-      'commit\n' +
-      'commit\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-
-    expect(Object.keys(commits).length).toBe(2)
-    expect(parser.yy.getCurrentBranch()).toBe('new')
-    const branchCommit = parser.yy.getBranches()['new']
-    expect(branchCommit).not.toBeNull()
-    expect(commits[branchCommit].parent).not.toBeNull()
-  })
-  it('should handle commit with args', function () {
-    const str = 'gitGraph:\n' +
-      'commit "a commit"\n'
-
-    parser.parse(str)
-    const commits = parser.yy.getCommits()
-
-    expect(Object.keys(commits).length).toBe(1)
-    const key = Object.keys(commits)[0]
-    expect(commits[key].message).toBe('a commit')
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-  })
-
-  it('it should reset a branch', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n' +
-      'commit\n' +
-      'branch newbranch\n' +
-      'checkout newbranch\n' +
-      'commit\n' +
-      'reset master\n'
-
-    parser.parse(str)
-
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(3)
-    expect(parser.yy.getCurrentBranch()).toBe('newbranch')
-    expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master'])
-    expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch'])
-  })
-
-  it('reset can take an argument', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n' +
-      'commit\n' +
-      'branch newbranch\n' +
-      'checkout newbranch\n' +
-      'commit\n' +
-      'reset master^\n'
-
-    parser.parse(str)
-
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(3)
-    expect(parser.yy.getCurrentBranch()).toBe('newbranch')
-    const master = commits[parser.yy.getBranches()['master']]
-    expect(parser.yy.getHead().id).toEqual(master.parent)
-  })
-
-  it('it should handle fast forwardable merges', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n' +
-      'branch newbranch\n' +
-      'checkout newbranch\n' +
-      'commit\n' +
-      'commit\n' +
-      'checkout master\n' +
-      'merge newbranch\n'
-
-    parser.parse(str)
-
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(3)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master'])
-    expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch'])
-  })
-
-  it('it should handle cases when merge is a noop', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n' +
-      'branch newbranch\n' +
-      'checkout newbranch\n' +
-      'commit\n' +
-      'commit\n' +
-      'merge master\n'
-
-    parser.parse(str)
-
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(3)
-    expect(parser.yy.getCurrentBranch()).toBe('newbranch')
-    expect(parser.yy.getBranches()['newbranch']).not.toEqual(parser.yy.getBranches()['master'])
-    expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch'])
-  })
-
-  it('it should handle merge with 2 parents', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n' +
-      'branch newbranch\n' +
-      'checkout newbranch\n' +
-      'commit\n' +
-      'commit\n' +
-      'checkout master\n' +
-      'commit\n' +
-      'merge newbranch\n'
-
-    parser.parse(str)
-
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(5)
-    expect(parser.yy.getCurrentBranch()).toBe('master')
-    expect(parser.yy.getBranches()['newbranch']).not.toEqual(parser.yy.getBranches()['master'])
-    expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['master'])
-  })
-
-  it('it should handle ff merge when history walk has two parents (merge commit)', function () {
-    const str = 'gitGraph:\n' +
-      'commit\n' +
-      'branch newbranch\n' +
-      'checkout newbranch\n' +
-      'commit\n' +
-      'commit\n' +
-      'checkout master\n' +
-      'commit\n' +
-      'merge newbranch\n' +
-      'commit\n' +
-      'checkout newbranch\n' +
-      'merge master\n'
-
-    parser.parse(str)
-
-    const commits = parser.yy.getCommits()
-    expect(Object.keys(commits).length).toBe(6)
-    expect(parser.yy.getCurrentBranch()).toBe('newbranch')
-    expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master'])
-    expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['master'])
-
-    parser.yy.prettyPrint()
-  })
-})
diff --git a/_submodules/mermaid/src/diagrams/git/gitGraphRenderer.js b/_submodules/mermaid/src/diagrams/git/gitGraphRenderer.js
deleted file mode 100644
index 3ef56478da7e4d3ffddd0c9d23c0dd639c5dcc84..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/git/gitGraphRenderer.js
+++ /dev/null
@@ -1,280 +0,0 @@
-import _ from 'lodash'
-import * as d3 from 'd3'
-
-import db from './gitGraphAst'
-import gitGraphParser from './parser/gitGraph'
-import { logger } from '../../logger'
-import { interpolateToCurve } from '../../utils'
-
-let allCommitsDict = {}
-let branchNum
-let config = {
-  nodeSpacing: 150,
-  nodeFillColor: 'yellow',
-  nodeStrokeWidth: 2,
-  nodeStrokeColor: 'grey',
-  lineStrokeWidth: 4,
-  branchOffset: 50,
-  lineColor: 'grey',
-  leftMargin: 50,
-  branchColors: ['#442f74', '#983351', '#609732', '#AA9A39'],
-  nodeRadius: 10,
-  nodeLabel: {
-    width: 75,
-    height: 100,
-    x: -25,
-    y: 0
-  }
-}
-let apiConfig = {}
-export const setConf = function (c) {
-  apiConfig = c
-}
-
-function svgCreateDefs (svg) {
-  svg
-    .append('defs')
-    .append('g')
-    .attr('id', 'def-commit')
-    .append('circle')
-    .attr('r', config.nodeRadius)
-    .attr('cx', 0)
-    .attr('cy', 0)
-  svg.select('#def-commit')
-    .append('foreignObject')
-    .attr('width', config.nodeLabel.width)
-    .attr('height', config.nodeLabel.height)
-    .attr('x', config.nodeLabel.x)
-    .attr('y', config.nodeLabel.y)
-    .attr('class', 'node-label')
-    .attr('requiredFeatures', 'http://www.w3.org/TR/SVG11/feature#Extensibility')
-    .append('p')
-    .html('')
-}
-
-function svgDrawLine (svg, points, colorIdx, interpolate) {
-  const curve = interpolateToCurve(interpolate, d3.curveBasis)
-  const color = config.branchColors[colorIdx % config.branchColors.length]
-  const lineGen = d3.line()
-    .x(function (d) {
-      return Math.round(d.x)
-    })
-    .y(function (d) {
-      return Math.round(d.y)
-    })
-    .curve(curve)
-
-  svg
-    .append('svg:path')
-    .attr('d', lineGen(points))
-    .style('stroke', color)
-    .style('stroke-width', config.lineStrokeWidth)
-    .style('fill', 'none')
-}
-
-// Pass in the element and its pre-transform coords
-function getElementCoords (element, coords) {
-  coords = coords || element.node().getBBox()
-  const ctm = element.node().getCTM()
-  const xn = ctm.e + coords.x * ctm.a
-  const yn = ctm.f + coords.y * ctm.d
-  return {
-    left: xn,
-    top: yn,
-    width: coords.width,
-    height: coords.height
-  }
-}
-
-function svgDrawLineForCommits (svg, fromId, toId, direction, color) {
-  logger.debug('svgDrawLineForCommits: ', fromId, toId)
-  const fromBbox = getElementCoords(svg.select('#node-' + fromId + ' circle'))
-  const toBbox = getElementCoords(svg.select('#node-' + toId + ' circle'))
-  switch (direction) {
-    case 'LR':
-      // (toBbox)
-      //  +--------
-      //          + (fromBbox)
-      if (fromBbox.left - toBbox.left > config.nodeSpacing) {
-        const lineStart = { x: fromBbox.left - config.nodeSpacing, y: toBbox.top + toBbox.height / 2 }
-        const lineEnd = { x: toBbox.left + toBbox.width, y: toBbox.top + toBbox.height / 2 }
-        svgDrawLine(svg, [lineStart, lineEnd], color, 'linear')
-        svgDrawLine(svg, [
-          { x: fromBbox.left, y: fromBbox.top + fromBbox.height / 2 },
-          { x: fromBbox.left - config.nodeSpacing / 2, y: fromBbox.top + fromBbox.height / 2 },
-          { x: fromBbox.left - config.nodeSpacing / 2, y: lineStart.y },
-          lineStart], color)
-      } else {
-        svgDrawLine(svg, [{
-          'x': fromBbox.left,
-          'y': fromBbox.top + fromBbox.height / 2
-        }, {
-          'x': fromBbox.left - config.nodeSpacing / 2,
-          'y': fromBbox.top + fromBbox.height / 2
-        }, {
-          'x': fromBbox.left - config.nodeSpacing / 2,
-          'y': toBbox.top + toBbox.height / 2
-        }, {
-          'x': toBbox.left + toBbox.width,
-          'y': toBbox.top + toBbox.height / 2
-        }], color)
-      }
-      break
-    case 'BT':
-      //      +           (fromBbox)
-      //      |
-      //      |
-      //              +   (toBbox)
-      if (toBbox.top - fromBbox.top > config.nodeSpacing) {
-        const lineStart = { x: toBbox.left + toBbox.width / 2, y: fromBbox.top + fromBbox.height + config.nodeSpacing }
-        const lineEnd = { x: toBbox.left + toBbox.width / 2, y: toBbox.top }
-        svgDrawLine(svg, [lineStart, lineEnd], color, 'linear')
-        svgDrawLine(svg, [
-          { x: fromBbox.left + fromBbox.width / 2, y: fromBbox.top + fromBbox.height },
-          { x: fromBbox.left + fromBbox.width / 2, y: fromBbox.top + fromBbox.height + config.nodeSpacing / 2 },
-          { x: toBbox.left + toBbox.width / 2, y: lineStart.y - config.nodeSpacing / 2 },
-          lineStart], color)
-      } else {
-        svgDrawLine(svg, [{
-          'x': fromBbox.left + fromBbox.width / 2,
-          'y': fromBbox.top + fromBbox.height
-        }, {
-          'x': fromBbox.left + fromBbox.width / 2,
-          'y': fromBbox.top + config.nodeSpacing / 2
-        }, {
-          'x': toBbox.left + toBbox.width / 2,
-          'y': toBbox.top - config.nodeSpacing / 2
-        }, {
-          'x': toBbox.left + toBbox.width / 2,
-          'y': toBbox.top
-        }], color)
-      }
-      break
-  }
-}
-
-function cloneNode (svg, selector) {
-  return svg.select(selector).node().cloneNode(true)
-}
-
-function renderCommitHistory (svg, commitid, branches, direction) {
-  let commit
-  const numCommits = Object.keys(allCommitsDict).length
-  if (_.isString(commitid)) {
-    do {
-      commit = allCommitsDict[commitid]
-      logger.debug('in renderCommitHistory', commit.id, commit.seq)
-      if (svg.select('#node-' + commitid).size() > 0) {
-        return
-      }
-      svg
-        .append(function () {
-          return cloneNode(svg, '#def-commit')
-        })
-        .attr('class', 'commit')
-        .attr('id', function () {
-          return 'node-' + commit.id
-        })
-        .attr('transform', function () {
-          switch (direction) {
-            case 'LR':
-              return 'translate(' + (commit.seq * config.nodeSpacing + config.leftMargin) + ', ' +
-                (branchNum * config.branchOffset) + ')'
-            case 'BT':
-              return 'translate(' + (branchNum * config.branchOffset + config.leftMargin) + ', ' +
-                ((numCommits - commit.seq) * config.nodeSpacing) + ')'
-          }
-        })
-        .attr('fill', config.nodeFillColor)
-        .attr('stroke', config.nodeStrokeColor)
-        .attr('stroke-width', config.nodeStrokeWidth)
-
-      const branch = _.find(branches, ['commit', commit])
-      if (branch) {
-        logger.debug('found branch ', branch.name)
-        svg.select('#node-' + commit.id + ' p')
-          .append('xhtml:span')
-          .attr('class', 'branch-label')
-          .text(branch.name + ', ')
-      }
-      svg.select('#node-' + commit.id + ' p')
-        .append('xhtml:span')
-        .attr('class', 'commit-id')
-        .text(commit.id)
-      if (commit.message !== '' && direction === 'BT') {
-        svg.select('#node-' + commit.id + ' p')
-          .append('xhtml:span')
-          .attr('class', 'commit-msg')
-          .text(', ' + commit.message)
-      }
-      commitid = commit.parent
-    } while (commitid && allCommitsDict[commitid])
-  }
-
-  if (_.isArray(commitid)) {
-    logger.debug('found merge commmit', commitid)
-    renderCommitHistory(svg, commitid[0], branches, direction)
-    branchNum++
-    renderCommitHistory(svg, commitid[1], branches, direction)
-    branchNum--
-  }
-}
-
-function renderLines (svg, commit, direction, branchColor) {
-  branchColor = branchColor || 0
-  while (commit.seq > 0 && !commit.lineDrawn) {
-    if (_.isString(commit.parent)) {
-      svgDrawLineForCommits(svg, commit.id, commit.parent, direction, branchColor)
-      commit.lineDrawn = true
-      commit = allCommitsDict[commit.parent]
-    } else if (_.isArray(commit.parent)) {
-      svgDrawLineForCommits(svg, commit.id, commit.parent[0], direction, branchColor)
-      svgDrawLineForCommits(svg, commit.id, commit.parent[1], direction, branchColor + 1)
-      renderLines(svg, allCommitsDict[commit.parent[1]], direction, branchColor + 1)
-      commit.lineDrawn = true
-      commit = allCommitsDict[commit.parent[0]]
-    }
-  }
-}
-
-export const draw = function (txt, id, ver) {
-  try {
-    const parser = gitGraphParser.parser
-    parser.yy = db
-
-    logger.debug('in gitgraph renderer', txt, id, ver)
-    // Parse the graph definition
-    parser.parse(txt + '\n')
-
-    config = _.extend(config, apiConfig, db.getOptions())
-    logger.debug('effective options', config)
-    const direction = db.getDirection()
-    allCommitsDict = db.getCommits()
-    const branches = db.getBranchesAsObjArray()
-    if (direction === 'BT') {
-      config.nodeLabel.x = branches.length * config.branchOffset
-      config.nodeLabel.width = '100%'
-      config.nodeLabel.y = -1 * 2 * config.nodeRadius
-    }
-    const svg = d3.select(`[id="${id}"]`)
-    svgCreateDefs(svg)
-    branchNum = 1
-    _.each(branches, function (v) {
-      renderCommitHistory(svg, v.commit.id, branches, direction)
-      renderLines(svg, v.commit, direction)
-      branchNum++
-    })
-    svg.attr('height', function () {
-      if (direction === 'BT') return Object.keys(allCommitsDict).length * config.nodeSpacing
-      return (branches.length + 1) * config.branchOffset
-    })
-  } catch (e) {
-    logger.error('Error while rendering gitgraph')
-    logger.error(e.message)
-  }
-}
-
-export default {
-  setConf,
-  draw
-}
diff --git a/_submodules/mermaid/src/diagrams/git/parser/gitGraph.jison b/_submodules/mermaid/src/diagrams/git/parser/gitGraph.jison
deleted file mode 100644
index e675a56e45fba82802e940bc7b8eb074a3d89192..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/git/parser/gitGraph.jison
+++ /dev/null
@@ -1,92 +0,0 @@
-
-/*
- * Parse following
- * gitGraph:
- *  commit
- *  commit
- *  branch 
- */
-%lex
-
-%x string
-%x options
-%options case-insensitive
-
-%%
-
-(\r?\n)+                           return 'NL';
-\s+                             /* skip all whitespace */
-\#[^\n]*                        /* skip comments */
-\%%[^\n]*                       /* skip comments */
-"gitGraph"                      return 'GG';
-"commit"                        return 'COMMIT';
-"branch"                        return 'BRANCH';
-"merge"                         return 'MERGE';
-"reset"                         return 'RESET';
-"checkout"                         return 'CHECKOUT';
-"LR"                            return 'DIR';
-"BT"                            return 'DIR';
-":"                             return ':';
-"^"                             return 'CARET'
-"options"\r?\n                       this.begin("options");
-<options>"end"\r?\n                   this.popState();
-<options>[^\n]+\r?\n                 return 'OPT';
-["]                             this.begin("string");
-<string>["]                     this.popState();
-<string>[^"]*                     return 'STR';
-[a-zA-Z][a-zA-Z0-9_]+           return 'ID';
-<<EOF>>                         return 'EOF';
-
-/lex
-
-%left '^'
-
-%start start
-
-%% /* language grammar */
-
-start
-    : GG ':' document EOF{ return $3; }
-    | GG DIR ':' document EOF {yy.setDirection($2); return $4;}
-    ;
-
-
-document
-    : /*empty*/
-    | options body { yy.setOptions($1); $$ = $2}
-    ;
-
-options
-    : options OPT {$1 +=$2; $$=$1}
-    | NL
-    ;
-body
-    : /*emmpty*/ {$$ = []}
-    | body line {$1.push($2); $$=$1;}
-    ;
-line
-    : statement NL{$$ =$1}
-    | NL
-    ;
-
-statement
-    : COMMIT commit_arg {yy.commit($2)}
-    | BRANCH ID {yy.branch($2)}
-    | CHECKOUT ID {yy.checkout($2)}
-    | MERGE ID {yy.merge($2)}
-    | RESET reset_arg {yy.reset($2)}
-    ;
-
-commit_arg
-    : /* empty */ {$$ = ""}
-    | STR {$$=$1}
-    ;
-
-reset_arg
-    : 'HEAD' reset_parents{$$ = $1+ ":" + $2 }
-    | ID reset_parents{$$ = $1+ ":"  + yy.count; yy.count = 0}
-    ;
-reset_parents
-    : /* empty */ {yy.count = 0}
-    | CARET reset_parents { yy.count += 1 }
-    ;
diff --git a/_submodules/mermaid/src/diagrams/git/parser/gitGraph.js b/_submodules/mermaid/src/diagrams/git/parser/gitGraph.js
deleted file mode 100644
index fd981cafb53fe346f0457b00a881b850530ce586..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/git/parser/gitGraph.js
+++ /dev/null
@@ -1,696 +0,0 @@
-/* parser generated by jison 0.4.18 */
-/*
-  Returns a Parser object of the following structure:
-
-  Parser: {
-    yy: {}
-  }
-
-  Parser.prototype: {
-    yy: {},
-    trace: function(),
-    symbols_: {associative list: name ==> number},
-    terminals_: {associative list: number ==> name},
-    productions_: [...],
-    performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
-    table: [...],
-    defaultActions: {...},
-    parseError: function(str, hash),
-    parse: function(input),
-
-    lexer: {
-        EOF: 1,
-        parseError: function(str, hash),
-        setInput: function(input),
-        input: function(),
-        unput: function(str),
-        more: function(),
-        less: function(n),
-        pastInput: function(),
-        upcomingInput: function(),
-        showPosition: function(),
-        test_match: function(regex_match_array, rule_index),
-        next: function(),
-        lex: function(),
-        begin: function(condition),
-        popState: function(),
-        _currentRules: function(),
-        topState: function(),
-        pushState: function(condition),
-
-        options: {
-            ranges: boolean           (optional: true ==> token location info will include a .range[] member)
-            flex: boolean             (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
-            backtrack_lexer: boolean  (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
-        },
-
-        performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
-        rules: [...],
-        conditions: {associative list: name ==> set},
-    }
-  }
-
-
-  token location info (@$, _$, etc.): {
-    first_line: n,
-    last_line: n,
-    first_column: n,
-    last_column: n,
-    range: [start_number, end_number]       (where the numbers are indexes into the input string, regular zero-based)
-  }
-
-
-  the parseError function receives a 'hash' object with these members for lexer and parser errors: {
-    text:        (matched text)
-    token:       (the produced terminal token, if any)
-    line:        (yylineno)
-  }
-  while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
-    loc:         (yylloc)
-    expected:    (string describing the set of expected tokens)
-    recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
-  }
-*/
-var parser = (function(){
-var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[2,3],$V1=[1,7],$V2=[7,12,15,17,19,20,21],$V3=[7,11,12,15,17,19,20,21],$V4=[2,20],$V5=[1,32];
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {"error":2,"start":3,"GG":4,":":5,"document":6,"EOF":7,"DIR":8,"options":9,"body":10,"OPT":11,"NL":12,"line":13,"statement":14,"COMMIT":15,"commit_arg":16,"BRANCH":17,"ID":18,"CHECKOUT":19,"MERGE":20,"RESET":21,"reset_arg":22,"STR":23,"HEAD":24,"reset_parents":25,"CARET":26,"$accept":0,"$end":1},
-terminals_: {2:"error",4:"GG",5:":",7:"EOF",8:"DIR",11:"OPT",12:"NL",15:"COMMIT",17:"BRANCH",18:"ID",19:"CHECKOUT",20:"MERGE",21:"RESET",23:"STR",24:"HEAD",26:"CARET"},
-productions_: [0,[3,4],[3,5],[6,0],[6,2],[9,2],[9,1],[10,0],[10,2],[13,2],[13,1],[14,2],[14,2],[14,2],[14,2],[14,2],[16,0],[16,1],[22,2],[22,2],[25,0],[25,2]],
-performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
-/* this == yyval */
-
-var $0 = $$.length - 1;
-switch (yystate) {
-case 1:
- return $$[$0-1]; 
-break;
-case 2:
-yy.setDirection($$[$0-3]); return $$[$0-1];
-break;
-case 4:
- yy.setOptions($$[$0-1]); this.$ = $$[$0]
-break;
-case 5:
-$$[$0-1] +=$$[$0]; this.$=$$[$0-1]
-break;
-case 7:
-this.$ = []
-break;
-case 8:
-$$[$0-1].push($$[$0]); this.$=$$[$0-1];
-break;
-case 9:
-this.$ =$$[$0-1]
-break;
-case 11:
-yy.commit($$[$0])
-break;
-case 12:
-yy.branch($$[$0])
-break;
-case 13:
-yy.checkout($$[$0])
-break;
-case 14:
-yy.merge($$[$0])
-break;
-case 15:
-yy.reset($$[$0])
-break;
-case 16:
-this.$ = ""
-break;
-case 17:
-this.$=$$[$0]
-break;
-case 18:
-this.$ = $$[$0-1]+ ":" + $$[$0] 
-break;
-case 19:
-this.$ = $$[$0-1]+ ":"  + yy.count; yy.count = 0
-break;
-case 20:
-yy.count = 0
-break;
-case 21:
- yy.count += 1 
-break;
-}
-},
-table: [{3:1,4:[1,2]},{1:[3]},{5:[1,3],8:[1,4]},{6:5,7:$V0,9:6,12:$V1},{5:[1,8]},{7:[1,9]},o($V2,[2,7],{10:10,11:[1,11]}),o($V3,[2,6]),{6:12,7:$V0,9:6,12:$V1},{1:[2,1]},{7:[2,4],12:[1,15],13:13,14:14,15:[1,16],17:[1,17],19:[1,18],20:[1,19],21:[1,20]},o($V3,[2,5]),{7:[1,21]},o($V2,[2,8]),{12:[1,22]},o($V2,[2,10]),{12:[2,16],16:23,23:[1,24]},{18:[1,25]},{18:[1,26]},{18:[1,27]},{18:[1,30],22:28,24:[1,29]},{1:[2,2]},o($V2,[2,9]),{12:[2,11]},{12:[2,17]},{12:[2,12]},{12:[2,13]},{12:[2,14]},{12:[2,15]},{12:$V4,25:31,26:$V5},{12:$V4,25:33,26:$V5},{12:[2,18]},{12:$V4,25:34,26:$V5},{12:[2,19]},{12:[2,21]}],
-defaultActions: {9:[2,1],21:[2,2],23:[2,11],24:[2,17],25:[2,12],26:[2,13],27:[2,14],28:[2,15],31:[2,18],33:[2,19],34:[2,21]},
-parseError: function parseError(str, hash) {
-    if (hash.recoverable) {
-        this.trace(str);
-    } else {
-        var error = new Error(str);
-        error.hash = hash;
-        throw error;
-    }
-},
-parse: function parse(input) {
-    var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
-    var args = lstack.slice.call(arguments, 1);
-    var lexer = Object.create(this.lexer);
-    var sharedState = { yy: {} };
-    for (var k in this.yy) {
-        if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
-            sharedState.yy[k] = this.yy[k];
-        }
-    }
-    lexer.setInput(input, sharedState.yy);
-    sharedState.yy.lexer = lexer;
-    sharedState.yy.parser = this;
-    if (typeof lexer.yylloc == 'undefined') {
-        lexer.yylloc = {};
-    }
-    var yyloc = lexer.yylloc;
-    lstack.push(yyloc);
-    var ranges = lexer.options && lexer.options.ranges;
-    if (typeof sharedState.yy.parseError === 'function') {
-        this.parseError = sharedState.yy.parseError;
-    } else {
-        this.parseError = Object.getPrototypeOf(this).parseError;
-    }
-    function popStack(n) {
-        stack.length = stack.length - 2 * n;
-        vstack.length = vstack.length - n;
-        lstack.length = lstack.length - n;
-    }
-            function lex() {
-            var token;
-            token = tstack.pop() || lexer.lex() || EOF;
-            if (typeof token !== 'number') {
-                if (token instanceof Array) {
-                    tstack = token;
-                    token = tstack.pop();
-                }
-                token = self.symbols_[token] || token;
-            }
-            return token;
-        }
-    var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
-    while (true) {
-        state = stack[stack.length - 1];
-        if (this.defaultActions[state]) {
-            action = this.defaultActions[state];
-        } else {
-            if (symbol === null || typeof symbol == 'undefined') {
-                symbol = lex();
-            }
-            action = table[state] && table[state][symbol];
-        }
-        if (typeof action === 'undefined' || !action.length || !action[0]) {
-            var errStr = '';
-            expected = [];
-            for (p in table[state]) {
-                if (this.terminals_[p] && p > TERROR) {
-                    expected.push('\'' + this.terminals_[p] + '\'');
-                }
-            }
-            if (lexer.showPosition) {
-                errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
-            } else {
-                errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
-            }
-            this.parseError(errStr, {
-                text: lexer.match,
-                token: this.terminals_[symbol] || symbol,
-                line: lexer.yylineno,
-                loc: yyloc,
-                expected: expected
-            });
-        }
-        if (action[0] instanceof Array && action.length > 1) {
-            throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
-        }
-        switch (action[0]) {
-        case 1:
-            stack.push(symbol);
-            vstack.push(lexer.yytext);
-            lstack.push(lexer.yylloc);
-            stack.push(action[1]);
-            symbol = null;
-            if (!preErrorSymbol) {
-                yyleng = lexer.yyleng;
-                yytext = lexer.yytext;
-                yylineno = lexer.yylineno;
-                yyloc = lexer.yylloc;
-                if (recovering > 0) {
-                    recovering--;
-                }
-            } else {
-                symbol = preErrorSymbol;
-                preErrorSymbol = null;
-            }
-            break;
-        case 2:
-            len = this.productions_[action[1]][1];
-            yyval.$ = vstack[vstack.length - len];
-            yyval._$ = {
-                first_line: lstack[lstack.length - (len || 1)].first_line,
-                last_line: lstack[lstack.length - 1].last_line,
-                first_column: lstack[lstack.length - (len || 1)].first_column,
-                last_column: lstack[lstack.length - 1].last_column
-            };
-            if (ranges) {
-                yyval._$.range = [
-                    lstack[lstack.length - (len || 1)].range[0],
-                    lstack[lstack.length - 1].range[1]
-                ];
-            }
-            r = this.performAction.apply(yyval, [
-                yytext,
-                yyleng,
-                yylineno,
-                sharedState.yy,
-                action[1],
-                vstack,
-                lstack
-            ].concat(args));
-            if (typeof r !== 'undefined') {
-                return r;
-            }
-            if (len) {
-                stack = stack.slice(0, -1 * len * 2);
-                vstack = vstack.slice(0, -1 * len);
-                lstack = lstack.slice(0, -1 * len);
-            }
-            stack.push(this.productions_[action[1]][0]);
-            vstack.push(yyval.$);
-            lstack.push(yyval._$);
-            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
-            stack.push(newState);
-            break;
-        case 3:
-            return true;
-        }
-    }
-    return true;
-}};
-/* generated by jison-lex 0.3.4 */
-var lexer = (function(){
-var lexer = ({
-
-EOF:1,
-
-parseError:function parseError(str, hash) {
-        if (this.yy.parser) {
-            this.yy.parser.parseError(str, hash);
-        } else {
-            throw new Error(str);
-        }
-    },
-
-// resets the lexer, sets new input
-setInput:function (input, yy) {
-        this.yy = yy || this.yy || {};
-        this._input = input;
-        this._more = this._backtrack = this.done = false;
-        this.yylineno = this.yyleng = 0;
-        this.yytext = this.matched = this.match = '';
-        this.conditionStack = ['INITIAL'];
-        this.yylloc = {
-            first_line: 1,
-            first_column: 0,
-            last_line: 1,
-            last_column: 0
-        };
-        if (this.options.ranges) {
-            this.yylloc.range = [0,0];
-        }
-        this.offset = 0;
-        return this;
-    },
-
-// consumes and returns one char from the input
-input:function () {
-        var ch = this._input[0];
-        this.yytext += ch;
-        this.yyleng++;
-        this.offset++;
-        this.match += ch;
-        this.matched += ch;
-        var lines = ch.match(/(?:\r\n?|\n).*/g);
-        if (lines) {
-            this.yylineno++;
-            this.yylloc.last_line++;
-        } else {
-            this.yylloc.last_column++;
-        }
-        if (this.options.ranges) {
-            this.yylloc.range[1]++;
-        }
-
-        this._input = this._input.slice(1);
-        return ch;
-    },
-
-// unshifts one char (or a string) into the input
-unput:function (ch) {
-        var len = ch.length;
-        var lines = ch.split(/(?:\r\n?|\n)/g);
-
-        this._input = ch + this._input;
-        this.yytext = this.yytext.substr(0, this.yytext.length - len);
-        //this.yyleng -= len;
-        this.offset -= len;
-        var oldLines = this.match.split(/(?:\r\n?|\n)/g);
-        this.match = this.match.substr(0, this.match.length - 1);
-        this.matched = this.matched.substr(0, this.matched.length - 1);
-
-        if (lines.length - 1) {
-            this.yylineno -= lines.length - 1;
-        }
-        var r = this.yylloc.range;
-
-        this.yylloc = {
-            first_line: this.yylloc.first_line,
-            last_line: this.yylineno + 1,
-            first_column: this.yylloc.first_column,
-            last_column: lines ?
-                (lines.length === oldLines.length ? this.yylloc.first_column : 0)
-                 + oldLines[oldLines.length - lines.length].length - lines[0].length :
-              this.yylloc.first_column - len
-        };
-
-        if (this.options.ranges) {
-            this.yylloc.range = [r[0], r[0] + this.yyleng - len];
-        }
-        this.yyleng = this.yytext.length;
-        return this;
-    },
-
-// When called from action, caches matched text and appends it on next action
-more:function () {
-        this._more = true;
-        return this;
-    },
-
-// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
-reject:function () {
-        if (this.options.backtrack_lexer) {
-            this._backtrack = true;
-        } else {
-            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
-                text: "",
-                token: null,
-                line: this.yylineno
-            });
-
-        }
-        return this;
-    },
-
-// retain first n characters of the match
-less:function (n) {
-        this.unput(this.match.slice(n));
-    },
-
-// displays already matched input, i.e. for error messages
-pastInput:function () {
-        var past = this.matched.substr(0, this.matched.length - this.match.length);
-        return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
-    },
-
-// displays upcoming input, i.e. for error messages
-upcomingInput:function () {
-        var next = this.match;
-        if (next.length < 20) {
-            next += this._input.substr(0, 20-next.length);
-        }
-        return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
-    },
-
-// displays the character position where the lexing error occurred, i.e. for error messages
-showPosition:function () {
-        var pre = this.pastInput();
-        var c = new Array(pre.length + 1).join("-");
-        return pre + this.upcomingInput() + "\n" + c + "^";
-    },
-
-// test the lexed token: return FALSE when not a match, otherwise return token
-test_match:function (match, indexed_rule) {
-        var token,
-            lines,
-            backup;
-
-        if (this.options.backtrack_lexer) {
-            // save context
-            backup = {
-                yylineno: this.yylineno,
-                yylloc: {
-                    first_line: this.yylloc.first_line,
-                    last_line: this.last_line,
-                    first_column: this.yylloc.first_column,
-                    last_column: this.yylloc.last_column
-                },
-                yytext: this.yytext,
-                match: this.match,
-                matches: this.matches,
-                matched: this.matched,
-                yyleng: this.yyleng,
-                offset: this.offset,
-                _more: this._more,
-                _input: this._input,
-                yy: this.yy,
-                conditionStack: this.conditionStack.slice(0),
-                done: this.done
-            };
-            if (this.options.ranges) {
-                backup.yylloc.range = this.yylloc.range.slice(0);
-            }
-        }
-
-        lines = match[0].match(/(?:\r\n?|\n).*/g);
-        if (lines) {
-            this.yylineno += lines.length;
-        }
-        this.yylloc = {
-            first_line: this.yylloc.last_line,
-            last_line: this.yylineno + 1,
-            first_column: this.yylloc.last_column,
-            last_column: lines ?
-                         lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
-                         this.yylloc.last_column + match[0].length
-        };
-        this.yytext += match[0];
-        this.match += match[0];
-        this.matches = match;
-        this.yyleng = this.yytext.length;
-        if (this.options.ranges) {
-            this.yylloc.range = [this.offset, this.offset += this.yyleng];
-        }
-        this._more = false;
-        this._backtrack = false;
-        this._input = this._input.slice(match[0].length);
-        this.matched += match[0];
-        token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
-        if (this.done && this._input) {
-            this.done = false;
-        }
-        if (token) {
-            return token;
-        } else if (this._backtrack) {
-            // recover context
-            for (var k in backup) {
-                this[k] = backup[k];
-            }
-            return false; // rule action called reject() implying the next rule should be tested instead.
-        }
-        return false;
-    },
-
-// return next match in input
-next:function () {
-        if (this.done) {
-            return this.EOF;
-        }
-        if (!this._input) {
-            this.done = true;
-        }
-
-        var token,
-            match,
-            tempMatch,
-            index;
-        if (!this._more) {
-            this.yytext = '';
-            this.match = '';
-        }
-        var rules = this._currentRules();
-        for (var i = 0; i < rules.length; i++) {
-            tempMatch = this._input.match(this.rules[rules[i]]);
-            if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
-                match = tempMatch;
-                index = i;
-                if (this.options.backtrack_lexer) {
-                    token = this.test_match(tempMatch, rules[i]);
-                    if (token !== false) {
-                        return token;
-                    } else if (this._backtrack) {
-                        match = false;
-                        continue; // rule action called reject() implying a rule MISmatch.
-                    } else {
-                        // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
-                        return false;
-                    }
-                } else if (!this.options.flex) {
-                    break;
-                }
-            }
-        }
-        if (match) {
-            token = this.test_match(match, rules[index]);
-            if (token !== false) {
-                return token;
-            }
-            // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
-            return false;
-        }
-        if (this._input === "") {
-            return this.EOF;
-        } else {
-            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
-                text: "",
-                token: null,
-                line: this.yylineno
-            });
-        }
-    },
-
-// return next match that has a token
-lex:function lex() {
-        var r = this.next();
-        if (r) {
-            return r;
-        } else {
-            return this.lex();
-        }
-    },
-
-// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
-begin:function begin(condition) {
-        this.conditionStack.push(condition);
-    },
-
-// pop the previously active lexer condition state off the condition stack
-popState:function popState() {
-        var n = this.conditionStack.length - 1;
-        if (n > 0) {
-            return this.conditionStack.pop();
-        } else {
-            return this.conditionStack[0];
-        }
-    },
-
-// produce the lexer rule set which is active for the currently active lexer condition state
-_currentRules:function _currentRules() {
-        if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
-            return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
-        } else {
-            return this.conditions["INITIAL"].rules;
-        }
-    },
-
-// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
-topState:function topState(n) {
-        n = this.conditionStack.length - 1 - Math.abs(n || 0);
-        if (n >= 0) {
-            return this.conditionStack[n];
-        } else {
-            return "INITIAL";
-        }
-    },
-
-// alias for begin(condition)
-pushState:function pushState(condition) {
-        this.begin(condition);
-    },
-
-// return the number of states currently on the stack
-stateStackSize:function stateStackSize() {
-        return this.conditionStack.length;
-    },
-options: {"case-insensitive":true},
-performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
-var YYSTATE=YY_START;
-switch($avoiding_name_collisions) {
-case 0:return 12;
-break;
-case 1:/* skip all whitespace */
-break;
-case 2:/* skip comments */
-break;
-case 3:/* skip comments */
-break;
-case 4:return 4;
-break;
-case 5:return 15;
-break;
-case 6:return 17;
-break;
-case 7:return 20;
-break;
-case 8:return 21;
-break;
-case 9:return 19;
-break;
-case 10:return 8;
-break;
-case 11:return 8;
-break;
-case 12:return 5;
-break;
-case 13:return 26
-break;
-case 14:this.begin("options");
-break;
-case 15:this.popState();
-break;
-case 16:return 11;
-break;
-case 17:this.begin("string");
-break;
-case 18:this.popState();
-break;
-case 19:return 23;
-break;
-case 20:return 18;
-break;
-case 21:return 7;
-break;
-}
-},
-rules: [/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit\b)/i,/^(?:branch\b)/i,/^(?:merge\b)/i,/^(?:reset\b)/i,/^(?:checkout\b)/i,/^(?:LR\b)/i,/^(?:BT\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:end\r?\n)/i,/^(?:[^\n]+\r?\n)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[a-zA-Z][a-zA-Z0-9_]+)/i,/^(?:$)/i],
-conditions: {"options":{"rules":[15,16],"inclusive":false},"string":{"rules":[18,19],"inclusive":false},"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,20,21],"inclusive":true}}
-});
-return lexer;
-})();
-parser.lexer = lexer;
-function Parser () {
-  this.yy = {};
-}
-Parser.prototype = parser;parser.Parser = Parser;
-return new Parser;
-})();
-
-
-if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
-exports.parser = parser;
-exports.Parser = parser.Parser;
-exports.parse = function () { return parser.parse.apply(parser, arguments); };
-exports.main = function commonjsMain(args) {
-    if (!args[1]) {
-        console.log('Usage: '+args[0]+' FILE');
-        process.exit(1);
-    }
-    var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
-    return exports.parser.parse(source);
-};
-if (typeof module !== 'undefined' && require.main === module) {
-  exports.main(process.argv.slice(1));
-}
-}
\ No newline at end of file
diff --git a/_submodules/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison b/_submodules/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison
deleted file mode 100644
index 507956ee49ad978027602a9350f8b53a4039c295..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/sequence/parser/sequenceDiagram.jison
+++ /dev/null
@@ -1,192 +0,0 @@
-/** mermaid
- *  https://mermaidjs.github.io/
- *  (c) 2014-2015 Knut Sveidqvist
- *  MIT license.
- *
- *  Based on js sequence diagrams jison grammr
- *  http://bramp.github.io/js-sequence-diagrams/
- *  (c) 2012-2013 Andrew Brampton (bramp.net)
- *  Simplified BSD license.
- */
-%lex
-
-%options case-insensitive
-
-// Special states for recognizing aliases
-%x ID
-%x ALIAS
-
-// A special state for grabbing text up to the first comment/newline
-%x LINE
-
-%%
-
-[\n]+                            return 'NL';
-\s+                              /* skip all whitespace */
-<ID,ALIAS,LINE>((?!\n)\s)+       /* skip same-line whitespace */
-<INITIAL,ID,ALIAS,LINE>\#[^\n]*  /* skip comments */
-\%%[^\n]*                        /* skip comments */
-"participant"     { this.begin('ID'); return 'participant'; }
-<ID>[^\->:\n,;]+?(?=((?!\n)\s)+"as"(?!\n)\s|[#\n;]|$)  { this.begin('ALIAS'); return 'ACTOR'; }
-<ALIAS>"as"       { this.popState(); this.popState(); this.begin('LINE'); return 'AS'; }
-<ALIAS>(?:)       { this.popState(); this.popState(); return 'NL'; }
-"loop"            { this.begin('LINE'); return 'loop'; }
-"opt"             { this.begin('LINE'); return 'opt'; }
-"alt"             { this.begin('LINE'); return 'alt'; }
-"else"            { this.begin('LINE'); return 'else'; }
-"par"             { this.begin('LINE'); return 'par'; }
-"and"             { this.begin('LINE'); return 'and'; }
-<LINE>[^#\n;]*    { this.popState(); return 'restOfLine'; }
-"end"             return 'end';
-"left of"         return 'left_of';
-"right of"        return 'right_of';
-"over"            return 'over';
-"note"            return 'note';
-"activate"        { this.begin('ID'); return 'activate'; }
-"deactivate"      { this.begin('ID'); return 'deactivate'; }
-"title"           return 'title';
-"sequenceDiagram" return 'SD';
-","               return ',';
-";"               return 'NL';
-[^\+\->:\n,;]+      { yytext = yytext.trim(); return 'ACTOR'; }
-"->>"             return 'SOLID_ARROW';
-"-->>"            return 'DOTTED_ARROW';
-"->"              return 'SOLID_OPEN_ARROW';
-"-->"             return 'DOTTED_OPEN_ARROW';
-\-[x]             return 'SOLID_CROSS';
-\-\-[x]           return 'DOTTED_CROSS';
-":"[^#\n;]+       return 'TXT';
-"+"               return '+';
-"-"               return '-';
-<<EOF>>           return 'NL';
-.                 return 'INVALID';
-
-/lex
-
-%left '^'
-
-%start start
-
-%% /* language grammar */
-
-start
-	: SPACE start
-	| NL start
-	| SD document { yy.apply($2);return $2; }
-	;
-
-document
-	: /* empty */ { $$ = [] }
-	| document line {$1.push($2);$$ = $1}
-	;
-
-line
-	: SPACE statement { $$ = $2 }
-	| statement { $$ = $1 }
-	| NL { $$=[];}
-	;
-
-statement
-	: 'participant' actor 'AS' restOfLine 'NL' {$2.description=$4; $$=$2;}
-	| 'participant' actor 'NL' {$$=$2;}
-	| signal 'NL'
-	| 'activate' actor 'NL' {$$={type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $2};}
-	| 'deactivate' actor 'NL' {$$={type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $2};}
-	| note_statement 'NL'
-	| title text2 'NL' {$$=[{type:'setTitle', text:$2}]}
-	| 'loop' restOfLine document end
-	{
-		$3.unshift({type: 'loopStart', loopText:$2, signalType: yy.LINETYPE.LOOP_START});
-		$3.push({type: 'loopEnd', loopText:$2, signalType: yy.LINETYPE.LOOP_END});
-		$$=$3;}
-	| opt restOfLine document end
-	{
-		$3.unshift({type: 'optStart', optText:$2, signalType: yy.LINETYPE.OPT_START});
-		$3.push({type: 'optEnd', optText:$2, signalType: yy.LINETYPE.OPT_END});
-		$$=$3;}
-	| alt restOfLine else_sections end
-	{
-		// Alt start
-		$3.unshift({type: 'altStart', altText:$2, signalType: yy.LINETYPE.ALT_START});
-		// Content in alt is already in $3
-		// End
-		$3.push({type: 'altEnd', signalType: yy.LINETYPE.ALT_END});
-		$$=$3;}
-	| par restOfLine par_sections end
-	{
-		// Parallel start
-		$3.unshift({type: 'parStart', parText:$2, signalType: yy.LINETYPE.PAR_START});
-		// Content in par is already in $3
-		// End
-		$3.push({type: 'parEnd', signalType: yy.LINETYPE.PAR_END});
-		$$=$3;}
-	;
-
-par_sections
-	: document
-	| document and restOfLine par_sections
-	{ $$ = $1.concat([{type: 'and', parText:$3, signalType: yy.LINETYPE.PAR_AND}, $4]); }
-	;
-
-else_sections
-	: document
-	| document else restOfLine else_sections
-	{ $$ = $1.concat([{type: 'else', altText:$3, signalType: yy.LINETYPE.ALT_ELSE}, $4]); }
-	;
-
-note_statement
-	: 'note' placement actor text2
-	{
-		$$ = [$3, {type:'addNote', placement:$2, actor:$3.actor, text:$4}];}
-	| 'note' 'over' actor_pair text2
-	{
-		// Coerce actor_pair into a [to, from, ...] array
-		$2 = [].concat($3, $3).slice(0, 2);
-		$2[0] = $2[0].actor;
-		$2[1] = $2[1].actor;
-		$$ = [$3, {type:'addNote', placement:yy.PLACEMENT.OVER, actor:$2.slice(0, 2), text:$4}];}
-	;
-
-spaceList
-    : SPACE spaceList
-    | SPACE
-    ;
-actor_pair
-	: actor ',' actor   { $$ = [$1, $3]; }
-	| actor             { $$ = $1; }
-	;
-
-placement
-	: 'left_of'   { $$ = yy.PLACEMENT.LEFTOF; }
-	| 'right_of'  { $$ = yy.PLACEMENT.RIGHTOF; }
-	;
-
-signal
-	: actor signaltype '+' actor text2
-	{ $$ = [$1,$4,{type: 'addMessage', from:$1.actor, to:$4.actor, signalType:$2, msg:$5},
-	              {type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $4}
-	             ]}
-	| actor signaltype '-' actor text2
-	{ $$ = [$1,$4,{type: 'addMessage', from:$1.actor, to:$4.actor, signalType:$2, msg:$5},
-	             {type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $1}
-	             ]}
-	| actor signaltype actor text2
-	{ $$ = [$1,$3,{type: 'addMessage', from:$1.actor, to:$3.actor, signalType:$2, msg:$4}]}
-	;
-
-actor
-	: ACTOR {$$={type: 'addActor', actor:$1}}
-	;
-
-signaltype
-	: SOLID_OPEN_ARROW  { $$ = yy.LINETYPE.SOLID_OPEN; }
-	| DOTTED_OPEN_ARROW { $$ = yy.LINETYPE.DOTTED_OPEN; }
-	| SOLID_ARROW       { $$ = yy.LINETYPE.SOLID; }
-	| DOTTED_ARROW      { $$ = yy.LINETYPE.DOTTED; }
-	| SOLID_CROSS       { $$ = yy.LINETYPE.SOLID_CROSS; }
-	| DOTTED_CROSS      { $$ = yy.LINETYPE.DOTTED_CROSS; }
-	;
-
-text2: TXT {$$ = $1.substring(1).trim().replace(/\\n/gm, "\n");} ;
-
-%%
diff --git a/_submodules/mermaid/src/diagrams/sequence/parser/sequenceDiagram.js b/_submodules/mermaid/src/diagrams/sequence/parser/sequenceDiagram.js
deleted file mode 100644
index aa94350990f6cfb09cfe3160f6e4bf2040307fd0..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/sequence/parser/sequenceDiagram.js
+++ /dev/null
@@ -1,804 +0,0 @@
-/* parser generated by jison 0.4.18 */
-/*
-  Returns a Parser object of the following structure:
-
-  Parser: {
-    yy: {}
-  }
-
-  Parser.prototype: {
-    yy: {},
-    trace: function(),
-    symbols_: {associative list: name ==> number},
-    terminals_: {associative list: number ==> name},
-    productions_: [...],
-    performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
-    table: [...],
-    defaultActions: {...},
-    parseError: function(str, hash),
-    parse: function(input),
-
-    lexer: {
-        EOF: 1,
-        parseError: function(str, hash),
-        setInput: function(input),
-        input: function(),
-        unput: function(str),
-        more: function(),
-        less: function(n),
-        pastInput: function(),
-        upcomingInput: function(),
-        showPosition: function(),
-        test_match: function(regex_match_array, rule_index),
-        next: function(),
-        lex: function(),
-        begin: function(condition),
-        popState: function(),
-        _currentRules: function(),
-        topState: function(),
-        pushState: function(condition),
-
-        options: {
-            ranges: boolean           (optional: true ==> token location info will include a .range[] member)
-            flex: boolean             (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
-            backtrack_lexer: boolean  (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
-        },
-
-        performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
-        rules: [...],
-        conditions: {associative list: name ==> set},
-    }
-  }
-
-
-  token location info (@$, _$, etc.): {
-    first_line: n,
-    last_line: n,
-    first_column: n,
-    last_column: n,
-    range: [start_number, end_number]       (where the numbers are indexes into the input string, regular zero-based)
-  }
-
-
-  the parseError function receives a 'hash' object with these members for lexer and parser errors: {
-    text:        (matched text)
-    token:       (the produced terminal token, if any)
-    line:        (yylineno)
-  }
-  while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
-    loc:         (yylloc)
-    expected:    (string describing the set of expected tokens)
-    recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
-  }
-*/
-var parser = (function(){
-var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,2],$V1=[1,3],$V2=[1,4],$V3=[2,4],$V4=[1,9],$V5=[1,11],$V6=[1,12],$V7=[1,14],$V8=[1,15],$V9=[1,17],$Va=[1,18],$Vb=[1,19],$Vc=[1,20],$Vd=[1,21],$Ve=[1,23],$Vf=[1,24],$Vg=[1,4,5,10,15,16,18,20,21,22,23,25,27,28,29,40],$Vh=[1,32],$Vi=[4,5,10,15,16,18,20,21,22,23,25,29,40],$Vj=[4,5,10,15,16,18,20,21,22,23,25,28,29,40],$Vk=[4,5,10,15,16,18,20,21,22,23,25,27,29,40],$Vl=[38,39,40];
-var parser = {trace: function trace() { },
-yy: {},
-symbols_: {"error":2,"start":3,"SPACE":4,"NL":5,"SD":6,"document":7,"line":8,"statement":9,"participant":10,"actor":11,"AS":12,"restOfLine":13,"signal":14,"activate":15,"deactivate":16,"note_statement":17,"title":18,"text2":19,"loop":20,"end":21,"opt":22,"alt":23,"else_sections":24,"par":25,"par_sections":26,"and":27,"else":28,"note":29,"placement":30,"over":31,"actor_pair":32,"spaceList":33,",":34,"left_of":35,"right_of":36,"signaltype":37,"+":38,"-":39,"ACTOR":40,"SOLID_OPEN_ARROW":41,"DOTTED_OPEN_ARROW":42,"SOLID_ARROW":43,"DOTTED_ARROW":44,"SOLID_CROSS":45,"DOTTED_CROSS":46,"TXT":47,"$accept":0,"$end":1},
-terminals_: {2:"error",4:"SPACE",5:"NL",6:"SD",10:"participant",12:"AS",13:"restOfLine",15:"activate",16:"deactivate",18:"title",20:"loop",21:"end",22:"opt",23:"alt",25:"par",27:"and",28:"else",29:"note",31:"over",34:",",35:"left_of",36:"right_of",38:"+",39:"-",40:"ACTOR",41:"SOLID_OPEN_ARROW",42:"DOTTED_OPEN_ARROW",43:"SOLID_ARROW",44:"DOTTED_ARROW",45:"SOLID_CROSS",46:"DOTTED_CROSS",47:"TXT"},
-productions_: [0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,5],[9,3],[9,2],[9,3],[9,3],[9,2],[9,3],[9,4],[9,4],[9,4],[9,4],[26,1],[26,4],[24,1],[24,4],[17,4],[17,4],[33,2],[33,1],[32,3],[32,1],[30,1],[30,1],[14,5],[14,5],[14,4],[11,1],[37,1],[37,1],[37,1],[37,1],[37,1],[37,1],[19,1]],
-performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
-/* this == yyval */
-
-var $0 = $$.length - 1;
-switch (yystate) {
-case 3:
- yy.apply($$[$0]);return $$[$0]; 
-break;
-case 4:
- this.$ = [] 
-break;
-case 5:
-$$[$0-1].push($$[$0]);this.$ = $$[$0-1]
-break;
-case 6: case 7:
- this.$ = $$[$0] 
-break;
-case 8:
- this.$=[];
-break;
-case 9:
-$$[$0-3].description=$$[$0-1]; this.$=$$[$0-3];
-break;
-case 10:
-this.$=$$[$0-1];
-break;
-case 12:
-this.$={type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $$[$0-1]};
-break;
-case 13:
-this.$={type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $$[$0-1]};
-break;
-case 15:
-this.$=[{type:'setTitle', text:$$[$0-1]}]
-break;
-case 16:
-
-		$$[$0-1].unshift({type: 'loopStart', loopText:$$[$0-2], signalType: yy.LINETYPE.LOOP_START});
-		$$[$0-1].push({type: 'loopEnd', loopText:$$[$0-2], signalType: yy.LINETYPE.LOOP_END});
-		this.$=$$[$0-1];
-break;
-case 17:
-
-		$$[$0-1].unshift({type: 'optStart', optText:$$[$0-2], signalType: yy.LINETYPE.OPT_START});
-		$$[$0-1].push({type: 'optEnd', optText:$$[$0-2], signalType: yy.LINETYPE.OPT_END});
-		this.$=$$[$0-1];
-break;
-case 18:
-
-		// Alt start
-		$$[$0-1].unshift({type: 'altStart', altText:$$[$0-2], signalType: yy.LINETYPE.ALT_START});
-		// Content in alt is already in $$[$0-1]
-		// End
-		$$[$0-1].push({type: 'altEnd', signalType: yy.LINETYPE.ALT_END});
-		this.$=$$[$0-1];
-break;
-case 19:
-
-		// Parallel start
-		$$[$0-1].unshift({type: 'parStart', parText:$$[$0-2], signalType: yy.LINETYPE.PAR_START});
-		// Content in par is already in $$[$0-1]
-		// End
-		$$[$0-1].push({type: 'parEnd', signalType: yy.LINETYPE.PAR_END});
-		this.$=$$[$0-1];
-break;
-case 21:
- this.$ = $$[$0-3].concat([{type: 'and', parText:$$[$0-1], signalType: yy.LINETYPE.PAR_AND}, $$[$0]]); 
-break;
-case 23:
- this.$ = $$[$0-3].concat([{type: 'else', altText:$$[$0-1], signalType: yy.LINETYPE.ALT_ELSE}, $$[$0]]); 
-break;
-case 24:
-
-		this.$ = [$$[$0-1], {type:'addNote', placement:$$[$0-2], actor:$$[$0-1].actor, text:$$[$0]}];
-break;
-case 25:
-
-		// Coerce actor_pair into a [to, from, ...] array
-		$$[$0-2] = [].concat($$[$0-1], $$[$0-1]).slice(0, 2);
-		$$[$0-2][0] = $$[$0-2][0].actor;
-		$$[$0-2][1] = $$[$0-2][1].actor;
-		this.$ = [$$[$0-1], {type:'addNote', placement:yy.PLACEMENT.OVER, actor:$$[$0-2].slice(0, 2), text:$$[$0]}];
-break;
-case 28:
- this.$ = [$$[$0-2], $$[$0]]; 
-break;
-case 29:
- this.$ = $$[$0]; 
-break;
-case 30:
- this.$ = yy.PLACEMENT.LEFTOF; 
-break;
-case 31:
- this.$ = yy.PLACEMENT.RIGHTOF; 
-break;
-case 32:
- this.$ = [$$[$0-4],$$[$0-1],{type: 'addMessage', from:$$[$0-4].actor, to:$$[$0-1].actor, signalType:$$[$0-3], msg:$$[$0]},
-	              {type: 'activeStart', signalType: yy.LINETYPE.ACTIVE_START, actor: $$[$0-1]}
-	             ]
-break;
-case 33:
- this.$ = [$$[$0-4],$$[$0-1],{type: 'addMessage', from:$$[$0-4].actor, to:$$[$0-1].actor, signalType:$$[$0-3], msg:$$[$0]},
-	             {type: 'activeEnd', signalType: yy.LINETYPE.ACTIVE_END, actor: $$[$0-4]}
-	             ]
-break;
-case 34:
- this.$ = [$$[$0-3],$$[$0-1],{type: 'addMessage', from:$$[$0-3].actor, to:$$[$0-1].actor, signalType:$$[$0-2], msg:$$[$0]}]
-break;
-case 35:
-this.$={type: 'addActor', actor:$$[$0]}
-break;
-case 36:
- this.$ = yy.LINETYPE.SOLID_OPEN; 
-break;
-case 37:
- this.$ = yy.LINETYPE.DOTTED_OPEN; 
-break;
-case 38:
- this.$ = yy.LINETYPE.SOLID; 
-break;
-case 39:
- this.$ = yy.LINETYPE.DOTTED; 
-break;
-case 40:
- this.$ = yy.LINETYPE.SOLID_CROSS; 
-break;
-case 41:
- this.$ = yy.LINETYPE.DOTTED_CROSS; 
-break;
-case 42:
-this.$ = $$[$0].substring(1).trim().replace(/\\n/gm, "\n");
-break;
-}
-},
-table: [{3:1,4:$V0,5:$V1,6:$V2},{1:[3]},{3:5,4:$V0,5:$V1,6:$V2},{3:6,4:$V0,5:$V1,6:$V2},o([1,4,5,10,15,16,18,20,22,23,25,29,40],$V3,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,22:$Vb,23:$Vc,25:$Vd,29:$Ve,40:$Vf},o($Vg,[2,5]),{9:25,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,22:$Vb,23:$Vc,25:$Vd,29:$Ve,40:$Vf},o($Vg,[2,7]),o($Vg,[2,8]),{11:26,40:$Vf},{5:[1,27]},{11:28,40:$Vf},{11:29,40:$Vf},{5:[1,30]},{19:31,47:$Vh},{13:[1,33]},{13:[1,34]},{13:[1,35]},{13:[1,36]},{37:37,41:[1,38],42:[1,39],43:[1,40],44:[1,41],45:[1,42],46:[1,43]},{30:44,31:[1,45],35:[1,46],36:[1,47]},o([5,12,34,41,42,43,44,45,46,47],[2,35]),o($Vg,[2,6]),{5:[1,49],12:[1,48]},o($Vg,[2,11]),{5:[1,50]},{5:[1,51]},o($Vg,[2,14]),{5:[1,52]},{5:[2,42]},o($Vi,$V3,{7:53}),o($Vi,$V3,{7:54}),o($Vj,$V3,{24:55,7:56}),o($Vk,$V3,{26:57,7:58}),{11:61,38:[1,59],39:[1,60],40:$Vf},o($Vl,[2,36]),o($Vl,[2,37]),o($Vl,[2,38]),o($Vl,[2,39]),o($Vl,[2,40]),o($Vl,[2,41]),{11:62,40:$Vf},{11:64,32:63,40:$Vf},{40:[2,30]},{40:[2,31]},{13:[1,65]},o($Vg,[2,10]),o($Vg,[2,12]),o($Vg,[2,13]),o($Vg,[2,15]),{4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[1,66],22:$Vb,23:$Vc,25:$Vd,29:$Ve,40:$Vf},{4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[1,67],22:$Vb,23:$Vc,25:$Vd,29:$Ve,40:$Vf},{21:[1,68]},{4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[2,22],22:$Vb,23:$Vc,25:$Vd,28:[1,69],29:$Ve,40:$Vf},{21:[1,70]},{4:$V4,5:$V5,8:8,9:10,10:$V6,11:22,14:13,15:$V7,16:$V8,17:16,18:$V9,20:$Va,21:[2,20],22:$Vb,23:$Vc,25:$Vd,27:[1,71],29:$Ve,40:$Vf},{11:72,40:$Vf},{11:73,40:$Vf},{19:74,47:$Vh},{19:75,47:$Vh},{19:76,47:$Vh},{34:[1,77],47:[2,29]},{5:[1,78]},o($Vg,[2,16]),o($Vg,[2,17]),o($Vg,[2,18]),{13:[1,79]},o($Vg,[2,19]),{13:[1,80]},{19:81,47:$Vh},{19:82,47:$Vh},{5:[2,34]},{5:[2,24]},{5:[2,25]},{11:83,40:$Vf},o($Vg,[2,9]),o($Vj,$V3,{7:56,24:84}),o($Vk,$V3,{7:58,26:85}),{5:[2,32]},{5:[2,33]},{47:[2,28]},{21:[2,23]},{21:[2,21]}],
-defaultActions: {5:[2,1],6:[2,2],32:[2,42],46:[2,30],47:[2,31],74:[2,34],75:[2,24],76:[2,25],81:[2,32],82:[2,33],83:[2,28],84:[2,23],85:[2,21]},
-parseError: function parseError(str, hash) {
-    if (hash.recoverable) {
-        this.trace(str);
-    } else {
-        var error = new Error(str);
-        error.hash = hash;
-        throw error;
-    }
-},
-parse: function parse(input) {
-    var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
-    var args = lstack.slice.call(arguments, 1);
-    var lexer = Object.create(this.lexer);
-    var sharedState = { yy: {} };
-    for (var k in this.yy) {
-        if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
-            sharedState.yy[k] = this.yy[k];
-        }
-    }
-    lexer.setInput(input, sharedState.yy);
-    sharedState.yy.lexer = lexer;
-    sharedState.yy.parser = this;
-    if (typeof lexer.yylloc == 'undefined') {
-        lexer.yylloc = {};
-    }
-    var yyloc = lexer.yylloc;
-    lstack.push(yyloc);
-    var ranges = lexer.options && lexer.options.ranges;
-    if (typeof sharedState.yy.parseError === 'function') {
-        this.parseError = sharedState.yy.parseError;
-    } else {
-        this.parseError = Object.getPrototypeOf(this).parseError;
-    }
-    function popStack(n) {
-        stack.length = stack.length - 2 * n;
-        vstack.length = vstack.length - n;
-        lstack.length = lstack.length - n;
-    }
-            function lex() {
-            var token;
-            token = tstack.pop() || lexer.lex() || EOF;
-            if (typeof token !== 'number') {
-                if (token instanceof Array) {
-                    tstack = token;
-                    token = tstack.pop();
-                }
-                token = self.symbols_[token] || token;
-            }
-            return token;
-        }
-    var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
-    while (true) {
-        state = stack[stack.length - 1];
-        if (this.defaultActions[state]) {
-            action = this.defaultActions[state];
-        } else {
-            if (symbol === null || typeof symbol == 'undefined') {
-                symbol = lex();
-            }
-            action = table[state] && table[state][symbol];
-        }
-        if (typeof action === 'undefined' || !action.length || !action[0]) {
-            var errStr = '';
-            expected = [];
-            for (p in table[state]) {
-                if (this.terminals_[p] && p > TERROR) {
-                    expected.push('\'' + this.terminals_[p] + '\'');
-                }
-            }
-            if (lexer.showPosition) {
-                errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
-            } else {
-                errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
-            }
-            this.parseError(errStr, {
-                text: lexer.match,
-                token: this.terminals_[symbol] || symbol,
-                line: lexer.yylineno,
-                loc: yyloc,
-                expected: expected
-            });
-        }
-        if (action[0] instanceof Array && action.length > 1) {
-            throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
-        }
-        switch (action[0]) {
-        case 1:
-            stack.push(symbol);
-            vstack.push(lexer.yytext);
-            lstack.push(lexer.yylloc);
-            stack.push(action[1]);
-            symbol = null;
-            if (!preErrorSymbol) {
-                yyleng = lexer.yyleng;
-                yytext = lexer.yytext;
-                yylineno = lexer.yylineno;
-                yyloc = lexer.yylloc;
-                if (recovering > 0) {
-                    recovering--;
-                }
-            } else {
-                symbol = preErrorSymbol;
-                preErrorSymbol = null;
-            }
-            break;
-        case 2:
-            len = this.productions_[action[1]][1];
-            yyval.$ = vstack[vstack.length - len];
-            yyval._$ = {
-                first_line: lstack[lstack.length - (len || 1)].first_line,
-                last_line: lstack[lstack.length - 1].last_line,
-                first_column: lstack[lstack.length - (len || 1)].first_column,
-                last_column: lstack[lstack.length - 1].last_column
-            };
-            if (ranges) {
-                yyval._$.range = [
-                    lstack[lstack.length - (len || 1)].range[0],
-                    lstack[lstack.length - 1].range[1]
-                ];
-            }
-            r = this.performAction.apply(yyval, [
-                yytext,
-                yyleng,
-                yylineno,
-                sharedState.yy,
-                action[1],
-                vstack,
-                lstack
-            ].concat(args));
-            if (typeof r !== 'undefined') {
-                return r;
-            }
-            if (len) {
-                stack = stack.slice(0, -1 * len * 2);
-                vstack = vstack.slice(0, -1 * len);
-                lstack = lstack.slice(0, -1 * len);
-            }
-            stack.push(this.productions_[action[1]][0]);
-            vstack.push(yyval.$);
-            lstack.push(yyval._$);
-            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
-            stack.push(newState);
-            break;
-        case 3:
-            return true;
-        }
-    }
-    return true;
-}};
-
-/* generated by jison-lex 0.3.4 */
-var lexer = (function(){
-var lexer = ({
-
-EOF:1,
-
-parseError:function parseError(str, hash) {
-        if (this.yy.parser) {
-            this.yy.parser.parseError(str, hash);
-        } else {
-            throw new Error(str);
-        }
-    },
-
-// resets the lexer, sets new input
-setInput:function (input, yy) {
-        this.yy = yy || this.yy || {};
-        this._input = input;
-        this._more = this._backtrack = this.done = false;
-        this.yylineno = this.yyleng = 0;
-        this.yytext = this.matched = this.match = '';
-        this.conditionStack = ['INITIAL'];
-        this.yylloc = {
-            first_line: 1,
-            first_column: 0,
-            last_line: 1,
-            last_column: 0
-        };
-        if (this.options.ranges) {
-            this.yylloc.range = [0,0];
-        }
-        this.offset = 0;
-        return this;
-    },
-
-// consumes and returns one char from the input
-input:function () {
-        var ch = this._input[0];
-        this.yytext += ch;
-        this.yyleng++;
-        this.offset++;
-        this.match += ch;
-        this.matched += ch;
-        var lines = ch.match(/(?:\r\n?|\n).*/g);
-        if (lines) {
-            this.yylineno++;
-            this.yylloc.last_line++;
-        } else {
-            this.yylloc.last_column++;
-        }
-        if (this.options.ranges) {
-            this.yylloc.range[1]++;
-        }
-
-        this._input = this._input.slice(1);
-        return ch;
-    },
-
-// unshifts one char (or a string) into the input
-unput:function (ch) {
-        var len = ch.length;
-        var lines = ch.split(/(?:\r\n?|\n)/g);
-
-        this._input = ch + this._input;
-        this.yytext = this.yytext.substr(0, this.yytext.length - len);
-        //this.yyleng -= len;
-        this.offset -= len;
-        var oldLines = this.match.split(/(?:\r\n?|\n)/g);
-        this.match = this.match.substr(0, this.match.length - 1);
-        this.matched = this.matched.substr(0, this.matched.length - 1);
-
-        if (lines.length - 1) {
-            this.yylineno -= lines.length - 1;
-        }
-        var r = this.yylloc.range;
-
-        this.yylloc = {
-            first_line: this.yylloc.first_line,
-            last_line: this.yylineno + 1,
-            first_column: this.yylloc.first_column,
-            last_column: lines ?
-                (lines.length === oldLines.length ? this.yylloc.first_column : 0)
-                 + oldLines[oldLines.length - lines.length].length - lines[0].length :
-              this.yylloc.first_column - len
-        };
-
-        if (this.options.ranges) {
-            this.yylloc.range = [r[0], r[0] + this.yyleng - len];
-        }
-        this.yyleng = this.yytext.length;
-        return this;
-    },
-
-// When called from action, caches matched text and appends it on next action
-more:function () {
-        this._more = true;
-        return this;
-    },
-
-// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
-reject:function () {
-        if (this.options.backtrack_lexer) {
-            this._backtrack = true;
-        } else {
-            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
-                text: "",
-                token: null,
-                line: this.yylineno
-            });
-
-        }
-        return this;
-    },
-
-// retain first n characters of the match
-less:function (n) {
-        this.unput(this.match.slice(n));
-    },
-
-// displays already matched input, i.e. for error messages
-pastInput:function () {
-        var past = this.matched.substr(0, this.matched.length - this.match.length);
-        return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
-    },
-
-// displays upcoming input, i.e. for error messages
-upcomingInput:function () {
-        var next = this.match;
-        if (next.length < 20) {
-            next += this._input.substr(0, 20-next.length);
-        }
-        return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
-    },
-
-// displays the character position where the lexing error occurred, i.e. for error messages
-showPosition:function () {
-        var pre = this.pastInput();
-        var c = new Array(pre.length + 1).join("-");
-        return pre + this.upcomingInput() + "\n" + c + "^";
-    },
-
-// test the lexed token: return FALSE when not a match, otherwise return token
-test_match:function (match, indexed_rule) {
-        var token,
-            lines,
-            backup;
-
-        if (this.options.backtrack_lexer) {
-            // save context
-            backup = {
-                yylineno: this.yylineno,
-                yylloc: {
-                    first_line: this.yylloc.first_line,
-                    last_line: this.last_line,
-                    first_column: this.yylloc.first_column,
-                    last_column: this.yylloc.last_column
-                },
-                yytext: this.yytext,
-                match: this.match,
-                matches: this.matches,
-                matched: this.matched,
-                yyleng: this.yyleng,
-                offset: this.offset,
-                _more: this._more,
-                _input: this._input,
-                yy: this.yy,
-                conditionStack: this.conditionStack.slice(0),
-                done: this.done
-            };
-            if (this.options.ranges) {
-                backup.yylloc.range = this.yylloc.range.slice(0);
-            }
-        }
-
-        lines = match[0].match(/(?:\r\n?|\n).*/g);
-        if (lines) {
-            this.yylineno += lines.length;
-        }
-        this.yylloc = {
-            first_line: this.yylloc.last_line,
-            last_line: this.yylineno + 1,
-            first_column: this.yylloc.last_column,
-            last_column: lines ?
-                         lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
-                         this.yylloc.last_column + match[0].length
-        };
-        this.yytext += match[0];
-        this.match += match[0];
-        this.matches = match;
-        this.yyleng = this.yytext.length;
-        if (this.options.ranges) {
-            this.yylloc.range = [this.offset, this.offset += this.yyleng];
-        }
-        this._more = false;
-        this._backtrack = false;
-        this._input = this._input.slice(match[0].length);
-        this.matched += match[0];
-        token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
-        if (this.done && this._input) {
-            this.done = false;
-        }
-        if (token) {
-            return token;
-        } else if (this._backtrack) {
-            // recover context
-            for (var k in backup) {
-                this[k] = backup[k];
-            }
-            return false; // rule action called reject() implying the next rule should be tested instead.
-        }
-        return false;
-    },
-
-// return next match in input
-next:function () {
-        if (this.done) {
-            return this.EOF;
-        }
-        if (!this._input) {
-            this.done = true;
-        }
-
-        var token,
-            match,
-            tempMatch,
-            index;
-        if (!this._more) {
-            this.yytext = '';
-            this.match = '';
-        }
-        var rules = this._currentRules();
-        for (var i = 0; i < rules.length; i++) {
-            tempMatch = this._input.match(this.rules[rules[i]]);
-            if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
-                match = tempMatch;
-                index = i;
-                if (this.options.backtrack_lexer) {
-                    token = this.test_match(tempMatch, rules[i]);
-                    if (token !== false) {
-                        return token;
-                    } else if (this._backtrack) {
-                        match = false;
-                        continue; // rule action called reject() implying a rule MISmatch.
-                    } else {
-                        // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
-                        return false;
-                    }
-                } else if (!this.options.flex) {
-                    break;
-                }
-            }
-        }
-        if (match) {
-            token = this.test_match(match, rules[index]);
-            if (token !== false) {
-                return token;
-            }
-            // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
-            return false;
-        }
-        if (this._input === "") {
-            return this.EOF;
-        } else {
-            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
-                text: "",
-                token: null,
-                line: this.yylineno
-            });
-        }
-    },
-
-// return next match that has a token
-lex:function lex() {
-        var r = this.next();
-        if (r) {
-            return r;
-        } else {
-            return this.lex();
-        }
-    },
-
-// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
-begin:function begin(condition) {
-        this.conditionStack.push(condition);
-    },
-
-// pop the previously active lexer condition state off the condition stack
-popState:function popState() {
-        var n = this.conditionStack.length - 1;
-        if (n > 0) {
-            return this.conditionStack.pop();
-        } else {
-            return this.conditionStack[0];
-        }
-    },
-
-// produce the lexer rule set which is active for the currently active lexer condition state
-_currentRules:function _currentRules() {
-        if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
-            return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
-        } else {
-            return this.conditions["INITIAL"].rules;
-        }
-    },
-
-// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
-topState:function topState(n) {
-        n = this.conditionStack.length - 1 - Math.abs(n || 0);
-        if (n >= 0) {
-            return this.conditionStack[n];
-        } else {
-            return "INITIAL";
-        }
-    },
-
-// alias for begin(condition)
-pushState:function pushState(condition) {
-        this.begin(condition);
-    },
-
-// return the number of states currently on the stack
-stateStackSize:function stateStackSize() {
-        return this.conditionStack.length;
-    },
-options: {"case-insensitive":true},
-performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
-var YYSTATE=YY_START;
-switch($avoiding_name_collisions) {
-case 0:return 5;
-break;
-case 1:/* skip all whitespace */
-break;
-case 2:/* skip same-line whitespace */
-break;
-case 3:/* skip comments */
-break;
-case 4:/* skip comments */
-break;
-case 5: this.begin('ID'); return 10; 
-break;
-case 6: this.begin('ALIAS'); return 40; 
-break;
-case 7: this.popState(); this.popState(); this.begin('LINE'); return 12; 
-break;
-case 8: this.popState(); this.popState(); return 5; 
-break;
-case 9: this.begin('LINE'); return 20; 
-break;
-case 10: this.begin('LINE'); return 22; 
-break;
-case 11: this.begin('LINE'); return 23; 
-break;
-case 12: this.begin('LINE'); return 28; 
-break;
-case 13: this.begin('LINE'); return 25; 
-break;
-case 14: this.begin('LINE'); return 27; 
-break;
-case 15: this.popState(); return 13; 
-break;
-case 16:return 21;
-break;
-case 17:return 35;
-break;
-case 18:return 36;
-break;
-case 19:return 31;
-break;
-case 20:return 29;
-break;
-case 21: this.begin('ID'); return 15; 
-break;
-case 22: this.begin('ID'); return 16; 
-break;
-case 23:return 18;
-break;
-case 24:return 6;
-break;
-case 25:return 34;
-break;
-case 26:return 5;
-break;
-case 27: yy_.yytext = yy_.yytext.trim(); return 40; 
-break;
-case 28:return 43;
-break;
-case 29:return 44;
-break;
-case 30:return 41;
-break;
-case 31:return 42;
-break;
-case 32:return 45;
-break;
-case 33:return 46;
-break;
-case 34:return 47;
-break;
-case 35:return 38;
-break;
-case 36:return 39;
-break;
-case 37:return 5;
-break;
-case 38:return 'INVALID';
-break;
-}
-},
-rules: [/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:participant\b)/i,/^(?:[^\->:\n,;]+?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:and\b)/i,/^(?:[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\b)/i,/^(?:sequenceDiagram\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?::[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],
-conditions: {"LINE":{"rules":[2,3,15],"inclusive":false},"ALIAS":{"rules":[2,3,7,8],"inclusive":false},"ID":{"rules":[2,3,6],"inclusive":false},"INITIAL":{"rules":[0,1,3,4,5,9,10,11,12,13,14,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"inclusive":true}}
-});
-return lexer;
-})();
-parser.lexer = lexer;
-function Parser () {
-  this.yy = {};
-}
-Parser.prototype = parser;parser.Parser = Parser;
-return new Parser;
-})();
-
-
-if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
-exports.parser = parser;
-exports.Parser = parser.Parser;
-exports.parse = function () { return parser.parse.apply(parser, arguments); };
-exports.main = function commonjsMain(args) {
-    if (!args[1]) {
-        console.log('Usage: '+args[0]+' FILE');
-        process.exit(1);
-    }
-    var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
-    return exports.parser.parse(source);
-};
-if (typeof module !== 'undefined' && require.main === module) {
-  exports.main(process.argv.slice(1));
-}
-}
\ No newline at end of file
diff --git a/_submodules/mermaid/src/diagrams/sequence/sequenceDb.js b/_submodules/mermaid/src/diagrams/sequence/sequenceDb.js
deleted file mode 100644
index 665ca820d82c9d1d67863896196c76727bcad069..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/sequence/sequenceDb.js
+++ /dev/null
@@ -1,172 +0,0 @@
-import { logger } from '../../logger'
-
-let actors = {}
-let messages = []
-const notes = []
-let title = ''
-
-export const addActor = function (id, name, description) {
-  // Don't allow description nulling
-  const old = actors[id]
-  if (old && name === old.name && description == null) return
-
-  // Don't allow null descriptions, either
-  if (description == null) description = name
-
-  actors[id] = { name: name, description: description }
-}
-
-export const addMessage = function (idFrom, idTo, message, answer) {
-  messages.push({ from: idFrom, to: idTo, message: message, answer: answer })
-}
-
-export const addSignal = function (idFrom, idTo, message, messageType) {
-  logger.debug('Adding message from=' + idFrom + ' to=' + idTo + ' message=' + message + ' type=' + messageType)
-  messages.push({ from: idFrom, to: idTo, message: message, type: messageType })
-}
-
-export const getMessages = function () {
-  return messages
-}
-
-export const getActors = function () {
-  return actors
-}
-export const getActor = function (id) {
-  return actors[id]
-}
-export const getActorKeys = function () {
-  return Object.keys(actors)
-}
-export const getTitle = function () {
-  return title
-}
-
-export const clear = function () {
-  actors = {}
-  messages = []
-}
-
-export const LINETYPE = {
-  SOLID: 0,
-  DOTTED: 1,
-  NOTE: 2,
-  SOLID_CROSS: 3,
-  DOTTED_CROSS: 4,
-  SOLID_OPEN: 5,
-  DOTTED_OPEN: 6,
-  LOOP_START: 10,
-  LOOP_END: 11,
-  ALT_START: 12,
-  ALT_ELSE: 13,
-  ALT_END: 14,
-  OPT_START: 15,
-  OPT_END: 16,
-  ACTIVE_START: 17,
-  ACTIVE_END: 18,
-  PAR_START: 19,
-  PAR_AND: 20,
-  PAR_END: 21
-}
-
-export const ARROWTYPE = {
-  FILLED: 0,
-  OPEN: 1
-}
-
-export const PLACEMENT = {
-  LEFTOF: 0,
-  RIGHTOF: 1,
-  OVER: 2
-}
-
-export const addNote = function (actor, placement, message) {
-  const note = { actor: actor, placement: placement, message: message }
-
-  // Coerce actor into a [to, from, ...] array
-  const actors = [].concat(actor, actor)
-
-  notes.push(note)
-  messages.push({ from: actors[0], to: actors[1], message: message, type: LINETYPE.NOTE, placement: placement })
-}
-
-export const setTitle = function (titleText) {
-  title = titleText
-}
-
-export const apply = function (param) {
-  if (param instanceof Array) {
-    param.forEach(function (item) {
-      apply(item)
-    })
-  } else {
-    switch (param.type) {
-      case 'addActor':
-        addActor(param.actor, param.actor, param.description)
-        break
-      case 'activeStart':
-        addSignal(param.actor, undefined, undefined, param.signalType)
-        break
-      case 'activeEnd':
-        addSignal(param.actor, undefined, undefined, param.signalType)
-        break
-      case 'addNote':
-        addNote(param.actor, param.placement, param.text)
-        break
-      case 'addMessage':
-        addSignal(param.from, param.to, param.msg, param.signalType)
-        break
-      case 'loopStart':
-        addSignal(undefined, undefined, param.loopText, param.signalType)
-        break
-      case 'loopEnd':
-        addSignal(undefined, undefined, undefined, param.signalType)
-        break
-      case 'optStart':
-        addSignal(undefined, undefined, param.optText, param.signalType)
-        break
-      case 'optEnd':
-        addSignal(undefined, undefined, undefined, param.signalType)
-        break
-      case 'altStart':
-        addSignal(undefined, undefined, param.altText, param.signalType)
-        break
-      case 'else':
-        addSignal(undefined, undefined, param.altText, param.signalType)
-        break
-      case 'altEnd':
-        addSignal(undefined, undefined, undefined, param.signalType)
-        break
-      case 'setTitle':
-        setTitle(param.text)
-        break
-      case 'parStart':
-        addSignal(undefined, undefined, param.parText, param.signalType)
-        break
-      case 'and':
-        addSignal(undefined, undefined, param.parText, param.signalType)
-        break
-      case 'parEnd':
-        addSignal(undefined, undefined, undefined, param.signalType)
-        break
-    }
-  }
-}
-
-export default {
-  addActor,
-  addMessage,
-  addSignal,
-  getMessages,
-  getActors,
-  getActor,
-  getActorKeys,
-  getTitle,
-  clear,
-  LINETYPE,
-  ARROWTYPE,
-  PLACEMENT,
-  addNote,
-  setTitle,
-  apply
-}
diff --git a/_submodules/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js b/_submodules/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
deleted file mode 100644
index 0631d1a610f743133fe7005a936ae51979dd35c8..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/sequence/sequenceDiagram.spec.js
+++ /dev/null
@@ -1,962 +0,0 @@
-/* eslint-env jasmine */
-import { parser } from './parser/sequenceDiagram'
-import sequenceDb from './sequenceDb'
-import renderer from './sequenceRenderer'
-
-function addConf (conf, key, value) {
-  if (value !== undefined) {
-    conf[key] = value
-  }
-  return conf
-}
-
-describe('when parsing a sequenceDiagram', function () {
-  beforeEach(function () {
-    parser.yy = sequenceDb
-    parser.yy.clear()
-  })
-  it('it should handle a sequenceDiagram defintion', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob:Hello Bob, how are you?\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob-->Alice: I am good thanks!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle a sequenceDiagram definition with a title', function () {
-    const str = 'sequenceDiagram\n' +
-      'title: Diagram Title\n' +
-      'Alice->Bob:Hello Bob, how are you?\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob-->Alice: I am good thanks!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-    const title = parser.yy.getTitle()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-    expect(title).toBe('Diagram Title')
-  })
-  it('it should space in actor names', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob:Hello Bob, how are - you?\n' +
-      'Bob-->Alice: I am good thanks!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(2)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[1].from).toBe('Bob')
-  })
-  it('it should alias participants', function () {
-    const str = 'sequenceDiagram\n' +
-      'participant A as Alice\n' +
-      'participant B as Bob\n' +
-      'A->B:Hello Bob, how are you?\n' +
-      'B-->A: I am good thanks!'
-
-    parser.parse(str)
-
-    const actors = parser.yy.getActors()
-    expect(Object.keys(actors)).toEqual(['A', 'B'])
-    expect(actors.A.description).toBe('Alice')
-    expect(actors.B.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-    expect(messages.length).toBe(2)
-    expect(messages[0].from).toBe('A')
-    expect(messages[1].from).toBe('B')
-  })
-  it('it should handle in async messages', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice-xBob:Hello Bob, how are you?'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(1)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID_CROSS)
-  })
-  it('it should handle in async dotted messages', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice--xBob:Hello Bob, how are you?'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(1)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED_CROSS)
-  })
-  it('it should handle in arrow messages', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->>Bob:Hello Bob, how are you?'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(1)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.SOLID)
-  })
-  it('it should handle in arrow messages', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice-->>Bob:Hello Bob, how are you?'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(1)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED)
-  })
-  it('it should handle actor activation', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice-->>Bob:Hello Bob, how are you?\n' +
-      'activate Bob\n' +
-      'Bob-->>Alice:Hello Alice, I\'m fine and  you?\n' +
-      'deactivate Bob'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(4)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED)
-    expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START)
-    expect(messages[1].from.actor).toBe('Bob')
-    expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED)
-    expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_END)
-    expect(messages[3].from.actor).toBe('Bob')
-  })
-  it('it should handle actor one line notation activation', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice-->>+Bob:Hello Bob, how are you?\n' +
-      'Bob-->>- Alice:Hello Alice, I\'m fine and  you?'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(4)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED)
-    expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START)
-    expect(messages[1].from.actor).toBe('Bob')
-    expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED)
-    expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_END)
-    expect(messages[3].from.actor).toBe('Bob')
-  })
-  it('it should handle stacked activations', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice-->>+Bob:Hello Bob, how are you?\n' +
-      'Bob-->>+Carol:Carol, let me introduce Alice?\n' +
-      'Bob-->>- Alice:Hello Alice, please meet Carol?\n' +
-      'Carol->>- Bob:Oh Bob, I\'m so happy to be here!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(8)
-    expect(messages[0].type).toBe(parser.yy.LINETYPE.DOTTED)
-    expect(messages[1].type).toBe(parser.yy.LINETYPE.ACTIVE_START)
-    expect(messages[1].from.actor).toBe('Bob')
-    expect(messages[2].type).toBe(parser.yy.LINETYPE.DOTTED)
-    expect(messages[3].type).toBe(parser.yy.LINETYPE.ACTIVE_START)
-    expect(messages[3].from.actor).toBe('Carol')
-    expect(messages[5].type).toBe(parser.yy.LINETYPE.ACTIVE_END)
-    expect(messages[5].from.actor).toBe('Bob')
-    expect(messages[7].type).toBe(parser.yy.LINETYPE.ACTIVE_END)
-    expect(messages[7].from.actor).toBe('Carol')
-  })
-  it('it should handle comments in a sequenceDiagram', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob-->Alice: I am good thanks!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle new lines in a sequenceDiagram', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob-->Alice: I am good thanks!\n'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle semicolons', function () {
-    const str = 'sequenceDiagram;' +
-      'Alice->Bob: Hello Bob, how are you?;' +
-      'Note right of Bob: Bob thinks;' +
-      'Bob-->Alice: I am good thanks!;'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle one leading space in lines in a sequenceDiagram', function () {
-    const str = 'sequenceDiagram\n' +
-      ' Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob-->Alice: I am good thanks!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle several leading spaces in lines in a sequenceDiagram', function () {
-    const str = 'sequenceDiagram\n' +
-      '   Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob-->Alice: I am good thanks!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(3)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle several leading spaces in lines in a sequenceDiagram', function () {
-    const str = 'sequenceDiagram\n' +
-      'participant Alice\n' +
-      'participant Bob\n' +
-      'Alice->John: Hello John, how are you?\n' +
-      '    loop Healthcheck\n' +
-      'John->John: Fight against hypochondria\n' +
-      ' end\n' +
-      'Note right of John: Rational thoughts<br/>prevail...\n' +
-      '    John-->Alice: Great!\n' +
-      '    John->Bob: How about you?\n' +
-      'Bob-->John: Jolly good!'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(8)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[2].from).toBe('John')
-  })
-  it('it should handle notes over a single actor', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Note over Bob: Bob thinks\n'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].from).toBe('Bob')
-    expect(messages[1].to).toBe('Bob')
-  })
-  it('it should handle notes over multiple actors', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Note over Alice,Bob: confusion\n' +
-      'Note over Bob,Alice: resolution\n'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].from).toBe('Alice')
-    expect(messages[1].to).toBe('Bob')
-    expect(messages[2].from).toBe('Bob')
-    expect(messages[2].to).toBe('Alice')
-  })
-  it('it should handle loop statements', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'loop Multiple happy responses\n\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(5)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[1].from).toBe('Bob')
-  })
-  it('it should handle opt statements', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'opt Perhaps a happy response\n\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(5)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[1].from).toBe('Bob')
-  })
-  it('it should handle alt statements', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'alt isWell\n\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'else isSick\n' +
-      'Bob-->Alice: Feel sick...\n' +
-      'end'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-
-    expect(actors.Alice.description).toBe('Alice')
-    actors.Bob.description = 'Bob'
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(7)
-    expect(messages[0].from).toBe('Alice')
-    expect(messages[1].from).toBe('Bob')
-  })
-  it('it should handle alt statements with multiple elses', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n\n' +
-      '%% Comment\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'alt isWell\n\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'else isSick\n' +
-      'Bob-->Alice: Feel sick...\n' +
-      'else default\n' +
-      'Bob-->Alice: :-)\n' +
-      'end'
-    parser.parse(str)
-    const messages = parser.yy.getMessages()
-    expect(messages.length).toBe(9)
-    expect(messages[1].from).toBe('Bob')
-    expect(messages[2].type).toBe(parser.yy.LINETYPE.ALT_START)
-    expect(messages[3].from).toBe('Bob')
-    expect(messages[4].type).toBe(parser.yy.LINETYPE.ALT_ELSE)
-    expect(messages[5].from).toBe('Bob')
-    expect(messages[6].type).toBe(parser.yy.LINETYPE.ALT_ELSE)
-    expect(messages[7].from).toBe('Bob')
-    expect(messages[8].type).toBe(parser.yy.LINETYPE.ALT_END)
-  })
-  it('it should handle par statements a sequenceDiagram', function () {
-    const str = 'sequenceDiagram\n' +
-      'par Parallel one\n' +
-      'Alice->>Bob: Hello Bob, how are you?\n' +
-      'Bob-->>Alice: I am good thanks!\n' +
-      'and Parallel two\n' +
-      'Alice->>Bob: Are you OK?\n' +
-      'Bob-->>Alice: Fine!\n' +
-      'and Parallel three\n' +
-      'Alice->>Bob: What do you think about it?\n' +
-      'Bob-->>Alice: It\'s good!\n' +
-      'end'
-
-    parser.parse(str)
-    const actors = parser.yy.getActors()
-
-    expect(actors.Alice.description).toBe('Alice')
-    expect(actors.Bob.description).toBe('Bob')
-
-    const messages = parser.yy.getMessages()
-
-    expect(messages.length).toBe(10)
-    expect(messages[0].message).toBe('Parallel one')
-    expect(messages[1].from).toBe('Alice')
-    expect(messages[2].from).toBe('Bob')
-  })
-  it('it should handle special characters in signals', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: -:<>,;# comment'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[0].message).toBe('-:<>,')
-  })
-  it('it should handle special characters in notes', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Note right of Bob: -:<>,;# comment'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('-:<>,')
-  })
-  it('it should handle special characters in loop', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'loop -:<>,;# comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('-:<>,')
-  })
-  it('it should handle special characters in opt', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'opt -:<>,;# comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('-:<>,')
-  })
-  it('it should handle special characters in alt', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'alt -:<>,;# comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'else ,<>:-#; comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('-:<>,')
-    expect(messages[3].message).toBe(',<>:-')
-  })
-  it('it should handle special characters in par', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'par -:<>,;# comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'and ,<>:-#; comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('-:<>,')
-    expect(messages[3].message).toBe(',<>:-')
-  })
-  it('it should handle no-label loop', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'loop\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('')
-    expect(messages[2].message).toBe('I am good thanks!')
-  })
-  it('it should handle no-label opt', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'opt # comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('')
-    expect(messages[2].message).toBe('I am good thanks!')
-  })
-  it('it should handle no-label alt', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'alt;' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'else # comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('')
-    expect(messages[2].message).toBe('I am good thanks!')
-    expect(messages[3].message).toBe('')
-    expect(messages[4].message).toBe('I am good thanks!')
-  })
-  it('it should handle no-label par', function () {
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'par;' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'and # comment\n' +
-      'Bob-->Alice: I am good thanks!\n' +
-      'end'
-
-    parser.parse(str)
-
-    const messages = parser.yy.getMessages()
-    expect(messages[1].message).toBe('')
-    expect(messages[2].message).toBe('I am good thanks!')
-    expect(messages[3].message).toBe('')
-    expect(messages[4].message).toBe('I am good thanks!')
-  })
-})
-
-describe('when checking the bounds in a sequenceDiagram', function () {
-  let conf
-  beforeEach(function () {
-    parser.yy = sequenceDb
-    parser.yy.clear()
-    conf = {
-      diagramMarginX: 50,
-      diagramMarginY: 10,
-      actorMargin: 50,
-      width: 150,
-      // Height of actor boxes
-      height: 65,
-      boxMargin: 10,
-      messageMargin: 40,
-      boxTextMargin: 15,
-      noteMargin: 25
-    }
-    renderer.setConf(conf)
-  })
-  it('it should handle a simple bound call', function () {
-    renderer.bounds.init()
-
-    renderer.bounds.insert(100, 100, 200, 200)
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(100)
-    expect(bounds.starty).toBe(100)
-    expect(bounds.stopx).toBe(200)
-    expect(bounds.stopy).toBe(200)
-  })
-  it('it should handle an expanding bound', function () {
-    renderer.bounds.init()
-
-    renderer.bounds.insert(100, 100, 200, 200)
-    renderer.bounds.insert(25, 50, 300, 400)
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(25)
-    expect(bounds.starty).toBe(50)
-    expect(bounds.stopx).toBe(300)
-    expect(bounds.stopy).toBe(400)
-  })
-  it('it should handle inserts within the bound without changing the outer bounds', function () {
-    renderer.bounds.init()
-
-    renderer.bounds.insert(100, 100, 200, 200)
-    renderer.bounds.insert(25, 50, 300, 400)
-    renderer.bounds.insert(125, 150, 150, 200)
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(25)
-    expect(bounds.starty).toBe(50)
-    expect(bounds.stopx).toBe(300)
-    expect(bounds.stopy).toBe(400)
-  })
-  it('it should handle a loop without expanding the area', function () {
-    renderer.bounds.init()
-
-    renderer.bounds.insert(25, 50, 300, 400)
-    renderer.bounds.verticalPos = 150
-    renderer.bounds.newLoop()
-    renderer.bounds.insert(125, 150, 150, 200)
-
-    const loop = renderer.bounds.endLoop()
-
-    expect(loop.startx).toBe(125 - conf.boxMargin)
-    expect(loop.starty).toBe(150 - conf.boxMargin)
-    expect(loop.stopx).toBe(150 + conf.boxMargin)
-    expect(loop.stopy).toBe(200 + conf.boxMargin)
-
-    // Check bounds of first loop
-    const bounds = renderer.bounds.getBounds()
-
-    expect(bounds.startx).toBe(25)
-    expect(bounds.starty).toBe(50)
-    expect(bounds.stopx).toBe(300)
-    expect(bounds.stopy).toBe(400)
-  })
-  it('it should handle multiple loops withtout expanding the bounds', function () {
-    renderer.bounds.init()
-
-    renderer.bounds.insert(100, 100, 1000, 1000)
-    renderer.bounds.verticalPos = 200
-    renderer.bounds.newLoop()
-    renderer.bounds.newLoop()
-    renderer.bounds.insert(200, 200, 300, 300)
-
-    // Check bounds of first loop
-    let loop = renderer.bounds.endLoop()
-
-    expect(loop.startx).toBe(200 - conf.boxMargin)
-    expect(loop.starty).toBe(200 - conf.boxMargin)
-    expect(loop.stopx).toBe(300 + conf.boxMargin)
-    expect(loop.stopy).toBe(300 + conf.boxMargin)
-
-    // Check bounds of second loop
-    loop = renderer.bounds.endLoop()
-
-    expect(loop.startx).toBe(200 - 2 * conf.boxMargin)
-    expect(loop.starty).toBe(200 - 2 * conf.boxMargin)
-    expect(loop.stopx).toBe(300 + 2 * conf.boxMargin)
-    expect(loop.stopy).toBe(300 + 2 * conf.boxMargin)
-
-    // Check bounds of first loop
-    const bounds = renderer.bounds.getBounds()
-
-    expect(bounds.startx).toBe(100)
-    expect(bounds.starty).toBe(100)
-    expect(bounds.stopx).toBe(1000)
-    expect(bounds.stopy).toBe(1000)
-  })
-  it('it should handle a loop that expands the area', function () {
-    renderer.bounds.init()
-
-    renderer.bounds.insert(100, 100, 200, 200)
-    renderer.bounds.verticalPos = 200
-    renderer.bounds.newLoop()
-    renderer.bounds.insert(50, 50, 300, 300)
-
-    const loop = renderer.bounds.endLoop()
-
-    expect(loop.startx).toBe(50 - conf.boxMargin)
-    expect(loop.starty).toBe(50 - conf.boxMargin)
-    expect(loop.stopx).toBe(300 + conf.boxMargin)
-    expect(loop.stopy).toBe(300 + conf.boxMargin)
-
-    // Check bounds after the loop
-    const bounds = renderer.bounds.getBounds()
-
-    expect(bounds.startx).toBe(loop.startx)
-    expect(bounds.starty).toBe(loop.starty)
-    expect(bounds.stopx).toBe(loop.stopx)
-    expect(bounds.stopy).toBe(loop.stopy)
-  })
-})
-
-describe('when rendering a sequenceDiagram', function () {
-  let conf
-  beforeEach(function () {
-    parser.yy = sequenceDb
-    parser.yy.clear()
-
-    conf = {
-      diagramMarginX: 50,
-      diagramMarginY: 10,
-      actorMargin: 50,
-      width: 150,
-      // Height of actor boxes
-      height: 65,
-      boxMargin: 10,
-      messageMargin: 40,
-      boxTextMargin: 15,
-      noteMargin: 25
-    }
-    renderer.setConf(conf)
-  });
-  ['tspan', 'fo', 'old', undefined].forEach(function (textPlacement) {
-    it('it should handle one actor, when textPlacement is ' + textPlacement, function () {
-      renderer.setConf(addConf(conf, 'textPlacement', textPlacement))
-      renderer.bounds.init()
-      const str = 'sequenceDiagram\n' +
-        'participant Alice'
-
-      parser.parse(str)
-      renderer.draw(str, 'tst')
-
-      const bounds = renderer.bounds.getBounds()
-      expect(bounds.startx).toBe(0)
-      expect(bounds.starty).toBe(0)
-      expect(bounds.stopx).toBe(conf.width)
-      expect(bounds.stopy).toBe(conf.height)
-    })
-  })
-  it('it should handle one actor and a centered note', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'participant Alice\n' +
-      'Note over Alice: Alice thinks\n'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-    expect(bounds.stopx).toBe(conf.width)
-    // 10 comes from mock of text height
-    expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10)
-  })
-  it('it should handle one actor and a note to the left', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'participant Alice\n' +
-      'Note left of Alice: Alice thinks'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(-(conf.width / 2) - (conf.actorMargin / 2))
-    expect(bounds.starty).toBe(0)
-    expect(bounds.stopx).toBe(conf.width)
-    // 10 comes from mock of text height
-    expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10)
-  })
-  it('it should handle one actor and a note to the right', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'participant Alice\n' +
-      'Note right of Alice: Alice thinks'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-    expect(bounds.stopx).toBe((conf.width / 2) + (conf.actorMargin / 2) + conf.width)
-    // 10 comes from mock of text height
-    expect(bounds.stopy).toBe(conf.height + conf.boxMargin + 2 * conf.noteMargin + 10)
-  })
-  it('it should handle two actors', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-    expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin)
-    expect(bounds.stopy).toBe(0 + conf.messageMargin + conf.height)
-  })
-  it('it should handle two actors and two centered shared notes', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Note over Alice,Bob: Looks\n' +
-      'Note over Bob,Alice: Looks back\n'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-    expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin)
-    expect(bounds.stopy).toBe(conf.height + conf.messageMargin + 2 * (conf.boxMargin + 2 * conf.noteMargin + 10))
-  })
-  it('it should draw two actors and two messages', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Bob->Alice: Fine!'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-    expect(bounds.stopx).toBe(0 + conf.width * 2 + conf.actorMargin)
-    expect(bounds.stopy).toBe(0 + 2 * conf.messageMargin + conf.height)
-  })
-  it('it should draw two actors notes to the right', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Note right of Bob: Bob thinks\n' +
-      'Bob->Alice: Fine!'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-
-    const expStopX = conf.actorMargin + conf.width + (conf.width / 2) + conf.noteMargin + conf.width
-
-    expect(bounds.stopx).toBe(expStopX)
-    expect(bounds.stopy).toBe(2 * conf.messageMargin + conf.height + conf.boxMargin + 10 + 2 * conf.noteMargin)
-  })
-  it('it should draw two actors notes to the left', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'Note left of Alice: Bob thinks\n' +
-      'Bob->Alice: Fine!'
-
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(-(conf.width / 2) - (conf.actorMargin / 2))
-    expect(bounds.starty).toBe(0)
-
-    expect(bounds.stopx).toBe(conf.width * 2 + conf.actorMargin)
-    expect(bounds.stopy).toBe(2 * conf.messageMargin + conf.height + conf.boxMargin + 10 + 2 * conf.noteMargin)
-  })
-  it('it should draw two loops', function () {
-    renderer.bounds.init()
-    const str = 'sequenceDiagram\n' +
-      'Alice->Bob: Hello Bob, how are you?\n' +
-      'loop Cheers\n' +
-      'Bob->Alice: Fine!\n' +
-      'end'
-    parser.parse(str)
-    renderer.draw(str, 'tst')
-
-    const bounds = renderer.bounds.getBounds()
-    expect(bounds.startx).toBe(0)
-    expect(bounds.starty).toBe(0)
-
-    expect(bounds.stopx).toBe(0 + conf.width * 2 + conf.actorMargin)
-    expect(bounds.stopy).toBe(0 + 2 * conf.messageMargin + conf.height + 3 * conf.boxMargin + conf.boxTextMargin)
-  })
-})
-
-describe('when rendering a sequenceDiagram with actor mirror activated', function () {
-  let conf
-  beforeEach(function () {
-    parser.yy = sequenceDb
-    parser.yy.clear()
-
-    conf = {
-      diagramMarginX: 50,
-      diagramMarginY: 10,
-      actorMargin: 50,
-      width: 150,
-      // Height of actor boxes
-      height: 65,
-      boxMargin: 10,
-      messageMargin: 40,
-      boxTextMargin: 15,
-      noteMargin: 25,
-      mirrorActors: true,
-      // Depending on css styling this might need adjustment
-      // Prolongs the edge of the diagram downwards
-      bottomMarginAdj: 1
-    }
-    renderer.setConf(conf)
-  });
-  ['tspan', 'fo', 'old', undefined].forEach(function (textPlacement) {
-    it('it should handle one actor, when textPlacement is' + textPlacement, function () {
-      renderer.setConf(addConf(conf, 'textPlacement', textPlacement))
-      renderer.bounds.init()
-      const str = 'sequenceDiagram\n' +
-        'participant Alice'
-
-      parser.parse(str)
-      renderer.draw(str, 'tst')
-
-      const bounds = renderer.bounds.getBounds()
-      expect(bounds.startx).toBe(0)
-      expect(bounds.starty).toBe(0)
-      expect(bounds.stopx).toBe(conf.width)
-      expect(bounds.stopy).toBe(2 * conf.height + 2 * conf.boxMargin)
-    })
-  })
-})
diff --git a/_submodules/mermaid/src/diagrams/sequence/sequenceRenderer.js b/_submodules/mermaid/src/diagrams/sequence/sequenceRenderer.js
deleted file mode 100644
index fcf41d28eabb88c092f29264c50e067cd6c28109..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/sequence/sequenceRenderer.js
+++ /dev/null
@@ -1,496 +0,0 @@
-import * as d3 from 'd3'
-
-import svgDraw from './svgDraw'
-import { logger } from '../../logger'
-import { parser } from './parser/sequenceDiagram'
-import sequenceDb from './sequenceDb'
-
-parser.yy = sequenceDb
-
-const conf = {
-
-  diagramMarginX: 50,
-  diagramMarginY: 30,
-  // Margin between actors
-  actorMargin: 50,
-  // Width of actor boxes
-  width: 150,
-  // Height of actor boxes
-  height: 65,
-  // Margin around loop boxes
-  boxMargin: 10,
-  boxTextMargin: 5,
-  noteMargin: 10,
-  // Space between messages
-  messageMargin: 35,
-  // mirror actors under diagram
-  mirrorActors: false,
-  // Depending on css styling this might need adjustment
-  // Prolongs the edge of the diagram downwards
-  bottomMarginAdj: 1,
-
-  // width of activation box
-  activationWidth: 10,
-
-  // text placement as: tspan | fo | old only text as before
-  textPlacement: 'tspan'
-}
-
-export const bounds = {
-  data: {
-    startx: undefined,
-    stopx: undefined,
-    starty: undefined,
-    stopy: undefined
-  },
-  verticalPos: 0,
-
-  sequenceItems: [],
-  activations: [],
-  init: function () {
-    this.sequenceItems = []
-    this.activations = []
-    this.data = {
-      startx: undefined,
-      stopx: undefined,
-      starty: undefined,
-      stopy: undefined
-    }
-    this.verticalPos = 0
-  },
-  updateVal: function (obj, key, val, fun) {
-    if (typeof obj[key] === 'undefined') {
-      obj[key] = val
-    } else {
-      obj[key] = fun(val, obj[key])
-    }
-  },
-  updateBounds: function (startx, starty, stopx, stopy) {
-    const _self = this
-    let cnt = 0
-    function updateFn (type) {
-      return function updateItemBounds (item) {
-        cnt++
-        // The loop sequenceItems is a stack so the biggest margins in the beginning of the sequenceItems
-        const n = _self.sequenceItems.length - cnt + 1
-
-        _self.updateVal(item, 'starty', starty - n * conf.boxMargin, Math.min)
-        _self.updateVal(item, 'stopy', stopy + n * conf.boxMargin, Math.max)
-
-        _self.updateVal(bounds.data, 'startx', startx - n * conf.boxMargin, Math.min)
-        _self.updateVal(bounds.data, 'stopx', stopx + n * conf.boxMargin, Math.max)
-
-        if (!(type === 'activation')) {
-          _self.updateVal(item, 'startx', startx - n * conf.boxMargin, Math.min)
-          _self.updateVal(item, 'stopx', stopx + n * conf.boxMargin, Math.max)
-
-          _self.updateVal(bounds.data, 'starty', starty - n * conf.boxMargin, Math.min)
-          _self.updateVal(bounds.data, 'stopy', stopy + n * conf.boxMargin, Math.max)
-        }
-      }
-    }
-
-    this.sequenceItems.forEach(updateFn())
-    this.activations.forEach(updateFn('activation'))
-  },
-  insert: function (startx, starty, stopx, stopy) {
-    const _startx = Math.min(startx, stopx)
-    const _stopx = Math.max(startx, stopx)
-    const _starty = Math.min(starty, stopy)
-    const _stopy = Math.max(starty, stopy)
-
-    this.updateVal(bounds.data, 'startx', _startx, Math.min)
-    this.updateVal(bounds.data, 'starty', _starty, Math.min)
-    this.updateVal(bounds.data, 'stopx', _stopx, Math.max)
-    this.updateVal(bounds.data, 'stopy', _stopy, Math.max)
-
-    this.updateBounds(_startx, _starty, _stopx, _stopy)
-  },
-  newActivation: function (message, diagram) {
-    const actorRect = parser.yy.getActors()[message.from.actor]
-    const stackedSize = actorActivations(message.from.actor).length
-    const x = actorRect.x + conf.width / 2 + (stackedSize - 1) * conf.activationWidth / 2
-    this.activations.push({
-      startx: x,
-      starty: this.verticalPos + 2,
-      stopx: x + conf.activationWidth,
-      stopy: undefined,
-      actor: message.from.actor,
-      anchored: svgDraw.anchorElement(diagram)
-    })
-  },
-  endActivation: function (message) {
-    // find most recent activation for given actor
-    const lastActorActivationIdx = this.activations
-      .map(function (activation) { return activation.actor })
-      .lastIndexOf(message.from.actor)
-    const activation = this.activations.splice(lastActorActivationIdx, 1)[0]
-    return activation
-  },
-  newLoop: function (title) {
-    this.sequenceItems.push({ startx: undefined, starty: this.verticalPos, stopx: undefined, stopy: undefined, title: title })
-  },
-  endLoop: function () {
-    const loop = this.sequenceItems.pop()
-    return loop
-  },
-  addSectionToLoop: function (message) {
-    const loop = this.sequenceItems.pop()
-    loop.sections = loop.sections || []
-    loop.sectionTitles = loop.sectionTitles || []
-    loop.sections.push(bounds.getVerticalPos())
-    loop.sectionTitles.push(message)
-    this.sequenceItems.push(loop)
-  },
-  bumpVerticalPos: function (bump) {
-    this.verticalPos = this.verticalPos + bump
-    this.data.stopy = this.verticalPos
-  },
-  getVerticalPos: function () {
-    return this.verticalPos
-  },
-  getBounds: function () {
-    return this.data
-  }
-}
-
-const _drawLongText = (text, x, y, g, width) => {
-  let textHeight = 0
-  const lines = text.split(/<br\/?>/ig)
-  for (const line of lines) {
-    const textObj = svgDraw.getTextObj()
-    textObj.x = x
-    textObj.y = y + textHeight
-    textObj.textMargin = conf.noteMargin
-    textObj.dy = '1em'
-    textObj.text = line
-    textObj.class = 'noteText'
-    const textElem = svgDraw.drawText(g, textObj, width)
-    textHeight += (textElem._groups || textElem)[0][0].getBBox().height
-  }
-  return textHeight
-}
-
-/**
- * Draws an actor in the diagram with the attaced line
- * @param center - The center of the the actor
- * @param pos The position if the actor in the liost of actors
- * @param description The text in the box
- */
-const drawNote = function (elem, startx, verticalPos, msg, forceWidth) {
-  const rect = svgDraw.getNoteRect()
-  rect.x = startx
-  rect.y = verticalPos
-  rect.width = forceWidth || conf.width
-  rect.class = 'note'
-
-  let g = elem.append('g')
-  const rectElem = svgDraw.drawRect(g, rect)
-
-  const textHeight = _drawLongText(msg.message, startx - 4, verticalPos + 24, g, rect.width - conf.noteMargin)
-
-  bounds.insert(startx, verticalPos, startx + rect.width, verticalPos + 2 * conf.noteMargin + textHeight)
-  rectElem.attr('height', textHeight + 2 * conf.noteMargin)
-  bounds.bumpVerticalPos(textHeight + 2 * conf.noteMargin)
-}
-
-/**
- * Draws a message
- * @param elem
- * @param startx
- * @param stopx
- * @param verticalPos
- * @param txtCenter
- * @param msg
- */
-const drawMessage = function (elem, startx, stopx, verticalPos, msg) {
-  const g = elem.append('g')
-  const txtCenter = startx + (stopx - startx) / 2
-
-  const textElem = g.append('text') // text label for the x axis
-    .attr('x', txtCenter)
-    .attr('y', verticalPos - 7)
-    .style('text-anchor', 'middle')
-    .attr('class', 'messageText')
-    .text(msg.message)
-
-  let textWidth = (textElem._groups || textElem)[0][0].getBBox().width
-
-  let line
-  if (startx === stopx) {
-    line = g.append('path')
-      .attr('d', 'M ' + startx + ',' + verticalPos + ' C ' + (startx + 60) + ',' + (verticalPos - 10) + ' ' + (startx + 60) + ',' +
-      (verticalPos + 30) + ' ' + startx + ',' + (verticalPos + 20))
-
-    bounds.bumpVerticalPos(30)
-    const dx = Math.max(textWidth / 2, 100)
-    bounds.insert(startx - dx, bounds.getVerticalPos() - 10, stopx + dx, bounds.getVerticalPos())
-  } else {
-    line = g.append('line')
-    line.attr('x1', startx)
-    line.attr('y1', verticalPos)
-    line.attr('x2', stopx)
-    line.attr('y2', verticalPos)
-    bounds.insert(startx, bounds.getVerticalPos() - 10, stopx, bounds.getVerticalPos())
-  }
-  // Make an SVG Container
-  // Draw the line
-  if (msg.type === parser.yy.LINETYPE.DOTTED || msg.type === parser.yy.LINETYPE.DOTTED_CROSS || msg.type === parser.yy.LINETYPE.DOTTED_OPEN) {
-    line.style('stroke-dasharray', ('3, 3'))
-    line.attr('class', 'messageLine1')
-  } else {
-    line.attr('class', 'messageLine0')
-  }
-
-  let url = ''
-  if (conf.arrowMarkerAbsolute) {
-    url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search
-    url = url.replace(/\(/g, '\\(')
-    url = url.replace(/\)/g, '\\)')
-  }
-
-  line.attr('stroke-width', 2)
-  line.attr('stroke', 'black')
-  line.style('fill', 'none') // remove any fill colour
-  if (msg.type === parser.yy.LINETYPE.SOLID || msg.type === parser.yy.LINETYPE.DOTTED) {
-    line.attr('marker-end', 'url(' + url + '#arrowhead)')
-  }
-
-  if (msg.type === parser.yy.LINETYPE.SOLID_CROSS || msg.type === parser.yy.LINETYPE.DOTTED_CROSS) {
-    line.attr('marker-end', 'url(' + url + '#crosshead)')
-  }
-}
-
-export const drawActors = function (diagram, actors, actorKeys, verticalPos) {
-  // Draw the actors
-  for (let i = 0; i < actorKeys.length; i++) {
-    const key = actorKeys[i]
-
-    // Add some rendering data to the object
-    actors[key].x = i * conf.actorMargin + i * conf.width
-    actors[key].y = verticalPos
-    actors[key].width = conf.diagramMarginX
-    actors[key].height = conf.diagramMarginY
-
-    // Draw the box with the attached line
-    svgDraw.drawActor(diagram, actors[key].x, verticalPos, actors[key].description, conf)
-    bounds.insert(actors[key].x, verticalPos, actors[key].x + conf.width, conf.height)
-  }
-
-  // Add a margin between the actor boxes and the first arrow
-  bounds.bumpVerticalPos(conf.height)
-}
-
-export const setConf = function (cnf) {
-  const keys = Object.keys(cnf)
-
-  keys.forEach(function (key) {
-    conf[key] = cnf[key]
-  })
-}
-
-const actorActivations = function (actor) {
-  return bounds.activations.filter(function (activation) {
-    return activation.actor === actor
-  })
-}
-
-const actorFlowVerticaBounds = function (actor) {
-  // handle multiple stacked activations for same actor
-  const actors = parser.yy.getActors()
-  const activations = actorActivations(actor)
-
-  const left = activations.reduce(function (acc, activation) { return Math.min(acc, activation.startx) }, actors[actor].x + conf.width / 2)
-  const right = activations.reduce(function (acc, activation) { return Math.max(acc, activation.stopx) }, actors[actor].x + conf.width / 2)
-  return [left, right]
-}
-
-/**
- * Draws a flowchart in the tag with id: id based on the graph definition in text.
- * @param text
- * @param id
- */
-export const draw = function (text, id) {
-  parser.yy.clear()
-  parser.parse(text + '\n')
-
-  bounds.init()
-  const diagram = d3.select(`[id="${id}"]`)
-
-  let startx
-  let stopx
-  let forceWidth
-
-  // Fetch data from the parsing
-  const actors = parser.yy.getActors()
-  const actorKeys = parser.yy.getActorKeys()
-  const messages = parser.yy.getMessages()
-  const title = parser.yy.getTitle()
-  drawActors(diagram, actors, actorKeys, 0)
-
-  // The arrow head definition is attached to the svg once
-  svgDraw.insertArrowHead(diagram)
-  svgDraw.insertArrowCrossHead(diagram)
-
-  function activeEnd (msg, verticalPos) {
-    const activationData = bounds.endActivation(msg)
-    if (activationData.starty + 18 > verticalPos) {
-      activationData.starty = verticalPos - 6
-      verticalPos += 12
-    }
-    svgDraw.drawActivation(diagram, activationData, verticalPos, conf)
-
-    bounds.insert(activationData.startx, verticalPos - 10, activationData.stopx, verticalPos)
-  }
-
-  // const lastMsg
-
-  // Draw the messages/signals
-  messages.forEach(function (msg) {
-    let loopData
-    switch (msg.type) {
-      case parser.yy.LINETYPE.NOTE:
-        bounds.bumpVerticalPos(conf.boxMargin)
-
-        startx = actors[msg.from].x
-        stopx = actors[msg.to].x
-
-        if (msg.placement === parser.yy.PLACEMENT.RIGHTOF) {
-          drawNote(diagram, startx + (conf.width + conf.actorMargin) / 2, bounds.getVerticalPos(), msg)
-        } else if (msg.placement === parser.yy.PLACEMENT.LEFTOF) {
-          drawNote(diagram, startx - (conf.width + conf.actorMargin) / 2, bounds.getVerticalPos(), msg)
-        } else if (msg.to === msg.from) {
-          // Single-actor over
-          drawNote(diagram, startx, bounds.getVerticalPos(), msg)
-        } else {
-          // Multi-actor over
-          forceWidth = Math.abs(startx - stopx) + conf.actorMargin
-          drawNote(diagram, (startx + stopx + conf.width - forceWidth) / 2, bounds.getVerticalPos(), msg,
-            forceWidth)
-        }
-        break
-      case parser.yy.LINETYPE.ACTIVE_START:
-        bounds.newActivation(msg, diagram)
-        break
-      case parser.yy.LINETYPE.ACTIVE_END:
-        activeEnd(msg, bounds.getVerticalPos())
-        break
-      case parser.yy.LINETYPE.LOOP_START:
-        bounds.bumpVerticalPos(conf.boxMargin)
-        bounds.newLoop(msg.message)
-        bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin)
-        break
-      case parser.yy.LINETYPE.LOOP_END:
-        loopData = bounds.endLoop()
-
-        svgDraw.drawLoop(diagram, loopData, 'loop', conf)
-        bounds.bumpVerticalPos(conf.boxMargin)
-        break
-      case parser.yy.LINETYPE.OPT_START:
-        bounds.bumpVerticalPos(conf.boxMargin)
-        bounds.newLoop(msg.message)
-        bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin)
-        break
-      case parser.yy.LINETYPE.OPT_END:
-        loopData = bounds.endLoop()
-
-        svgDraw.drawLoop(diagram, loopData, 'opt', conf)
-        bounds.bumpVerticalPos(conf.boxMargin)
-        break
-      case parser.yy.LINETYPE.ALT_START:
-        bounds.bumpVerticalPos(conf.boxMargin)
-        bounds.newLoop(msg.message)
-        bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin)
-        break
-      case parser.yy.LINETYPE.ALT_ELSE:
-        bounds.bumpVerticalPos(conf.boxMargin)
-        loopData = bounds.addSectionToLoop(msg.message)
-        bounds.bumpVerticalPos(conf.boxMargin)
-        break
-      case parser.yy.LINETYPE.ALT_END:
-        loopData = bounds.endLoop()
-
-        svgDraw.drawLoop(diagram, loopData, 'alt', conf)
-        bounds.bumpVerticalPos(conf.boxMargin)
-        break
-      case parser.yy.LINETYPE.PAR_START:
-        bounds.bumpVerticalPos(conf.boxMargin)
-        bounds.newLoop(msg.message)
-        bounds.bumpVerticalPos(conf.boxMargin + conf.boxTextMargin)
-        break
-      case parser.yy.LINETYPE.PAR_AND:
-        bounds.bumpVerticalPos(conf.boxMargin)
-        loopData = bounds.addSectionToLoop(msg.message)
-        bounds.bumpVerticalPos(conf.boxMargin)
-        break
-      case parser.yy.LINETYPE.PAR_END:
-        loopData = bounds.endLoop()
-        svgDraw.drawLoop(diagram, loopData, 'par', conf)
-        bounds.bumpVerticalPos(conf.boxMargin)
-        break
-      default:
-        try {
-          // lastMsg = msg
-          bounds.bumpVerticalPos(conf.messageMargin)
-          const fromBounds = actorFlowVerticaBounds(msg.from)
-          const toBounds = actorFlowVerticaBounds(msg.to)
-          const fromIdx = fromBounds[0] <= toBounds[0] ? 1 : 0
-          const toIdx = fromBounds[0] < toBounds[0] ? 0 : 1
-          startx = fromBounds[fromIdx]
-          stopx = toBounds[toIdx]
-
-          const verticalPos = bounds.getVerticalPos()
-          drawMessage(diagram, startx, stopx, verticalPos, msg)
-          const allBounds = fromBounds.concat(toBounds)
-          bounds.insert(Math.min.apply(null, allBounds), verticalPos, Math.max.apply(null, allBounds), verticalPos)
-        } catch (e) {
-          logger.error('error while drawing message', e)
-        }
-    }
-  })
-
-  if (conf.mirrorActors) {
-    // Draw actors below diagram
-    bounds.bumpVerticalPos(conf.boxMargin * 2)
-    drawActors(diagram, actors, actorKeys, bounds.getVerticalPos())
-  }
-
-  const box = bounds.getBounds()
-
-  // Adjust line height of actor lines now that the height of the diagram is known
-  logger.debug('For line height fix Querying: #' + id + ' .actor-line')
-  const actorLines = d3.selectAll('#' + id + ' .actor-line')
-  actorLines.attr('y2', box.stopy)
-
-  let height = box.stopy - box.starty + 2 * conf.diagramMarginY
-  if (conf.mirrorActors) {
-    height = height - conf.boxMargin + conf.bottomMarginAdj
-  }
-
-  const width = (box.stopx - box.startx) + (2 * conf.diagramMarginX)
-
-  if (title) {
-    diagram.append('text')
-      .text(title)
-      .attr('x', ((box.stopx - box.startx) / 2) - (2 * conf.diagramMarginX))
-      .attr('y', -25)
-  }
-
-  if (conf.useMaxWidth) {
-    diagram.attr('height', '100%')
-    diagram.attr('width', '100%')
-    diagram.attr('style', 'max-width:' + (width) + 'px;')
-  } else {
-    diagram.attr('height', height)
-    diagram.attr('width', width)
-  }
-  const extraVertForTitle = title ? 40 : 0
-  diagram.attr('viewBox', (box.startx - conf.diagramMarginX) + ' -' + (conf.diagramMarginY + extraVertForTitle) + ' ' + width + ' ' + (height + extraVertForTitle))
-}
-
-export default {
-  bounds,
-  drawActors,
-  setConf,
-  draw
-}
diff --git a/_submodules/mermaid/src/diagrams/sequence/svgDraw.js b/_submodules/mermaid/src/diagrams/sequence/svgDraw.js
deleted file mode 100644
index 29dbbafba57237f9ec987edc7c030c2df474dca8..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/diagrams/sequence/svgDraw.js
+++ /dev/null
@@ -1,313 +0,0 @@
-export const drawRect = function (elem, rectData) {
-  const rectElem = elem.append('rect')
-  rectElem.attr('x', rectData.x)
-  rectElem.attr('y', rectData.y)
-  rectElem.attr('fill', rectData.fill)
-  rectElem.attr('stroke', rectData.stroke)
-  rectElem.attr('width', rectData.width)
-  rectElem.attr('height', rectData.height)
-  rectElem.attr('rx', rectData.rx)
-  rectElem.attr('ry', rectData.ry)
-
-  if (typeof rectData.class !== 'undefined') {
-    rectElem.attr('class', rectData.class)
-  }
-
-  return rectElem
-}
-
-export const drawText = function (elem, textData, width) {
-  // Remove and ignore br:s
-  const nText = textData.text.replace(/<br\/?>/ig, ' ')
-
-  const textElem = elem.append('text')
-  textElem.attr('x', textData.x)
-  textElem.attr('y', textData.y)
-  textElem.style('text-anchor', textData.anchor)
-  textElem.attr('fill', textData.fill)
-  if (typeof textData.class !== 'undefined') {
-    textElem.attr('class', textData.class)
-  }
-
-  const span = textElem.append('tspan')
-  span.attr('x', textData.x + textData.textMargin * 2)
-  span.attr('fill', textData.fill)
-  span.text(nText)
-
-  return textElem
-}
-
-export const drawLabel = function (elem, txtObject) {
-  function genPoints (x, y, width, height, cut) {
-    return x + ',' + y + ' ' +
-      (x + width) + ',' + y + ' ' +
-      (x + width) + ',' + (y + height - cut) + ' ' +
-      (x + width - cut * 1.2) + ',' + (y + height) + ' ' +
-      (x) + ',' + (y + height)
-  }
-  const polygon = elem.append('polygon')
-  polygon.attr('points', genPoints(txtObject.x, txtObject.y, 50, 20, 7))
-  polygon.attr('class', 'labelBox')
-
-  txtObject.y = txtObject.y + txtObject.labelMargin
-  txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin
-  drawText(elem, txtObject)
-}
-
-let actorCnt = -1
-/**
- * Draws an actor in the diagram with the attaced line
- * @param center - The center of the the actor
- * @param pos The position if the actor in the liost of actors
- * @param description The text in the box
- */
-export const drawActor = function (elem, left, verticalPos, description, conf) {
-  const center = left + (conf.width / 2)
-  const g = elem.append('g')
-  if (verticalPos === 0) {
-    actorCnt++
-    g.append('line')
-      .attr('id', 'actor' + actorCnt)
-      .attr('x1', center)
-      .attr('y1', 5)
-      .attr('x2', center)
-      .attr('y2', 2000)
-      .attr('class', 'actor-line')
-      .attr('stroke-width', '0.5px')
-      .attr('stroke', '#999')
-  }
-
-  const rect = getNoteRect()
-  rect.x = left
-  rect.y = verticalPos
-  rect.fill = '#eaeaea'
-  rect.width = conf.width
-  rect.height = conf.height
-  rect.class = 'actor'
-  rect.rx = 3
-  rect.ry = 3
-  drawRect(g, rect)
-
-  _drawTextCandidateFunc(conf)(description, g,
-    rect.x, rect.y, rect.width, rect.height, { 'class': 'actor' })
-}
-
-export const anchorElement = function (elem) {
-  return elem.append('g')
-}
-/**
- * Draws an actor in the diagram with the attaced line
- * @param elem - element to append activation rect
- * @param bounds - activation box bounds
- * @param verticalPos - precise y cooridnate of bottom activation box edge
- */
-export const drawActivation = function (elem, bounds, verticalPos) {
-  const rect = getNoteRect()
-  const g = bounds.anchored
-  rect.x = bounds.startx
-  rect.y = bounds.starty
-  rect.fill = '#f4f4f4'
-  rect.width = bounds.stopx - bounds.startx
-  rect.height = verticalPos - bounds.starty
-  drawRect(g, rect)
-}
-
-/**
- * Draws an actor in the diagram with the attaced line
- * @param center - The center of the the actor
- * @param pos The position if the actor in the list of actors
- * @param description The text in the box
- */
-export const drawLoop = function (elem, bounds, labelText, conf) {
-  const g = elem.append('g')
-  const drawLoopLine = function (startx, starty, stopx, stopy) {
-    return g.append('line')
-      .attr('x1', startx)
-      .attr('y1', starty)
-      .attr('x2', stopx)
-      .attr('y2', stopy)
-      .attr('class', 'loopLine')
-  }
-  drawLoopLine(bounds.startx, bounds.starty, bounds.stopx, bounds.starty)
-  drawLoopLine(bounds.stopx, bounds.starty, bounds.stopx, bounds.stopy)
-  drawLoopLine(bounds.startx, bounds.stopy, bounds.stopx, bounds.stopy)
-  drawLoopLine(bounds.startx, bounds.starty, bounds.startx, bounds.stopy)
-  if (typeof bounds.sections !== 'undefined') {
-    bounds.sections.forEach(function (item) {
-      drawLoopLine(bounds.startx, item, bounds.stopx, item).style('stroke-dasharray', '3, 3')
-    })
-  }
-
-  let txt = getTextObj()
-  txt.text = labelText
-  txt.x = bounds.startx
-  txt.y = bounds.starty
-  txt.labelMargin = 1.5 * 10 // This is the small box that says "loop"
-  txt.class = 'labelText' // Its size & position are fixed.
-
-  drawLabel(g, txt)
-
-  txt = getTextObj()
-  txt.text = '[ ' + bounds.title + ' ]'
-  txt.x = bounds.startx + (bounds.stopx - bounds.startx) / 2
-  txt.y = bounds.starty + 1.5 * conf.boxMargin
-  txt.anchor = 'middle'
-  txt.class = 'loopText'
-
-  drawText(g, txt)
-
-  if (typeof bounds.sectionTitles !== 'undefined') {
-    bounds.sectionTitles.forEach(function (item, idx) {
-      if (item !== '') {
-        txt.text = '[ ' + item + ' ]'
-        txt.y = bounds.sections[idx] + 1.5 * conf.boxMargin
-        drawText(g, txt)
-      }
-    })
-  }
-}
-
-/**
- * Setup arrow head and define the marker. The result is appended to the svg.
- */
-export const insertArrowHead = function (elem) {
-  elem.append('defs').append('marker')
-    .attr('id', 'arrowhead')
-    .attr('refX', 5)
-    .attr('refY', 2)
-    .attr('markerWidth', 6)
-    .attr('markerHeight', 4)
-    .attr('orient', 'auto')
-    .append('path')
-    .attr('d', 'M 0,0 V 4 L6,2 Z') // this is actual shape for arrowhead
-}
-/**
- * Setup arrow head and define the marker. The result is appended to the svg.
- */
-export const insertArrowCrossHead = function (elem) {
-  const defs = elem.append('defs')
-  const marker = defs.append('marker')
-    .attr('id', 'crosshead')
-    .attr('markerWidth', 15)
-    .attr('markerHeight', 8)
-    .attr('orient', 'auto')
-    .attr('refX', 16)
-    .attr('refY', 4)
-
-  // The arrow
-  marker.append('path')
-    .attr('fill', 'black')
-    .attr('stroke', '#000000')
-    .style('stroke-dasharray', ('0, 0'))
-    .attr('stroke-width', '1px')
-    .attr('d', 'M 9,2 V 6 L16,4 Z')
-
-  // The cross
-  marker.append('path')
-    .attr('fill', 'none')
-    .attr('stroke', '#000000')
-    .style('stroke-dasharray', ('0, 0'))
-    .attr('stroke-width', '1px')
-    .attr('d', 'M 0,1 L 6,7 M 6,1 L 0,7')
-  // this is actual shape for arrowhead
-}
-
-export const getTextObj = function () {
-  const txt = {
-    x: 0,
-    y: 0,
-    'fill': 'black',
-    'text-anchor': 'start',
-    style: '#666',
-    width: 100,
-    height: 100,
-    textMargin: 0,
-    rx: 0,
-    ry: 0
-  }
-  return txt
-}
-
-export const getNoteRect = function () {
-  const rect = {
-    x: 0,
-    y: 0,
-    fill: '#EDF2AE',
-    stroke: '#666',
-    width: 100,
-    anchor: 'start',
-    height: 100,
-    rx: 0,
-    ry: 0
-  }
-  return rect
-}
-
-const _drawTextCandidateFunc = (function () {
-  function byText (content, g, x, y, width, height, textAttrs) {
-    const text = g.append('text')
-      .attr('x', x + width / 2).attr('y', y + height / 2 + 5)
-      .style('text-anchor', 'middle')
-      .text(content)
-    _setTextAttrs(text, textAttrs)
-  }
-
-  function byTspan (content, g, x, y, width, height, textAttrs) {
-    const text = g.append('text')
-      .attr('x', x + width / 2).attr('y', y)
-      .style('text-anchor', 'middle')
-    text.append('tspan')
-      .attr('x', x + width / 2).attr('dy', '0')
-      .text(content)
-
-    text.attr('y', y + height / 2.0)
-      .attr('dominant-baseline', 'central')
-      .attr('alignment-baseline', 'central')
-
-    _setTextAttrs(text, textAttrs)
-  }
-
-  function byFo (content, g, x, y, width, height, textAttrs) {
-    const s = g.append('switch')
-    const f = s.append('foreignObject')
-      .attr('x', x).attr('y', y)
-      .attr('width', width).attr('height', height)
-
-    const text = f.append('div').style('display', 'table')
-      .style('height', '100%').style('width', '100%')
-
-    text.append('div').style('display', 'table-cell')
-      .style('text-align', 'center').style('vertical-align', 'middle')
-      .text(content)
-
-    byTspan(content, s, x, y, width, height, textAttrs)
-    _setTextAttrs(text, textAttrs)
-  }
-
-  function _setTextAttrs (toText, fromTextAttrsDict) {
-    for (const key in fromTextAttrsDict) {
-      if (fromTextAttrsDict.hasOwnProperty(key)) {
-        toText.attr(key, fromTextAttrsDict[key])
-      }
-    }
-  }
-
-  return function (conf) {
-    return conf.textPlacement === 'fo' ? byFo : (
-      conf.textPlacement === 'old' ? byText : byTspan)
-  }
-})()
-
-export default {
-  drawRect,
-  drawText,
-  drawLabel,
-  drawActor,
-  anchorElement,
-  drawActivation,
-  drawLoop,
-  insertArrowHead,
-  insertArrowCrossHead,
-  getTextObj,
-  getNoteRect
-}
diff --git a/_submodules/mermaid/src/logger.js b/_submodules/mermaid/src/logger.js
deleted file mode 100644
index adaadf31d34554bec1e13a0aacda57cfbf3703b3..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/logger.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import moment from 'moment'
-
-export const LEVELS = {
-  debug: 1,
-  info: 2,
-  warn: 3,
-  error: 4,
-  fatal: 5
-}
-
-export const logger = {
-  debug: () => {},
-  info: () => {},
-  warn: () => {},
-  error: () => {},
-  fatal: () => {}
-}
-
-export const setLogLevel = function (level) {
-  logger.debug = () => {}
-  logger.info = () => {}
-  logger.warn = () => {}
-  logger.error = () => {}
-  logger.fatal = () => {}
-  if (level <= LEVELS.fatal) {
-    logger.fatal = console.log.bind(console, '\x1b[35m', format('FATAL'))
-  }
-  if (level <= LEVELS.error) {
-    logger.error = console.log.bind(console, '\x1b[31m', format('ERROR'))
-  }
-  if (level <= LEVELS.warn) {
-    logger.warn = console.log.bind(console, `\x1b[33m`, format('WARN'))
-  }
-  if (level <= LEVELS.info) {
-    logger.info = console.log.bind(console, '\x1b[34m', format('INFO'))
-  }
-  if (level <= LEVELS.debug) {
-    logger.debug = console.log.bind(console, '\x1b[32m', format('DEBUG'))
-  }
-}
-
-const format = (level) => {
-  const time = moment().format('HH:mm:ss.SSS')
-  return `${time} : ${level} : `
-}
diff --git a/_submodules/mermaid/src/mermaid.js b/_submodules/mermaid/src/mermaid.js
deleted file mode 100644
index a8f05ffea1df32ef3a8f80bf9112b3fe30a199b8..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/mermaid.js
+++ /dev/null
@@ -1,167 +0,0 @@
-/**
- * Web page integration module for the mermaid framework. It uses the mermaidAPI for mermaid functionality and to render
- * the diagrams to svg code.
- */
-import he from 'he'
-
-import mermaidAPI from './mermaidAPI'
-import { logger } from './logger'
-
-/**
- * ## init
- * Function that goes through the document to find the chart definitions in there and render them.
- *
- * The function tags the processed attributes with the attribute data-processed and ignores found elements with the
- * attribute already set. This way the init function can be triggered several times.
- *
- * Optionally, `init` can accept in the second argument one of the following:
- * - a DOM Node
- * - an array of DOM nodes (as would come from a jQuery selector)
- * - a W3C selector, a la `.mermaid`
- *
- * ```mermaid
- * graph LR;
- *  a(Find elements)-->b{Processed}
- *  b-->|Yes|c(Leave element)
- *  b-->|No |d(Transform)
- * ```
- * Renders the mermaid diagrams
- * @param nodes a css selector or an array of nodes
- */
-const init = function () {
-  const conf = mermaidAPI.getConfig()
-  logger.debug('Starting rendering diagrams')
-  let nodes
-  if (arguments.length >= 2) {
-    /*! sequence config was passed as #1 */
-    if (typeof arguments[0] !== 'undefined') {
-      mermaid.sequenceConfig = arguments[0]
-    }
-
-    nodes = arguments[1]
-  } else {
-    nodes = arguments[0]
-  }
-
-  // if last argument is a function this is the callback function
-  let callback
-  if (typeof arguments[arguments.length - 1] === 'function') {
-    callback = arguments[arguments.length - 1]
-    logger.debug('Callback function found')
-  } else {
-    if (typeof conf.mermaid !== 'undefined') {
-      if (typeof conf.mermaid.callback === 'function') {
-        callback = conf.mermaid.callback
-        logger.debug('Callback function found')
-      } else {
-        logger.debug('No Callback function found')
-      }
-    }
-  }
-  nodes = nodes === undefined ? document.querySelectorAll('.mermaid')
-    : typeof nodes === 'string' ? document.querySelectorAll(nodes)
-      : nodes instanceof window.Node ? [nodes]
-        : nodes // Last case  - sequence config was passed pick next
-
-  logger.debug('Start On Load before: ' + mermaid.startOnLoad)
-  if (typeof mermaid.startOnLoad !== 'undefined') {
-    logger.debug('Start On Load inner: ' + mermaid.startOnLoad)
-    mermaidAPI.initialize({ startOnLoad: mermaid.startOnLoad })
-  }
-
-  if (typeof mermaid.ganttConfig !== 'undefined') {
-    mermaidAPI.initialize({ gantt: mermaid.ganttConfig })
-  }
-
-  let txt
-
-  for (let i = 0; i < nodes.length; i++) {
-    const element = nodes[i]
-
-    /*! Check if previously processed */
-    if (!element.getAttribute('data-processed')) {
-      element.setAttribute('data-processed', true)
-    } else {
-      continue
-    }
-
-    const id = `mermaid-${Date.now()}`
-
-    // Fetch the graph definition including tags
-    txt = element.innerHTML
-
-    // transforms the html to pure text
-    txt = he.decode(txt).trim().replace(/<br>/ig, '<br/>')
-
-    mermaidAPI.render(id, txt, (svgCode, bindFunctions) => {
-      element.innerHTML = svgCode
-      if (typeof callback !== 'undefined') {
-        callback(id)
-      }
-      bindFunctions(element)
-    }, element)
-  }
-}
-
-const initialize = function (config) {
-  logger.debug('Initializing mermaid')
-  if (typeof config.mermaid !== 'undefined') {
-    if (typeof config.mermaid.startOnLoad !== 'undefined') {
-      mermaid.startOnLoad = config.mermaid.startOnLoad
-    }
-    if (typeof config.mermaid.htmlLabels !== 'undefined') {
-      mermaid.htmlLabels = config.mermaid.htmlLabels
-    }
-  }
-  mermaidAPI.initialize(config)
-}
-
-/**
- * ##contentLoaded
- * Callback function that is called when page is loaded. This functions fetches configuration for mermaid rendering and
- * calls init for rendering the mermaid diagrams on the page.
- */
-const contentLoaded = function () {
-  let config
-
-  if (mermaid.startOnLoad) {
-    // No config found, do check API config
-    config = mermaidAPI.getConfig()
-    if (config.startOnLoad) {
-      mermaid.init()
-    }
-  } else {
-    if (typeof mermaid.startOnLoad === 'undefined') {
-      logger.debug('In start, no config')
-      config = mermaidAPI.getConfig()
-      if (config.startOnLoad) {
-        mermaid.init()
-      }
-    }
-  }
-}
-
-if (typeof document !== 'undefined') {
-  /*!
-   * Wait for document loaded before starting the execution
-   */
-  window.addEventListener('load', function () {
-    contentLoaded()
-  }, false)
-}
-
-const mermaid = {
-  startOnLoad: true,
-  htmlLabels: true,
-
-  mermaidAPI,
-  parse: mermaidAPI.parse,
-  render: mermaidAPI.render,
-
-  init,
-  initialize,
-
-  contentLoaded
-}
-
-export default mermaid
diff --git a/_submodules/mermaid/src/mermaid.spec.js b/_submodules/mermaid/src/mermaid.spec.js
deleted file mode 100644
index 996ad21f56078261dad2752e45bd629f1f159569..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/mermaid.spec.js
+++ /dev/null
@@ -1,217 +0,0 @@
-/* eslint-env jasmine */
-import mermaid from './mermaid'
-import flowDb from './diagrams/flowchart/flowDb'
-import flowParser from './diagrams/flowchart/parser/flow'
-import flowRenderer from './diagrams/flowchart/flowRenderer'
-
-describe('when using mermaid and ', function () {
-  describe('when detecting chart type ', function () {
-    it('should not start rendering with mermaid.startOnLoad set to false', function () {
-      mermaid.startOnLoad = false
-      document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>'
-      spyOn(mermaid, 'init')
-      mermaid.contentLoaded()
-      expect(mermaid.init).not.toHaveBeenCalled()
-    })
-
-    it('should start rendering with both startOnLoad set', function () {
-      mermaid.startOnLoad = true
-      document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>'
-      spyOn(mermaid, 'init')
-      mermaid.contentLoaded()
-      expect(mermaid.init).toHaveBeenCalled()
-    })
-
-    it('should start rendering with mermaid.startOnLoad', function () {
-      mermaid.startOnLoad = true
-      document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>'
-      spyOn(mermaid, 'init')
-      mermaid.contentLoaded()
-      expect(mermaid.init).toHaveBeenCalled()
-    })
-
-    it('should start rendering as a default with no changes performed', function () {
-      document.body.innerHTML = '<div class="mermaid">graph TD;\na;</div>'
-      spyOn(mermaid, 'init')
-      mermaid.contentLoaded()
-      expect(mermaid.init).toHaveBeenCalled()
-    })
-  })
-
-  describe('when calling addEdges ', function () {
-    beforeEach(function () {
-      flowParser.parser.yy = flowDb
-      flowDb.clear()
-    })
-    it('it should handle edges with text', function () {
-      flowParser.parser.parse('graph TD;A-->|text ex|B;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('normal')
-          expect(options.label.match('text ex')).toBeTruthy()
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-
-    it('should handle edges without text', function () {
-      flowParser.parser.parse('graph TD;A-->B;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('normal')
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-
-    it('should handle open-ended edges', function () {
-      flowParser.parser.parse('graph TD;A---B;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('none')
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-
-    it('should handle edges with styles defined', function () {
-      flowParser.parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('none')
-          expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;')
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-    it('should handle edges with interpolation defined', function () {
-      flowParser.parser.parse('graph TD;A---B; linkStyle 0 interpolate basis')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('none')
-          expect(options.curve).toBe('basis') // mocked as string
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-    it('should handle edges with text and styles defined', function () {
-      flowParser.parser.parse('graph TD;A---|the text|B; linkStyle 0 stroke:val1,stroke-width:val2;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('none')
-          expect(options.label.match('the text')).toBeTruthy()
-          expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;')
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-
-    it('should set fill to "none" by default when handling edges', function () {
-      flowParser.parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('none')
-          expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:none;')
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-
-    it('should not set fill to none if fill is set in linkStyle', function () {
-      flowParser.parser.parse('graph TD;A---B; linkStyle 0 stroke:val1,stroke-width:val2,fill:blue;')
-      flowParser.parser.yy.getVertices()
-      const edges = flowParser.parser.yy.getEdges()
-      const mockG = {
-        setEdge: function (start, end, options) {
-          expect(start).toBe('A')
-          expect(end).toBe('B')
-          expect(options.arrowhead).toBe('none')
-          expect(options.style).toBe('stroke:val1;stroke-width:val2;fill:blue;')
-        }
-      }
-
-      flowRenderer.addEdges(edges, mockG)
-    })
-  })
-
-  describe('checking validity of input ', function () {
-    it('it should throw for an invalid definiton', function () {
-      expect(() => mermaid.parse('this is not a mermaid diagram definition')).toThrow()
-    })
-
-    it('it should not throw for a valid flow definition', function () {
-      expect(() => mermaid.parse('graph TD;A--x|text including URL space|B;')).not.toThrow()
-    })
-    it('it should throw for an invalid flow definition', function () {
-      expect(() => mermaid.parse('graph TQ;A--x|text including URL space|B;')).toThrow()
-    })
-
-    it('it should not throw for a valid sequenceDiagram definition', function () {
-      const text = 'sequenceDiagram\n' +
-        'Alice->Bob: Hello Bob, how are you?\n\n' +
-        '%% Comment\n' +
-        'Note right of Bob: Bob thinks\n' +
-        'alt isWell\n\n' +
-        'Bob-->Alice: I am good thanks!\n' +
-        'else isSick\n' +
-        'Bob-->Alice: Feel sick...\n' +
-        'end'
-      expect(() => mermaid.parse(text)).not.toThrow()
-    })
-
-    it('it should throw for an invalid sequenceDiagram definition', function () {
-      const text = 'sequenceDiagram\n' +
-        'Alice:->Bob: Hello Bob, how are you?\n\n' +
-        '%% Comment\n' +
-        'Note right of Bob: Bob thinks\n' +
-        'alt isWell\n\n' +
-        'Bob-->Alice: I am good thanks!\n' +
-        'else isSick\n' +
-        'Bob-->Alice: Feel sick...\n' +
-        'end'
-      expect(() => mermaid.parse(text)).toThrow()
-    })
-  })
-})
diff --git a/_submodules/mermaid/src/mermaidAPI.js b/_submodules/mermaid/src/mermaidAPI.js
deleted file mode 100644
index d40c336c4290e95d9b84bd817e910fb68028fc8f..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/mermaidAPI.js
+++ /dev/null
@@ -1,487 +0,0 @@
-/**
- * ---
- * title: mermaidAPI
- * order: 5
- * ---
- * # mermaidAPI
- * This is the api to be used when handling the integration with the web page instead of using the default integration
- * (mermaid.js).
- *
- * The core of this api is the **render** function that given a graph definitionas text renders the graph/diagram and
- * returns a svg element for the graph. It is is then up to the user of the API to make use of the svg, either insert it
- * somewhere in the page or something completely different.
-*/
-import * as d3 from 'd3'
-import scope from 'scope-css'
-
-import { logger, setLogLevel } from './logger'
-import utils from './utils'
-import flowRenderer from './diagrams/flowchart/flowRenderer'
-import flowParser from './diagrams/flowchart/parser/flow'
-import flowDb from './diagrams/flowchart/flowDb'
-import sequenceRenderer from './diagrams/sequence/sequenceRenderer'
-import sequenceParser from './diagrams/sequence/parser/sequenceDiagram'
-import sequenceDb from './diagrams/sequence/sequenceDb'
-import ganttRenderer from './diagrams/gantt/ganttRenderer'
-import ganttParser from './diagrams/gantt/parser/gantt'
-import ganttDb from './diagrams/gantt/ganttDb'
-import classRenderer from './diagrams/class/classRenderer'
-import classParser from './diagrams/class/parser/classDiagram'
-import classDb from './diagrams/class/classDb'
-import gitGraphRenderer from './diagrams/git/gitGraphRenderer'
-import gitGraphParser from './diagrams/git/parser/gitGraph'
-import gitGraphAst from './diagrams/git/gitGraphAst'
-
-const themes = {}
-for (const themeName of ['default', 'forest', 'dark', 'neutral']) {
-  themes[themeName] = require(`./themes/${themeName}/index.scss`)
-}
-
-/**
- * ## Configuration
- * These are the default options which can be overridden with the initialization call as in the example below:
- * ```
- * mermaid.initialize({
- *   flowchart:{
- *      htmlLabels: false
- *   }
- * });
- * ```
- */
-const config = {
-  theme: 'default',
-  themeCSS: undefined,
-
-  /**
-   * logLevel , decides the amount of logging to be used.
-   *    * debug: 1
-   *    * info: 2
-   *    * warn: 3
-   *    * error: 4
-   *    * fatal: 5
-   */
-  logLevel: 5,
-
-  /**
-   * **startOnLoad** - This options controls whether or mermaid starts when the page loads
-   */
-  startOnLoad: true,
-
-  /**
-   * **arrowMarkerAbsolute** - This options controls whether or arrow markers in html code will be absolute paths or
-   * an anchor, #. This matters if you are using base tag settings.
-   */
-  arrowMarkerAbsolute: false,
-
-  /**
-   * ### flowchart
-   * *The object containing configurations specific for flowcharts*
-   */
-  flowchart: {
-    /**
-     * **htmlLabels** - Flag for setting whether or not a html tag should be used for rendering labels
-     * on the edges
-     */
-    htmlLabels: true,
-
-    curve: 'linear'
-  },
-
-  /**
-   * ###  sequenceDiagram
-   * The object containing configurations specific for sequence diagrams
-   */
-  sequence: {
-
-    /**
-     * **diagramMarginX** - margin to the right and left of the sequence diagram
-     */
-    diagramMarginX: 50,
-
-    /**
-     * **diagramMarginY** - margin to the over and under the sequence diagram
-     */
-    diagramMarginY: 10,
-
-    /**
-     * **actorMargin** - Margin between actors
-     */
-    actorMargin: 50,
-
-    /**
-     * **width** - Width of actor boxes
-     */
-    width: 150,
-
-    /**
-     * **height** - Height of actor boxes
-     */
-    height: 65,
-
-    /**
-     * **boxMargin** - Margin around loop boxes
-     */
-    boxMargin: 10,
-
-    /**
-     * **boxTextMargin** - margin around the text in loop/alt/opt boxes
-     */
-    boxTextMargin: 5,
-
-    /**
-     * **noteMargin** - margin around notes
-     */
-    noteMargin: 10,
-
-    /**
-     * **messageMargin** - Space between messages
-     */
-    messageMargin: 35,
-
-    /**
-     * **mirrorActors** - mirror actors under diagram
-     */
-    mirrorActors: true,
-
-    /**
-     * **bottomMarginAdj** - Depending on css styling this might need adjustment.
-     * Prolongs the edge of the diagram downwards
-     */
-    bottomMarginAdj: 1,
-
-    /**
-     * **useMaxWidth** - when this flag is set the height and width is set to 100% and is then scaling with the
-     * available space if not the absolute space required is used
-     */
-    useMaxWidth: true
-  },
-
-  /** ### gantt
-   * The object containing configurations specific for gantt diagrams*
-   */
-  gantt: {
-    /**
-     * **titleTopMargin** - margin top for the text over the gantt diagram
-     */
-    titleTopMargin: 25,
-
-    /**
-     * **barHeight** - the height of the bars in the graph
-     */
-    barHeight: 20,
-
-    /**
-     * **barGap** - the margin between the different activities in the gantt diagram
-     */
-    barGap: 4,
-
-    /**
-     *  **topPadding** - margin between title and gantt diagram and between axis and gantt diagram.
-     */
-    topPadding: 50,
-
-    /**
-     *  **leftPadding** - the space allocated for the section name to the left of the activities.
-     */
-    leftPadding: 75,
-
-    /**
-     *  **gridLineStartPadding** - Vertical starting position of the grid lines
-     */
-    gridLineStartPadding: 35,
-
-    /**
-     *  **fontSize** - font size ...
-     */
-    fontSize: 11,
-
-    /**
-     * **fontFamily** - font family ...
-     */
-    fontFamily: '"Open-Sans", "sans-serif"',
-
-    /**
-     * **numberSectionStyles** - the number of alternating section styles
-     */
-    numberSectionStyles: 4,
-
-    /**
-     * **axisFormat** - datetime format of the axis, this might need adjustment to match your locale and preferences
-     */
-    axisFormat: '%Y-%m-%d'
-  },
-  class: {},
-  git: {}
-}
-
-setLogLevel(config.logLevel)
-
-function parse (text) {
-  const graphType = utils.detectType(text)
-  let parser
-
-  switch (graphType) {
-    case 'git':
-      parser = gitGraphParser
-      parser.parser.yy = gitGraphAst
-      break
-    case 'flowchart':
-      parser = flowParser
-      parser.parser.yy = flowDb
-      break
-    case 'sequence':
-      parser = sequenceParser
-      parser.parser.yy = sequenceDb
-      break
-    case 'gantt':
-      parser = ganttParser
-      parser.parser.yy = ganttDb
-      break
-    case 'class':
-      parser = classParser
-      parser.parser.yy = classDb
-      break
-  }
-
-  parser.parser.yy.parseError = (str, hash) => {
-    const error = { str, hash }
-    throw error
-  }
-
-  parser.parse(text)
-}
-
-export const encodeEntities = function (text) {
-  let txt = text
-
-  txt = txt.replace(/style.*:\S*#.*;/g, function (s) {
-    const innerTxt = s.substring(0, s.length - 1)
-    return innerTxt
-  })
-  txt = txt.replace(/classDef.*:\S*#.*;/g, function (s) {
-    const innerTxt = s.substring(0, s.length - 1)
-    return innerTxt
-  })
-
-  txt = txt.replace(/#\w+;/g, function (s) {
-    const innerTxt = s.substring(1, s.length - 1)
-
-    const isInt = /^\+?\d+$/.test(innerTxt)
-    if (isInt) {
-      return 'fl°°' + innerTxt + '¶ß'
-    } else {
-      return 'fl°' + innerTxt + '¶ß'
-    }
-  })
-
-  return txt
-}
-
-export const decodeEntities = function (text) {
-  let txt = text
-
-  txt = txt.replace(/fl°°/g, function () {
-    return '&#'
-  })
-  txt = txt.replace(/fl°/g, function () {
-    return '&'
-  })
-  txt = txt.replace(/¶ß/g, function () {
-    return ';'
-  })
-
-  return txt
-}
-/**
- * ##render
- * Function that renders an svg with a graph from a chart definition. Usage example below.
- *
- * ```
- * mermaidAPI.initialize({
- *      startOnLoad:true
- *  });
- *  $(function(){
- *      const graphDefinition = 'graph TB\na-->b';
- *      const cb = function(svgGraph){
- *          console.log(svgGraph);
- *      };
- *      mermaidAPI.render('id1',graphDefinition,cb);
- *  });
- *```
- * @param id the id of the element to be rendered
- * @param txt the graph definition
- * @param cb callback which is called after rendering is finished with the svg code as inparam.
- * @param container selector to element in which a div with the graph temporarily will be inserted. In one is
- * provided a hidden div will be inserted in the body of the page instead. The element will be removed when rendering is
- * completed.
- */
-const render = function (id, txt, cb, container) {
-  if (typeof container !== 'undefined') {
-    container.innerHTML = ''
-
-    d3.select(container).append('div')
-      .attr('id', 'd' + id)
-      .append('svg')
-      .attr('id', id)
-      .attr('width', '100%')
-      .attr('xmlns', 'http://www.w3.org/2000/svg')
-      .append('g')
-  } else {
-    const element = document.querySelector('#' + 'd' + id)
-    if (element) {
-      element.innerHTML = ''
-    }
-
-    d3.select('body').append('div')
-      .attr('id', 'd' + id)
-      .append('svg')
-      .attr('id', id)
-      .attr('width', '100%')
-      .attr('xmlns', 'http://www.w3.org/2000/svg')
-      .append('g')
-  }
-
-  window.txt = txt
-  txt = encodeEntities(txt)
-
-  const element = d3.select('#d' + id).node()
-  const graphType = utils.detectType(txt)
-
-  // insert inline style into svg
-  const svg = element.firstChild
-  const firstChild = svg.firstChild
-
-  // pre-defined theme
-  let style = themes[config.theme]
-  if (style === undefined) {
-    style = ''
-  }
-
-  // user provided theme CSS
-  if (config.themeCSS !== undefined) {
-    style += `\n${config.themeCSS}`
-  }
-
-  // classDef
-  if (graphType === 'flowchart') {
-    const classes = flowRenderer.getClasses(txt)
-    for (const className in classes) {
-      style += `\n.${className} > * { ${classes[className].styles.join(' !important; ')} !important; }`
-    }
-  }
-
-  const style1 = document.createElement('style')
-  style1.innerHTML = scope(style, `#${id}`)
-  svg.insertBefore(style1, firstChild)
-
-  const style2 = document.createElement('style')
-  const cs = window.getComputedStyle(svg)
-  style2.innerHTML = `#${id} {
-    color: ${cs.color};
-    font: ${cs.font};
-  }`
-  svg.insertBefore(style2, firstChild)
-
-  switch (graphType) {
-    case 'git':
-      config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute
-      gitGraphRenderer.setConf(config.git)
-      gitGraphRenderer.draw(txt, id, false)
-      break
-    case 'flowchart':
-      config.flowchart.arrowMarkerAbsolute = config.arrowMarkerAbsolute
-      flowRenderer.setConf(config.flowchart)
-      flowRenderer.draw(txt, id, false)
-      break
-    case 'sequence':
-      config.sequence.arrowMarkerAbsolute = config.arrowMarkerAbsolute
-      if (config.sequenceDiagram) { // backwards compatibility
-        sequenceRenderer.setConf(Object.assign(config.sequence, config.sequenceDiagram))
-        console.error('`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.')
-      } else {
-        sequenceRenderer.setConf(config.sequence)
-      }
-      sequenceRenderer.draw(txt, id)
-      break
-    case 'gantt':
-      config.gantt.arrowMarkerAbsolute = config.arrowMarkerAbsolute
-      ganttRenderer.setConf(config.gantt)
-      ganttRenderer.draw(txt, id)
-      break
-    case 'class':
-      config.class.arrowMarkerAbsolute = config.arrowMarkerAbsolute
-      classRenderer.setConf(config.class)
-      classRenderer.draw(txt, id)
-      break
-  }
-
-  d3.select(`[id="${id}"]`).selectAll('foreignobject > *').attr('xmlns', 'http://www.w3.org/1999/xhtml')
-
-  let url = ''
-  if (config.arrowMarkerAbsolute) {
-    url = window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search
-    url = url.replace(/\(/g, '\\(')
-    url = url.replace(/\)/g, '\\)')
-  }
-
-  // Fix for when the base tag is used
-  let svgCode = d3.select('#d' + id).node().innerHTML.replace(/url\(#arrowhead/g, 'url(' + url + '#arrowhead', 'g')
-
-  svgCode = decodeEntities(svgCode)
-
-  if (typeof cb !== 'undefined') {
-    cb(svgCode, flowDb.bindFunctions)
-  } else {
-    logger.warn('CB = undefined!')
-  }
-
-  const node = d3.select('#d' + id).node()
-  if (node !== null && typeof node.remove === 'function') {
-    d3.select('#d' + id).node().remove()
-  }
-
-  return svgCode
-}
-
-const setConf = function (cnf) {
-  // Top level initially mermaid, gflow, sequenceDiagram and gantt
-  const lvl1Keys = Object.keys(cnf)
-  for (let i = 0; i < lvl1Keys.length; i++) {
-    if (typeof cnf[lvl1Keys[i]] === 'object' && cnf[lvl1Keys[i]] != null) {
-      const lvl2Keys = Object.keys(cnf[lvl1Keys[i]])
-
-      for (let j = 0; j < lvl2Keys.length; j++) {
-        logger.debug('Setting conf ', lvl1Keys[i], '-', lvl2Keys[j])
-        if (typeof config[lvl1Keys[i]] === 'undefined') {
-          config[lvl1Keys[i]] = {}
-        }
-        logger.debug('Setting config: ' + lvl1Keys[i] + ' ' + lvl2Keys[j] + ' to ' + cnf[lvl1Keys[i]][lvl2Keys[j]])
-        config[lvl1Keys[i]][lvl2Keys[j]] = cnf[lvl1Keys[i]][lvl2Keys[j]]
-      }
-    } else {
-      config[lvl1Keys[i]] = cnf[lvl1Keys[i]]
-    }
-  }
-}
-
-function initialize (options) {
-  logger.debug('Initializing mermaidAPI')
-  // Update default config with options supplied at initialization
-  if (typeof options === 'object') {
-    setConf(options)
-  }
-  setLogLevel(config.logLevel)
-}
-
-function getConfig () {
-  return config
-}
-
-const mermaidAPI = {
-  render,
-  parse,
-  initialize,
-  getConfig
-}
-
-export default mermaidAPI
diff --git a/_submodules/mermaid/src/mermaidAPI.spec.js b/_submodules/mermaid/src/mermaidAPI.spec.js
deleted file mode 100644
index 51749677cd7090172b2dec138d96e71f5d365d73..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/mermaidAPI.spec.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* eslint-env jasmine */
-import mermaidAPI from './mermaidAPI'
-
-describe('when using mermaidAPI and ', function () {
-  describe('doing initialize ', function () {
-    beforeEach(function () {
-      document.body.innerHTML = ''
-    })
-
-    it('should copy a literal into the configuration', function () {
-      const orgConfig = mermaidAPI.getConfig()
-      expect(orgConfig.testLiteral).toBe(undefined)
-
-      mermaidAPI.initialize({ 'testLiteral': true })
-      const config = mermaidAPI.getConfig()
-
-      expect(config.testLiteral).toBe(true)
-    })
-    it('should copy a an object into the configuration', function () {
-      const orgConfig = mermaidAPI.getConfig()
-      expect(orgConfig.testObject).toBe(undefined)
-
-      const object = {
-        test1: 1,
-        test2: false
-      }
-
-      mermaidAPI.initialize({ 'testObject': object })
-      mermaidAPI.initialize({ 'testObject': { 'test3': true } })
-      const config = mermaidAPI.getConfig()
-
-      expect(config.testObject.test1).toBe(1)
-      expect(config.testObject.test2).toBe(false)
-      expect(config.testObject.test3).toBe(true)
-    })
-  })
-  describe('checking validity of input ', function () {
-    it('it should throw for an invalid definiton', function () {
-      expect(() => mermaidAPI.parse('this is not a mermaid diagram definition')).toThrow()
-    })
-    it('it should not throw for a valid definiton', function () {
-      expect(() => mermaidAPI.parse('graph TD;A--x|text including URL space|B;')).not.toThrow()
-    })
-  })
-})
diff --git a/_submodules/mermaid/src/themes/class.scss b/_submodules/mermaid/src/themes/class.scss
deleted file mode 100644
index 5e7de91503d085c62ad225d75c6edf8633eb00ed..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/class.scss
+++ /dev/null
@@ -1,78 +0,0 @@
-g.classGroup text {
-  fill: $nodeBorder;
-  stroke: none;
-  font-family: 'trebuchet ms', verdana, arial;
-  font-size: 10px;
-}
-
-g.classGroup rect {
-  fill: $nodeBkg;
-  stroke: $nodeBorder;
-}
-
-g.classGroup line {
-  stroke: $nodeBorder;
-  stroke-width: 1;
-}
-
-.classLabel .box {
-  stroke: none;
-  stroke-width: 0;
-  fill: $nodeBkg;
-  opacity: 0.5;
-}
-
-.classLabel .label {
-  fill: $nodeBorder;
-  font-size: 10px;
-}
-
-.relation {
-  stroke: $nodeBorder;
-  stroke-width: 1;
-  fill: none;
-}
-
-@mixin composition {
-  fill: $nodeBorder;
-  stroke: $nodeBorder;
-  stroke-width: 1;
-}
-
-#compositionStart {
-  @include composition;
-}
-
-#compositionEnd {
-  @include composition;
-}
-
-@mixin aggregation {
-  fill: $nodeBkg;
-  stroke: $nodeBorder;
-  stroke-width: 1;
-}
-
-#aggregationStart {
-  @include aggregation;
-}
-
-#aggregationEnd {
-  @include aggregation;
-}
-
-#dependencyStart {
-  @include composition;
-}
-
-#dependencyEnd {
-  @include composition;
-}
-
-#extensionStart {
-  @include composition;
-}
-
-#extensionEnd {
-  @include composition;
-}
diff --git a/_submodules/mermaid/src/themes/default/index.scss b/_submodules/mermaid/src/themes/default/index.scss
deleted file mode 100644
index e98fc0741e34cc34363934f6db1489a5bfc2db4a..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/default/index.scss
+++ /dev/null
@@ -1,52 +0,0 @@
-$mainBkg: #ECECFF;
-$secondBkg: #ffffde;
-$lineColor: #333333;
-$border1: #CCCCFF;
-$border2: #aaaa33;
-$arrowheadColor: #333333;
-
-/* Flowchart variables */
-
-$nodeBkg: $mainBkg;
-$nodeBorder: #9370DB;
-$clusterBkg: $secondBkg;
-$clusterBorder: $border2;
-$defaultLinkColor: $lineColor;
-$titleColor: #333;
-$edgeLabelBackground: #e8e8e8;
-
-/* Sequence Diagram variables */
-
-$actorBorder: $border1;
-$actorBkg: $mainBkg;
-$actorTextColor: black;
-$actorLineColor: grey;
-$signalColor: #333;
-$signalTextColor: #333;
-$labelBoxBkgColor: $actorBkg;
-$labelBoxBorderColor: $actorBorder;
-$labelTextColor: $actorTextColor;
-$noteBorderColor: $border2;
-$noteBkgColor: #fff5ad;
-
-/* Gantt chart variables */
-
-$sectionBkgColor: rgba(102, 102, 255, 0.49);
-$altSectionBkgColor: white;
-$sectionBkgColor2: #fff400;
-$taskBorderColor: #534fbc;
-$taskBkgColor: #8a90dd;
-$taskTextLightColor: white;
-$taskTextColor: $taskTextLightColor;
-$taskTextDarkColor: black;
-$taskTextOutsideColor: $taskTextDarkColor;
-$activeTaskBorderColor: #534fbc;
-$activeTaskBkgColor: #bfc7ff;
-$gridColor: lightgrey;
-$doneTaskBkgColor: lightgrey;
-$doneTaskBorderColor: grey;
-$critBorderColor: #ff8888;
-$critBkgColor: red;
-$todayLineColor: red;
-
-@import '../mermaid';
diff --git a/_submodules/mermaid/src/themes/flowchart.scss b/_submodules/mermaid/src/themes/flowchart.scss
deleted file mode 100644
index edafcf5e75e4d52906c291cce0703878ec92454e..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/flowchart.scss
+++ /dev/null
@@ -1,54 +0,0 @@
-.label {
-  font-family: 'trebuchet ms', verdana, arial;
-  color: #333;
-}
-
-.node rect,
-.node circle,
-.node ellipse,
-.node polygon {
-  fill: $mainBkg;
-  stroke: $nodeBorder;
-  stroke-width: 1px;
-}
-
-.node.clickable {
-  cursor: pointer;
-}
-
-.arrowheadPath {
-  fill: $arrowheadColor;
-}
-
-.edgePath .path {
-  stroke: $lineColor;
-  stroke-width: 1.5px;
-}
-
-.edgeLabel {
-  background-color: $edgeLabelBackground;
-}
-
-.cluster rect {
-  fill: $secondBkg !important;
-  stroke: $clusterBorder !important;
-  stroke-width: 1px !important;
-}
-
-.cluster text {
-  fill: $titleColor;
-}
-
-div.mermaidTooltip {
-  position: absolute;
-  text-align: center;
-  max-width: 200px;
-  padding: 2px;
-  font-family: 'trebuchet ms', verdana, arial;
-  font-size: 12px;
-  background: $secondBkg;
-  border: 1px solid $border2;
-  border-radius: 2px;
-  pointer-events: none;
-  z-index: 100;
-}
diff --git a/_submodules/mermaid/src/themes/forest/index.scss b/_submodules/mermaid/src/themes/forest/index.scss
deleted file mode 100644
index f6e1a1dae7fd6c12d6533d8e7fa8914c764d943a..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/forest/index.scss
+++ /dev/null
@@ -1,53 +0,0 @@
-$mainBkg: #cde498;
-$secondBkg: #cdffb2;
-$lineColor: #1a3318;
-$lineColor: green;
-$border1: #13540c;
-$border2: #6eaa49;
-$arrowheadColor: green;
-
-/* Flowchart variables */
-
-$nodeBkg: $mainBkg;
-$nodeBorder: $border1;
-$clusterBkg: $secondBkg;
-$clusterBorder: $border2;
-$defaultLinkColor: $lineColor;
-$titleColor: #333;
-$edgeLabelBackground: #e8e8e8;
-
-/* Sequence Diagram variables */
-
-$actorBorder: $border1;
-$actorBkg: $mainBkg;
-$actorTextColor: black;
-$actorLineColor: grey;
-$signalColor: #333;
-$signalTextColor: #333;
-$labelBoxBkgColor: $actorBkg;
-$labelBoxBorderColor: #326932;
-$labelTextColor: $actorTextColor;
-$noteBorderColor: $border2;
-$noteBkgColor: #fff5ad;
-
-/* Gantt chart variables */
-
-$sectionBkgColor: #6eaa49;
-$altSectionBkgColor: white;
-$sectionBkgColor2: #6eaa49;
-$taskBorderColor: $border1;
-$taskBkgColor: #487e3a;
-$taskTextLightColor: white;
-$taskTextColor: $taskTextLightColor;
-$taskTextDarkColor: black;
-$taskTextOutsideColor: $taskTextDarkColor;
-$activeTaskBorderColor: $taskBorderColor;
-$activeTaskBkgColor: $mainBkg;
-$gridColor: lightgrey;
-$doneTaskBkgColor: lightgrey;
-$doneTaskBorderColor: grey;
-$critBorderColor: #ff8888;
-$critBkgColor: red;
-$todayLineColor: red;
-
-@import '../mermaid';
diff --git a/_submodules/mermaid/src/themes/gantt.scss b/_submodules/mermaid/src/themes/gantt.scss
deleted file mode 100644
index 6793135ec854b44e26f15d006c1a5cb151f5d1f8..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/gantt.scss
+++ /dev/null
@@ -1,209 +0,0 @@
-/** Section styling */
-
-.section {
-  stroke: none;
-  opacity: 0.2;
-}
-
-.section0 {
-  fill: $sectionBkgColor;
-}
-
-.section2 {
-  fill: $sectionBkgColor2;
-}
-
-.section1,
-.section3 {
-  fill: $altSectionBkgColor;
-  opacity: 0.2;
-}
-
-.sectionTitle0 {
-  fill: $titleColor;
-}
-
-.sectionTitle1 {
-  fill: $titleColor;
-}
-
-.sectionTitle2 {
-  fill: $titleColor;
-}
-
-.sectionTitle3 {
-  fill: $titleColor;
-}
-
-.sectionTitle {
-  text-anchor: start;
-  font-size: 11px;
-  text-height: 14px;
-}
-
-
-/* Grid and axis */
-
-.grid .tick {
-  stroke: $gridColor;
-  opacity: 0.3;
-  shape-rendering: crispEdges;
-}
-
-.grid path {
-  stroke-width: 0;
-}
-
-
-/* Today line */
-
-.today {
-  fill: none;
-  stroke: $todayLineColor;
-  stroke-width: 2px;
-}
-
-
-/* Task styling */
-
-
-/* Default task */
-
-.task {
-  stroke-width: 2;
-}
-
-.taskText {
-  text-anchor: middle;
-  font-size: 11px;
-}
-
-.taskTextOutsideRight {
-  fill: $taskTextDarkColor;
-  text-anchor: start;
-  font-size: 11px;
-}
-
-.taskTextOutsideLeft {
-  fill: $taskTextDarkColor;
-  text-anchor: end;
-  font-size: 11px;
-}
-
-
-/* Specific task settings for the sections*/
-
-.taskText0,
-.taskText1,
-.taskText2,
-.taskText3 {
-  fill: $taskTextColor;
-}
-
-.task0,
-.task1,
-.task2,
-.task3 {
-  fill: $taskBkgColor;
-  stroke: $taskBorderColor;
-}
-
-.taskTextOutside0,
-.taskTextOutside2,
-{
-  fill: $taskTextOutsideColor;
-}
-
-.taskTextOutside1,
-.taskTextOutside3 {
-  fill: $taskTextOutsideColor;
-}
-
-
-/* Active task */
-
-.active0,
-.active1,
-.active2,
-.active3 {
-  fill: $activeTaskBkgColor;
-  stroke: $activeTaskBorderColor;
-}
-
-.activeText0,
-.activeText1,
-.activeText2,
-.activeText3 {
-  fill: $taskTextDarkColor !important;
-}
-
-
-/* Completed task */
-
-.done0,
-.done1,
-.done2,
-.done3 {
-  stroke: $doneTaskBorderColor;
-  fill: $doneTaskBkgColor;
-  stroke-width: 2;
-}
-
-.doneText0,
-.doneText1,
-.doneText2,
-.doneText3 {
-  fill: $taskTextDarkColor !important;
-}
-
-
-/* Tasks on the critical line */
-
-.crit0,
-.crit1,
-.crit2,
-.crit3 {
-  stroke: $critBorderColor;
-  fill: $critBkgColor;
-  stroke-width: 2;
-}
-
-.activeCrit0,
-.activeCrit1,
-.activeCrit2,
-.activeCrit3 {
-  stroke: $critBorderColor;
-  fill: $activeTaskBkgColor;
-  stroke-width: 2;
-}
-
-.doneCrit0,
-.doneCrit1,
-.doneCrit2,
-.doneCrit3 {
-  stroke: $critBorderColor;
-  fill: $doneTaskBkgColor;
-  stroke-width: 2;
-  cursor: pointer;
-  shape-rendering: crispEdges;
-}
-
-.doneCritText0,
-.doneCritText1,
-.doneCritText2,
-.doneCritText3 {
-  fill: $taskTextDarkColor !important;
-}
-
-.activeCritText0,
-.activeCritText1,
-.activeCritText2,
-.activeCritText3 {
-  fill: $taskTextDarkColor !important;
-}
-
-.titleText {
-  text-anchor: middle;
-  font-size: 18px;
-  fill: $taskTextDarkColor;
-}
diff --git a/_submodules/mermaid/src/themes/git.scss b/_submodules/mermaid/src/themes/git.scss
deleted file mode 100644
index f4072ef6526819fb162af3b02146ceb4f79f8dcb..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/git.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-.commit-id,
-.commit-msg,
-.branch-label {
-  fill: lightgrey;
-  color: lightgrey;
-}
diff --git a/_submodules/mermaid/src/themes/mermaid.scss b/_submodules/mermaid/src/themes/mermaid.scss
deleted file mode 100644
index 9a46f5142e06ce354a2dad513acc5a678360c314..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/mermaid.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-@import 'flowchart';
-@import 'sequence';
-@import 'gantt';
-@import 'class';
-@import 'git';
diff --git a/_submodules/mermaid/src/themes/neutral/index.scss b/_submodules/mermaid/src/themes/neutral/index.scss
deleted file mode 100644
index f0560142f0d87358ce74356362e49fd805f818b1..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/neutral/index.scss
+++ /dev/null
@@ -1,57 +0,0 @@
-$mainBkg: #eee;
-$contrast: #26a;
-$secondBkg: lighten($contrast, 55%);
-$lineColor: #666;
-$border1: #999;
-$border2: $contrast;
-$note: #ffa;
-$text: #333;
-$critical: #d42;
-$done: #bbb;
-$arrowheadColor: #333333;
-
-/* Flowchart variables */
-
-$nodeBkg: $mainBkg;
-$nodeBorder: $border1;
-$clusterBkg: $secondBkg;
-$clusterBorder: $border2;
-$defaultLinkColor: $lineColor;
-$titleColor: $text;
-$edgeLabelBackground: white;
-
-/* Sequence Diagram variables */
-
-$actorBorder: $border1;
-$actorBkg: $mainBkg;
-$actorTextColor: $text;
-$actorLineColor: $lineColor;
-$signalColor: $text;
-$signalTextColor: $text;
-$labelBoxBkgColor: $actorBkg;
-$labelBoxBorderColor: $actorBorder;
-$labelTextColor: white;
-$noteBorderColor: darken($note, 60%);
-$noteBkgColor: $note;
-
-/* Gantt chart variables */
-
-$sectionBkgColor: lighten($contrast, 30%);
-$altSectionBkgColor: white;
-$sectionBkgColor2: lighten($contrast, 30%);
-$taskBorderColor: darken($contrast, 10%);
-$taskBkgColor: $contrast;
-$taskTextLightColor: white;
-$taskTextColor: $taskTextLightColor;
-$taskTextDarkColor: $text;
-$taskTextOutsideColor: $taskTextDarkColor;
-$activeTaskBorderColor: $taskBorderColor;
-$activeTaskBkgColor: $mainBkg;
-$gridColor: lighten($border1, 30%);
-$doneTaskBkgColor: $done;
-$doneTaskBorderColor: $lineColor;
-$critBkgColor: $critical;
-$critBorderColor: darken($critBkgColor, 10%);
-$todayLineColor: $critBkgColor;
-
-@import '../mermaid';
diff --git a/_submodules/mermaid/src/themes/sequence.scss b/_submodules/mermaid/src/themes/sequence.scss
deleted file mode 100644
index 780e8ecf5dc74059d24730fe46a01937667c99f8..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/themes/sequence.scss
+++ /dev/null
@@ -1,75 +0,0 @@
-.actor {
-  stroke: $actorBorder;
-  fill: $actorBkg;
-}
-
-text.actor {
-  fill: $actorTextColor;
-  stroke: none;
-}
-
-.actor-line {
-  stroke: $actorLineColor;
-}
-
-.messageLine0 {
-  stroke-width: 1.5;
-  stroke-dasharray: '2 2';
-  marker-end: 'url(#arrowhead)';
-  stroke: $signalColor;
-}
-
-.messageLine1 {
-  stroke-width: 1.5;
-  stroke-dasharray: '2 2';
-  stroke: $signalColor;
-}
-
-#arrowhead {
-  fill: $signalColor;
-}
-
-#crosshead path {
-  fill: $signalColor !important;
-  stroke: $signalColor !important;
-}
-
-.messageText {
-  fill: $signalTextColor;
-  stroke: none;
-}
-
-.labelBox {
-  stroke: $labelBoxBorderColor;
-  fill: $labelBoxBkgColor;
-}
-
-.labelText {
-  fill: $labelTextColor;
-  stroke: none;
-}
-
-.loopText {
-  fill: $labelTextColor;
-  stroke: none;
-}
-
-.loopLine {
-  stroke-width: 2;
-  stroke-dasharray: '2 2';
-  marker-end: 'url(#arrowhead)';
-  stroke: $labelBoxBorderColor;
-}
-
-.note {
-  //stroke: #decc93;
-  stroke: $noteBorderColor;
-  fill: $noteBkgColor;
-}
-
-.noteText {
-  fill: black;
-  stroke: none;
-  font-family: 'trebuchet ms', verdana, arial;
-  font-size: 14px;
-}
diff --git a/_submodules/mermaid/src/utils.js b/_submodules/mermaid/src/utils.js
deleted file mode 100644
index a18bed14a61f89aef49dc423976d83cc0dfa59bf..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/utils.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import * as d3 from 'd3'
-
-/**
- * @function detectType
- * Detects the type of the graph text.
- * ```mermaid
- * graph LR
- *  a-->b
- *  b-->c
- *  c-->d
- *  d-->e
- *  e-->f
- *  f-->g
- *  g-->h
- * ```
- *
- * @param {string} text The text defining the graph
- * @returns {string} A graph definition key
- */
-export const detectType = function (text) {
-  text = text.replace(/^\s*%%.*\n/g, '\n')
-  if (text.match(/^\s*sequenceDiagram/)) {
-    return 'sequence'
-  }
-
-  if (text.match(/^\s*gantt/)) {
-    return 'gantt'
-  }
-
-  if (text.match(/^\s*classDiagram/)) {
-    return 'class'
-  }
-
-  if (text.match(/^\s*gitGraph/)) {
-    return 'git'
-  }
-  return 'flowchart'
-}
-
-/**
- * @function isSubstringInArray
- * Detects whether a substring in present in a given array
- * @param {string} str The substring to detect
- * @param {array} arr The array to search
- * @returns {number} the array index containing the substring or -1 if not present
- **/
-export const isSubstringInArray = function (str, arr) {
-  for (let i = 0; i < arr.length; i++) {
-    if (arr[i].match(str)) return i
-  }
-  return -1
-}
-
-export const interpolateToCurve = (interpolate, defaultCurve) => {
-  if (!interpolate) {
-    return defaultCurve
-  }
-  const curveName = `curve${interpolate.charAt(0).toUpperCase() + interpolate.slice(1)}`
-  return d3[curveName] || defaultCurve
-}
-
-export default {
-  detectType,
-  isSubstringInArray,
-  interpolateToCurve
-}
diff --git a/_submodules/mermaid/src/utils.spec.js b/_submodules/mermaid/src/utils.spec.js
deleted file mode 100644
index 43341fb6d116b0a8f9af03ee6a3b33b9964c1d59..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/src/utils.spec.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* eslint-env jasmine */
-import utils from './utils'
-
-describe('when detecting chart type ', function () {
-  it('should handle a graph defintion', function () {
-    const str = 'graph TB\nbfs1:queue'
-    const type = utils.detectType(str)
-    expect(type).toBe('flowchart')
-  })
-  it('should handle a graph defintion with leading spaces', function () {
-    const str = '    graph TB\nbfs1:queue'
-    const type = utils.detectType(str)
-    expect(type).toBe('flowchart')
-  })
-
-  it('should handle a graph defintion with leading spaces and newline', function () {
-    const str = '  \n  graph TB\nbfs1:queue'
-    const type = utils.detectType(str)
-    expect(type).toBe('flowchart')
-  })
-  it('should handle a graph defintion for gitGraph', function () {
-    const str = '  \n  gitGraph TB:\nbfs1:queue'
-    const type = utils.detectType(str)
-    expect(type).toBe('git')
-  })
-})
-
-describe('when finding substring in array ', function () {
-  it('should return the array index that contains the substring', function () {
-    const arr = ['stroke:val1', 'fill:val2']
-    const result = utils.isSubstringInArray('fill', arr)
-    expect(result).toEqual(1)
-  })
-  it('should return -1 if the substring is not found in the array', function () {
-    const arr = ['stroke:val1', 'stroke-width:val2']
-    const result = utils.isSubstringInArray('fill', arr)
-    expect(result).toEqual(-1)
-  })
-})
diff --git a/_submodules/mermaid/todo.md b/_submodules/mermaid/todo.md
deleted file mode 100644
index 615856d5a1626e59b1974b30ef2d904717e9fa93..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/todo.md
+++ /dev/null
@@ -1,4 +0,0 @@
-- Get familar with jison
-- git graph requires a blank line at the end. why?
-- Create a desktop client
-- Do the rendering in an iframe to avoid global CSS to affect rendering.
diff --git a/_submodules/mermaid/webpack.config.babel.js b/_submodules/mermaid/webpack.config.babel.js
deleted file mode 100644
index 73faab7840d7fcfa6826a556c55aa9319c270c60..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/webpack.config.babel.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import nodeExternals from 'webpack-node-externals'
-
-import { jsConfig } from './webpack.config.base'
-
-const config = jsConfig()
-
-const coreConfig = jsConfig()
-coreConfig.externals = [nodeExternals()]
-coreConfig.output.filename = '[name].core.js'
-
-export default [config, coreConfig]
diff --git a/_submodules/mermaid/webpack.config.base.js b/_submodules/mermaid/webpack.config.base.js
deleted file mode 100644
index 727880fd64d4c649df1bb8bd6b3ac0b4aff3663f..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/webpack.config.base.js
+++ /dev/null
@@ -1,48 +0,0 @@
-import path from 'path'
-
-const amdRule = {
-  parser: {
-    amd: false // https://github.com/lodash/lodash/issues/3052
-  }
-}
-
-const jsRule = {
-  test: /\.js$/,
-  exclude: /node_modules/,
-  use: {
-    loader: 'babel-loader'
-  }
-}
-
-const scssRule = { // load scss to string
-  test: /\.scss$/,
-  use: [
-    { loader: 'css-to-string-loader' },
-    { loader: 'css-loader' },
-    { loader: 'sass-loader' }
-  ]
-}
-
-export const jsConfig = () => {
-  return {
-    mode: 'development',
-    target: 'web',
-    entry: {
-      mermaid: './src/mermaid.js'
-    },
-    node: {
-      fs: 'empty' // jison generated code requires 'fs'
-    },
-    output: {
-      path: path.join(__dirname, './dist/'),
-      filename: '[name].js',
-      library: 'mermaid',
-      libraryTarget: 'umd',
-      libraryExport: 'default'
-    },
-    module: {
-      rules: [amdRule, jsRule, scssRule]
-    },
-    devtool: 'source-map'
-  }
-}
diff --git a/_submodules/mermaid/webpack.config.prod.babel.js b/_submodules/mermaid/webpack.config.prod.babel.js
deleted file mode 100644
index 9ae00d575982af91b85916bc0c9a73df49bf4d36..0000000000000000000000000000000000000000
--- a/_submodules/mermaid/webpack.config.prod.babel.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import { jsConfig } from './webpack.config.base'
-
-const minConfig = jsConfig()
-minConfig.mode = 'production'
-minConfig.output.filename = '[name].min.js'
-
-export default [minConfig]
diff --git a/assets/img/favicon.ico b/assets/img/favicon.ico
index ab8b4f414a5efddf26f976d9ce62347ade1d9567..3de0ab46720fce42c4729feab729cefe27aa7dcf 100644
Binary files a/assets/img/favicon.ico and b/assets/img/favicon.ico differ
diff --git a/assets/img/favicon.png b/assets/img/favicon.png
deleted file mode 100644
index 88dfa211eefa5809335386ac67d8ccf80bb9f132..0000000000000000000000000000000000000000
Binary files a/assets/img/favicon.png and /dev/null differ
diff --git a/assets/img/staff/bricker.jpg b/assets/img/staff/bricker.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..abe76467726d570ebe746fda39cc2f8f1b13cac9
Binary files /dev/null and b/assets/img/staff/bricker.jpg differ
diff --git a/assets/img/staff/cheung.jpg b/assets/img/staff/cheung.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4648b38f0ca813ddf9af8be7942c660f919049ac
Binary files /dev/null and b/assets/img/staff/cheung.jpg differ
diff --git a/assets/img/staff/tian.jpg b/assets/img/staff/tian.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a531ec3bb4af788679e53de05212e40e93a7de43
Binary files /dev/null and b/assets/img/staff/tian.jpg differ
diff --git a/assignments/accessibility-img/1.png b/assignments/accessibility-img/1.png
new file mode 100644
index 0000000000000000000000000000000000000000..3fe614231cd6230ba6a3b991586b395deb8c716f
Binary files /dev/null and b/assignments/accessibility-img/1.png differ
diff --git a/assignments/accessibility-img/androidview.png b/assignments/accessibility-img/androidview.png
new file mode 100644
index 0000000000000000000000000000000000000000..5c2a96411489346986a080ee71da78784200b448
Binary files /dev/null and b/assignments/accessibility-img/androidview.png differ
diff --git a/assignments/accessibility-img/avd.png b/assignments/accessibility-img/avd.png
new file mode 100644
index 0000000000000000000000000000000000000000..e05be3735ec7e19965d73551c612437f1a51b4bc
Binary files /dev/null and b/assignments/accessibility-img/avd.png differ
diff --git a/assignments/accessibility-img/mdnavigator1.png b/assignments/accessibility-img/mdnavigator1.png
new file mode 100644
index 0000000000000000000000000000000000000000..950525e2567ba10111a4f26a564fd0efeb6ad358
Binary files /dev/null and b/assignments/accessibility-img/mdnavigator1.png differ
diff --git a/assignments/accessibility-img/mdnavigator2.png b/assignments/accessibility-img/mdnavigator2.png
new file mode 100644
index 0000000000000000000000000000000000000000..4ab68f1b37bd4822de70d661c760c7953029fd0d
Binary files /dev/null and b/assignments/accessibility-img/mdnavigator2.png differ
diff --git a/assignments/accessibility-img/mdnavigator3.png b/assignments/accessibility-img/mdnavigator3.png
new file mode 100644
index 0000000000000000000000000000000000000000..8e2d0cac78c497137515a7c6b54c94f8f70c2e06
Binary files /dev/null and b/assignments/accessibility-img/mdnavigator3.png differ
diff --git a/assignments/accessibility-img/mdnavigator4.png b/assignments/accessibility-img/mdnavigator4.png
new file mode 100644
index 0000000000000000000000000000000000000000..1d4bbb09575e89bf589c6aed75c7ace4413d92ec
Binary files /dev/null and b/assignments/accessibility-img/mdnavigator4.png differ
diff --git a/assignments/accessibility-img/playstoreemulator.png b/assignments/accessibility-img/playstoreemulator.png
new file mode 100644
index 0000000000000000000000000000000000000000..d94e82b70f54006c3dbef22db91a64d19c2e111b
Binary files /dev/null and b/assignments/accessibility-img/playstoreemulator.png differ
diff --git a/assignments/accessibility-img/projectview.png b/assignments/accessibility-img/projectview.png
new file mode 100644
index 0000000000000000000000000000000000000000..79c64e5fa0e56b3b431e5f1e41e352c0ea8d4b73
Binary files /dev/null and b/assignments/accessibility-img/projectview.png differ
diff --git a/assignments/accessibility.md b/assignments/accessibility.md
new file mode 100644
index 0000000000000000000000000000000000000000..69630ce781f9f84a5a04346db6367370e91e3144
--- /dev/null
+++ b/assignments/accessibility.md
@@ -0,0 +1,232 @@
+---
+layout: assignment
+published: true
+
+title: Accessibility
+code: as3
+
+assigned: April 22, 2020
+due:
+ - <strong>Due</strong> April 30, 2020, 10:00pm
+ - <strong>Lock</strong> May 2, 2020, 10:00pm
+
+revised: 10:00 PM Tuesday, April 21st, 2020
+
+objective: Identify and repair app accessibility issues.
+
+android_goals:
+  - Basics of Android assistive tools
+hci_goals:
+  - Explore App accessibility
+  - Understanding the impact of different accessibility issues
+  - Simple repairs to accessibility issues
+  - Write up a report on accessiblity issues
+---
+
+* TOC
+{:toc}
+
+This assignment has two parts that are inter-related. Part 1 of this assignment involves finding
+all the accessibility problems in the code base for our toy camera app, a  and documenting them,
+while in Part 2 of the assignment you will fix these problems. It will be important to iterate on this find/fix cycles as
+fixing one problem may uncover new ones. You will use a number of tools to find these issues,
+including but not limited to the Google Accessibility Scanner and TalkBack. It will be important
+for you to experience the app through the use of a screen reader to find all of the problems
+a user might encounter.
+
+# GitGrade links
+
+**Classroom** [Summary](https://gitgrade.cs.washington.edu/student/summary/8723)
+
+**Links:** [Accept the Assignment](https://gitgrade.cs.washington.edu/student/assignment/122) / [Turn-in the Assignment](https://gitgrade.cs.washington.edu/student/assignment/122/turnin)
+
+# Part 1
+
+Tasks:
+- Learn different categories of app accessibility issues
+- Identify accessibility issues in our example app
+- Write a detailed report as a communication tool to developers who need to make the app accessible
+
+Accessibility is an important part of any app. Whether you are developing a new app or adding features
+to an existing one, it is important to consider the accessibility of your app's components.
+
+For some background you will want to do the following:
+
+- Start by watching this [quick video](https://youtu.be/1by5J7c5Vz4) to learn how visually-impaired
+users interact with Android applications. The video also offers some tips on ensuring your app is
+compatible with assistive tools.
+- Next read the list of errors that are found by Google's accessibility Scanner which is
+show in Table 2 on the 8th page of the PDF (which is numbered page 9) of
+[Epidemiology as a Framework for Large-Scale Mobile Application Accessibility Assessment](https://xiaoyizhang.me/assets/Paper/ASSETS_2017_Epidemiology.pdf).
+- Finally, because it is important to write succinct and yet descriptive alt text (content descriptions), you
+should read about [proper alt text writing](https://webaim.org/techniques/alttext/).
+
+For example, consider this view of the Layout Inspector of the layout app that we recently completed.
+(You will not be using your layout code for this assignment, we are using it for illustrative
+purposes here.) The selected image in the upper left of the screen does not have
+`contentDescription` property. **Google's Accessibility Scanner** will classify this as
+"Item Label" error (defined in the paper above), which will also mean a screen reader cannot
+read the alternative text of the image to people with visual impairments.
+
+![Screenshot of an image without contentDescription property in layout editor](accessibility-img/1.png){:width="500px"}
+
+The goal of Part 1 of the assignment is to identify **at least 10** accessibility issues in the app
+you will be given, **at least one** can't be found with the Accessibility Scanner. All of
+the issues listed in the ASSETS/Epidemiology paper may NOT be represented in the app, but you should be aware
+that they could be found in other apps. For your reference, we identified at least 12 errors in the app.
+
+## Setup
+In order to proceed you will need to setup your device and your Android Studio IDE.
+
+### Adding Markdown Viewing in Android Studio
+You will be writing your report in "Markdown." Markdown is a a text markup language that
+allows for simple formatting using plain text files. We have provided you with a `Part1.md` starter
+file that is in the root directory of your the repository you received when you accessed the
+assignment.
+
+You can edit your markdown file in any text editor, including Android Studio. We recommend you install
+the [Markdown Navigator](https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced) to help
+you preview your edits. (Click on the pictures to see a larger version)
+
+[![Screenshot of the first step of installing the markdown navigator](accessibility-img/mdnavigator1.png){:width="250px"}](accessibility-img/mdnavigator1.png)
+[![Screenshot of the second step of installing the markdown navigator](accessibility-img/mdnavigator2.png){:width="250px"}](accessibility-img/mdnavigator2.png)
+[![Screenshot of the third step of installing the markdown navigator](accessibility-img/mdnavigator3.png){:width="250px"}](accessibility-img/mdnavigator3.png)
+
+Once you have the Markdown Navigator installed, open up `Part1.md` and click the button pointed to
+by the arrow in the following image to bring up the Markdown Preview pane.
+
+![Screenshot preview pane of the Markdown navigator](accessibility-img/mdnavigator4.png){:width="500px"}
+
+### Installing Accessibility Scanner
+
+You must first install the Accessibility scanner on your Android Device or in your Emulator using the
+Google Play store. IMPORTANT: The Pixel 2 XL Emulator does NOT have the Google Play store on it,
+so you have to start by installing the Pixel 2 or other Emulator where you can also install the Play Store
+using the *Tools-&gt;AVD Manager*. The best way to determine if the Emulator has the Play Store
+is to look for the icon under the Play Store column in the AVD Manager.
+
+![Screenshot of the AVD Manager with an emulator that has the play store and one that does not](accessibility-img/avd.png){:width="300px"}
+
+To create another emulator, press the *Create Virtual Device* button, then find an emulator that has
+the Play Store icon in the Play Store column. Click Next and follow the instructions for the rest of the installation.
+
+![Creating a new device with the play store using the AVD Manager ](accessibility-img/playstoreemulator.png){:width="500px"}
+
+Note that you will have to specifically choose this new emulator (as opposed to the one you were
+using before) when you are running your application on the emulator through Android Studio.
+
+To install the Accessibility Scanner, search for it in the Play Store and install it on your device or emulator.
+The installation process will be the same for a physical phone or the emulator equipt with the Play Store.
+Follow the instructions on the
+[Getting started with Google Accessibility Scanner](https://support.google.com/accessibility/android/answer/6376570?hl=en&ref_topic=6376582)
+page to get the scanner working on your device.
+
+Another option is to install the Android Accessibility Suite which contains both the Accessibility
+Scanner and TalkBack if it has not been installed before.
+
+### Installing TalkBack
+
+You will need to have a good understanding of how to set up and use
+[Talkback](https://support.google.com/accessibility/android/answer/6283677?hl=en) one
+of the assistive tools built-in to you Android.  You may want to try using
+talk back on another application before you use it on the app you are given for this assignment.
+
+
+### Other Tools
+
+Another built-in assistive tool is [Switch Access](https://support.google.com/accessibility/android/answer/6122836?hl=en),
+which you may choose to set up and use.
+
+## Writing the report.
+
+Use the Accessibility Scanner, Talkback, and perhaps other tools to detect defects in our toy camera app.
+The Accessibility Scanner is decent with suggested fixes to problems it finds, however, some solutions
+are not obvious for each screen element type, so you will have to do some research to
+find all of the attributes that help to make an application more accessible. It may also help
+to use other tools (such as the Layout Inspector in Android) to help you track down the location
+of the issue the Accessibility tools find.
+
+As you find issues in the app, write them up in your report. Your report structure will contain
+two sections, an Overview in which you will describe your experience using assistive tools while testing the
+accessibility of the app before and after fixing issues, and a "table" of issues you found
+and how you fixed them. The outline of this report is given to you in `Part1.md` which remember is
+in the root directory of your the repository you received when you accessed the
+assignment. To open this file you can either use the _File-&gt;Open_ menu item, or change the _Android_
+drop down above the `app` folder to say _Project_ and double click on `Part1.md` from there.
+
+
+![Viewing the project as an android project you can't see Part1.md](accessibility-img/androidview.png){:width="200px"} &nbsp; &nbsp; 
+![Viewing the project as just a project you can see Part1.md](accessibility-img/projectview.png){:width="200px"}
+
+
+For each issue you identify within the app, document the following details:
+- The XML id of the item that needs to be fixed. If there is no id you can describe it briefly (~3 words)
+- The issue type as drawn from the list in ASSETS/Epidemiology paper.
+- The fix should provide a brief description (1 sentence or so) of what you did. If the fix involves
+changing or adding alt text, you should include the alt text you added for each inaccessible UI element in your
+fix description.
+- The file or files in which you fixed this issue
+- The line number(s) where you fixed this issue
+
+An example issue is shown in the `Part1.md` file. *Please* retain the two spaces at the end
+of every line so the line breaks will be maintained
+([examples](https://gist.github.com/shaunlebron/746476e6e7a4d698b373)). This will help the staff
+in grading your assignment.
+
+------ Sample Issue ------  
+*Id*: @+id/edit  
+*Issue*: Item Type Label contains unnecessary text  
+*Fix*: Remove the word "button" from the text description  
+*File*: string.xml  
+*Line number*: 11
+
+**Resources**
+
+- [Android Accessibility Overview](https://developer.android.com/guide/topics/ui/accessibility/)
+- [Android Accessibility Guides](https://developer.android.com/guide/topics/ui/accessibility/apps)
+- [Material Design: Assistive Technology](https://material.io/design/usability/accessibility.html#assistive-technology)
+
+
+# Part 2
+
+Tasks:
+
+- Repair accessibility issues you identified in part 1, including the sample issue
+
+For each issue that you identified in the app, please repair it by modifying code or XML layout file.
+You must also repair the sample issue that we have identified but not yet fixed in the code.
+For reference, in the sample solution we ran the app through the Accessibility Scanner and
+identified and fixed at least 12 issues (including the one we identified).
+
+For any repairs involving strings, please add a new entry for the fix into the strings.xml file,
+and then reference it (thereby retaining the old entry in the file). Recall that you can reference
+a string by changing the `contentDescription` property in the
+layout editor, or calling the equivalent method (`imageView.setContentDescription(...)`)
+
+All of these changes only require modifying existing XML attributes or adding new ones;
+or changing a line or two of code.
+
+# Turn-in
+
+## Submission Instructions
+
+You will turn in both Part 1 and Part 2 via GitGrade. The files you will need to include are:
+
+```
+- Part1.md
+- MainActivity.java
+- app_bar_main.xml
+- content_main.xml
+- nav_header_main.xml
+- strings.xml
+- colors.xml
+```
+
+## Grading (25pts)
+
+- Part 1
+  - Description of the experience using assistive tools to test the app (Accessibility Scanner, TalkBack etc.): 3 pts
+  - Correctly documents all 10 or more accessibility issues including location of the fix: 10 pts
+- Part 2
+  - Fixes the issues identified in part 1 by modifying / adding new attributes to the xml tags: 10 pts
+  - Updated content descriptions are correct per Webaim's guidelines: 2 pts
diff --git a/assignments/colorpicker-img/1.png b/assignments/colorpicker-img/1.png
new file mode 100644
index 0000000000000000000000000000000000000000..b34a0f5c049fd18795bbb93ab224100f1945d277
Binary files /dev/null and b/assignments/colorpicker-img/1.png differ
diff --git a/assignments/colorpicker-img/2.png b/assignments/colorpicker-img/2.png
new file mode 100644
index 0000000000000000000000000000000000000000..b5b03dcd14635f68272108dc4f05252c752a2946
Binary files /dev/null and b/assignments/colorpicker-img/2.png differ
diff --git a/assignments/colorpicker-img/Destroy_Activities.png b/assignments/colorpicker-img/Destroy_Activities.png
new file mode 100644
index 0000000000000000000000000000000000000000..d871eafc70fecd331b9554cfd7eab7dd6f6a8fed
Binary files /dev/null and b/assignments/colorpicker-img/Destroy_Activities.png differ
diff --git a/assignments/colorpicker-img/FSM.key b/assignments/colorpicker-img/FSM.key
new file mode 100755
index 0000000000000000000000000000000000000000..381251d8e1e958bf5d29e5b7175be232ce7969a5
Binary files /dev/null and b/assignments/colorpicker-img/FSM.key differ
diff --git a/assignments/colorpicker-img/doorlocked.jpg b/assignments/colorpicker-img/doorlocked.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..ef3df3e3168002966bde98ecce44e43ea12b7138
Binary files /dev/null and b/assignments/colorpicker-img/doorlocked.jpg differ
diff --git a/assignments/colorpicker-img/doorunlocked.jpg b/assignments/colorpicker-img/doorunlocked.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..26ef94f9ee783c460bcc1534003363465542af02
Binary files /dev/null and b/assignments/colorpicker-img/doorunlocked.jpg differ
diff --git a/assignments/colorpicker-img/fsm.png b/assignments/colorpicker-img/fsm.png
new file mode 100644
index 0000000000000000000000000000000000000000..e848395aea631596b14fbe7f51726da13aee70d4
Binary files /dev/null and b/assignments/colorpicker-img/fsm.png differ
diff --git a/assignments/colorpicker-img/logcat_diagram.png b/assignments/colorpicker-img/logcat_diagram.png
new file mode 100644
index 0000000000000000000000000000000000000000..e48b6b6f18bfac73a59b13a34f834aea1e689ec6
Binary files /dev/null and b/assignments/colorpicker-img/logcat_diagram.png differ
diff --git a/assignments/colorpicker-img/oven.mp4 b/assignments/colorpicker-img/oven.mp4
new file mode 100644
index 0000000000000000000000000000000000000000..5eb6c0f8a58e9f9b9ec31158405d20d9be8eae97
Binary files /dev/null and b/assignments/colorpicker-img/oven.mp4 differ
diff --git a/assignments/colorpicker-img/thumb_diagrams.jpg b/assignments/colorpicker-img/thumb_diagrams.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d4ff332324ad8475585b2649b8916f7c47153056
Binary files /dev/null and b/assignments/colorpicker-img/thumb_diagrams.jpg differ
diff --git a/assignments/colorpicker.md b/assignments/colorpicker.md
new file mode 100644
index 0000000000000000000000000000000000000000..2dee3c91f2b25d3b9bdb9b77228686e8d0ad6198
--- /dev/null
+++ b/assignments/colorpicker.md
@@ -0,0 +1,530 @@
+---
+layout: assignment
+published: true
+
+title: Color Picker
+code: as4
+
+assigned: May 1st, 2020
+due:
+ - <strong>Due</strong> May 11th, 2020, 10:00pm (including reflection)
+ - <strong>Lock</strong> May 13th, 2020, 10:00pm
+revised: 11:00pm Thursday,  April 30th, 2020
+
+objective: Create an RGB color picker which lets you choose a color on a rainbow circle (color wheel).
+
+android_goals:
+  - Understand Android event handling APIs
+  - Handle touch input properly
+  - Understand app lifecycle
+  - Save app state in Bundle
+hci_goals:
+  - Create non-rectangle interactor
+  - Propositional Production System
+  - Event handlers and event bubbling
+  - Callbacks
+---
+
+* TOC
+{:toc}
+
+# GitGrade links
+
+**Classroom** [Summary](https://gitgrade.cs.washington.edu/student/summary/8723)
+
+**ColorPicker:** [Accept the Assignment](https://gitgrade.cs.washington.edu/student/assignment/124) / [Turn-in the Assignment](https://gitgrade.cs.washington.edu/student/assignment/124/turnin)
+
+
+# Goal
+
+There are two parts to this assignment, creating an RGB color picker interactor which lets you choose a color on a rainbow circle (color wheel), then using it in an application.
+
+__Important definition__: The term `wheel` used throughout the spec refers to the dial **and** inner circle; it is the larger circle that contains all interface you will be drawing.
+
+The RGB color picker works as follows: There is a small white "thumb" that marks the color currently indicated on the dial (the outer rim of the color picker), and that indicated color is displayed in the inner circle of the color wheel. The user interacts with this thumb by pressing down on it, then rotating it around the wheel. While the thumb is moving it is 50% opaque, and it will return to 100% opaque as soon as the user lifts their pointer from the screen and a new color is selected.
+
+When the user has completed the selection of a new color using the RGB color picker interactor, the application will change the color displayed on the screen behind the wheel.
+
+A video of how this interactor works in the application can be found
+[here](https://courses.cs.washington.edu/courses/cse340/videos/colorpicker_su19.webm).
+
+
+You will play two developer roles in this assignment
+- You will be a __Component Developer__ as you implement the RBG Color Picker interactor.
+- You will be an __Interface Programmer__ as you use this new interactor in your App.
+
+## Component Developer Role
+Your primary goal in this assignment is to create
+`ColorPickerView.java`. This is your _custom interactor_ and it must
+be implemented so it can be used by any application. `ColorPickerView.java` inherits from
+`AbstractColorPickerView.java` which must remain **untouched**.
+
+Tasks for `ColorPickerView`
+
+- Handle different input events in `onTouchEvent`
+- Initialize properties during `onLayout`
+- Draw the rainbow colored wheel and thumb in `onDraw`
+- Save/restore view state locally
+
+## Interface Programmer Role
+
+You will also edit `MainActivity.java`. This is your
+_application_ which will _use_ your custom color picker interactor. `MainActivity`
+inherits from `AbstractMainActivity` which must remain **untouched**.
+
+Tasks for `MainActivity`
+
+- Register callbacks
+- Save application state in bundle
+- Restore activity state from bundle
+
+You will be turning in  `ColorPickerView.java` and `MainActivity.java` so make sure that any variables/fields you create/modify are in these files. **Do NOT modify any other files in this project.**
+
+<span style="color:red">Note: We will be asking you to re-use your color picker (`ColorPickerView`
+which inherits from `AbstractColorPickerView`) in a later assignment so it is important that you understand
+how the custom interactor communicates with an application.</span>
+
+# Getting Started
+
+You will be editing `ColorPickerView.java` and `MainActivity.java`. As such it is important to understand the inheritance chains of these two files, as you will be using **a lot** of variables and functions defined in parent classes.
+
+**Read the abstract base classes, including all of the comments in `AbstractColorPicker.java` and `AbstractMainActivity.java` before you begin**. Where applicable, you **must** use the inherited variables and functions (do not overload the inherited functions).
+
+The structure of the code is represented by the
+[Unified Modeling Language](https://en.wikipedia.org/wiki/Unified_Modeling_Language) (UML)
+diagram shown below. The symbols can be read as follows: + is a public field or method, #
+is protected, and - is private. Any method that is in _italics_ is an abstract method, meaning
+is must be overridden in the child class.
+
+<div class="mermaid">
+classDiagram
+  AppCompatActivity <|-- AbstractMainActivity
+  AbstractMainActivity <|-- MainActivity
+  AppCompatImageView <|-- AbstractColorPickerView
+  AbstractColorPickerView <|-- ColorPickerView
+  class AbstractMainActivity{
+    #ColorPicker mColorPicker
+    +colorToString()
+    #setStartingColor()*
+  }
+  class MainActivity{
+    -mColorView
+    -mLabelView
+    +onColorSelected()
+    #setStartingColor()
+    +onSaveInstanceState()
+    +onRestoreInstanceState()
+  }
+  class AbstractColorPickerView{
+    +DEFAULT_COLOR
+    +RADIUS_TO_THUMB_RATIO
+    #mCenterX
+    #mCenterY
+    #mRadius
+    #mState
+    -mColorChangeListeners
+    +setColor()*
+    +addColorChangeListener()
+    +removeColorChangeListener()
+    #invokeColorChangeListeners()
+    #essentialGeometry()*
+    #getTouchAngle()
+    +getColorFromAngle()
+  }
+  class ColorPickerView{
+    #mCurrentColor
+    +setColor()
+    -updateModel()
+    +onDraw()
+    +onLayout()
+    #essentialGeometry()
+    +onTouchEvent()
+    +getAngleFromColor()
+  }
+
+</div>
+
+
+_Related Readings_:
+It will be helpful to read
+[Android/Custom-Drawing](https://developer.android.com/training/custom-views/custom-drawing)
+and
+[Android/UI-Events](https://developer.android.com/guide/topics/ui/ui-events)
+to understand parts of the assignment that seem tricky.
+
+# Part 1: Creating your interactor
+
+Implementing your color picker interactor will require you to support input handling, maintaining and mutating state, and drawing to the screen in `ColorPickerView.java`.
+
+## Drawing
+
+Drawing is implemented in `ColorPickerView#onDraw(Canvas)`. You will need to draw the thumb and the color in the center of the circle. We provide a color
+dial in the drawable folder and it is already being drawn by `AbstractColorPickerView#onDraw(Canvas)`
+which is called because `ColorPickerView` inherits from `AbstractColorPickerView`.
+
+The height and width of the of the dial determined by the bounding box of the `ColorPickerView`. The
+the radius of the actual ColorPicker interactor is the half the smaller of the width or the height of that
+that bounding box.
+
+![Screenshot of color picker, original](colorpicker-img/1.png){:width="49%"}
+![Screenshot of color picker, after moving to a new color](colorpicker-img/2.png){:width="49%"}
+
+### Important Variables
+
+- Some parts of your drawing code will require you to know the size of the view you are drawing in.
+The protected variables `mRadius` (the radius of both dial and inner circle), `mCenterX`, and `mCenterY`
+in  `AbstractColorPickerView.java` must be calculated in your `onLayout` method.
+- The ColorPicker displays the last selected color on the wheel when it is made visible on the screen.
+The ColorPicker saves its internal state in the ColorPicker model which, for the purposes
+of this assignment, is stored in the protected `mCurrentColor` variable accessible through the
+public `setColor` method. The ColorPicker interactor will need to be redrawn when the model changes.
+
+_Related APIs_:
+[View#onLayout](<https://developer.android.com/reference/android/view/View.html#onLayout(boolean,%20int,%20int,%20int,%20int)>)
+
+### Thumb
+
+In the screenshots above there is a visible thumb (the white circle) that marks the selected color
+on the dial. The thumb is drawn in `ColorPickerView#onDraw(Canvas)`. It must move around as a user
+interacts with the color picker.
+
+The thumb must be constrained to move along a circular track that places it within the dial. It must move along that track even when the user is dragging their finger inside the inner circle.
+
+Visually, the thumb's radius is `0.085` times the outer-radius of the dial (center of circle to outside edge of color). This value is provided to you as a constant in `AbstractColorPickerView`. Positioning the thumb is similar to `AbstractColorPickerView#getTouchAngle(float, float)` but instead of finding the angle based on the thumb location, you're finding the thumb location based on the angle, additionally constraining the thumb to stay within the color band.
+
+The PPS specification (found below) uses a float [0,1] to represent alpha, but Paint expects an int
+[0, 255]. Be sure to make the correct conversion (multiply by 255, then cast the result to `int`).
+
+### Center Circle
+
+Inside the multi-color dial is a circle whose color is the same as the live selected color.
+It must be centered on the center of the wheel, and use up all available space up to the dial.
+The color of the inner circle, which represents the RGB Color Picker model, must update while you
+drag the thumb. In contrast, the colored box and text, which represent the application’s model
+(remember the Model View Controller (MVC)), must update only when the mouse is released.
+
+## Touch Input Events
+
+<div class="mermaid">
+graph LR
+S((.)) --> A((Start))
+A -- "Press:insideWheel? A" --> I((Inside))
+I -- "Release:B" --> E[End]
+I -- "Drag:insideWheel? C" --> I
+I -- "Drag:outsideWheel? D" --> I
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+class S invisible
+class A start
+class E finish
+class I normal
+
+</div>
+
+Where
+- A is updateModel();invalidate()
+- B is invokeColorChangeListeners();invalidate()
+- C is updateModel();invalidate()
+- D is doNothing()
+
+Note that the End state only exists to show the lifetime of a _single_ interaction. Because the user can interact with the color picker any number of times, we would actually return to the Start state when the thumb is released. For some examples of single interactions, see the images below.
+
+We'll handle touch input by implementing `ColorPickerView#onTouchEvent(MotionEvent)`. This is the event handler that will be called when a touch occurs in this view. Feedback is needed when the user is interacting with the color picker, so you will have to ensure that the view is _redrawn_. Recall that we want to use `invalidate()` to do this and even though `invalidate()` does not directly trigger redraws and may have no impact, you still do not want to call it more than needed. In other words, it is considered good code quality to only call `invalidate()` when necessary.
+In fact we **will be taking off points** for unnecessary `invalidate()` calls. Follow the PPS spec and don't call aything it doesn't specify. You should never need to call `onDraw()`.
+
+As you write the PPS, make sure to utilize proper coding style to ensure that the code is readable to someone not familiar with the project. For an example of how to translate PPS into code, see the [PPS page]({{site.baseurl}}/docs/pps).
+
+_Related APIs_:
+[View](https://developer.android.com/reference/android/view/View) (see documentation on Drawing)
+
+![Diagrams of single interactions](colorpicker-img/thumb_diagrams.jpg)
+
+### Transitioning out of the Start State
+
+As shown in the state diagram, when in the Start state (before interaction begins), we ignore any touches that are outside of the wheel. These events must be _rejected_ by your `ColorPickerView` so that other interactors can use them if they want. Specifically, views that may lie underneath our `ColorPickerView` must be able to react to events outside the wheel, but within the square of the `ColorPickerView`. Only transition out of the start state when the user presses on or inside the wheel. When you transition out of the start state, color is updated, thumb transparency is changed (alpha becomes `0.5f`), and thumb position is updated.
+
+The starter code already has some built-in functionality to help you test whether or not you are
+correctly rejecting input. When you click outside the wheel, there will be a Toast (a pop up message)
+that says "You have clicked outside the wheel!". If this message does not appear when you
+click outside the wheel, then you are not correctly rejecting input.
+
+### Transitions within the Inside State
+
+Once interaction with the wheel begins, you must only update the ColorPickerView's local model
+when the user is dragging their finger inside the wheel.
+
+- When a finger drags on screen inside the wheel, the thumb will follow the angle the finger is at,
+and the color of the center circle will update to reflect the change in the local model for the Color Picker.
+- When a finger drags on screen outside the wheel, the thumb will stay at the most recent angle
+within the wheel. If the finger re-enters the wheel at a different angle, the thumb must jump to
+that angle and the color within the wheel must display the corresponding color.
+
+Use the `x` and `y` coordinates of the touch event to calculate the angle (in radians) of the touch
+on the wheel with `AbstractColorPickerView#getTouchAngle(float, float)`. It is difficult to do this
+mapping in traditional RGB color space. The HSV color space discussed during class fits this task well.
+You can read more about the HSV color space [here](https://en.wikipedia.org/wiki/HSL_and_HSV). Since
+we're just adjusting color, we only want to modify hue while leaving saturation and value constant.
+You may see detailed instruction in code comments under `AbstractColorPickerView#getColorFromAngle(double)`,
+ which we provide you. Use this implementation to guide your work on `ColorPickerView#getAngleFromColor(int)`, which does the opposite operation.
+
+Notice that our color dial is rotated `90°` from just the hue value converted to radians - our
+red color is at the top, but in the HSV model, the red color is to the right. This adjustment is
+applied in `AbstractColorPickerView#getColorFromAngle(double)`. You will also have to apply this
+ when implementing `ColorPickerView#getAngleFromColor(int)`. For information about why colors are
+ being stored as `int` values, see the [Misc.](#misc) section below.
+
+Here are some test values to help test your implementation of `ColorPickerView#getAngleFromColor(int)`:
+- angle: 2.5769272, color: -16774401 (blue)
+- angle: -1.5461564, color: -64000 (red)
+- angle: 0.42093232, color: -15073536 (green)
+
+### Transition to the end state.
+
+When the user finishes interacting with the wheel, you must update the UI to reflect the new selected color, by calling the `onColorSelected` method in the `ColorChangeListener` with our newly selected color. In addition, the thumb transparency must be reset to an alpha of `1f` (fully opaque).
+
+### Essential Geometry
+
+When a motion event occurs, we must change the coordinates into the form consumed by the state
+machine queries. The `essentialGeometry` method translates these coordinates into an ENUM which
+represents whether or not the motion event was inside of the dial. This is important because the
+state machine only relies on whether or not the motion event is within the color wheel and
+must not be interpreting "raw" coordinates.
+
+_Related APIs_:
+[MotionEvent](https://developer.android.com/reference/android/view/MotionEvent) / [Color](https://developer.android.com/reference/android/graphics/Color) / [ColorUtils](https://developer.android.com/reference/android/support/v4/graphics/ColorUtils) / [View#onTouchEvent](<https://developer.android.com/reference/android/view/View.html#onTouchEvent(android.view.MotionEvent)>) / [EssentialGeometry](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)
+
+# Part 2: Implementing the application layer
+
+Your application is to make use of your color picker. The application needs to be notified from the `ColorPickerView` when the color changes. In our case, it will use the information to display the newly chosen color in a rectangle at the bottom of the screen and update the application model, though other applications might do something different. Examples of other applications that use their own implementation of a color picker include Photoshop, MS Paint, etc.
+
+## Setting up the Application
+
+The code you will write for the application is in `MainActivity` which inherits from `AbstractMainActivity`. An important variable stored in `AbstractMainActivity` is the `ColorPickerView` named `colorPicker`.
+
+The application layer must set the default color of `colorPicker` using
+`MainActivity#setStartingColor(int)`. We provide this default as `AbstractColorPickerView.DEFAULT_VALUE`
+(it's red). `MainActivity#setStartingColor(int)` must also trigger `onColorSelected` to
+ensure that the default color value is shown on the screen.
+
+## Managing Application State with Listeners
+
+To find out about color changes, the application needs to register a callback by calling
+`AbstractColorPickerView.addColorListener(ColorChangeListener)`. This callback
+must update the application's `colorView` and `colorTextView` whenever `onColorSelected`
+is called to demonstrate that the application correctly retrieved a color from `colorPickerView`.
+This means you are **prohibited** from leveraging publicly accessible
+fields/functions on the color picker to observe the `ColorPickerView` state.
+
+As good practice, you should always unregister listeners when they are no longer relevant. This must
+done in `MainActivity.java#onDestroy()` which is called when the application is killed.
+
+You may notice that `AbstractColorPickerView.java` keeps a `List` of `ColorChangeListeners`. This allows for our interactor to be more flexible because it can register many listeners that will all be notified when a new color is selected. For more on custom listeners, see [CodePath's guide to creating custom listeners](https://guides.codepath.com/android/Creating-Custom-Listeners). For more information about Fragments, see the [Android Fragment API](https://developer.android.com/guide/components/fragments).
+
+# Part 3: Save and Restore Application Model using Bundle
+
+You are to also save application model (i.e. the current color as known by the application) in the
+`onSaveInstanceState` bundle object. When user switches focus to some other app, Android kills our Activity.
+We will use the bundle to get the saved state back.
+
+We want to manage the state at the application level (`MainActivity.java`) versus at the interactor level. Thus you will need to set the state of the color picker in the application layer when the bundle is loaded.
+
+Notice from the documentation that `onRestoreInstanceState` is called after `onCreate` if a bundle
+exists. This is where you will access the information we saved in `onSaveInstanceState` to restore
+the current color with the color we had before our Activity was killed.
+
+<span style="color:red">We will kill your application during our testing process to ensure the state
+is properly saved. To simulate our tests, you can use the adb to test killing it, or in your phone's Developer options set Apps -> Don't keep activity.</span>
+
+![Clicking 'Don't Keep Activites' Android Developer Settings, 50%](colorpicker-img/Destroy_Activities.png){:width="30%"}
+
+If you do not already have developer options enabled follow the guide [here.]({{site.baseurl}}/docs/dev_mode)
+
+
+
+## Wheel default state and bundle interaction
+
+The best way to test this functionality is to enable the setting referenced above, and then press
+home, then return to the app. The color that was selected when you killed the app should still be
+restored when the app is restarted. **Quitting the app from multitasking (i.e. when the app is open,
+click on the square) will destroy the bundle.** Steps to test this is working correctly are as follows:
+
+Using the bundle:
+
+1. User opens app for first time. The wheel is invisible and color in the box is red (the default).
+2. User clicks on box to show wheel and changes color to blue.
+3. User leaves app (via home button) while wheel is still visible.
+4. User returns to app. The color in the box is blue and the wheel is invisible.
+5. User clicks in the color box and the wheel becomes visible with blue as the selected color.
+
+No bundle exists when app is unloaded:
+
+1. User opens app for first time. The wheel is invisible and color in the box is red (the default).
+2. User clicks on box to show wheel and changes color to blue.
+3. User leaves app (via home button).
+4. User unloads the app completely from memory.  
+5. User returns to app. The color in the box is red and the wheel is not visible. Clicking
+on the color box brings up the Color Picker with red as the selected color.
+
+Note that you do not have to do anything to handle the logic for displaying the wheel.
+The wheel is invisible by default when the activity is created,
+and its visible/invisible state is NOT stored in the bundle.
+
+
+
+_Related APIs_:
+[Saving and Restoring State](https://developer.android.com/guide/components/activities/activity-lifecycle.html#saras)
+| [Android Developer Options](https://developer.android.com/studio/debug/dev-options) | [Explanations for how to use Bundle](https://stackoverflow.com/questions/6525698/how-to-use-onsavedinstancestate-example-please)
+
+# Part 4: Reflection
+
+For this part, you will submit your reflection on this assignment to Gradescope. Create a MS Word, Google or other type of document and copy the following questions (in italics below) into that document. Add your responses below each question. You can have more than one answer per page, but if you can, please try to avoid page breaks in the middle of a question. Insert page breaks between questions as needed.
+
+- _The ColorPicker app as it is written is not accessible._
+  - _Without actually running the
+Accessibility Scanner, describe at least two issues that you think you would find with that tool.
+Why would these issues be an impediment to some users? How would you fix them?_
+  - _After you responded to the above, run accessibility scanner. Were you surprised by any of
+  the results?_
+
+- _The GE Oven/Microwave combo has a REALLY annoying knob for changing the time on a timer. You can see
+a [video](colorpicker-img/oven.mp4) of how this works in action but the gist is this:_  
+  _1. Start: Timer mode has been selected and your cursor is on the Minutes/Seconds menu item_
+  _2. Press the rotating dial button (hopefully not rotating at the same time, which will switch you back to Hours/Minutes mode) to
+  switch to "change minutes" mode._  
+  _3. Rotate the dial clockwise to add a minute._  
+  _4. Rotate the dial counter clockwise to subtract a minute._  
+  _5. Press the button to switch to "change seconds" mode._  
+  _6. Rotate the dial clockwise to add a second._  
+  _7. Rotate the dial counter clockwise to subtract a second._  
+  _8. Press the button to "end" the setting and start the timer._  
+
+  _Draw the PPS for this interactor. To help you with this problem you can use the following:_
+
+  - _EssentialGeometry: Clockwise, Counterclockwise_
+  - _The following events: Press, Rotate_
+  - _And the following methods or actions: `initTimer()`, `subMinute()`, `addMinute()`
+   `switchToSeconds()`, `addSecond()`, `subSecond()`, `startTimer()`_
+
+- _On our side, we've learned a lot about ourselves by quickly trying to transition this course
+online and at a distance. What do you think you are learning about yourself and your study habits so far this quarter?"_
+
+
+
+
+# Debugging tips and tricks
+
+Logging output is especially useful for testing the functionality of sections of code such as `getAngleFromColor` and other methods. Much like `System.out.print` in Java, Android provides its own class for producing output: `Log`. We suggest that you use `Log.i` and create your own custom tag so that you can filter the output for the information you want. Below is an example of how to use the `Log.i` function.
+
+```java
+private static final String TAG = "ColorPicker MainActivity";
+
+Log.i(TAG, "Hello world!");
+```
+
+To make full use of Logcat, make sure to configure the priority level (in this case, the "i" in `Log.i` stands for "Info") and use the correct tag (in this case, "ColorPicker MainActivity"). It's also good to check that you have the correct device/emulator selected.
+
+__Note__: Remember to take your `Log.i` debugging calls out of your code before turning it in.
+
+![Logcat diagram](colorpicker-img/logcat_diagram.png)
+
+_Related APIs_:
+[Android Log.\*](https://developer.android.com/reference/android/util/Log.html) | [Using Logcat](https://developer.android.com/studio/debug/am-logcat)
+
+# Misc.
+
+
+This assignment does require doing some math, and you are welcome to use the Java Math functions.
+**Hint:** Remember that the `y` direction is positive pointing down the canvas, not pointing up
+like a traditional cartesian coordinate system. This may impact the
+values returned from trigonometric functions.
+
+_Related APIs_:
+[Java Math.\*](https://docs.oracle.com/javase/7/docs/api/java/lang/Math.html)
+
+## Integer representations of RGB colors
+
+Colors on computer screens are often thought of as R, G, B, (and alpha) values ranging from 0 to 255, using
+hexidecimal representations (`#00` to `#FF`) of those numbers for each value. For example the
+hexidecimal representation of the color #FF0410 would be
+
+FF <- red value = 255 in decimal  
+04 <- green value = 4 in decimal  
+10 <- blue value  =  16 in decimal  
+
+But the real `int` representation of this RGB  value is
+
+`255 * 256 ^ 2 + 04 * 256 + 16 * 1` = 16712720.
+
+
+
+# Turn-in
+
+## Submission Instructions
+
+### Part 1-3:
+
+Remember to continually commit your changes to Gitlab (`git add`/`git commit`/`git push`), and then turn in your code using the GitGrade link at the top of this page.
+
+Note: we will ONLY be using your code in the following files:
+
+```
+ - ColorPickerView.java
+ - MainActivity.java
+```
+
+### Part 4:
+
+You are to turn in Part 4 to Gradescope.
+
+## Grading (40pts)
+
+### Code (31 pts)
+
+This code portion of this homework will be out of 31 points and will roughly (subject to small adjustments) be distributed as:
+
+- Code quality(4 pts)
+  - Code compiles and runs
+  - Does not re-write helper methods in stub code
+  - Does not duplicate inherited instance variables
+  - Utilizes callback and MVC correctly
+- Event Handling (`onTouchEvent`, etc) : (9 pts)
+  - Correctly determines essential geometry
+  - Implement PPS properly
+  - Implements circular interaction properly
+- Feedback (onDraw)  (6pts)
+- Responds to callback in Application (3 pts)
+- Layout Management (2 pts)
+- View Model Management (2 pts)
+- Correctly calls `invalidate` when `setColor` is called (1pt)
+- Correctly update model in the view whenever internal state changes (1 pt)
+- Application model management (2 pts)
+- Application/View Resilience (3 pts)
+
+### Reflection (9pts)
+
+For this part, you will submit your reflection on this assignment to Gradescope. Create a MS Word,
+Google or other type of document and copy the following questions (in italics below) into that document.
+Add your responses below each question. You can have more than one answer per page, but if you can,
+please try to avoid page breaks in the middle of a question. Insert page breaks between questions as needed.
+
+Each of the 3 reflection questions is worth 3 points. Remember that the grading for these reflection
+questions is based on the following rubric:
+
+- Student gives at least a minimum answer to all parts of the guiding question.
+- Clear/concise but descriptive examples are given throughout the response. An uninformed reader
+can create a mental picture of the situation being described. Abstract concepts are explained accurately.
+- Student elaborates on the significance and meaning of the examples; why they are important.
+- Occasionally a student will be given extra credit for an particularly insightful reflection.
+
+## IDE Errors/Warnings you can ignore
+
+<span style="color:red;">**NOTE:**</span> An error/warning that can be ignored for this assignment **cannot** be ignored for every assignment. Check IDE notices against specs on per assignment basis.
+
+- `onTouchEvent`
+  - Custom view ColorPickerView overrides `onTouchEvent` but not `performClick`
+- Anonymous Class Replaced with Lambda
+  - "anonymous new `AbstractColorPickerView.ColorListener()` can be replaced with lambda"
diff --git a/assignments/consent.md b/assignments/consent.md
new file mode 100644
index 0000000000000000000000000000000000000000..0d0ed84f2eb04c86327323c99608f8790b9fb91b
--- /dev/null
+++ b/assignments/consent.md
@@ -0,0 +1,42 @@
+---
+layout: default
+---
+
+# Consent Form for CSE340
+
+Contact information for person running study: _[Fill in]_
+
+# Introduction and Purpose of study (Beneficience)
+
+_[Fill in: Write 1-2 sentences about what this study is about]_
+
+# Requirements for participation (Respect for Persons)
+
+To participate in this study you must be _[Fill in: Requirements (only age:
+must be 18 or older)]_
+
+# Study procedures (Respect for Persons)
+You will complete a series of menu selections during this study. You
+will need to click on 108 menus to complete the session as
+mentioned above. You should expect this to take approximately _[Fill
+in: X Minutes]_
+
+_[Fill in: Tell the participant if they will be compensated or not]_
+
+# Voluntary nature of Study (Respect for Persons)
+Your participation is voluntary and you can stop at any time without
+penalty. Your decision not to participate will not have an impact on _[Fill
+in: What might be coercive to the participant]_
+
+# Benefits of Study (Beneficience)
+This study will not directly benefit you. However, it will help us to
+understand _[Fill in]_  
+
+# Contact (of IRB typically; Me in this case)
+If you have any concerns about this study, you can reach out to the
+Professor in charge, {{site.author.name}}, bricker [at] uw.edu
+
+# Written Consent
+
+To affirm your consent to participate in this study, please fill out the following form
+[https://bit.ly/20sp-Menus-Consent](https://bit.ly/20sp-Menus-Consent).
diff --git a/assignments/contextaware.md b/assignments/contextaware.md
new file mode 100644
index 0000000000000000000000000000000000000000..49ff953a608a897aa9601c6154c890a3a723d427
--- /dev/null
+++ b/assignments/contextaware.md
@@ -0,0 +1,161 @@
+---
+layout: assignment
+title: Context Awareness
+code: A3
+published: draft
+assigned: <!-- Tuesday, May 28, 2019 -->
+due: <!-- 11:59 PM Friday, June 7, 2019 -->
+revised: <!-- 9 pm Friday, June 8, 2019 -->
+
+objective: Build a context aware application.
+
+hci_goals:
+  - Create an app that uses implicit data
+  - Make a usable app as defined by the <a href="https://www.usability.gov/how-to-and-tools/methods/system-usability-scale.html">SUS
+    </a> when evaluated by a TA 
+  - Make an accessible app
+---
+
+- TOC
+{:toc}
+
+# Task for Assignment
+
+You have learned many things this quarter. Now is your chance to use
+  them to create something larger than any one assignment we did. In
+  this assignment, that could include an existing interface but must
+  *also* use context somehow.
+
+## Kinds of Context
+
+There are 3 kinds of context aware applications, which function in the
+following ways:
+- Attach context information for retrieval later (e.g., Leave a note
+  while at CSE; when come back to CSE the day after, user can see the
+  note again) 
+- Automatically execute things (e.g., Automatically suggest a new
+  navigation route when a driver exits from a wrong ramp.) 
+- Present info based on context (e.g., Send a notification of bus
+  schedule when user is at bus station) 
+
+You may build an utility app or game, and you should use at least two
+fences (**one of them must be location**). 
+
+If you want to start with an existing app, you could think about how
+  to extend the drawing app to be context aware. For example, you
+  could support loading of drawings based on location (you could store
+  them in the bundle and only provide access to drawings that were
+  created in the current location).  Or, you could
+  automatically undo the last action whenever the user runs, and redo
+  it when they walk and do nothing when they hold still. Finally, the
+  colors available could change depending upon what location you are
+  in (maybe purple is only available on the UW campus!). 
+
+# Important Assessment goals 
+We will be looking for whether you app is accessible and
+    usable. Although there isn't a simple scale available for
+    assessing context-aware applications, we have modified the
+     system usability scale (
+    [SUS](https://www.usability.gov/how-to-and-tools/methods/system-usability-scale.html))
+    as follows and will use it to assess your app (each rated from
+    Strongly Agree to Strongly Disagree on a 5 point scale)
+	
+1) I think that I would like to keep using this app.
+
+2) I found the system unnecessarily complex.
+
+3) I thought the system was easy to use.
+
+4) I found the use of implicit and explicit data in this app to be well integrated.
+
+5) I thought there was too much inconsistency in this system.
+
+6) I would imagine that most people would learn to use this system very quickly.
+
+7) I found the system very cumbersome to use.
+
+8) I felt very confident using the system.
+
+# Group Project
+This is a **group project**. We will assign you to groups to make sure
+every group has an android phone. 
+
+We will also assess the group experience as part of the grade.  This
+will be based on a survey at the end asking you to describe your
+contributions, your group members' contributions and mention any
+issues. We expect everyone to get full credit for this point, but will
+be using this to check for any problems.
+
+# Video
+The video for this project should be about 2 minutes long (+/- 30
+secs). It can be made with slides/photos + video clips for the
+visuals, and you can either use text (shown in the video) or spoken
+audio to provide the information listed below. It should
+have the following structure:
+
+## Opening slide
+Should use text, not voiceover for this.
+
+Title for the project 
+Names of team members
+
+## Story
+Brief (30 second) introduction to what you created. Should cover the
+following
+- What is the need (e.g. "Remembering not to be late for class")
+- Why is this hard (e.g. "I tend to sleep late")
+- What is the solution (e.g. "Calculate distance to class an hour
+  before class starts and set an alarm to go off with enough time to
+  walk there")
+  
+## Demonstration
+Pick 1-3 use scenarios and show clips of someone using the application
+with explanations
+
+## Credits
+End with credits saying who did what in the project
+
+# Turn-in
+Turn in your code, an apk file and a video.
+
+This video will serve as the demonstration
+for the modified SUS assessment. You can use captions or voice-over to
+explain your application. 
+
+## Submission Instructions
+
+You submit this assignment <a href="https://canvas.uw.edu/courses/1317447/assignments/4723261">on canvas</a>:
+
+- Files to turn in:
+  - `src.zip`: a ZIP file containing your source
+  - `video.mp4`: your video (other filetypes also work) unless using a
+    video hosting website such as YouTube
+  - `context.apk`: Your apk 
+- Then, make a comment on your submission with:
+  - A link to your repository. Make sure that we have access to it by
+    giving access to the `cse340` if visible to you, otherwise `rfrowe`
+  - Brief notes on anything you wish to tell us about your assignment
+    - These will be visible to all group members
+  - Link to your hosted video (unless you turned in a video file)
+
+- **In Addition**: *every* member of your group should fill
+out [this group participation survey](https://forms.gle/79xCgpa99nBXbq7W6)
+
+## Grading (5pts)
+
+- Part 1: App (3 pts)
+  - Use location and another sensor: 1pt
+  - App is context-aware: 1pt
+  - App is accessible: 1 pt
+  - You score well on the modified
+    [SUS](https://www.usability.gov/how-to-and-tools/methods/system-usability-scale.html)
+    when evaluated by a TA 
+- Group participation: 1pt 
+
+In peer grading survey,
+- We will ask what type of context is used
+- Ask if the app is enjoyable, in a Likert scale
+- Prompt to write a paragraph feedback
+
+Late policy: Since context uses half days, all group members must have
+at least 1/2 day left to get a free late day 
diff --git a/assignments/doodle.md b/assignments/doodle.md
index c3b2c8f1fe4ab01f16fb1dcc0ef4dd5405a65461..fed97d397f1399185972542b5379502c7ab6a0aa 100644
--- a/assignments/doodle.md
+++ b/assignments/doodle.md
@@ -3,14 +3,14 @@
 layout: assignment
 published: true
 
-title: Sample Assignment
+title: Doodle
 code: AS1
 
-assigned: Date Assigned
+assigned: Wednesday, April 1, 2020
 due:
 - <strong>Code</strong><br>
-  Due 10:00pm, Date<br>
-  Lock 10:00pm Date
+  Due 10:00pm, Thursday, April 9, 2020<br>
+  Lock 10:00pm Saturday, April 11, 2020
 - <strong>Peer evaluation</strong><br>
   Due 10:00PM Date
 - <strong>Reflection</strong><br>
@@ -18,23 +18,42 @@ due:
   Lock 10:00PM 12-Apr, 2021<br>
 revised: March 31, 2021
 
-objective: Objective
+objective: Create an Android app that draws a doodle consisting of a text, a line, and a set of images on the main canvas.
 
 hci_goals:
-  - Goal 1...
+  - Use abstractions to draw on screen
+  - Create animations
+  - Use coordinate transformation
+  - Try to create something appealing
 android_goals:
-  - Goal 2...
+  - Get familiar with Android Studio
+  - Understand XML and View
+  - Load image and drawable resources
+  - Learn Activity Lifecycle
 ---
 
 ## GitGrade Turn-in links
 
-- [Accept the Assignment](https://gitgrade.cs.washington.edu/student/assignment/xxx)
-- [Turn-in the Assignment](https://gitgrade.cs.washington.edu/student/assignment/xxx/turnin)
-- [Review your Submissions](https://gitgrade.cs.washington.edu/student/summary/xxx)
+- [Accept the Assignment](https://gitgrade.cs.washington.edu/student/assignment/116)
+- [Turn-in the Assignment](https://gitgrade.cs.washington.edu/student/assignment/116/turnin)
+- [Review your Submissions](https://gitgrade.cs.washington.edu/student/summary/8723)
 
 # Assignment Description
 
-For this assignment, you will be creating an activity class which will allow ....
+For this assignment, you will be creating an activity class which will allow you to create
+"Doodles" consisting of images, lines, and text.
+
+This assignment will take about 6 - 8 hours to complete. You should expect this amount of workload
+on most assignments this quarter, so make sure to build good habits when completing it.
+
+If you find yourself taking additional time on this submission, we strongly suggest that you
+get in touch with the course staff on Ed or in person.
+
+The assignment is broken into four parts
+- Part 1: Demonstrate that you can build an app in Android studio that includes images, text, lines and an animation.
+- Part 2: Create an interesting and creative Doodle of your own.
+- Part 3: Review three of your peers Doodles.
+- Part 4: Reflect on what you learned in the assignment and from the peer reviews you receive.
 
 * TOC
 {:toc}
@@ -44,11 +63,21 @@ For this assignment, you will be creating an activity class which will allow ...
 
 **Tasks**:
 
-* task1...
-* task2...
+* Get your development environment ready
+  * Download and install Android development environment and git if you do not already have it
+  * Accept the Doodle assignment from [Gitgrade](https://gitgrade.cs.washington.edu/student/assignment/116)
+  * Successfully clone our starter code to your computer
+* Open our skeleton code in Android Studio, read through and understand it
+* Implement three methods: `addImage`, `addText`, `addLine`
+* Call the methods you implemented and compare your app screen with our screenshot
+* Animate `UW` so it slides from left to right when the app opens.
 
 ## Prepping your development environment
 
+Instructions for downloading and installing the Android development environment are on our
+[schedule](../schedule) page and have been sent out through our Ed discussion platform.
+Please come to our first section or office hours if you are having any trouble with your machine set up.
+
 Use GitGrade to accept the assignment and receive the starter code. See the
 [instructions](../docs/gitgrade) for more details.  
 
@@ -58,35 +87,177 @@ We have provided you with the shell of an application which has the following cl
 
 <div class="mermaid" style="width:100%;">
 classDiagram
-  Aclass --> Bclass
-  Bclass --> Cclass
+  AppCompatActivity --> TabActivity
+  TabActivity --> Doodler
+  Doodler --> Part1
+  Part1 --> Part1Activity
+  Part1 --> Part2Activity
 
-  Dclass --> Eclass
+  View --> ImageView
+  View --> TextView
+  View --> LineView
 
-  class Dclass {
+  class Doodler {
     &lt;&lt;abstract&gt;&gt;
     +addImage()
     +addText()
     +addLine()
     +doodle()
   }
+  class Part1 {
+    +addImage()
+    +addText()
+    +addLine()
+  }
+  class LineView {
+    - endPoint
+    - brush
+  }
+
+  class Part1Activity {
+    +doodle()
+  }
 
-class Cclass {
+  class Part2Activity {
     +doodle()
   }
 
 </div>
 
 
-`Aclass` is an Android class that we subclassed in `Bclass` so we can...
+`AppCompatActivity` is an Android class that we subclassed in `TabActivity` so we can switch back and
+forth between your Part 1 and Part 2 code using the blue navigation bar at the bottom of the screen.
+You should not edit this part of the code but if you are curious, this tabbing functionality is
+controlled by the code in the `Part1Activity#onCreate(Bundle)` and `Part2Activity#onCreate(Bundle)` methods.
+We are using a View called BottomNavigationView that gives the functionality of a navigation bar -
+the switch statement in each of the `onCreate` methods tells the program when to show which activity.
+
+**Note:** The notation such as `Part1Activity#onCreate(Bundle)` is a common shortcut to demonstrate a specific
+method in a specific class (here the `onCreate` method which takes a `Bundle` as parameter
+in the `Part1Activity` class).
+
 
 ## Your Tasks...
 
+This task involves implementing three methods in `Part1.java`. Each method is named here but
+detailed doc comments can be found in `Part1`'s superclass, `Doodler`, which also defines some
+nice helper methods. It also defines the `onCreate` behavior of the Activity which calls the
+method `Doodler#doodle(FrameLayout)`.
+
+In `Part1`, you'll find missing implementations for three methods: `addImage`, `addText`, and `addLine`.
+
+Subclasses of `Part1` will have access to these methods once they are implemented. Take a look at
+an example of this in `Part1Activity`. It extends `Part1` and uses the three methods to
+draw the following image on the screen:
+
 ![A screenshot with a heart on it made up of smaller pictures. There's an "I" in the upper left and a "UW" in the middle left](doodle-img/screenshot_no_animation.png){:width="25%"}
 
+You'll notice in `doodle` in `Part1` that we use `scaleX` and `scaleY` around our coordinates
+(and size for images). These allow us to ensure the doodle still looks good on smaller screen sizes.
+**If you use _any_ pixel coordinates in your solutions, remember to wrap them in these scaling methods**.
+These will scale coordinates from the Pixel 2 XL to the dimensions of your device's screen.
+We'd recommend that you use a Pixel 2 XL emulator to compare the finished doodle against our
+screenshot to be sure you're implementing everything right.
+
+### Specification for addImage
+
+```java
+ImageView addImage(FrameLayout doodleView, String imageName, float x, float y, int size);
+```
+
+Most of this method is implemented for you. Please read through it to understand how it works,
+then try to set the size and location of ImageView added in this method. Critically, the images are
+going to be squished into a square, so only one `size` parameter is given.
+
+In order to implement this correctly you need to properly position the bounding box of the view:
+the `x` and `y` location relative to the parents are passed in as parameters and the `size` parameter
+is used for both the width and height. Setting the width and height will be done using the  
+`getLayoutParams()` and `setLayoutParams()`.
+
+If you implement it correctly, you'll see the image below if you run:
+
+```java
+addImage(doodleView, "food_3", scaleX(300), scaleY(300), scaleX(300));
+```
+
+![An image of a sushi bowl in the middle of the screen.](doodle-img/add_image_sample.png){:width="25%"}
+
+
+Remember that this is covered in section (😉).
+
+*Related APIs*:
+[ImageView](https://developer.android.com/reference/android/widget/ImageView.html)
+
+### Specification for addText
+
+```java
+TextView addText(FrameLayout doodleView, String text, float x, float y, int fontSize, int color);
+```
+This does not need to have it's bounding box adjusted.
+
+You may find the comments and the implementation of `addImage` useful. Make sure you are not
+editing the `xml`, `addText` is an abstracted function for adding text to a canvas, not
+specific to the contents in Part1. The font-family is the default one, no need to do anything
+special here.
+
+If you implement it correctly, you'll see the image below if you run:
+
+```java
+addText(doodleView, "CSE340", scaleX(550), scaleY(200), 60, Color.rgb(51,0,111));
+```
+
+![A purple text "CSE340" shows at the top right of the screenshot.](doodle-img/add_text_sample.png){:width="25%"}
+
+*Related APIs*: [TextView](https://developer.android.com/reference/android/widget/TextView.html)
+
+### Specification for addLine
+
+```java
+LineView addLine(FrameLayout doodleView, float startX, float startY, float endX, float endY,
+                int lineWidth, int color);
+```
+
+There are several ways to draw a line. The Android Code snippets blog has
+[a good example](https://android--code.blogspot.com/2015/11/android-how-to-draw-line-on-canvas.html).
+
+For this method, you will be using a class called `LineView` whose job is to draw a line onto the
+canvas. Parameters passed into `addLine` should also be passed into the `LineView` constructor to create a line
+of the appropriate color. You will be implementing both the constructor and `onDraw` methods in `LineView`.
+To this end, we have provided some blank stub code for you to
+fill in. Each `LineView` should draw a single line onto the canvas.
+
+By default, the size of the `LineView` will start out as the size of it's parent, i.e. the Canvas.
+In order to implement `addLine` correctly you need to adjust the size of this view (the bounding box)
+to be _ONLY_ from the from `startx`, `starty`, to `endx` and `endy`, and ensure that it is correctly
+located at `startx` `starty`. To do this you will use the method we discussed in
+class (`getLayoutParams()` and `setLayoutParams()` and `setX()` `setY()`).
+
+If you implement it correctly, you'll see the image below if you run:
+
+```java
+addLine(doodleView, scaleX(100), scaleY(250), scaleX(700), scaleY(1200), 15, Color.rgb(200,0,0));
+addLine(doodleView, scaleX(400), scaleY(1500), scaleX(250), scaleY(100), 20, Color.rgb(0,0,255));
+```
 
 ![A red line starts from top left to the center of the screenshot. A blue line also is present](doodle-img/add_line_sample.png){:width="25%"}
 
+**Updated Note for 2020:** You only have to handle lines that have a negative, 0, or infinite slope. In other words,
+you do not need to handle a line that draws from the lower left to upper right OR the upper right to the
+lower left.
+
+### Animating Text
+
+Once you've implemented the three methods defined above, your doodle should match. For the last part,
+ you will need to figure out how to animate text. In `Part1Activity#doodle(FrameLayout)`,
+ use animations to move the `TextView` variable `uw` from `(50f, 1650f)` to `(1050f, 1650f)`. Remember to apply
+ `scaleX` and `scaleY` to these animations. The animation should last `1000ms` (milliseconds not seconds).
+
+Once you've finished your animation, your doodle should match this screenshot:
+
+![A screenshot with a heart on it made up of smaller pictures. There's an "I" in the upper left and a "UW" in the middle right](doodle-img/screenshot.png){:width="25%"}
+
+A gif  of this animation is shown below but you can also see a higher resolution
+[.webm version](doodle-img/part1playback.webm) of this file as well.
 
 ![An animation with a heart on it made up of smaller pictures. There's an "I" in the upper left and a "UW" in the middle left](doodle-img/part1playback.gif){:width="25%"}
 
@@ -98,11 +269,165 @@ class Cclass {
 
 
 
+### Important note for Windows Users
+
+In the past we have had issues with the app crashing because of the
+line endings in the `.csv` file on Windows machines. When you
+clone the repository onto your Windows machine, all the line endings are automatically converted to
+carriage returns (`“\r\n”`) instead of the usual new line character (`“\n”`). This will prevent the
+`.csv` from being parsed correctly due to the regular expression (regex) we use. There are 2 ways to fix this:
+
+- Changing the line endings to “LF” in the bottom right hand corner of Android Studio
+(should initially say “CRLF”). See this animated [.gif](doodle-img/csverror.gif) for more details.
+- Replacing the `scan.useDelimiter(“[\n]”)` line in `Doodler.java` with
+`scan.useDelimiter("[,]|\\r\\n|[\\n\\r\\u2028\\u2029\\u0085]")`
+
+
+# Part 2: Custom Doodle
+
+***
+
+**Tasks**:
+
+* Design a beautiful doodle of your own.
+* Implement your design in Android.
+* Create a video of your Animation
+
+This is where your creativity comes into play. We've created a blank slate for you in `Part2Activity`.
+In here you must use all three methods implemented in [Part 1](#part-1-learning-by-doing) to draw your own doodle,
+and your doodle should have an animation incorporated into it. You are also
+welcome to implement new methods in `Part2Activity` to make a more creative and beautiful doodle.
+
+To start you must spend 5-15 minutes sketching out your idea. Here you should you think about how
+to incorporate lines, text, and images, and how these will be moved around the screen. Storyboarding
+is a good way to sketch out how this animation will progress. For more information about
+[storyboarding](https://en.wikipedia.org/wiki/Storyboard)
+watch at least the first 1:30 of this [video](https://www.youtube.com/watch?v=m2JJxRlxV2s). This storyboard
+does not have to be very complex - even 2-3 frames will give you an idea of how to progress. **This
+storyboard will be turned in as part of your reflection.**
+
+To ensure your peer reviewers see your Custom Doodle once you've completed it, take a video of the
+running doodle to submit through
+[this web form](https://docs.google.com/forms/d/e/1FAIpQLSd8sN1aB7JZIS_POZWVdtTsL7e0ZVGkjS_WBINo_cKLv6OH_w/viewform).
+
+* To see how to capture a your running animation on the emulator,  
+watch this [video](doodle-img/recordingvideo.mp4).
+* To capture your doodle on your phone
+(tethered to Android Studio), do [this](https://developer.android.com/studio/debug/am-video), but you
+have to put your phone into [Developer mode](https://developer.android.com/studio/debug/dev-options) first.
+
+
+**Tips**:
+
+* Aim for complexity similar to [Part 1](#part-1-learning-by-doing) (images, text, and shapes) though you don't need
+to use as many images. Try to be creative - your work will be evaluated by your peers.
+* You may use the attractive home-cooked food images ([photo credit](https://www.XiaoyiZhang.me))
+we include in `res/drawable` or use your own images.
+* If your animation is  slow, laggy, or not visibly showing (particularly ) on the emulator), try the following
+  * Reduce the number of images you put on canvas or reduce the file size of images
+  (e.g., convert png to jpg, reduce resolution of image file).
+  * Check the duration of the animation. Recall that the parameter to the method if in milliseconds, not
+  seconds. It may be worth inflating the number you pass in during testing.
+  * Ensure that your animation `propertyName` is set correctly for your intended animation
+  * Ensure that your animation starts and ends in different locations if necessary (translating in place is not visibly discernible)
+  * Recall that `Path` and `onFloat` take absolute coordinates unless otherwise specified
+  * Ensure that animations have not been turned off in the settings app of the phone/emulator
+* Recall that "Child views are drawn in a stack, with the most recently added child on top."
+(from the [FrameLayout](https://developer.android.com/reference/android/widget/FrameLayout) documentation).
+You can add a child at a specific index in the child list,
+see the documentation of the [ViewGroup](https://developer.android.com/reference/android/view/ViewGroup)
+documentation for more about how to add and remove children.
+* You can switch between the activities by using the navigation bar at the bottom of the screen.
+* **Make sure that your doodle depends on _nothing_ outside of the files described in [Turn-in](#turn-in).**
+
+
+*Related APIs*:
+[Android Animation](https://developer.android.com/training/animation/reposition-view) /
+[View Animation](https://developer.android.com/guide/topics/graphics/view-animation.html) /
+[Property Animation](https://developer.android.com/guide/topics/graphics/prop-animation.html) /
+[Vogella Tutorials - Android Animation](http://www.vogella.com/tutorials/AndroidAnimation/article.html)
+
+## Commenting your code
+
+Most of the starter code has been fairly well commented for you. However there are some places you
+should add comments as you are completing your solution:
+1.  If you have any significantly complicated code for your custom doodle, add comments that might
+help your TA effectively grade your awesome work!
+2.  If you received significant help from a source on any part of your code, be sure to
+add a comment referencing their help.  See the
+[Collaboration Policies](../academic-conduct#collaboration-policies)
+portion of our syllabus for more details.
+3.  If you add and use an image that requires copyright, you may add the attribution in your
+source code where you add the image to the screen. See the
+[Application Content](../academic-conduct#application-content)
+portion of our syllabus for more details.
+
+# Part 3: Peer Review
+
+The Custom Doodle will be peer reviewed as part of the grading process. We will use these
+peer reviews to ensure that you have implemented all of the parts required for [Part 2](#part-2-custom-doodle)
+
+Peer grading will take place once everyone has turned in their assignments. You will receive an
+email with links to three other students' `.apk` files (and associated videos) and a link to a form to fill
+out for each student you have been assigned to peer grade. You will load these files into the
+emulator via Android Studio or onto a physical phone, view and review their
+custom doodles for Part 2, then fill out the survey to give them your feedback. **Note:** you *must*
+evaluate the a given doodle based on the `.apk`, using the video only as a backup, for instance, if
+the animation does not run on your emulator or phone when you load it.
+
+Additionally, you will have a chance to nominate the most creative doodles! The winners will be
+shown off in class later this term.
+
+# Part 4: Reflection
+
+Each assignment this quarter will have a reflection component as it is a vital part of your
+work as a Programmer, Computer Scientist, and/or Engineer.  Your reflections do not have to be long
+(please no more than a paragraph or two in length). Details on what a well
+written reflection includes can be found [here](reflection). You will be graded on your answers to
+these reflection questions based on the following
+
+* Student gives at least a minimum answer to all parts of the guiding question.
+* Clear/concise but descriptive examples are given throughout the response. An uninformed
+reader can create a mental picture of the situation being described. Abstract concepts are explained accurately.
+* Student elaborates on the significance and meaning of the examples; why they are important.
+* Occasionally a student will be given extra credit for an particularly insightful reflection.  
+
+Create a MS Word, Google or other type of document and copy the following questions (in italics below) into
+that document. Add your your responses below each question. You can have
+more than one answer per page, but if you can, please try to avoid page breaks in the middle of
+a question. Insert page breaks between questions as needed.
+
+You will need to submit your write up as a PDF file. If you are new to Gradescope, see this
+[document](https://gradescope-static-assets.s3-us-west-2.amazonaws.com/help/submitting_hw_guide.pdf)
+for instructions on how to scan and submit hand-written solutions.
+
+Gradescope accounts will be created on the first (or second) day of the quarter for all
+registered students. You will receive an email message from Gradescope with a link that you can
+use to create an account and submit your solution. Your Gradescope username will be your UW
+email address. If you are not registered for the course before the assignment is due, please
+email the instructor with your name, your UW ID number, and your
+UW email address (uwnetid@uw.edu) so we can set up a Gradescope account for you.
+
+For this assignment, your reflection should cover the following:
+
+* _Include the sketches and storyboard you made as part of your design work for [Part 2](#part-2-custom-doodle) and
+a screen capture of your beautiful Doodle._
+
+* _In looking at your design sketches from [Part 2](#part-2-custom-doodle), what changed when you did your
+actual implementation? Why did you make those changes from your original design vision?_
+
+* _Why is be better to animate a `View`, rather than invalidate/redraw its contents?_
+
+* _At the moment, other than the bottomNavigationBar, our application does not respond to the user at all.
+Think of at least two ways that you would go about adding interactivity to this application._
+
+* _What did you learn from reading the peer evaluation about the user experience of your doodle?_
+
 # Turn-in
 
 ## Part 1 and Part 2: Code
 
-You will turn in the following files on GitGrade [here](https://gitgrade.cs.washington.edu/student/assignment/XXX/turnin).
+You will turn in the following files on GitGrade [here](https://gitgrade.cs.washington.edu/student/assignment/116/turnin).
 
 Make sure you only edited the following files for turn in:
 
@@ -114,7 +439,20 @@ Make sure you only edited the following files for turn in:
 - part2.csv (optional)
 ```
 
-Remember to submit a video of your custom doodle animation through [this web form]({{site.baseurl}}/404.html) at the same time you submit your code.
+Do not edit any of the other files with one exception: if you are on a Windows machine and need
+to modify the `scan.useDelimiter(“[\n]”)` call in `Doodler#addAllImagesFromData(FrameLayout)`.
+
+If you use your own images in [Part 2](#part-2-custom-doodle), please make sure to add and commit them to
+your repository in the `res/drawable` directory. If your images are not there, your custom doodle
+will not work for others and you will NOT get credit for the work you did.
+
+If you're positioning a large number of images for [Part 2](#part-2-custom-doodle), it is best to use a
+CSV similar to `data.csv` which is used for the heart in [Part 1](#part-1-learning-by-doing). Include this as
+`part2.csv` if necessary. Remember, the CSV coordinates are on a Pixel 2 XL and scaled to the
+current screen in `Doodler#addAllImagesFromData(FrameLayout)`.
+
+Remember to submit a video of your custom doodle animation through [this web form](https://docs.google.com/forms/d/e/1FAIpQLSd8sN1aB7JZIS_POZWVdtTsL7e0ZVGkjS_WBINo_cKLv6OH_w/viewform) at the same time you submit your code.
+
 
 **Follow these instructions to submit to GitGrade**
 
@@ -124,11 +462,33 @@ Remember to submit a video of your custom doodle animation through [this web for
 - Go to the turn in link
 - Check the box and click "Turn in"
 
-## Part 4: Reflection
+## Part 3: Peer Evaluation
 
-The reflection will be turned in to Gradescope.
+You will receive more details about this step of the assignment in our second lab. We will
+send out the emails to your uw.edu email account. Make sure to reach out on our discussion board
+if you do not receive the emails when it is announced that they were sent out (but check your
+  spam folder first!)
 
-### Grading (XX pts)
+## Part 4: Reflection
 
-This HW will be out of XX points and will roughly (subject to small adjustments) be distributed as:
+The reflection will be turned in to Gradescope.
 
+### Grading (40pts)
+
+This HW will be out of 40 points and will roughly (subject to small adjustments) be distributed as:
+
+* Part 1
+  * `addImage`: 2 pts
+  * `addText`: 3 pts
+  * `addLine`: 8 pts
+  * `UW` Animation: 4 pts
+* Part 2
+  * Static verification of custom Doodle (1pt)
+  * Active custom Doodle as verified through Peer Evaluation
+    * Using each of the three methods at least once: 3 pts
+    * Using an animation: 1 pt
+* Part 1 & 2 Code quality (2 pts)
+* Part 3: Complete assigned peer evaluations: 3 pt
+* Part 4: Reflection
+  * Sketch for part 2 is turned in with reflection (1pt)
+  * Each of the 4 question is worth 3 points (12 pts total)
diff --git a/assignments/index.md b/assignments/index.md
index 421efe212d484abd410f1570650fda55cb84a7be..16c45ad82e2de07534c6606a428cd668bacff85d 100644
--- a/assignments/index.md
+++ b/assignments/index.md
@@ -19,4 +19,11 @@ on public repositories such as Github.
 
 | Assignment                                                  | out    | due    | lock    | Peer Eval        | Reflection |
 |-------------------------------------------------------------|--------|--------|---------|------------------|------------|
-| [Doodle]({{site.baseurl}}/assignments/doodle)               |   |  |  | |     |
+| [Doodle]({{site.baseurl}}/assignments/doodle)               | 1-Apr  | 9-Apr  | 11-Apr  | 12 Apr -- 14 Apr | 15-Apr     |
+| [Layout]({{site.baseurl}}/assignments/layout)  parts 1-2    | 10-Apr | 17-Apr | N/A     | N/A              | N/A        |
+| [Layout]({{site.baseurl}}/assignments/layout)  parts 3-4    |        | 24-Apr | 25-Apr  | N/A              | 24-Apr     |
+| [Accessibility]({{site.baseurl}}/assignments/accessibility) | 22-Apr | 30-Apr | 2-May   | N/A              | N/A        |
+| [Color Picker]({{site.baseurl}}/assignments/colorpicker)    | 1-May  | 11-May | 13-May  | N/A              | 11-May     |
+| [Menus]({{site.baseurl}}/assignments/menus) parts 1-4       | 12-May | 21-May | 22-May  | N/A              | N/A        |
+| [Menus]({{site.baseurl}}/assignments/menus) parts 5-6       | 20-May | 25-May | 27-May  | N/A              | 25-May     |
+| [Undo]({{site.baseurl}}/assignments/undo)                   | 22-May | 1-Jun  | 3-Jun   | 3-Jun -- 5-Jun   | 8-Jun      |
diff --git a/assignments/layout-img/1_landscape.png b/assignments/layout-img/1_landscape.png
new file mode 100644
index 0000000000000000000000000000000000000000..81910a74050cea8f28e3bec26cc10fa97d08d473
Binary files /dev/null and b/assignments/layout-img/1_landscape.png differ
diff --git a/assignments/layout-img/1_portrait.png b/assignments/layout-img/1_portrait.png
new file mode 100644
index 0000000000000000000000000000000000000000..9bd05c02c72702aa248ba15346a46bf1e9ae0036
Binary files /dev/null and b/assignments/layout-img/1_portrait.png differ
diff --git a/assignments/layout-img/3_landscape.png b/assignments/layout-img/3_landscape.png
new file mode 100644
index 0000000000000000000000000000000000000000..2b35654bbbaf23c88394da72f780ac675447e613
Binary files /dev/null and b/assignments/layout-img/3_landscape.png differ
diff --git a/assignments/layout-img/3_landscape_scrolled.png b/assignments/layout-img/3_landscape_scrolled.png
new file mode 100644
index 0000000000000000000000000000000000000000..ed704982bc17697e0f2cc8f9674659dfe4a42214
Binary files /dev/null and b/assignments/layout-img/3_landscape_scrolled.png differ
diff --git a/assignments/layout-img/3_portrait.png b/assignments/layout-img/3_portrait.png
new file mode 100644
index 0000000000000000000000000000000000000000..5c0b44bfdbd1e87ec6765a0fa67022f85285c41e
Binary files /dev/null and b/assignments/layout-img/3_portrait.png differ
diff --git a/assignments/layout-img/3_portrait_measured.png b/assignments/layout-img/3_portrait_measured.png
new file mode 100644
index 0000000000000000000000000000000000000000..1a6d04655cb7a7c78c82a637839b436c0d4ea2ac
Binary files /dev/null and b/assignments/layout-img/3_portrait_measured.png differ
diff --git a/assignments/layout-img/3_portrait_measured_bottom.png b/assignments/layout-img/3_portrait_measured_bottom.png
new file mode 100644
index 0000000000000000000000000000000000000000..c27b5bd3f31446224bf9546815c57d62da83929a
Binary files /dev/null and b/assignments/layout-img/3_portrait_measured_bottom.png differ
diff --git a/assignments/layout-img/3_portrait_scrolled.png b/assignments/layout-img/3_portrait_scrolled.png
new file mode 100644
index 0000000000000000000000000000000000000000..75dea3cc77afe1a7de03d4b62e7bf48eff82c9f4
Binary files /dev/null and b/assignments/layout-img/3_portrait_scrolled.png differ
diff --git a/assignments/layout-img/LayoutSpec.pdf b/assignments/layout-img/LayoutSpec.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..b1a9bf3628f70c46e6aec4bae7413274d9319097
--- /dev/null
+++ b/assignments/layout-img/LayoutSpec.pdf
@@ -0,0 +1,966 @@
+%PDF-1.5
%âãÏÓ
+1 0 obj
<</Metadata 2 0 R/OCProperties<</D<</OFF[9 0 R]/ON[10 0 R 11 0 R 12 0 R]/Order 13 0 R/RBGroups[]>>/OCGs[9 0 R 10 0 R 11 0 R 12 0 R]>>/Pages 3 0 R/Type/Catalog>>
endobj
2 0 obj
<</Length 54424/Subtype/XML/Type/Metadata>>stream
+<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c145 79.163499, 2018/08/13-16:40:22        ">
+   <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+      <rdf:Description rdf:about=""
+            xmlns:dc="http://purl.org/dc/elements/1.1/"
+            xmlns:xmp="http://ns.adobe.com/xap/1.0/"
+            xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/"
+            xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
+            xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
+            xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
+            xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/"
+            xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
+            xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
+            xmlns:stFnt="http://ns.adobe.com/xap/1.0/sType/Font#"
+            xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/"
+            xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
+         <dc:format>application/pdf</dc:format>
+         <dc:title>
+            <rdf:Alt>
+               <rdf:li xml:lang="x-default">LayoutSpec</rdf:li>
+            </rdf:Alt>
+         </dc:title>
+         <xmp:MetadataDate>2019-09-09T01:26:12-07:00</xmp:MetadataDate>
+         <xmp:ModifyDate>2019-09-09T01:26:12-07:00</xmp:ModifyDate>
+         <xmp:CreateDate>2019-09-09T01:26:12-07:00</xmp:CreateDate>
+         <xmp:CreatorTool>Adobe Illustrator CC 23.0 (Windows)</xmp:CreatorTool>
+         <xmp:Thumbnails>
+            <rdf:Alt>
+               <rdf:li rdf:parseType="Resource">
+                  <xmpGImg:width>256</xmpGImg:width>
+                  <xmpGImg:height>160</xmpGImg:height>
+                  <xmpGImg:format>JPEG</xmpGImg:format>
+                  <xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA&#xA;AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAoAEAAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7&#xA;FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FUv8w6hLp2hX99CAZbaCSSMHpyVSVr9OKvm6&#xA;7vLq8uHubqV555DV5JCWYn5nJIUsVdirsVdirsVZ7+UWt6hD5hXSxKzWN0khaFiSquilg6jsdqHA&#xA;Ve04EuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxVJfOv/ACiWr/8A&#xA;MLL/AMRxVfJpWl/odm+pwcvq5NfTSteHyxVif1Gy/wCWeL/gF/phQvvDoUUMcci26uu7SOsadR9n&#xA;enT3xVSluvLTRRQxvaSSDq/7oHf9gdzTFURJBpUlvEsUEUhG5lCJ/wACKDcDFUZoGnae+oqGtYmH&#xA;Ftiint8sVRepWdpb+bfLxt4I4S31zl6aqtaQjrQDFLXkPzTfa/pOo3t9HHG9nqV/ZItur0MVpO0a&#xA;EqWclyq7079BgVLrv82tJsYbiXUdI1Sw9C3S+9K5igSRrN51t2ueHrFkWNnUyLIFkUb8MVRV3+Zm&#xA;jRapcaVa2d7qOoRXS2EEFqkRFxObf6zIsUkssUdIYiDIzsoFabnFW9M/M3y9qN1b2tvFciea2vbp&#xA;43RAYTp0qw3EMo5njKrvsBUHx6Yql3lz8zLzX/N1pYWekXA0K+0a21aC8k+rrIn1l3+KQC5Y+n8I&#xA;j4qhbnX9ijYql+sfmV5gtvMmrabC2mWk+nTxx6domocoLrVIikbPJbXcs8FulTIQo4PuN6Yqncv5&#xA;paRDe3UMum6gllY6imk32qmOH6rDcy+mI+RE3qlWaZV5KhoT8VBTFVVPzO0Br1I2guo9MluLiyg1&#xA;t0j+pSXNosjTRKRIZtvRejNGFYqeJOKo3yx5yi8wFWh0rUbK2mgW7sry8hRYbiB2oro8by8SwowS&#xA;Xg/E140xVjWlfmdqr3mtT6rpksGn2mpDRtIsYYoXurm82/d+qLtk5EVYho0RV39Q7gKpk35qaT6l&#xA;raRaXqE+rXN5PpzaTGtubiG5t4fXdJS06wgGMhg4kK074q35m8x+Z4/OWg+XNGks7MaraXl1cXF9&#xA;bSXbIbUxcUVIbm1G/qmvxHFUu0z83AfK8Ot6no160MaTyalfWUaGyhjt7qS2MokmkjZw3pF+EfNw&#xA;u5FKEqorW/zOMVh5rbRdIu7258swzGa6YWwtPWS3WdN2uIpHTi/JuArQHuV5KusfzSWRbW2m0HU5&#xA;dUNjDqGo2tqltK1vDOxRJeCXDvIrlSyrD6jhftAHbFUX+aXmfzJ5Y8pXetaFZ2t1JZxvNcveSOqR&#xA;ogrURxjlIWO1Oa/PFUf5t8yXOieSr7X4YUmntLUXAjavCpAqxA+Iha8qDc0oMVa8h+YL7X9AGo3Y&#xA;jes80dteQRyQQ3UEchWO5iilaR0SRRUVc+IJBGKpRp/mvzbF5r0jStcgs4RriXksWmwBjdWSWtCj&#xA;TzCaWKYOpAJVEAY03xVnGKuxV2KuxV2KpL51/wCUS1f/AJhZf+I4qgz5fvF8vJCdd1FliiSTkTbc&#xA;39OknB3EAYq3Hi2+67Yq8l1545/NN/ba/e3iaQYeFrb2bcODlVKuRVVfv9qvXJISVvIfkW4eJofM&#xA;01opB9Zbi0eV+XYgpwXfwrgVSg/LzypxRrjzWinn+8VLOY/B7Enr/sT/AFVTWy0f8uNJjmeG6v76&#xA;5cj0XUvBwAHYoYatU9TX5DFWaflpb6rqOmwpdapdJJFO7w3kZjErxR0IRzIsgZSahqjfEpZReabP&#xA;b+dtBuJdRubv1EuoxDP6IjThETyVYo4vibnQk+AxVDeX/I3mfRIr+xttdtf0VqF5eXkiiwlW8j+u&#xA;yNIwjuRecAyFvhb0T8sCpLpf5Sp5e+t6iYYNaeTR5dHuNN0+zhsZr0Tyxs0889xcsskzBDzZ236i&#xA;n2SqiPLX5Xanpnlby0sWorZ+adHklvLi8njN7FLPeIUuY5l9SBnHFgqsrrTiMVVIfyluLOS2u9O1&#xA;kQ6nw1KPU7qa19VZzq0yzzvHGJo/RdXUcN3AHUHFUf5Z/Lu78vX2i3NrqkcqadpEOiX0cts1biK3&#xA;ZnjkiYTD0W5ua1D7be+KrfMn5e6xrVtrOltr5/QOuSepdWd3bG6ngBVQyWc5mRYUPCoDRPxJJWmK&#xA;pPY/lr5hvJ9dsr++Fl5dvdeTURYiJZZ7iG3W3eIrcrN+7V5IAHV4y3w7UrhVEWX5LaVa6rJMGsTp&#xA;0k13OVGmW51FvrnOsbajIZH4RmU8OKK9KDlTbArJPKPlvzDokMFnfa4uo6bY2qWdjbJaLbsFjICS&#xA;TyepKZJAi8fg4KevGuKpdcflw72t36Gpelfvrh8w6fctBzSGcqE9OSL1F9VOHJTR0O+1KYqs0v8A&#xA;LM2mv2Wv3GoifU49QutT1BkgMcc8lzZ/U1jiQyyGJIkoRVnJ7nfFUd5l/L3SPMfmjSdZ1aO3vbTS&#xA;7e6gOmXVslxHI1yYyJKyEqpT0/5D17YqkPnn8m7fzNcXRjvLa1tLiwTT4La4sVuhZGMsVlsf3sKQ&#xA;M3IB/gJIGxXFU7svy+ig07zVYTXplh80NIZCsfAwrJZpaED4m5bR8q7daYqkWt/lNrGtabZ2Ooa1&#xA;YS/VrWO0Fz+iU9eH0Wqs9lMbgzW8xXYsXda7qq9MVZd5y8s/4k8o6l5e+tG1/SFubf62U9UpWnxF&#xA;OScun8wxVT81eUhr2g2+mC5EEtpNbXNvLJEJ4WltXDoJoCyepGSu68h89sVSvyL+XcnlfVtS1F76&#xA;G6OpJGn1eG2e3it/Tkkk9O2DTz+nCWmZvT3+I15U2CrflbyV5k0rzFe61qes2erT6gSLiY6fLDcr&#xA;CAfSt4JTeSxxQxtvxEXxftGu+KszxV2KuxV2KuxVJfOv/KJav/zCy/8AEcVRsn/HFb/mGP8AybxV&#xA;5T5z8uSahEt5aLyuoRxeMdXTrt7jJIeesrKxVgQwNCDsQRirWKo7R9GvNVuhBbr8I/vZSPhRfEn9&#xA;QxV7R5Qs4bKeC1gFIoYyq+PTcn3J3wFUw1r/AJSzy5/0e/8AJkYpTbUtV07TLf6xf3MdtDWgeRgK&#xA;nwHcn5YFST/lZHkn/q6J/wABL/zRhpXf8rI8k/8AV0T/AICX/mjGld/ysjyT/wBXRP8AgJf+aMaV&#xA;3/KyPJP/AFdE/wCAl/5oxpXf8rI8k/8AV0T/AICX/mjGld/ysjyT/wBXRP8AgJf+aMaVE6f538qa&#xA;hcrbWupRPO5oiNyQsT0C8wtT7YKVPMVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdiqS+df+US&#xA;1f8A5hZf+I4qj+DSaRwQVdrfio8SUoMVY3+htT/3wfvX+uFCXaj5Fi1Budzp/KX/AH6pCN9JUiv0&#xA;4qlGnfl/ot1NdLBbSzNYzG2uUdnULKEWSm/Dl8Mi7rUY2rI7by3dWsQht7MRRjoicQPwOKppoum3&#xA;sF8JJoiiBWFSR3+RxS7Wv+Us8uf9Hv8AyZGKvL/zdvrmfzY9tI5MFpFGsKdhzUOx+ZJxCGE4Vdir&#xA;sVaxVvFXYq4Eggg0I6HFX0d5Ovbi+8r6ZdXLc55IF9Rz1Yr8NT7mm+RSnGKuxV2KuxV2KuxV2Kux&#xA;V2KuxV2KuxV2KuxV2KpL51/5RLV/+YWX/iOKplDKsWnJK1SscIYgdaBa4qgf8TWH++5fuX/mrDSu&#xA;/wATWH++5fuX/mrGlS/S9dWK61SS5gKLcXYktvTYOWiFvDGGevDi3KNvhFfniqYf4msP99y/cv8A&#xA;zVjSq9nrVrdziGNHDEE1YADb5E4FS7Wv+Us8uf8AR7/yZGFVLQ/+U28z/wCpp/8AyakxVkuBXYq7&#xA;FUg8oHS+Os/o/hxGq3f1rhX/AHo5D1a178uuKp/irsVUrz/eSf8A4xt/xE4qkvkD/lDdK/4wD/iR&#xA;xKp/irsVdiqje31lYWkt5fXEdraQKXnuJ3WONFHVndiFUfPFWJ3mgaf50079I2usSXGi6n6c9qi8&#xA;zDwERSqDkmztxbp2P8xxdro+0/AoxgOIdevO+73j+wIh/KmuLZFRrM1xeRiQ25aSeCPlKy15+nI5&#xA;ZVRSFBrStRQ74EjX4uL+7AiavaJO18rA68+/qut/KOqK8EsmsS+pGtoJSnq85PqqcWV5DLVw5Zju&#xA;OpqQcUT7QxkEDGKPF3bcXcOHatvkm+g+YtC8wWC6hot9DqFmxK+tA4cBh1VgN1Yd1bcYXVJjirsV&#xA;dirsVdirsVdiqS+df+US1f8A5hZf+I4qjZP+OK3/ADDH/k3irEMKETPFGkETIOQfdpa96fZp2pir&#xA;p4o0giKDlz3aWvem607UxV08UaQRFBy57tLXvT7FO1MVRXl7/jpL/qt+rEpROtf8pZ5c/wCj3/ky&#xA;MVUtD/5TbzP/AKmn/wDJqTFVXzR/eW/yb9YxCpHihfJFJHxDjiWHIA9ae+KuMLpGrleKuTx7V7k/&#xA;jirhFJ6Rlp8ANOR7k+GKrMVZvef7yT/8Y2/4icCUl8gf8obpX/GAf8SOJVP8VdirsVYf+Z/5XeX/&#xA;AMxNCXStYluIPQZpbSe2lZPTlIoGaP8Au5B7MvyIrirDtD/5xb/LG00i0tdTtpb+/hjVLi9WeeES&#xA;uu3P01kIWvgMVR3/AELL+UH/AFapv+ku4/5rxW3f9Cy/lB/1apv+ku4/5rxW0R+U35FeXvy7ludQ&#xA;gvLm/wBavQRdXTu0UPEsW4Jbo3Cm43csa9CMVel4q7FXYq7FXYq7FXYqkvnX/lEtX/5hZf8AiOKo&#xA;Y+bvKr6EsiazZMksKxRMLiIhnkAjRV+Lcs7BRTqcVYfrHm3y9pDtHf3iRzKOTQqGkkAPQlUDFa17&#xA;4UJFdfnR5W4rGkd1JGmwEUSAVpu3xupxVTk/O3y1IiR/VbxY06KI4qV7k/veuKpha/mv5WvgsQea&#xA;BI6bNC5Wv8zGP1OvicVZXoHmHQkkgv31C3SymJiiuHlRY2kbYIGJA5bdMUo291rR77zpoFvZX1vd&#xA;TxLdySxQypIyo8VFYhSaAlTiqvof/KbeZ/8AU0//AJNSYqq+aP7y3+TfrGIVJYywkUru1RxHvXbF&#xA;CtfBfWqPtkVlAPIBu4BxVdebpEz7TkUZQa/CAOJPgfbFXSb2UZkorLtDQ7lSTWq/PviqFxVm95/v&#xA;JP8A8Y2/4icCUl8gf8obpX/GAf8AEjiVT/FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FUl86/8&#xA;olq//MLL/wARxVFyRx/oNl4jiLeoWgpUJUH798VeI61NceX/ADdd6lBBFK+oQem/1hPUR4mCh0IP&#xA;ulPlkkIObX9DuJY5LnyxphaMEKIYzEtD24gsPl4dsVU01LylEqiHyrZjg3qJ6jyS/FWvxc6ll/yS&#xA;aYqjx5/vIIJ7fTdNsNOhuDWZLaHhzNKVahHL/ZVxVmX5SaWlnYRKYwq3DSXCx02FacTT/Y8hgKsr&#xA;1lV/xf5dag5EXgLdyBCKD8cUpZZ6hqFt+YOvRW+lzX0EsVmZ7iGSBREUibgpWaSNm58j9npTftir&#xA;XmTWrtfrE99pk9la2URkilkeCQzrx5OESKSQqykU+KlaineiFedjzn541TSm1Xy/oKy2SzNASxea&#xA;UMgBLGNPT+H4tyK074oY7e+dfzRiuJIJLN7eaNfUeNbQkhCKhviDfD74qhYfP/5kTJFNErzRSvwi&#xA;dbUMrv8AyKQu59hillei6n+b9zK6zaREsUIq8t3G8CnelEYN8RB68Qad8UJ5oPmq4v8AU73SL2xa&#xA;11KwXlIEbnE42+yzBOvIEV+/FWeXeva8dDknPlq8F4YiXs/Xsfhrsw9T1+Jou+BK/wAgf8obpX/G&#xA;Af8AEjiVT/FXYq7FWE6n+aljpd9c2t9oWsxx27yJ9eW05Wr8JlhUpLzH94XBWoFfuqqtl/Na0WBp&#xA;U8u68/BRIyfUHDcP3RagLblVmrx6niwxVq4/NSOOVUj8ta5KjOiFxZstAW4uaE/s7H3xVMrnzyIt&#xA;KtdSi0PVZorlVdoRbUmiVmZaSRluQYcK08KYhztHohn/AI4Q/rGlSTzrCtz9Wj0u/lnUr6kawgso&#xA;ZZGUkBv2vS2r4jBbYOzDw8RnAD3+7y82R4XWuxV2KuxV2KuxV2KpL51/5RLV/wDmFl/4jiqNk/44&#xA;rf8AMMf+TeKvPte0O31ez9GQ8Jkq0E1KlW/oe+FDzfUtA1XTnIuIG9MdJkBaM/7IfxwqgY45JGCR&#xA;qXc9FUEn7hirKfL3km6nlS41NDDbLuIW2d/Yj9kePfFXqPlxQuoIqgBQjAAdAKYClFa1/wApZ5c/&#xA;6Pf+TIxVS0P/AJTbzP8A6mn/APJqTFXedLZLqBbZ/sTRSRt8mAGIV4cLzWtIuJLaK6mtZIno6RyM&#xA;g5Kag0BHzGFCMi87eaYiCt+7FSWBdY5DyPUnmrVO/fFVR/P3m114tfk7ca+lDWn+twr7fLbFUJP5&#xA;q8yTsWk1O5LGlSJGXoKD7JGKsk8gWEzfWdUnLM0v7qNmJJYA1c1PuAMVe0Xn+8k//GNv+InIpSXy&#xA;B/yhulf8YB/xI4lU/wAVdirF/wAx9NivPLvqPNqcL2UyTw/oZ3S7Z2BhCjhuV/e1Pyrirzl9SM9q&#xA;Ldk87vE13FeC5IZZUaISELQKP3bAhjGduQUUpU4VUdQmuZYkgh1PzrbNHMITfXEIAjYpFGrCvpq3&#xA;qgmh5bMxqO2KEZ5pk006sbjVbrzjavpkxihkt6pbN6LRW4kV14owndUk+Lqa7b7qXfWg+j2U8Vx5&#xA;4DXtxzlk9Phcxrpq8SZY6UC3JkUdKtTsARiqisbyT3wivvPDJbxwzAvUOHeUWZMIdCWYJMXZa9Fr&#xA;Su+KvUvJgr5fgnE2oSrdM86jVhxu0DsfgdSBxAP2R2GBU8xV2KuxV2KuxV2KpL51/wCUS1f/AJhZ&#xA;f+I4qqWuv+XzZxK2pWhBjUMpmj/l6H4sVb/S3lT/AJbLH/kZD/XFXfpbyp/y2WP/ACMh/riqT6Dq&#xA;vlH65rhS8tuJ1D/dso6i1gDcPUP2OVacfh8MVTj9LeVP+Wyx/wCRkP8AXFW01nywjckvrJW8VliB&#xA;/A4qld/qWnXnm3y8LS6huCn1zmIpFelYRSvEmmFV+h/8pt5n/wBTT/8Ak1Jiqr5o/vLf5N+sYhWC&#xA;eZvKsWrD14CIr5RQMfsuB0DU/XhQwC/0jUrByt1bvGB+3SqH5MNsVQscckjBI1LseiqCT9wxVkmh&#xA;+Sb+7kSW+U21r1KttIw8Av7P04q9BgghghSGFAkUYCog6ADArOrz/eSf/jG3/ETgSkvkD/lDdK/4&#xA;wD/iRxKp/irsVdiqRaz5UTU72K8/Sd/ZyRGqpbTlI9wFPwUI3Axc/Ta84oGPBCQPfHf5rYPKky3p&#xA;uJtXvZY1YNFD6rCgUR7MamtTGeXGleRFMFMp68GHCIQHnXv/AF7c+SSW35Vta2/oW3mzX4o1DCIf&#xA;XeXAMgTbkjdKVHgdxvhdciYPy8uYr03b+adamf0bmBI3uE9NRdV+IKIx8UWxjPagxVdo35eS6XqZ&#xA;vh5l1m7DTC4ktbm6EkLOAwIKlfssrAcRt8IpirL8VdirsVdirsVdirsVSXzr/wAolq//ADCy/wDE&#xA;cVfG/lNhYeY7C9vYK2kEnOZZYPWRlAPwlGR68ulaVHUUIrhVKfqd5/viT/gG/pirJLuy0yPyLaCO&#xA;KGbW5rotJ6aTi4hhUOKSFl4NzPH7P2aDqWNFUp0K14axZSXkfp2qTI8rTQvLHRTWjoFcsppQ/Cfk&#xA;emKq/mpLe58wXs2lWrJp7OBbhIiilVULy4hI6ciK/YX/AFV6BVHeX18v2/l3Xl1C2nfXbiFYtK5W&#xA;vqwqPUQuVYuCkpFfiK/CoNDU0xVmX/OOcM0fnsepGyVienIEV/dv44q9+0P/AJTbzP8A6mn/APJq&#xA;TFU01XSmvmjIkEfpgjcVrWnvgVAf4Xk/5aB/wJ/rhtXf4Xk/5aB/wJ/rjaoDR9Iu70XnrKLQ213N&#xA;boKh/USMjjL8J25g/ZO4xVH/AOF5P+Wgf8Cf642rv8Lyf8tA/wCBP9cbVO7z/eSf/jG3/ETgVJfI&#xA;H/KG6V/xgH/EjiVT/FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FUv8w6fLqOhX9jCQJbmCSOOv&#xA;TkykLX6cVfN13aXVncPbXUTQTxmjxOCrA/I5JClirsVdirsVdirPfyi0W/m8wrqgjZbK1SQNMwIV&#xA;ndSgVT3O9TgKvRND/wCU28z/AOpp/wDyakxSmuqat9QaMel6nqAn7XGlKexwKgf8U/8ALr/w/wDz&#xA;bhpXf4p/5df+H/5txpUv0fW720F59bjjmNxdzTw+lyjCRORwRuXPk4A+JhQHwGKph/in/l1/4f8A&#xA;5txpXf4p/wCXX/h/+bcaVObz/eSf/jG3/ETgVJfIH/KG6V/xgH/EjiVT/FXYq7FXYq7FXYq7FXYq&#xA;7FXYq7FXYq7FXYq7FXYqskhhkp6kavTpyAP68VW/U7T/AHxH/wACv9MVd9TtP98R/wDAr/TFXfU7&#xA;T/fEf/Ar/TFXfU7T/fEf/Ar/AExV31O0/wB8R/8AAr/TFVUAAAAUA2AGKsa0P/lNvM/+pp//ACak&#xA;wqq+aP7y3+TfrGIVJFALAE0BIBJ7YoVruNY5fTVCoUUqerf5W22Kt3MSRJGFUnkORl7NXsKeGKua&#xA;JFtFcKWaQ7v2WhPw/M4qh8VZvef7yT/8Y2/4icCWG6brx0H8r7PU1jEskUCrFGdgXd+Ir7CtThVK&#xA;vI/mzzb5ovbqB76G0ECCQFbdXryalN2GKE11TU/MunyzibWYVhg3eZ7ZEUClSSS9BirC9Q/OoWhI&#xA;i1g3hG1YLJeNf9aR0H3Yqks//OQHmAV9Aep4c440/VzxSoH/AJyC829oYvuX/mjFXD/nIPzZ3hi+&#xA;gL/zRiqNtvz+1Rj/AKS7xDxjt4pP1vHirJNF/NGTWJUgtdfiS5fZbea0Ebk+Aq3Fj7A4oZlpS+ar&#xA;6ORjrEcfAgUFohrUf64xSw6f8z/MGkeZp7C/aK8sbadoZmEfpuUVqF14k796Y0h61gS7FXYq7FXY&#xA;q7FXYq7FXYq7FXYq7FXYqxrQ/wDlNvM/+pp//JqTCqr5o/vLf5N+sYhWO3F/YWlGvLiOBO5kdU2+&#xA;bEYoS+889+UuYrqlqqJ8KKkgcAdeq8sVWSfmD5OkVIo9TgRF6VY7saAkkjFUZb+avLtzEsFpqNrI&#xA;7GrhZkLsQTT4a1p9GKo0EEVG4OKs3vP95J/+Mbf8ROBLzXWP/JMWn+pB/wAnsKEB+SX/AB1tS/4w&#xA;J/xPEqmP5pWZu9M1OHcpVGkUd1UqT93XEKwPyxrOhaX5em0DUdKGoWNxMZ5Wkep5bAUUcaEBdmVl&#xA;PvTbFUXexflHqkEccmlXWmPG4IktCinhQVDE+py38Vr/AJWKqE3lr8nriWGWOa+tEjY+rbjkRIoN&#xA;RUsJivzB+gdcVVotI/Ju31BLsQXkyIpH1VyxgL/ssUJ5n5erT27YqmOmeafIuivJdaTofoajKnFp&#xA;YwV4n/IkMrMAe4VV964qkfmLU183eZdNvDa+hdQenBEwkaRmCvVS5PEfCSTsB13wq9w8sf3E/wDr&#xA;D9WApeGedP8AlLdX/wCYuX/iZwofRuRS7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqwuz0Szv/zA166n&#xA;e4WW2is1jEFzPApEsTcuaxOgb7AoW6dupwqoeb9FTTrW+udPmufrd3buay3E8/FokIUxLK7hDv26&#xA;7V6DEK8f0vSfJdxphi8wG+l1RpzK2oQMvIxkAcCX9TwrupNT18VCtJ5D/LuaZ5IPMk9tCy1jt5bZ&#xA;5HRvAyARq/y4r/rYqpRfl75J9CNpvNLeqG/eqlpJTj4Dc0/1t/8AVxVNLPRPyk06SWRkvdUBUBI5&#xA;W2G+5UiODf8A1gf44qj/ACPHAPMGqLphnh0OWPlBYyPyETEqNiO5+Lp28aVwq9Uu/JmkDQ5NPE+o&#xA;CBIqKf0he86J8Q+Mzcu3XrkUsT1j/wAkxaf6kH/J7ChKPybso7jWr13eVfSgFFjleNTyYD4ghXlS&#xA;m1cSll+p2MMVzdWpLyxOzlvWdpWIlqzLycs3EcqAV2Gw2xQ8h13R59Kv3t3BMRJaCTsydvpHfCqX&#xA;Yq7FXYq7FWY+Q9DdpTqs60jQFbYHux2Zvo6Yq9R8vadDNJLctJOGUCP00mlSOleXIorBeX+V1wFL&#xA;xHzVbrbeZNSt1d3WK4kQPK7SSEK1Ks7Esx8ScKH0lkUuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KvDv&#xA;zK/NPV/InnnUF0+0t7r9IR25l+sc/h9GMU48GXr6hwqxjUfz68532lrq0mlacLOOYWtVkYv6jqXA&#xA;MfqFwKIdyKYqwCbz5evK7raQxqzEhByotT0FT0GNqi9Q17zDp9vb3F1ZQJDdVELLIr7qiSMrBHYo&#xA;wWZCVah3xVBx+ddSkdY0tomdyFVRy3J2HfG1RWqeYte0udIL20t0eRPUjMcizIyFitVeJ3Q/EpHX&#xA;FUy8tfmtr1iwstP0y3uLm7kVVFJC7sfhRAFYdztirLNW/wCckPPFld3emXujafFdW7vb3MYaR+Lq&#xA;SjryWRlND4HFXoOsf+SYtP8AUg/5PYoQH5Jf8dbUv+MCf8TxKsv1n/jpz/Mf8RGKpNqmlWep2pt7&#xA;par1Rxsyt4qcVYDqvkrV7N2a3T63B+y0Y+OnunX7q4VSKWCaI8ZY2jbwYEH8cVVrXTdQumAtraSW&#xA;vdVJH0npirKtD8hSFln1UgINxaoak/67Dp9H34qzZESNFRFCooAVQKAAdABgVkflj+4n/wBYfqxK&#xA;XhnnT/lLdX/5i5f+JnCh9G5FLsVdirsVdirsVdirsVdirsVdirsVdir5v/PXQH1XzzMyzCL0o4xu&#xA;vKvKNPceGFDBD5WvTpa6aLqP0BObkt6bcy5QJQnlSgA227nFUJ/gWf8A5a1/4A/1xpKZax5fudSW&#xA;2SttZxWkfpQw26TBAvUmkksnxE7k9SeuKEDa+S54LmKczwzCJ1cxSRsyPxNeLgMKqeh3xpKN17Qt&#xA;U1u/+vXl2nrCOOEUEr/DEgRavLJJIxoOrMfuxQ1oWg6roepR6jY3cBuIwy0nt0nQq44upSXkPiUk&#xA;HvTGlUtU8q3up6ldajc3cYuLuV55RHCETnIxY8VU0AqcaV75rH/kmLT/AFIP+T2Ksb/LLzT5e8vX&#xA;97PrV9FYxTxKkTykgMwapAoD2xKvQ7v8xvy0i9KW71O0j+soJoZJY2HqRklQ6lk+JaqRUeGKVD/l&#xA;Z/5S/wDV40//AIH/AJtxVefzJ/KpYllOq2IiclUkKHiStKgHhTauKpbrn5lflPLYBF1W2kPr2xKW&#xA;zNFJRbiMk819M8QBVvi3WoNRtiqZL+ZP5VNG8q6rYmKMgO4QlVLV41PHatNsVWf8rP8Ayl/6vGn/&#xA;APA/824qq235i/lddTCG21OznmIZhHHGXYhFLMaKhOygk+2KtRfmx+VsQIi12yjB6harX7lwK8e8&#xA;y39nqHmDUb6zlWe0ubiSWCZfsujMSGHzySH0pkUuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KvOvzI/L&#xA;y/1m9XVdJ4vclBHcWzMEL8fssrNRa02NThBVgX/KufOv/Vrk/wCDj/5qwod/yrnzr/1a5P8Ag4/+&#xA;asVd/wAq586/9WuT/g4/+asVd/yrnzr/ANWuT/g4/wDmrFXf8q586/8AVrk/4OP/AJqxV3/KufOv&#xA;/Vrk/wCDj/5qxVFad+VnnC7uVjmtRZwk/HPM6EKPZVLMT9GC1eqa55QS78mHy9ZSemYo41t3foWi&#xA;Ib46fzEb0wJeIeZvyW/MLUooorewjrE5JZ7iEAilNviJwqlN9+RX5r3kVnFLY2wWxg+rQ8bmOpT1&#xA;Hl+IljvylP0bYqhP+hePzP8A+WKD/pJi/riqaXn5Lfmvc6FYaP8Ao63SCxeWTkLtWLtKa1IZiF47&#xA;0C0G5PUmqqV/9C8fmf8A8sUH/STF/XFU0tvyX/Nm38v3eix6baiG9lSWaY3KepSOhCD4+IHJQem/&#xA;foKKpX/0Lx+Z/wDyxQf9JMX9cVTXQPyc/OPQprmXT7O0DXdvLaT+pLBJWOZSpoW3UivIUPUCtRti&#xA;qVf9C8fmf/yxQf8ASTF/XFWdeWfye83gWVnqUCWlvEqLcT+rG/wr9rgEZiT4VAxtD3rAl2KuxV2K&#xA;uxV2KuxV2KuxV2KuxV2KuxV//9k=</xmpGImg:image>
+               </rdf:li>
+            </rdf:Alt>
+         </xmp:Thumbnails>
+         <xmpMM:InstanceID>uuid:559e743a-28e7-4925-88aa-a149edfbb1ef</xmpMM:InstanceID>
+         <xmpMM:DocumentID>xmp.did:578294d2-d6b0-344f-b159-7628ac6a8f47</xmpMM:DocumentID>
+         <xmpMM:OriginalDocumentID>uuid:5D20892493BFDB11914A8590D31508C8</xmpMM:OriginalDocumentID>
+         <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>
+         <xmpMM:DerivedFrom rdf:parseType="Resource">
+            <stRef:instanceID>uuid:fee9adc9-99ff-4f50-b2e9-7f830b63b763</stRef:instanceID>
+            <stRef:documentID>xmp.did:cc21c36f-daca-5d4d-86ed-0422dbc64d3a</stRef:documentID>
+            <stRef:originalDocumentID>uuid:5D20892493BFDB11914A8590D31508C8</stRef:originalDocumentID>
+            <stRef:renditionClass>proof:pdf</stRef:renditionClass>
+         </xmpMM:DerivedFrom>
+         <xmpMM:History>
+            <rdf:Seq>
+               <rdf:li rdf:parseType="Resource">
+                  <stEvt:action>saved</stEvt:action>
+                  <stEvt:instanceID>xmp.iid:cc21c36f-daca-5d4d-86ed-0422dbc64d3a</stEvt:instanceID>
+                  <stEvt:when>2019-08-04T17:05:28-07:00</stEvt:when>
+                  <stEvt:softwareAgent>Adobe Illustrator CC 23.0 (Windows)</stEvt:softwareAgent>
+                  <stEvt:changed>/</stEvt:changed>
+               </rdf:li>
+               <rdf:li rdf:parseType="Resource">
+                  <stEvt:action>saved</stEvt:action>
+                  <stEvt:instanceID>xmp.iid:578294d2-d6b0-344f-b159-7628ac6a8f47</stEvt:instanceID>
+                  <stEvt:when>2019-09-09T01:25:58-07:00</stEvt:when>
+                  <stEvt:softwareAgent>Adobe Illustrator CC 23.0 (Windows)</stEvt:softwareAgent>
+                  <stEvt:changed>/</stEvt:changed>
+               </rdf:li>
+            </rdf:Seq>
+         </xmpMM:History>
+         <illustrator:StartupProfile>Print</illustrator:StartupProfile>
+         <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
+         <xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency>
+         <xmpTPg:NPages>1</xmpTPg:NPages>
+         <xmpTPg:MaxPageSize rdf:parseType="Resource">
+            <stDim:w>8.500000</stDim:w>
+            <stDim:h>8.017512</stDim:h>
+            <stDim:unit>Inches</stDim:unit>
+         </xmpTPg:MaxPageSize>
+         <xmpTPg:Fonts>
+            <rdf:Bag>
+               <rdf:li rdf:parseType="Resource">
+                  <stFnt:fontName>AcuminVariableConcept</stFnt:fontName>
+                  <stFnt:fontFamily>Acumin Variable Concept</stFnt:fontFamily>
+                  <stFnt:fontFace>Default</stFnt:fontFace>
+                  <stFnt:fontType>Open Type</stFnt:fontType>
+                  <stFnt:versionString>Version 1.020;hotconv 1.0.108;makeotfexe 2.5.65593</stFnt:versionString>
+                  <stFnt:composite>False</stFnt:composite>
+                  <stFnt:fontFileName>AcuminVariableConcept.otf</stFnt:fontFileName>
+               </rdf:li>
+               <rdf:li rdf:parseType="Resource">
+                  <stFnt:fontName>AktivGrotesk-Medium</stFnt:fontName>
+                  <stFnt:fontFamily>Aktiv Grotesk</stFnt:fontFamily>
+                  <stFnt:fontFace>Medium</stFnt:fontFace>
+                  <stFnt:fontType>Open Type</stFnt:fontType>
+                  <stFnt:versionString>Version 3.002</stFnt:versionString>
+                  <stFnt:composite>False</stFnt:composite>
+                  <stFnt:fontFileName>14038</stFnt:fontFileName>
+               </rdf:li>
+               <rdf:li rdf:parseType="Resource">
+                  <stFnt:fontName>RobotoMono-BoldItalic</stFnt:fontName>
+                  <stFnt:fontFamily>Roboto Mono</stFnt:fontFamily>
+                  <stFnt:fontFace>Bold Italic</stFnt:fontFace>
+                  <stFnt:fontType>TrueType</stFnt:fontType>
+                  <stFnt:versionString>Version 2.000985; 2015; ttfautohint (v1.3)</stFnt:versionString>
+                  <stFnt:composite>False</stFnt:composite>
+                  <stFnt:fontFileName>RobotoMono-BoldItalic.ttf</stFnt:fontFileName>
+               </rdf:li>
+               <rdf:li rdf:parseType="Resource">
+                  <stFnt:fontName>RobotoMono-Italic</stFnt:fontName>
+                  <stFnt:fontFamily>Roboto Mono</stFnt:fontFamily>
+                  <stFnt:fontFace>Italic</stFnt:fontFace>
+                  <stFnt:fontType>TrueType</stFnt:fontType>
+                  <stFnt:versionString>Version 2.000985; 2015; ttfautohint (v1.3)</stFnt:versionString>
+                  <stFnt:composite>False</stFnt:composite>
+                  <stFnt:fontFileName>RobotoMono-Italic.ttf</stFnt:fontFileName>
+               </rdf:li>
+            </rdf:Bag>
+         </xmpTPg:Fonts>
+         <xmpTPg:PlateNames>
+            <rdf:Seq>
+               <rdf:li>Cyan</rdf:li>
+               <rdf:li>Magenta</rdf:li>
+               <rdf:li>Yellow</rdf:li>
+               <rdf:li>Black</rdf:li>
+            </rdf:Seq>
+         </xmpTPg:PlateNames>
+         <xmpTPg:SwatchGroups>
+            <rdf:Seq>
+               <rdf:li rdf:parseType="Resource">
+                  <xmpG:groupName>Default Swatch Group</xmpG:groupName>
+                  <xmpG:groupType>0</xmpG:groupType>
+                  <xmpG:Colorants>
+                     <rdf:Seq>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>White</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>Black</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>100.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>CMYK Red</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>100.000000</xmpG:magenta>
+                           <xmpG:yellow>100.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>CMYK Yellow</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>100.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>CMYK Green</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>100.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>100.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>CMYK Cyan</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>100.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>CMYK Blue</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>100.000000</xmpG:cyan>
+                           <xmpG:magenta>100.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>CMYK Magenta</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>100.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=15 M=100 Y=90 K=10</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>15.000000</xmpG:cyan>
+                           <xmpG:magenta>100.000000</xmpG:magenta>
+                           <xmpG:yellow>90.000000</xmpG:yellow>
+                           <xmpG:black>10.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=90 Y=85 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>90.000000</xmpG:magenta>
+                           <xmpG:yellow>85.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=80 Y=95 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>80.000000</xmpG:magenta>
+                           <xmpG:yellow>95.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=50 Y=100 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>50.000000</xmpG:magenta>
+                           <xmpG:yellow>100.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=35 Y=85 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>35.000000</xmpG:magenta>
+                           <xmpG:yellow>85.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=5 M=0 Y=90 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>5.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>90.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=20 M=0 Y=100 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>20.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>100.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=50 M=0 Y=100 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>50.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>100.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=75 M=0 Y=100 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>75.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>100.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=85 M=10 Y=100 K=10</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>85.000000</xmpG:cyan>
+                           <xmpG:magenta>10.000000</xmpG:magenta>
+                           <xmpG:yellow>100.000000</xmpG:yellow>
+                           <xmpG:black>10.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=90 M=30 Y=95 K=30</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>90.000000</xmpG:cyan>
+                           <xmpG:magenta>30.000000</xmpG:magenta>
+                           <xmpG:yellow>95.000000</xmpG:yellow>
+                           <xmpG:black>30.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=75 M=0 Y=75 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>75.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>75.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=80 M=10 Y=45 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>80.000000</xmpG:cyan>
+                           <xmpG:magenta>10.000000</xmpG:magenta>
+                           <xmpG:yellow>45.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=70 M=15 Y=0 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>70.000000</xmpG:cyan>
+                           <xmpG:magenta>15.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=85 M=50 Y=0 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>85.000000</xmpG:cyan>
+                           <xmpG:magenta>50.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=100 M=95 Y=5 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>100.000000</xmpG:cyan>
+                           <xmpG:magenta>95.000000</xmpG:magenta>
+                           <xmpG:yellow>5.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=100 M=100 Y=25 K=25</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>100.000000</xmpG:cyan>
+                           <xmpG:magenta>100.000000</xmpG:magenta>
+                           <xmpG:yellow>25.000000</xmpG:yellow>
+                           <xmpG:black>25.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=75 M=100 Y=0 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>75.000000</xmpG:cyan>
+                           <xmpG:magenta>100.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=50 M=100 Y=0 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>50.000000</xmpG:cyan>
+                           <xmpG:magenta>100.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=35 M=100 Y=35 K=10</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>35.000000</xmpG:cyan>
+                           <xmpG:magenta>100.000000</xmpG:magenta>
+                           <xmpG:yellow>35.000000</xmpG:yellow>
+                           <xmpG:black>10.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=10 M=100 Y=50 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>10.000000</xmpG:cyan>
+                           <xmpG:magenta>100.000000</xmpG:magenta>
+                           <xmpG:yellow>50.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=95 Y=20 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>95.000000</xmpG:magenta>
+                           <xmpG:yellow>20.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=25 M=25 Y=40 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>25.000000</xmpG:cyan>
+                           <xmpG:magenta>25.000000</xmpG:magenta>
+                           <xmpG:yellow>40.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=40 M=45 Y=50 K=5</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>40.000000</xmpG:cyan>
+                           <xmpG:magenta>45.000000</xmpG:magenta>
+                           <xmpG:yellow>50.000000</xmpG:yellow>
+                           <xmpG:black>5.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=50 M=50 Y=60 K=25</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>50.000000</xmpG:cyan>
+                           <xmpG:magenta>50.000000</xmpG:magenta>
+                           <xmpG:yellow>60.000000</xmpG:yellow>
+                           <xmpG:black>25.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=55 M=60 Y=65 K=40</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>55.000000</xmpG:cyan>
+                           <xmpG:magenta>60.000000</xmpG:magenta>
+                           <xmpG:yellow>65.000000</xmpG:yellow>
+                           <xmpG:black>40.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=25 M=40 Y=65 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>25.000000</xmpG:cyan>
+                           <xmpG:magenta>40.000000</xmpG:magenta>
+                           <xmpG:yellow>65.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=30 M=50 Y=75 K=10</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>30.000000</xmpG:cyan>
+                           <xmpG:magenta>50.000000</xmpG:magenta>
+                           <xmpG:yellow>75.000000</xmpG:yellow>
+                           <xmpG:black>10.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=35 M=60 Y=80 K=25</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>35.000000</xmpG:cyan>
+                           <xmpG:magenta>60.000000</xmpG:magenta>
+                           <xmpG:yellow>80.000000</xmpG:yellow>
+                           <xmpG:black>25.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=40 M=65 Y=90 K=35</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>40.000000</xmpG:cyan>
+                           <xmpG:magenta>65.000000</xmpG:magenta>
+                           <xmpG:yellow>90.000000</xmpG:yellow>
+                           <xmpG:black>35.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=40 M=70 Y=100 K=50</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>40.000000</xmpG:cyan>
+                           <xmpG:magenta>70.000000</xmpG:magenta>
+                           <xmpG:yellow>100.000000</xmpG:yellow>
+                           <xmpG:black>50.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=50 M=70 Y=80 K=70</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>50.000000</xmpG:cyan>
+                           <xmpG:magenta>70.000000</xmpG:magenta>
+                           <xmpG:yellow>80.000000</xmpG:yellow>
+                           <xmpG:black>70.000000</xmpG:black>
+                        </rdf:li>
+                     </rdf:Seq>
+                  </xmpG:Colorants>
+               </rdf:li>
+               <rdf:li rdf:parseType="Resource">
+                  <xmpG:groupName>Grays</xmpG:groupName>
+                  <xmpG:groupType>1</xmpG:groupType>
+                  <xmpG:Colorants>
+                     <rdf:Seq>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=0 Y=0 K=100</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>100.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=0 Y=0 K=90</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>89.999400</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=0 Y=0 K=80</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>79.998800</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=0 Y=0 K=70</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>69.999700</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=0 Y=0 K=60</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>59.999100</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=0 Y=0 K=50</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>50.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=0 Y=0 K=40</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>39.999400</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=0 Y=0 K=30</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>29.998800</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=0 Y=0 K=20</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>19.999700</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=0 Y=0 K=10</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>9.999100</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=0 Y=0 K=5</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>0.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>4.998800</xmpG:black>
+                        </rdf:li>
+                     </rdf:Seq>
+                  </xmpG:Colorants>
+               </rdf:li>
+               <rdf:li rdf:parseType="Resource">
+                  <xmpG:groupName>Brights</xmpG:groupName>
+                  <xmpG:groupType>1</xmpG:groupType>
+                  <xmpG:Colorants>
+                     <rdf:Seq>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=100 Y=100 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>100.000000</xmpG:magenta>
+                           <xmpG:yellow>100.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=75 Y=100 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>75.000000</xmpG:magenta>
+                           <xmpG:yellow>100.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=0 M=10 Y=95 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>0.000000</xmpG:cyan>
+                           <xmpG:magenta>10.000000</xmpG:magenta>
+                           <xmpG:yellow>95.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=85 M=10 Y=100 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>85.000000</xmpG:cyan>
+                           <xmpG:magenta>10.000000</xmpG:magenta>
+                           <xmpG:yellow>100.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=100 M=90 Y=0 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>100.000000</xmpG:cyan>
+                           <xmpG:magenta>90.000000</xmpG:magenta>
+                           <xmpG:yellow>0.000000</xmpG:yellow>
+                           <xmpG:black>0.000000</xmpG:black>
+                        </rdf:li>
+                        <rdf:li rdf:parseType="Resource">
+                           <xmpG:swatchName>C=60 M=90 Y=0 K=0</xmpG:swatchName>
+                           <xmpG:mode>CMYK</xmpG:mode>
+                           <xmpG:type>PROCESS</xmpG:type>
+                           <xmpG:cyan>60.000000</xmpG:cyan>
+                           <xmpG:magenta>90.000000</xmpG:magenta>
+                           <xmpG:yellow>0.003100</xmpG:yellow>
+                           <xmpG:black>0.003100</xmpG:black>
+                        </rdf:li>
+                     </rdf:Seq>
+                  </xmpG:Colorants>
+               </rdf:li>
+            </rdf:Seq>
+         </xmpTPg:SwatchGroups>
+         <pdf:Producer>Adobe PDF library 15.00</pdf:Producer>
+      </rdf:Description>
+   </rdf:RDF>
+</x:xmpmeta>
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                                                                                                    
+                           
+<?xpacket end="w"?>
+endstream
endobj
3 0 obj
<</Count 1/Kids[14 0 R]/Type/Pages>>
endobj
14 0 obj
<</ArtBox[23.5835 0.0 592.654 555.137]/BleedBox[0.0 0.0 612.0 577.261]/Contents 15 0 R/CropBox[0.0 0.0 612.0 577.261]/MediaBox[0.0 0.0 612.0 577.261]/Parent 3 0 R/Resources<</ExtGState<</GS0 16 0 R>>/Font<</T1_0 6 0 R/TT0 5 0 R/TT1 7 0 R/TT2 8 0 R>>/ProcSet[/PDF/Text]/Properties<</MC0 9 0 R/MC1 10 0 R/MC2 11 0 R/MC3 12 0 R>>>>/Thumb 17 0 R/TrimBox[0.0 0.0 612.0 577.261]/Type/Page>>
endobj
15 0 obj
<</Filter/FlateDecode/Length 20803>>stream
+H‰\WInl¹Üëu½ÏäÌ­Û†W
£á… x�\ß@Û÷%Õ#zñ›¡zIæùã/¿<~üúKzü᏿<ÞÒCÿ]©=þýöãÏMþï­Î«Æ�^¢^+꣖¸FôÇÿþö·?ýŠï~ØJÜ­dÉ¥ÀZ~ä:®Õûã=z½æ¨Ïeäw|ÓƸrGüxÿ<à¯{üçËb‡Åß¡S<æºJžñ(¥_)Çãã§~øóí½_-Uüï{ÄU*níWøg]kÁz”k´õøx{/W�ð¸RÆ#·k®õxþá!Wžãóôñ¶h¤|ž#÷+hz%_­×ã×WÌÏË#¯+
Æ12~
+K	?ú¼ÿíË¿yó/çÓ­ÂÁtÕTÊ·‡pm\£à­ÈEŽ†k땯ëëˆÅç>FšWÎãû'QÖUkþ2ñyNúõ>àotf«Oë—õ}d�}ý’?K2EÇ~Cjcµ«-¦)_áÿ	$óg÷ã+y	±~>HíµÒ` äùHýˆ÷-XÀ9!ãIY¨Ì˜ásEõÁƁÐF»-ÈúZ¸w"]Ÿ?(8:I¼"UY¸4(í. ÓÀXˆÅÐ3â£_™~ãœ+èD`c”«ô*
HŒÀcš^‚ÁEÑCL¨%Ú¸#°¤ÌÂ{™|Óžr‡`teòŽ¬ò‡¡
´¶¬"3Ý‰`Û(îùê}ß1Ž¡
ÔB›B$Úº«—Îg´åÔq l0q`¡•«§.¤1¢-“Šh°L8Ö×ô(2-ܘ¨k›@¶*’�öÒ+ãšH;:öê¹í³rr 4Qý,,}<ʱj¥*ž¾1+!w€ßÇ…
+׳+『êÅ~vö
+èª×f¿ËyŠ;z+Žh3Ð*+;Ú‹&Ðò²^A^x;˜�ßdU<Ι—&_3çÍ^YLMn
 ³«»ðªI/2JËáìFRU- CºŠ™wâ0²û…µðzwC¸¶Ȧa¤³A賸	g¥MŒ™i"ˆew6Àas÷T'y%Æp§£WpFÔëþ{U>„6Êáªþ]k,w2
+ç$߯Ò<Ú`4šx® Ëm‹AA$g­®iA–szÞ¼OI<Š•ö�­†X4+œ‹ó4dnj\ÝÎOž[Ÿ:sXâëÄܐtã8ÅeK#Ÿß|ˆ·&�UôX ¹f²« 8S79æÙøý ûHLrPË`Èðé/É!íËÝ^×g_§¡„[ŒŽoPŒÅ%ºÂç¹ÜŒ#œÊ;âràùMÞ§e…µls1ÜÖ$>,ÊÁáç#;EœêrÔ±Ëú¡	¼aØæX4æ±E¿Ð*«l‚îêïÙ͵LS˜â´'6¹„å“)çäȁЮíx:;“Ï@1ôá_°Ú©i&ÝѪzü@ÌTEl‡îÇ¿Qê×yÎ.¶«
+'KÙl÷ŠÐŠH,ÅƒdÌÒíÛªä\[õ­©6‘î1ëNeÞõ,Ú®eahË'óOŸsùbþoÄÃcð^!œ?±RvÄ4Žúò³’¹ÿ@<Âf÷8a4Ü=Žº,v$ÜÑ¥í!øŠÐnLJ‰st&G‡Ì9›¦/•…Ûù©ÉÜ”£$¾ål/i:ËíN5—têxJb´ìP–º,J†/¢-±;hªÀï�- ?kQ=OÖ3Ϋx:up…ÐÊזF¯m@íe÷UMòji8°£©ñ í‡¹ /â@žÒlsù"}âÛÝE“£�ªpÊ3,.ŠyJ}îižiÚ5†ikð«h,tF„&ªœÒ\CÅó<’É•Ä\-¤!!›¡
.³LÂfe-Jqó1†INáùÚ•\=€'�ø,þ’™ÌÈæǹ •3Æ"—)ò»Ây�´€!\l“t‘Áœ~|RCÍëïœ1ECðDl#/O-0±ney9ÀΓ 	ýç,Í|�´€
+ÏͼµHÑkÐU¾
+ƒ7Ñ»LÜÚ@N§W’FyÅYœuÔú€X—ùuüx;�fcH
~|ùT÷±ð|èçEšÒ‘ú©’¨|¦átY!æ>]cÒœUKËÇÛ‰ðPÛÕ̲8v¸$%+ø¤œÚ6S».„íQüI_íÀû³1Ë•ˆªY6Õ¥wÀ
–gßìÅ%ŠÚÆ{CãTt܃-…w ;b²À²ÁpÅ`ÓZ³BЏ´—øIé8S–
+
ÌM’àÄîä9–Io0:1 Ÿóf½W„¼	}.žÄ_(&À›­Úé„;Q¦öÄ­›þÄ;ÐæÒY¹{ar˜Š'¿u­B¢fKÿÙDâ	å30c2¹&K„¶ •<ØÜe'²Å\©†ó¢T„¡òÒà+>öõ5
+¿‘½‘¢ô‰· ÆñJ‹C[PÉûʺöôŠ<5£—“T¸†r¨í‰2 ïóÖjbq!›éah
")¼L3Õiöièb‘ÓÓ÷Ã=Hé¢4*¡Tå;uáÜB額"ªRÒZU¾ò>Ϫ['H|ŸM¤½_¡o%ñ¬=÷«+Ú^\árQ…ˆ•g'ÒV6Ç·ÔJ,þµ…‚Äï
 öâ;>¢ƒðäZµ²…jŒj¹„ÕËp‰ÈSª<Ç–#Z… ’ª÷L¯F Ë‹bnÖñwä©å xØ7®>hÒáy	Žã^“½j­>¼Š¼ZeòðR˜‘'gÙ;á@$×#¯™I£ð�ð=ÉJÔË}•Ü«5:“†³zx‹å¶¥EêÐÕ\\Ñ8NÍItÔ÷¤â˜K2ßÏøšåè€6¬
EËuËvSAe5s݁xœ›æ£M“ö(ÌÃaÚÖEBè÷åžHØ(
+'iå¡Â*ÉMT‡Êà@žZ‹FÛNYÔ~y··–¢5Ì|´2qGh	^?(y^á¾ãFò¨oŠŽ½½"n+ÎÐÔäÆ"‰JÇÐÂjí”|âÊçÖ~EL™£Ï£¸á¤jc÷uSNå UäÇxj'ZُÊLHk5ÏzVKݦj2Ͻ"^€Bcý9Š¸’£On1¸ Rè=Ê=q"^€:ãË8Ï*ÆÖ(ìµ\#Èñ¥ùìeî@<7æ¬ñÔf±M¢Ù—:!ÂñéO-çËD»ÒöŒìÛšÇÁéÝðŽÐ
+›
F†¦'¢¹{š1ǝ	N@Y{zEžšÌI9@©†0ËÕ2¡ŠŽŽ€×,{r O©m {­Kº/­Ý’Èñ̳‰î@hÜ»³X8¯Ý»”=<úÅS/*+÷•–0p8—¼Ñš‡3hrnX{”¢Ï„6‹îÛû5@ïqÿÐû&õ%…ŽÊ‡6îÈSʳnõQ½îŒ><‘³7™éÍñ’R½#´€M)Yñ¡b)•kì…*‰íšM§Ãýq Öëµì]pm;=mN®C;€P4qöòrG¼7Œa„Aàb1ç4o¯¡mfÕØ;ª·—ÿs]Yv1p¯Sø~ÃyfKÝë
+à˜Ý+‰5Ÿ` Â‰ hpéyƒJ&5[ÆøUUÊexSò¸WhÓbÔ”^@ëÚÉ*1
‹Y[ûÍPäQ$R$z³w@vÓ5Òv"Rº¡ÓIïi|§ÁݽŽ¹–Nt.§C°ì?<ñÚ~þ\�¯u«1Ð¥M§^zò;òüè…:íx&óW)—––Z¨~D§¤jÈf³íùú,õç…<BR	OgŠ~-Í„“ÚR.Êam»ê…pN¦}Ô‡æd•àÍÚnúÉ{¹GÑhö—Ô‡æu2èb’šÍ„bÛ¹mÛ/ÄlÑöÓæŠOªWJÕesԲϼ³–­?b_Af«@¢gü(ù^Þû�¤NêZÒõgn¨	’TšÊx?À
+À
+´©!©¼ÖÁldl	hP|«HM5¸·KyH†™â2¥KEdÈ5©Â<ÊDI2^i©lª—½)HŸ\™žGˆáq-' QWT¬Ž@Ÿs‰ôAÞ´cÝÛ(¯ØÖ–7ÈiÅÆwxƒ/b{±ö{z[†$
k2OïÖlJŒ3бÉÉ\YoÊ@I¦’Þ‘Œ–¢ª̉°ÆVÒ€NbgÑjmùKÓ‰á[ßÞË…<òo-;U¦f׬GóŽÎ×Þ¹·.ľÓ3²°I8×ðÏô
+ƒ	fj5ò
+Õ	æDì~[˜Æ>ùNGú±eÉJA5üY»„ƒþ"2ÍÚ^šS©'­pÔC¶>ìrq9ž¦‚½Ìt
ÆD8xc8ã„•€Óº$=–#ÌP„¡¯¡x1A{ÁÌ'3/Še¨x$§À‚ÁÅS'ÏŸIðKDW}ü”¿¤¾¼MÜÁ&:^tIÝv®N¶Áù¬­çeRk89†¿.~µ¦{†÷ª“û>úÞ<�<Læ!,E¸q
+¨ÕÏ39€žk`¼†éa×¢¶Í£;óR[•éÁ­]u!2Ñ”»j®ÎÜÙ–¼nwsZÞYÊ9ºù‹°2¨ò
+ÓÇÐDä°ä-
+'¯6­“V˜5NÄCÕMm£y.ÁDxf2Úšíž°,l`éDo„³áV€´VÅ)SÝœtõäœ"ƒuNA_Ä<åiG—‘²ƒh·²;»Š¤€nZbÜqJÛ¤SG]&©,û{DªZÖ¿)èpšôùØÈÄ\‘´58‰½ÙÌû#žMbé(ôz§Jlä9Þš>Vº€:Ú^ˆõË!‘+ïJA½¯ØY–ΐ§fÒ¾Ç ?OP*”Ø¡Yz$_€:ôBœ‚–º×Èóƒ”ON*¯™Ý63“¯}YG/ä‘ÃhÅ5d×'­¤Uq”¦DSÔõEþççύ°ÆøPšÍ<ÑåÓÜ)isÛr’o/„þ*£5í*o…igyrÈÌ:)&©l{´yäÚÆ´ïàÌ=J‹Æd¿j]#EÜÈ£xSº—^€0mTöªJ7#ŒaQ¸Ö�Ù8cÕ=åœë°§­2ÞÚæÖpØx�[÷^³ø¸W¹ý©Œáb(–š¹BN€ þœ~°e<­]ôXؤÕArW™ÿaŽð/¢täžP³•‡×Òs™]Ï;/Õ8‘GUw².1_•—@!j©g=§fUœÕ5NäQ:ÚKÈ?Ü×äâ¯59á•ìÀ1â(NäÑáä¹CYY£‰š%¬¸56…"žþÜk`”Nßwp1ÓÉ23Åœ¹çG/dZª“Tp9L¥'°Rßj«¢$Ô#]`ú"Mˆ[sš eQ)ta“€!ó³›±Ùv,q":GÙ‚=É­i£À1‰NצGìD<bÙœEGÏT”»McÁp®ÍqOf	kpN1KÎAîu‹yô1´ëHfš1[ÍÜ-¦Áy½l
EjåÔsW[ÞYsŠ/ˆ/láÐ#igöø‚Á…˜we·±.Ñ,µÒ§ú’ÿÞVèì˼g‚%öÜ
+@$B~d2À@”:â­7¶#}‘2v*ºžsÅT´UNÅp“™ôœC¿ˆCД€©NAl;ÖLÃ)¨ÏøjSЉ”ßµWÉzž%öVe
WÎÝ[P/ÄîÂ>?É~åŠlAFâw–Ä‘Kö A_Ä&gLßëbˆ,°ÿÍKb¦-*Ñ+=½Fé‹8%77l¶è¤ù0(­Ø"1•lÝÊ…<2p}†Y`›g²q‰¶ÇÍ’I·Ÿ§]ãØxÖå4WpÓÈ‹ÿVËXç ãjÆ°Xô±ÿelÑdƒ¶pvµá#%ÓSmçÕ/ä¡1o1ûò¤BázHo*Š 'ð0´f93B¤dú[[Ss¸Zm;Á|¼‚*K’…ë�m­!×Ak®¶3GôVñ¯Ó؉lQµgîá=ØÒ ôµÃ Ü®#^GÅ	‘†—)°d½~xžA‹/0¯ávª[;£cq-ÛGw<ëÜ3Í�ª8w¸ÕÉ¡f0¥©ÁsÛ¯'ÂÛçÂÝùƒIýÑx>üÅT?e®_ˆ:‘GqhtgˆAïDŨÁ`e¨‹ÓòßíNO€]Œ›/Þ‡£Pó2;ó.SûÆ?Ësp�ž$<–_9Ið"‚ímœL†þ.qhÃÆ%bR¨J>
Æ·‰Hª¾ÒÙ¤™EêÆã®â„15É«rÊèD|ZzõÃÉg/<Ga
�í­©IˆÕµ5nêÃé¨]#ú|gŸÁ>ã昘}Tj„MçF¢ñ¬Î¸KFãQÁ¤:d•,Ž>3MÔŠq!V®½ß¥oEŸ½cg.ä×êÞËÍâw"ÔϤ¤ä‰B@ûŠÞTäjË;èZÆ…<Rå>†/’´
+—n5÷'d_ÎÏÿ/òÈ^4ÚöIêÖÂÚ}ðo‰ŽÜºØa
üOŠÊxÉ+Ôq+2æE¯S¡œ�•m£'+ËRíøIŽ«Í³é'Â>Z
8[’ü'J˜>PÚh%À©åD嘔ü]º\¦˜V<ñ
+`Ûs+ë:a¨L§\‚I¸€Þº™h—˜÷èµá‹RWwf•ÔƒúqÍ;+´æŠs+3\kl%%ñ7|S…Q¥.…¿äNQ3e°av!‡ëöVÀ^i,)
+•E—çCۻĸ‚ø/Û¯ñ•´AIkU	ªé›¶+NP_äQR¦bQ}5áŽ,„d1¦#ß¾‘•ä.Äi°.këÆœ‘†ÖQ01<qYèxþùs#¬Xõ󺧇<ëžÏÀó£7F¶a˜è³¿Ê¹5†.ºg÷PºôÛJv‘;9ˆ{tΰg]©iW쪎Dc„™µ6^È£PT·y•á(CüÁ“úE¦ÿG$êÛϳ8ÈãX4mÅ+¿»è�l9y¡á‚íC£/„ı~Éf'“MA´LVLGÝRV=nbÛ"‚*ïÀç$ë@§È4c#Ö,
+¬q"äQ–l–ùQ:’È¢㐏‰Ÿ ‰&žˆ©87ër¬æQ$7ÜJb¸íÎüû*#$á‹PU0-’»&ïDÝéœ7|…šO¥Ê’2Fq:‹Û”ú3)Må¡)¶NJ”Ã*™¡—Ù!_„"Ë5ï@¦DV]Êš\ҏø‰_Moú"jù…*Ï8T¶u»³;~¬Tt¥‘†þì8Ü-4¤[.…$ÍŠaX5ôŸ¯�Ú)ãs"6>­Æ²¨HCeVmd)Ù0¸hýlž¾kP——Êž„ó$àê™"~ê´¹*v>b—²
WC6°›:RJAìf7U‡zôBlF{Èîf�úù*É‘#9‚÷~E} ˆØ—/H'A= ¡Á�S`tÑ÷e‹Wwf@:k@€dXezFx¸››q2فfn‹­œÜ ÝRò@,‰s´[‚ŽÍ8·5R‘¬î+hÀ­r /
+õ2fèÀAT—7ÅÛ#>˜‹-HË„—@ž¤&;´¡´)÷¶ørÔ0%WÀžfØ0`¥²Ã¢ì°LšyÙ®ò¾ÆÛœþøcóm6 ÷clª{ª’6í¨®À‹­‰&1ì(rÓYZ¤fÊ×xÑ$ÕùE!u»æ7.
+¹,}ƒtûÉ+ð"•G«†«X©˜°+ÈŽ¹z¨ZÌðþÑŒî†J1ƒkïÅô’»*ªøñ黿®_òG+œGe31mÅTÌÙÎ’
!ÉQë¾�lðÚôŽ7ª"¿õ…v«-–|J‘
+dˆ;âV*Ág{µß†Ú+T]UÝ)Â@º£¯ˆYôEI±	;”1êùÄ$݁i¦&ŠßÊû@ÌNE<‘UôC–¼`v4ÝÏÖò‹Þ¾×|¥©ìfS}eI
K¾&…,g’sx¡+bŠÝÕ'KÕ^ˆ2±H2˜êêWëL8,²üŠ�Œî^ɏë]¥®¢8­1ãB”æcñvú––TZ’ÜNÎnÇéœmiÅæ¢éÙͳh˜^ä¥iܱ]n{•­ñ=¨´Ù!’˜EK?¼;@..ù
+‘dA€>xÐáÌÖ‡'b1³£«Äv“íµ2w±8«Ý½(BQ…ôúj:šœ4º[ZÀŽ7à%¶¤ìh>°	PVZÛÌûíñû´¹#/YšÔb~ñ l­´5&–ßm¬²dÿ TÆõíÜ©ÎÎ"ÎÂÄ“2”¤hå·Ü¾ ŒÖd¥fz[’ùjüœ$¹hpÖˆ7fUŒ;bë 1»åé-öò¶äè ¸o©o»;†ÉŸíhx®'Ó%?¥e•¹C$‡qÖg–œØ ±?¬vU-~ö&nÀKžh€†ÆE[ạiˆv|`e9ÊyEn¦>ÊYÂlÎTcr”…ÐKÊà됥Šç1ÆålÈÜô`w§óùñÇïéá?¿}üñÈúÞ,r@8
õÇîçO=È¿ŸtNûñ¬ Ulû‰yAÙô[Dý^~<³ªa~?Bmøò;Ä{ôt,ð[{|½«WÛWôXâñø|�ɯ%…úåãoøóöÚA�*s âŸïÅ¿þy=8òñ׏þø7Îý—Ç%	RwšÍ\î¾$—!Ïáºnÿçíou¬—n­ôýŸÒ$'>ƒ¹Ý+^¼/ 79ðï<Ç÷Ž0ºhàO³#’c¦Zøÿî¨`²'˜LΫ'ÞšMæl ôqå¿|]ø¸Õ:ôceqtÃtîï<ñ…Äšzæ¬y
+`‚Ÿ[Â詆ïªÅ9xâz'7;{N¶]Cí¡Iç×Rr›³ø
ÐïÀÌ}½NÕÒG»Ä§n¡ÞˆïS
+%pv_ð(B±èUٿϸþ{?çŠ9’)üîýëtígxŽ[?s}ô³¹ö3Cü¯~æñ/
S¾64—·†&â½{GÃD…3E!G~!™ÙªRPýSÓà eq,ò¾™ÀÔ<H¯kŽbnƒR2íÁeJ[K>Àѝ¤üh±b–_��ɶ!€â7¯*Oèš:¤ÓM""KŠ+ÂY>‹È¢¢˜žÀ¬t;uý—š@UÂ]Æ0¥ÓÞÞT¡>›¨ˆQ-¢{Qˆ;B}†áRÎ…F	ïb¨»9l±Â<¤¸¡,÷&„ ˆ¢ ¡¤äōw2xœ¥/`|*ƱÎ,}»ÆqÁT¢]…‹¦—VÌ;–F¼.)sÑîç\Ïj©zgø^ÈpL6Ô›6p Ôë;B Â˜ü¶ð/7Ôi됨ÖæåЄ!Ðd´nzeJòe֍Ÿ$Át^ºuêØ6d:·^m=mO¦|°šO^TÙòmŒ^\šÉÕ±‹³“–ñžª³ßwX¨+BÆRÜÞYŽêX¾cß-È«FXªc`F;DcƒÃë•ö}é$±’|‰¥(ÂìtíY†R·‚#É
B
Ú[:¾Þ”^šÒ
+5定<>X}wo–’UYÙ«Eî�€ÁT×4š<;ä×d±Ë8A ·fuëO±anb*háÆ!º÷ð6q_Z§QÄPÅŒs Œ‘eëDæH,
•®™Št=0^vörË”À‹@ZÜnrœÊø;ªNc,B¥oÅëwàE@.�Ê’/lRg0.¢Ñßr™
+‹ê�ðþ Âèâó¨pfQ¥oÚ�'}óîkž>¹3¨Ø3ÌÆpg´äŽéJí»F¯ˆo¡ðÎY‚¼âĽ¹ÛRÎZ/â(Ù•ÔÂçvÏ&F‡xß.ûÅt ºzv•Ó±žî+—_‚„yÈÐÉ\âòÅ}0jTõaŒebDÔÍ­c½¦ÆÍNqÓO=Çw$º‹LÂRô"·ÉÆíÚÊ8k™{VƒÞ�FÀW»{›¹À݈éðÀ*¾[é?¼7ºr f«ºÌ’M#*pE~“˳•ÓåÍxW„1ŠÅìDÿGÖ¬ªáÛèMæÙÝu fÞU¶ÇÎ{71^Qý›ï§×fÞñ™škDpþšk$lk._mÊǁx–­áÓ%ήæ#ñhdOL¾É:ãáû{^†À­d“ô¦âÀ0]É)®M¶iûÞGaÈK#š*˜[ŸÑ1äköE³‰H½<LñJÆxIite§ýhœ\Ô&ËEµ8z)ƒ³ïh/ÝɁ0Fsƒ¼ûkOÐ
+i×jf…Dº"Œ±|@z²ÈÚÛëTð$DXŽÙ¬Nä%éæA6I¸Õݲ÷ÉŠ6\Q±CÔy"/éO=‹˜´”¯yyŸ›²qön='9Æ@n«»J2kv#H¡è/ô®Èíz A*ìn2¶Ð¦`òAW–Dõ±µì"ñy)È}-Íwh¹ªvÕ@ü¸ŠCöäw„1V(û¶’v¨ë†áÍË"£Fzí�¡&ÎS~£j8Y••4$츮º“a|­8èÀ/Ó¡IŽS¿­Oš’ßh©+ÆaÜëòe‡q&ó:1b‹ù¶@÷úóãDx'Ô —WBWrlsyw>Ÿz¾Æ	K÷S…ѲG#'½JgYLWò;‹}ÏÙP]w„»È’_´‹‚íÙ¬’ùï"Å3„uҁ°M–œÊ¾è?ÊŒ‚Ìæˆ[¹¸î³ò¦2º€•4ýÕGT>“·ìNÄÖÕïwÄœQc:ʾ‰ÞMæÂ䀇¦ø i1Æ1w

5Î>¦G’)Âþ¸cÝL–°á/„§ÆùÊ'= q“ThUð‰¬V;›¢)"Bw²]ÌP6Éš×I@Ëí£HŒ“æ™>øÎû+RåpB;yˆµÚÃ]‘kÒåP2<¼ÑÔð„™ÔxeÉæXϯÑø„9Ò5$Ó#¡DL¦V¨ÛÖz˜£+òÒÐÞËùh$SŽùé|Œhíú„„c©pE,7²õ‡è#‡Ø@†wÐqñÅcIòÜkž¾Wä'Ì[‹îåúEJ̲éŠ0…hTC÷/-ÇÝwg¥ÖSÙ8Æ€ ®n¯ÊÒƒaÑ&Ï–ÉÖ{¥Z‰Þ+Ñž|†Éwá}ú›Ç5hvGÌÚt–± VawkðlÕG°-:G°l	Å·rHêð’N׌aÈdeßB¨©r*þ³ÓªüŽ¼äŠïM’ÍâTL/ì‰NGNÍ9mM.k9›Ò=XI ÏÊÖÀÛZK‰JÄ<�Þ/á0AW¨ñíR‘3iôI©‡"™ÃÆê
+È—ý‡ëêH’]ǁû:ÌzsžÚj4¨~WÌjQ"¤É²ÛK£°‡§J¤‡ç§½ýñÖóo�Ïã¹°ñ¼<ÖbÛȶåræé&©}?7âh¹²Ù“T<•$@¦U*£B˜Îáù٣ɇZggnòZK®[2F²ßÈ£¨4«é+Ã[°=IpZ¥Ýý{1I\÷€€iA|Ì$X{•˜0$J­äiÓî…Ä`©AAUú>|Us¤jÃ:!‰5 ‡ó˜$ŠN°¬hÌiÈ4\î­¾üã
<JJñòvk÷¬uØÉM–;7Ó€3Qž~@Z²Ìõ$_.­=hŠ‡êB‰äºx,ñ<£ZUIC–'i]~¼ ÖŽµ~HU$êËÅLÍz$Ì·Ö‘èD¨aÍÅ㧓;È;j1h8:Ä¿mÞús!ÜcûBÈÒÔThi™fmʤv¸ø¥F ú·~$ÎiT}ö`ù“ˆ9wàŠÍÓðT±Áyd3jlQÙ^0&2Îl3ÒÍl§Únîá=*‘§±Þ4JŒede„”b€ÌùB“…º†j6êØ"xȈI•ü¨²º‘á-ü#˜ÂøåiÙÚr~8b±DŽ¥¹G´éµÕl¿«ƒ&•™¼maHseè3.„{@s²©²É~} tA&µN­×þÙﱃ§½[oE Q
Ù9BAŽà6‹2ÀpŒ˜šTŒ<´œAC„Gþž[áfÔœÚá`á
+õÂUAóþ‹ÿM¿vS]×÷s#Þ¡ÑU’ErÓ;•¯¬`ŠO3~Þå¨äQ>Ú›CMJê–üŠ¢BìmM¹E%NÄÙp;™løÖr’ÓX+¦¶¿õ÷s#¼R\Cÿ÷Œ.Œ­…uæ”\éç«'ìá › ¼ÿ)÷:0È)BYp›MÖŽï–Ùr¤z#T=h‰í€n-º3éñˆ0».Æ<ŠG)›C2­ðŠL#‚_JGu™±³®õF$y*Òµu1KXc;Gx®È)Ô®ã~"¦Œž½G㍓Tš­y⼑†Š…±‹Ã߀‰KSF%åeM¶ëÐ:‹;—ÓYæô ¿!Ò¬P
+A8ªÛJR’é4Õ¯pz#܇f!)©ì~0ø RR§U ñº±îÖı’T2¥œ¡5á
+2{âTÆŠÏRs]È£x”x„Ì&ÃÚŽ5òå¸È0ZçÅq䜿g`ÄXYía(D3¾ãB"íøöÈB¹Æɦ³†Ï>Â!œˆ-ÆZaJ¦g*u«šÜ5þ±ù’¶Sî…ØçDkùÇé¦â=ó@Ì]¾öµZ8¥à¸ÝÑTÓÿŒ^a32â“öT5/„ŽGöœ%o´VK­Qëd»ß7`×Ù¶gfP=Hž)Íβs`Lù~.ÀÞ·†c”ýw–°0YüÇ&lÙþùDeš³^ØšXÛÇ’ø&]½“ãà]ÀÃ\ ñE‰8iU8 3‰h”ÔœaŽµ"L·fUôÈÎSQêæ²Æ2)Ã]ÀC ém8øê|àp‘‡ ô‘\•!ßků>}¸°umöãA.oA_r# sgwJcZ[:¯]ÖbÙ
º¥+¹\€ßM+œDC8£…Jr‹O_Ýà`Øê¦ÞÌháQå¡›.±¿?׏RÐŒ`B—ó1’M„Ù"·ð¶g´ï‰p‡á/§Ý~qÎægLžŒ'áÐÕ™çD<C]e#Åôd2ÞVº¹éóê/^Gï“å­áì¶U{ôäÌS¨oxG-3Bω˜’F7»&ù“J—%>áß
+EO&ÊnJºŸ´¼…Ì`AÉ4‹9’‰a¥ÉçâäcÉ«‘tКŠ£}eS<]?×L0žl¶wÜ¥â~ã#.ÄbÕ÷ø÷áˆ=lY¬Hð¦$ò¯âسÓQ@ˆ¦¼§ê‹#CT«z·Ë2}?7âì³z‰{¬ï¹ú¿{°Ê$u‚õÿ<2òÝì§a'E¿±GáR\®¡˜øýÜ÷Àä‡%àë'Ú|õÈ`´%Û‚ÌÁ¨ÞâÐP4zŒ=º’‡ŸZŠX“bbjwôy#\ڐî¢Ö´užrξì)‰P?Å…x”b
+«Æùo2§£öH»KFCŒd„ù~n„[`3åB•'çÙ£…f–Ïnü6¬÷já³OÄV½w³ðW¯Ö|~Ý•{­jlnñF¸ÅÒGä¬ÐQ’C
?`§ÎwîªÜòF˜[ê½Ð½p­v Žà¬\W^L¹”çFíºëÑ2>íjiÛ´NN±Ã¹~ÇØÔ2ªO@·Í¥8Wde†LÒ÷s#j“9©RS†FtM±ª°„ÂyýýÜ÷€æÆgûÈÒ²$VùŠ9_=ñËÿù?¥ÛŸïX,ë¦Íò�”åf›ËížÌ:âþôt¥1MóÁ&?íOtª¸;ü�8!4˜æ‹MEª"qtU‡IhØï,ιONL†g‘„2]æ¨Ò1c´5o™—žcØOÄ|1‚/åÂÀ(Y¹¥ÙbN+YŠnœ{¼óÖ̦þÁeRèÈbi2]oSëÞ~Üw"äÏ¡#œ²Ï’]aDQHÑ…;û€ØÕ¨tºƒDPuŽF#ÖßÛç*ù|NÄZ"]§{`ý|¶*ŽYÕùï«W)‘|N$$MY(yÀ|
+©ëBno#öLšËâ‰DòÙ;áä#÷•œ-™szÔ7ÿ%Ÿ‰ä“ãÓ³ô=KÒp´<åVµbÌÂ#œˆmFÏnÑÊBÕdËVc¢vx,Ni‰äs"v;ä2~V3]ôâK-<2‰Ô?÷òK>À
ÀSÑJ3â„"Aþiœª|K•ÿ~näùØÅúZç´ðÇÔ„{cŸCr!¶ŸµÛîJ\ÓŠ‰ó°ìiXŸ8šE
~!6Àøz8k-ÙÑ ›¾ŠÔÖýM-÷x#myótIà±.e!WAïz	’êlŠx
+t I¨*8lOgÂ]”_fr¶\;òË	ày˜ðÈZ˜HØJA¬¸[òYrVۍ¯¿€‡@a;1ïÁc9I»l.ï%‹¯ò”¾dúQ{wlûwÔ„|¬9¤êðá×ÏÂ.—²à,¨DWW!]-Å¡ºÌhòDïµê.ˆuG1-»VÑCiuÛ7iøðöiÜùcwuLÊlÄÑQiÛ.f5áx‰†®_&‡•<ѹùcSwßOÌa÷ ٝ€òdO­°ŠI߀¯lÛAêxš¦z3ÑìÉT,|°úYÖ§iݶ&òBL•‚$˧lÙhž‘[ƒh¤ÈXnä
˜šÊ6gŠ)‘€ªRˆe;îuv»îþϦ–D–E$ÚŒB<U¬û⥭D:� R=ÏU–ó&žŠq>‡®–Ëe–~#V¥=bÅ)QL%äIåá+k °fYÅðÕhV柕Hœ€·cY…pk‡@ÝÄ7,k­3•³/ï8)ƒ]ïWnyªy$Ɲ)–È*C½û4Qf„qϾðîT{!|Eë~f“àD’ Ù)Ù,‹Cöo„{Ì8š®aÒUEÃsdý¢Ig—7BW…±ÞÂL¸èí<ý]¸®¶GL¦üB¸Ç÷‚ñf-AvÕ"Æv“™ƒä_À£8c™ƒõçׁË[±`‘û{
Ó9.„{l‡ŠV/òÊêkpöÛ¢lêá·O„~N¤Z2z[J<k.“vYÊMëÂ+Úã8:”fj
+ML<åÐE¹kÃ$Ù¸�F—rŒNÆœsâ)‹;ÀWëéîû¹ïQ9ªÔ²2ôÖ*CRT-¦Fäï}E„:‘G‘¨ê½Øu32ýŸù*Éq%7¢{¢. ‡àt{exáºaÀÙÚ_ßo TJ^ |CÊH2ñ†mFi9Ñs…3ÛüÄèCµ¸Gì#û½ò“Ý¢K9;”[Ây¯¿g„)Ш”/ïgØ;ΑÑê§áùÖ}kþN¤NFEV¨›–î„Ò¯«Û¦Ùk[{Àý)ògGS_WߤDÙ#vÞšÖ”xD.Y¢(Æç€.Æ98¢¾ñxX)‘KžHóÀ»!ÚÍ°RÇNÕ#B ~Dˆ`ÚaB[Å8£M0ÝŽh˜¾ªz㌻$SÓ0‘aªi¾q?ƒXÚµ.š“3B–Ù‰µü¢!*<,S]:.Kºq£Æ1ç
¡I0\\ÊÄaZ"6"¿Ÿ‘7|FH(ͼŽHg¡À8W«Ö¢(q6LÑ>Žˆim¨„]ÌDG3Oy¢¡IÖÚ¢ýˆ[þu?CR¹®Ø)ÅÎ@xö_šb{ Ïˆù9o¾å„Ò	My4™" YxÍínô±Ò$+!EÂ5ç»Ê:ˆ¿­3ŽˆÅNd_äö@…wC(8ÐL}=mGÄ.¨Ñz!R©ƒ�}mø`eëyߘÄ︤␡¶>Ò_¤Uö`o	0¬ûîëÏØNlY±ÔeNË»kûF€6l_î‹`ˆ‘T(ç è»U“êÁ/Ó˜·ºG.JóR¼ó—·Æ�’–
+o‡Ê¼ËÃÜ2‰ˆ¨K�•š0‡êpÑ„”d_×£Ù„|lb$#»Ä⤘2¶bîÀúK_b0¥âÀÅ�ß#xóñäeÂñ|;RÒ—,ÔÇú¢#‹að¹È�ì�68Kìêځ‹®¨ï©Ûè›| fâµ,ÉPò6Ÿ‹UŒr}Ê€
+ŒÝ
+‹†nkÙ®âÝl�È™í~ªÆ¬Y®ñ¢‚a‹ˆÏÑlƒî‘KÆh殺×aÊY£æýõ˜»•?#¨špÒ5}=mµ=³¾ÍY=nزrÜ#¶A™ýž^ršØ†‹¢S=–jØÆ:Í—
úŒ2)|Éåæ †½‰74ÙÒ#°m ¶–¡
"ÞJ¦…mj…þ³‡9"ÌÁÛ­à"ŒLT<Ù¦Ç,•J<#ÆY9'žŒ
¬ž2JPÃN(dŒ(IòÆûÏ)ª*ïÈ2Í̹sr‚[˜áùV刘ºú.Ð"
6(ž´F’k8[1VMßë!…ðL3œ2hš( å…–®T^^è3r‰–Ûð5Nj¹»­èy¼ÐUÑ#B=ÙÎÑÃ’¤ø ‰½›C$ñ¶B÷ˆeÍ*{:ñĿː±	arô)ûesP\ð£mC6d|zµ7åÍÐã,3Ýr-ŽÈ%ÅæÎÀ&ä[òîxà%qˆÔ_Ýt#rÉÙ¤¹·N° ¯	“ÙÄ[¨fûv¼öcg„¢]UeMif"íí�Uv³Ýš[3ß#Lħ®x´f¹_ú͍:�m59{ߏ3b1ö{£WِT½¯…·ð´Ä­ç°
¹G˜Ã¢Sû(Ì1U‚XÔ¡uˆòÐ	É9îç °“Ć_›D$T¯U‹¥ï§MÙ=rÉÍ9¶ßdŽ²™­Jw)Ò‰¥Y9î;ÕìP‰9,é¨Û±Ö&wYÓÏÚîò3âk1¿žÁˆìu–+»™ŸïÇ?¾þýH_þ÷¯Ç_Y¡ ©€ ‰Âfûwýÿ?1]8þ³f
è“·&}vêÚü^?žÒ\@¶÷O¨ñ¥x­“~½üŽÏì‡õl~§ßKü~¿Ò~.)Ùo¿áßØmˆ›â|¾ÿùõóè°_}´¯ÿâäùú(ƒZQÚ½Q›„Ê€«¬£ns¬†éZKôó½>
+*Ç’¾À`]
+œ¿»/úöç)~ö¦h"ñÿd?„ÉLíýgNÜx¢)À-ù-qÙ¿½¯ºßúØA6‰ÌñÑæO�?„@R§Ô&;—LM¢Ù'¨2öÑ1¡xž‹|MÉ"-)|öñŽ Þïçó€0ÊùãyPÏÔ×rŸ"cl¿C{Ôª~ÿ§:þuÈy;dƒ”êƒD3pþB?ò1Ì(3§Žü‚(fëgÉᄬ魿À«o,È~þµö$ïÅë»ýì=÷;õ~µ×i?tã ú¦×CuÈ/¿#‚:ÑM\2¤Z@ÿKnáŒr>`VIµÛÞ~?ÎÈõ€–Õ
+‰’Œ©
+t§Ðè]$&>¹oÜQdöäa²öÑCÌ8z¢'Ó/°DH+azUŠ{) N
+•6¶‘€çŸTlØhÂc0¥µSäèl䬬dÀg¥ŠÇ¶ ¦‚ôV²›||F˜õ)•W ïCjÆ' 'EºnI/ž¤hæF:ôr@ƒN	GêH®c’†rÜ#ÌQlÄ°
+²Š†UßcÐÐ oÐBÕZÆî C CY
+@I Á
+ÝI§³À.*'©jW¡ZÜÈPqËç¨à¨´Eš9¸¬–¨Zª·ŽS¤_Ú~›ÆjGȉµ/Pü¦Æ:"HP¨2,º*
+•ý>ë�ŠÎÕuiÉ9îä ÈÉ~f@%Ðku×
dj.¾”Þa
+‚Ì.
v•BüãI= 8BߦL°º¯ñ8í[ñ󼓠»ÓŽ
+-D$b­Dïªä¹w¨!Œ”u
Ëh´ø\5
+S<ÅmPæ@iŠÁ³ÀüTˆs@¢~Q@•j¾9gpG�&m\Ó.”�û󄹫 ŸAÕˆõ9#H1¨ì/ìð
+#“Ø4ØD€3êàHn„ôŸæÀ
+Ñ^€¬
+·´Ö+q@°ˆò-í㈠q¦ó”	w)Cw›z(Ĺ½� 9#—"D¼©Gd*K J,Jpðù|
+E
+ËÇA›ò²ŽÕÔ&`K‰…3ÂR`3c©ÀLÅÒôjH‰¥Aái5;ýDUŽ{„9ÍíÞôZބшޭ™ûîÞU}#÷è"C­ÄcŽ"g«•p3”ãˆ0ÇB{ºç;—ë9fm±¥é[òûûahæe0¬Iêo,¯°…¶QP­9"{Î^FÚ¡MäèÔ;Ù0‘–¼Î2 g„ã¾0­ÿBBœTR.~°ð² V߯Hš³3BÀARJnl,‘wè]c0H§µM1Ƭ{„ÐIG[,PÈ(¨Ç/iBc\‘¶5_„zD¿«x됸BðĆ¥5¸"~IÅë›>#¦‘ŠxE‚§gåL¸¿€.Êaõ\MGÄdÖ9¬Ü{"™‡Â�ÜØ/–×ÍzD˜í»†Ø)5t³¸-ò(7û¥Ë¤ü¹&%“6†¯‘·[UÎ"Ŧw¹’dù¹¤7¢9GH‘ G÷ųFPšÍw6šºëˆ0Çr…9Zì…A)å®Ï”ƒ5¬iZÞBé3B±(¿%p'@�¿¥Šñ(Æz³
+êYÕ8"—$\ß²O	˜Ç./°!搲ã×]q ÁÚ×LܯczS¸õ é÷ˆKŽS c·ì¨jŠ>-BЉ÷\¯Íçˆ\†ùŠ°Šøl¤æ1ôÖ¬%mF-qp˜S.¸DnŒ7ú5¬ÚÓ‚Ú÷ã;FŠ#‚�€Zš"DÆõ,&¸Y¼®œnàÿ”r=#—²N–·
i€ÞLh51¸cùûU•âàI0ÝÓn"CZ‚rh¦Õh<ùm?àZÜ—ŠSÃ4[‡Š9	(Ã6¯%²C¼×ÌpðJQxBòŽèÊúfnt÷ၾõ@“á”u¹"0\²?™ÿãºL²åÖq :÷*j	lÀn=žjÿãŠé/qä#<'ER@D\*ú¦–ªî>5-3~O*úVÜœcZO©îä¦A»Â¤*òíåPBÉVÞº+œìNH§#²º×(d…ow×’_Nêù§t“ï…9K18EX+xÓÇcwBªsU¬J¯hñ%Ñɸ«½¥A¥¥J…nôªX·&£ûJ¡¢¤ÂÿHMMçÐËñBï¶ö½+ÔÏ­ïÃJ9ÖÏ)·A¯ó$ø÷4;ÇÚ-±è]±—º¤¹›Éy0€Û±*ƒ9T²¨Ñ
+ w%½Dî²B�£Ñ½f×l$€ã}í‘dô®ØÓ˜(*ö³øeFGwŠ†‡B™„V>ÿ|ñ]1…ü•ò֪ѥ§±}é¥l+ÓÑ»òÈ°wZäÇ_}ØExE(hóðsfLxWœ4¦>%¢‡ƒâ´¦ÖÔ°@%ú´}ï\ã[qà™Ä}0ì½`­ðǯ{*4¡-õ<L¼W…k`³¥Ôæ¡ë`.Ç•–ä:F‘mHúVÅ9	ÎÂÖb�œÃ£h—Ž1ŸÍ|YûQ�üV˜B±Æ6½m|Z!˜Ž#âÆÿ åt•&´øœ…kuXi‡+`t«nµ©|½‰]4ý©]\•G!½¶ßªMTT«wU!CŒý{:Ú’Ðþþ¹+`!(çLÐø
+¤]§ì³fâ1†‰ñ[ ŸDÒöGèÄ؇"7Ú6=×’+š¯
+×Àw­cŠ!ÿG×É(ÊøFŒDËádMÊU1«UíŒÈr’ïœ<xÔ·²,pÇK|+¼&E+kE›ñrfõ PÏÉM»¸í©tÿÜ•G :•q8"#>Òl‘ƒ ’]²]	Ç]ao@”gx­vOŠUä¦Uý
+Cç·ðˆ›Æq„ä�M%åBéð­]¬nö¶»Â1	ñETh5Š(³˜´‹-ÛÓ‰Zߊ'M®ñ¢s'yepŽ8ñP‚ÎËC]žò-X3ªî¦hò¨*ÌvX ˜ä Cƒé/I8ߊ¥«é¥hKÈJGiÚfC~¡Ø1ÍÊqþÉß»bJ0Ý´“‹ßr0$Ñ"S?n±[†¿SÒ’Ï“5HVÛÿ#ˆÕ”ÄáåóX?JzUì(ÁUeŠ’&s×Ä ‘‰B^XÕ•¦¤wÅÎväSØAàä–èdÚ¼ðLßOqª¿*¦$S"Æ“²‹Õ‹¤¼k¢HEkù!	½+|{žªõ…÷²U}”BÅØv¹ŽÖ9ß
+ÇHSÆëÍE£¦¿29Í_×SÚÌZß
+“SIÖâh‘“`(=çy0I±K¦ÉìzU¸îGÃûñ5HA<‘Ìq1ÁA_"Á!ðS`lâî¢Ã¤bÓ¼}㊀GúÎ?7§«Â(
+Mí~)U—qV°?éFžíØyªV¸*\£ìrRfê.lj…pZ-¥¹ž_,U˜ì1}ÛÀOcò¯NÔ”’cÕ¿9×
+f‹&Å+qpÒI)αBY¹h	Mþ{"Ù,­¢·u’
’[x3ì<ý]èiûûç®p
̨ÿbòÑMÐS›÷%žŠ¡¿ór“°^•GÀ´ô¤½F²ƒt-›]oÄÄžæwy
ߊiqŸ|oYºÈž¦;¿Ew§çóß?w…k€RÆû7Uƒ%ã¦þ\DôW¿°E2Òö
¡I(·è™QÜúWK„ªÕ¾t”Å¿wåžÎ|3"ÔN!m8 ©(á9ns‰oå2µã)§p˜ÖtHÓÀ´gäš²‘«ò™Öð>*„‹ÀTç‡)Iæ?ïҐ¿Ÿ-g9vOî›Bҏe•{⥆¤)äÈWÁZuàå°{ßd‚•’W‰?S½µîU Zâg<Rp]«åÊŸC8‚ÎQäêú˜wÅXt˜ôè¥4Bì}¤�˹4G
+ÏMáæ®Pø»×àih/´H¾…²NCj̨Ü×’ä^›˜’Dib=lL×S åcü|ð]1M†gýdˆŠZ^W¢"mŠ—3Š^…d"Ž-÷f¢#¤*°®“ÇÎPð®d°÷@° V{ØÁZaÐ�hÛD6‡“o%óMñwlü‚.ß
ú\	il×–é]áè•È^àY Ë+ÏV“.g¦o*Ü•Gٍ"¡›Çi/
Ýigœ9çd`|Wœ9ÛvÐ¥AB°0+¿ …}lÎk†„¶[¿'_‡ç&!îœS=ÕhÊÎÍ©Ëéæ*<ŠãÑz†½.ê¹Kö}¶÷Ú›–øVaÁ,–Ù7=Í]ÚA6±ÀWy°yæ]1Ï0
+ÈK'©ŠÙ¥™aó£˜Ê5Ußʣʘvð…µ¸†òã®ò=#~Ï%¾•G¬VUè(¸¯r26„Ž6t8À֍^®ÔUšiÂbJ_Å`óŠkqD/»'d¾+*�¶äœKu(=q_²ÇƒQª`âªp
xP¶y!›13‘ÿ£©Ýúöó–'Þ¶=8#8¹
+_ÖÙ*×á<3Ùch>N	L¶Xý*ØU4J;L¿
+3¡t«ì0ˆûP˜hšö¦?ãzúoÚßN;˜j«½
+ˆêZCOþ©’:˜äYIDï
+…+DÜÅ¢)W
+°·ÉLE©«©¦Ý
+|ULDe¨P·õ³S?x°•@´–^Z­[W%èø(;šDœN…ILJ5
‚	Ÿ#}àU°“œ’¿ “¾ËoEææ ‹†ßY"qè]±£MŽw>«phïê“møíd58zOS|è«è¦á»@B’¯Zq>&G‰¿àyW¹õªùiÍÛŒÁ¯\8{დ̷€ÚhÛ½Dœ[ô¡ƒñzaÆÊf4^Æ|Õ–3E;Çœª5É[1éôõo€”Þ®±•Lè¤ã~	‹Ð•¨S­Ë<õ-0«¡ç‡±—!80´'|átÏ€ó4bÿ>Í2ßÊ£ ʐ«Ñgìd~Û›Éfö*‘Sáªpü2‘Œþ@ØÙéíÁ·´¶$Ì|
+ñ7V6Ö&ílŠà`ªÌÀûÔÄaÿB˜Àåt£boG�"!%®v>T¾£VCÍ·‚5Z±Ibº¹
<n^ø t=÷îŒ?—¶qU-ª@=‹ô{Ô­èM{£i’¤Ø&‡H´zqÒ궷E°"òyALÁÿMÌázAh®Šápq2é”»¤–-vñ:áq¢I?ÿýsW¸ÄPôýï7=—Dýïæ®Ü­L±	¦î~vÔGì7¥á¹Õf‘ãÓ-YW…}5}.vs,1T™·L~$¤ji8Ç­ù)p>°'
+%ùh1“ãyï0-‡ãq4èWå!ÍâœÙ5c%-aÃ29øЮbiH.»*%b¬zÊ‘ÀD´ÔÖ&ZB¼«›j¾•G˜Ôö–‚÷ÆßLÐwŠ·À+ÓV(ûé:ËUá©0¨LLÅsQ’‚™gÓ4ùmš¾ê/Tí¬jvË躱`萞 Rà®iߊÄß!4ôšP„T“ø@B³ï<[K6zWÒÑȶt2ñº‚g#E…=q²õÜpô®$1è7]¾joæšÛt$Ÿý·«b>Zò°Ü;ü=¦Ïf:ªuæÙÛ/ ¼*²{^àuJ›.xŽZZ¹ä[pЉ~ò32¡Íæøï3c6‹²È–Þ£Q	Ÿ‹	š¾ŽOÕI$˜_;
ï0”ؾ•GnDæÜ"3ßFOßJ5Ýñ]aìÄd:¹"= vþÄa”(hV€)žøœ}Kq†;ÂÊŠGÄ37åDÇña~þVÎÞøbxÕ¸†vÁÑg®/Ìù*D±À·ò˜¦ÍæB¾Ð¨Á6á'B”XF>¤J­ñ­kšã* È†§¥cªuŸWåQ¥µÿ“^-;rGð>_±GíaVõ~\Eûbƒ0/àƒmÆÚôkH@„aÿ¾#"³{º‹K‰!@œÊíʪÌÊŒŒ0I§í™Ñ9G“¸ŠÙ`¹i°®–›$[Ú"Ÿ‰hZ#­4EVºÓ@Í÷ÕB(
«Œ£éÄál$%8eãîªz”³Å%f+ûYM¯FÇCŠ.éYò¶…U×b¡<`2¼#Ñcõô7šLdÀ\çõM*i¸Äèà‹ÔHÅydfqN)XcéJÄba$	NÅÅ=ÒI†|©sMe­;5XW‹õY§W V)U½9ɧ€ˆ•£šìškò1¶ûÙb¡GÍìÙ$ix*~1ª0ˆM
|m<­
²Ê4°%Õ+±zb9õ¤`=£Û )šîga3BPNR7YÙs™)“*Dw¸i¢ûÚ³’ÊKéïUy%Öwâ×i:ú-Dÿ¡Ia{¦4Q#	¢O
+F¼‰œß¹&:[8É€òe»65Pu¨`XSÓ0oag†ç)@;O]Ó<í5zjáÍÞhL}ÍY,7Miâ½�昪?.Z…D SðùÄ/–›GÊf©Ó4P®Ã‹Œkè-”a4Mt¶æPuN+æJ
„‹v§
+± ýj·É6LÑ,Ò-Šk)ÀvT¡ÖA£
aªŽ”ÌÊ[Á«ÉDÆ0ÁÅn'ËšÙÈ:¯—Œ0ž-7±Ð@ã©mªQÊLòÍ)I‘Á‘6÷ž-dÎhñbøÈÖ&sÎÕ–T¦st““pq	*”?ë²w.”hFÖД8[LDLAÕTPeðƒ2õÊ5!EÝ\r²PÉœ-C„Þª[°Ø¹žq>*nÆ•òrY-ò¡i•AC+:¾5“#˜ºéãßú«å&q¤¦¥ÇÎÐ1£‹MÑ®TàNÃÎH©+g‹	CÒpZ�aRKö÷LZ&Eik“–G߃T3ö�÷ÉØ8—åêQû¼èû6ŒÖpN¼—âÍÓeE°:ªNšÑ­TKAk4ÿT‹…¥I²n$/)(êZqUâØVkÞ°¢ÝgD$ÓЫGöŽ G²_¶+ú%ž¢x‹á&u4‚µ|‡˜eÿ…nl¸Ã^:(£ü´[,‰"À×½9:�#Éo%ä&Ù†ÂÃpæd0¨šä5ݐ—q‰ÒvÖ:ê9V= 3#Ca/uQT¤kUº(ù¬(bV«Å07Ì®k•BÜø� ú­4‘H]5ËM:ÍgÖÄQnpJC¶8‘²v !l’/›bp“óQ‰—g´i„F-“T7œ„g}°'6‹é -?÷£ê™ò‰S³Ë ƒAóØ„£#Q³&‹ª&Ó@>ZÀf6
t°¡ ™¤¥ÿ°i×èIˆ>ÞÅ1W‹Qš˜ýN¼F  œ
+¢±¼ÑƒU­8%ÚVܜϫ¦äO¢>âsÊNÅ©ût1»³á&š6RqjÐEì\†ÔÅ
ã´ªï397<ZŒ^v×–U™5û¢¾¨ƒw
+ôÄ‚êb1†Û“õt˜ÜÃ*5®P‹±äЊ+ލ%-7q¾'á'w³{aˆ½—bL¼UùX,7I€ÁžãGŠ)"f1¡†ÜA‡`®–Mù‰ç.Ó.9˜D- Ü‘Ž¬*ÒÄucS•ŽÅr“…DŸó›ˆ-Dr]+I¥lücÖéêh¹I—¥d2`PÈ¥§l0<0ë5")=ìb¡̍hH#÷àVÓ ¢É�9uçkC>Ζ›f«Vpô•Ô‹5K€r(O³b«Þõdà³";äZ¬q‰.$<Uë ®j딟<@$qµ°BIÓ‰)&1ò4Ñ@åš1/¤‡H í‹…}•+06íDAԝƒ£
+ó$ï3|ÁôÏÙbú'†.´byN2jž¤QØÙA×æ`ìÞëGûmÂîO¤wUøR¢ùà„'þT¬.€W@[Ј
T@Cg ïI!xfŠZ5üj1
$ô'l’cÒc¡†JUãŠG¦ªK,–›p8q!Ž9Š€»²UrB
+Œ¤%f[ëîà´Ø�!­¤¥H`Ae","#Ö¸ˆú—Cèlá «‚9ݽQ:5Ö”"…EhJÌ­>
+ŽSì” %³‹§“mÇüN®‘_›jÁåÙ@œIY·
+x*õÆ|j˜q]Ÿ’Ç•ªfÈb!1@­P]tŽ¡©CZ§Bý'gjÔÕB~SEU5
ùŒh»Ú½•;}â‰\¬…)eºXȳPmÒ€äxTAðžm:†JDÅ``³žu±ÜDÞŠ÷?}‘ý¥a<I÷àÀÊÖþÍ2ºXn"¡$âšr€\J›¤ŠÅDÈQÒ¦OãƒÕÉóÙBU<³!`@’<SIa%ñïMð^-Æ๕–Y«X?Ù^¥²õ¤Ù°a‰€³….@¦IÑÚMŒˆuâV³PÜ æ`;j®#gÅ`ϵé5¯‰<®iÜà¾üó$`>E“e‹Å\ˆË–!ÄCb´uÆ
+Åÿ^\S-ôAÅå5LfcŠq]ŠI=#èÍÅÕr³5sŠ[D#“ºEª˜U#ÏÖ&0z�àôØöàÕªRNÏÒ8k —Ëï>\ƒý÷¯ËQ¿¨'çÞ#­%ñË{}Èÿ_§R}E9
‹+ž`{e-ß—/—+ÇqCÛ‘˾[}ì‹ío¾÷ì{wíGÛ:ø¦ Oï.ß_~ùöÍÃåÛß¼yøöí›ôðÝ/°úþò®Ž&ÒƇ©uÝÿzÌÃSC&€Æ¨|פ©®	5€Fš×à=Ø’HWbvDT/e£ØDqÀçÜ
ðˆDÊæK
+Ö.’b`hš¢þH
^1Þý,_½ì·qÃí‚t=õýóDîÂ9b¾¶¥…íÛßý2·»Åoëþ¶XÖè™÷Œrcr"X4Ûú½˜ñ˜ðJ*Š¬m߈�u&m&c$‡uD¦çP_lÀ)Y`^`ólO`ûûiÑx„Ê$OØ
	ûˆûÛ×~"²á»Óm_“*b¿»ËQs`;ΗèK¿€_Ø
[<æí?Óx,Þ¼/ˆeemâ	‚cj{–XWä2…@µµìé‡s\»1¾¼në¿«gîŽ2»
+cüSGËƳ[sÜɯ/é`…hE%¯£ß½ö‰·ËoO÷P¯¾:¢HÍøy!ý�Î'å—„æ0C€2ëæà‹ÒSY’Ä××ÝðÉÃLH!Ê'¾Ö­‹kó4–Á‚–ë殧ƒ»¿ŒøJ8[‘‘õÒ¯¯-²O}Á‹|¦´ä‹ðÅ•õÕaì•õ³âx¥²¾8†X˜äÒÐDzSxwœój=ùî|bÆz8Yû¸(v=/_uC^Ǫ*¡Ž#c@dXŸ
!ŒRûjñÃgO—'Ötóµ(ÎAüX	<és1|÷L;U'TŠ¸Ó·ÏÏtñüî’ñOœ£ @Æ͸x~ùæ?oÿüñoÿøðøüÏ,¹=þÉ÷ÇdV ÚpP~f°ZˆÌÈý¿ÿæèÙÇ+4'µÇ+¦4UØìWÁ/¨ßùñ
+¸ã¯„_]¿â#FÏnú°§˜5õÍSj´êWݾLô¾û‘…gÄûyà¤ö×?>ÿê•4E“ýOÎöü—ŸN	#Hà
^ð=SöpRT¸ËÕ™˜ý"nBè×xx¿òv}IiËf;Ì_[ê^ÙÅÓA¸ì¬´ßd9ÿÓÓ³þ»¼Ï-&è»xÞÛýþ{¤Q�ÕwÑ=Cìþpø.åýæ}?GÆw×rz5è…SºcÞ¶ßÓqÿ¥Còáùtôù²ý|ÁCeUM/ãø÷ãµæc†ï.Uø÷Rú‡:”~[^8ݳýÿâIåŸ^­Šm�(Æy¯éŸìÜOZÇd?}éƒ{O;@¼VÝéþu«-·ÝkóP×öÕÿX¯¶Õ†aú+~ä!&¾Hµ?`o{¬?PÊú4ØØ:Jÿ~G²§cƒB$ùXŠtÎw\ãÎÕ$ÀÔ×£m†ÅK)ˆšea¡4´¤×{äÿª©ý<›§7}ñ|4§ÁÉ»wó8HRFš»ó"ܯï÷³†ËMÃ1&3:ZgÑpÈÊŠbäTû¸þÖ©a³?Jn°^Œ:ŸJ[¯Ï”mJÙ›]�ÑbÖÎî<êùëB Me1™0wÆYÉmÀÅö$Ajñu½@™�„VE}8H’‘1³€²ÿ³^�±÷
+—)/i)l³ŸTuÛ~h67Ý’’ª]3×ÛâÅu<N]!WŒÏ	Jq9~„)æ{O!ú-¹ª‹<9^j„«Ä}iÛ±í7„´(Sºá©³\ûÝøâÄՏŸT®b¸!xg½ÿÙGñ¯((fòoP¨\ý`�|zi2
+endstream
endobj
17 0 obj
<</BitsPerComponent 8/ColorSpace 18 0 R/Filter[/ASCII85Decode/FlateDecode]/Height 72/Length 938/Width 76>>stream
+8;Z\7bE7E2%+U>,Eq@jL:+:o5[LT3fU^jf=P5IV/NVVY>1HR+J!#oE4`3Z%$r3qk*
+3_^dQ<;!]IcB$gKOS7B.!<SDd;Fu"FPJTKDMV8Y`S$Z\qEm,Peb@;CkcNYQ;"t29+
+4f!P;0)%[QWm8Oa=KiZJLb"LE['X<kmkG/R-]J(kCgJ1+QCf45<6gK2h!'qqs$^0>
+6Js'=HfFuU`uZj3"%2#gY4$Qd/M9u.Hsc5.#o10]1a$sr3f>M4OFb4)jR1?M0mS<B
+\q_g"aT1+0gc]h_K8Z>()2*ne9=j_YNAL=_GF[0j^Su2:U&)9B/E,Ro8\sK6KWE;"
+D-M!CQ!_Rs?O_p'Y4q^6%$uh(AR(*kEQkUR\E72B-!V*th@s\BH2a7rF7U3R(>`n8
+d7839er,jgb@V-u[58d[?fotX7u$:\^M^]ZnD<)\D+;4aY;XjRp_E(S!`\5!>g_U.
+KO7In2u(@!NcJlp'M$C&0"gqWY3-*t3,>l*q.jYi4g(/9c!T<la^8ia_gHq:=1*I)
+gr$OgQ%RERf:G1oj#X9&#B66\a.p0@qDd9&j^N1/IH3q5I2qWdRsgaS7nd6/V-0c5
+]HTngd[-*`ki5r,RLs2-#ZVTbQ/BbsF=1AufA->*@D-]k]Ik[_4Yj2>?Ct-k'6>7T
+bGh8Sjh@,)F:)+#7i_p+XH/Ul!%*L@qu7K\"MU2,BQ$D_TgU,ieNHE+RNT+bs4:2L
+UfMTh`![[3_OD:TKPt.&8Q;to3@TA5Z1.[+PcEg&L0pGH=SNUiqA=[8O_J'+%CN^%
+!gndoktK!m1\o0HiLYm,iM5BKc!IWJ3i8+[V,^Km\K7mg:I-H->$QLa@-WQ5?\dWP
+XSiU.hf50QaF0chi*.\GL)H3<*$Q3"\2IAkEotXc_l\")'-gb,'NYb"0T2!d=l"Re
+5AECb!:p^i])~>
+endstream
endobj
18 0 obj
[/Indexed/DeviceRGB 255 19 0 R]
endobj
19 0 obj
<</Filter[/ASCII85Decode/FlateDecode]/Length 428>>stream
+8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
+b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
+E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
+6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
+VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
+PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
+l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~>
+endstream
endobj
9 0 obj
<</Intent 20 0 R/Name(Layer 3)/Type/OCG/Usage 21 0 R>>
endobj
10 0 obj
<</Intent 22 0 R/Name(Layer 2)/Type/OCG/Usage 23 0 R>>
endobj
11 0 obj
<</Intent 24 0 R/Name(Layer 1)/Type/OCG/Usage 25 0 R>>
endobj
12 0 obj
<</Intent 26 0 R/Name(Layer 4)/Type/OCG/Usage 27 0 R>>
endobj
26 0 obj
[/View/Design]
endobj
27 0 obj
<</CreatorInfo<</Creator(Adobe Illustrator 23.0)/Subtype/Artwork>>>>
endobj
24 0 obj
[/View/Design]
endobj
25 0 obj
<</CreatorInfo<</Creator(Adobe Illustrator 23.0)/Subtype/Artwork>>>>
endobj
22 0 obj
[/View/Design]
endobj
23 0 obj
<</CreatorInfo<</Creator(Adobe Illustrator 23.0)/Subtype/Artwork>>>>
endobj
20 0 obj
[/View/Design]
endobj
21 0 obj
<</CreatorInfo<</Creator(Adobe Illustrator 23.0)/Subtype/Artwork>>>>
endobj
6 0 obj
<</BaseFont/GDVRAG+AcuminVariableConcept/Encoding 28 0 R/FirstChar 9/FontDescriptor 29 0 R/LastChar 31/Subtype/Type1/Type/Font/Widths[168 455 641 170 548 484 214 289 324 251 550 550 214 538 529 548 260 444 502 546 508 829 250]>>
endobj
5 0 obj
<</BaseFont/MMXBGU+RobotoMono-BoldItalic/Encoding/WinAnsiEncoding/FirstChar 77/FontDescriptor 30 0 R/LastChar 118/Subtype/TrueType/Type/Font/Widths[587 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 587 0 0 0 0 0 587 0 587 0 0 0 0 587 0 0 0 587 0 0 0 587]>>
endobj
7 0 obj
<</BaseFont/YRUVSW+RobotoMono-Italic/Encoding/WinAnsiEncoding/FirstChar 49/FontDescriptor 31 0 R/LastChar 118/Subtype/TrueType/Type/Font/Widths[587 587 587 587 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 587 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 587 0 0 0 0 0 587 0 587 0 0 0 0 587 0 0 0 587 0 0 0 587]>>
endobj
8 0 obj
<</BaseFont/QATZKM+AktivGrotesk-Medium/Encoding/WinAnsiEncoding/FirstChar 32/FontDescriptor 32 0 R/LastChar 121/Subtype/TrueType/Type/Font/Widths[223 0 0 0 0 0 653 0 0 0 0 0 0 0 0 0 0 592 592 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 573 0 0 0 633 0 0 644 0 0 0 0 0 0 0 0 0 0 0 0 0 549 0 564 0 580 356 0 0 0 0 0 0 0 0 609 610 0 393 530 363 574 0 0 0 545]>>
endobj
32 0 obj
<</Ascent 1160/CapHeight 714/Descent -831/Flags 32/FontBBox[-454 -831 2384 1160]/FontFamily(Aktiv Grotesk Medium)/FontFile2 33 0 R/FontName/QATZKM+AktivGrotesk-Medium/FontStretch/Normal/FontWeight 500/ItalicAngle 0/StemV 116/Type/FontDescriptor/XHeight 520>>
endobj
33 0 obj
<</Filter/FlateDecode/Length 13710/Length1 41868>>stream
+H‰|ÖyTGðouÏ´4ˆ€Š’(}Íô¨hÐàDAÐõƒw¢Ü¨„‘QQñŠ¼¬îF¢nÄãÓ¼‘¸QŒTŒD#k<׃M¦™gg³y/š5šUGè­	›vû½š©_uuUwÕçõ¯A�„¢,RǧõŒkë‹‹¡-ßÑ’‘mÏtœ½û÷(€$�á]³I/ØV9€Ù”ç˜eîy§?Ða6ÀÝ™U°$/ößËÑC€ ë³s3sB·…Þlát¼~³iCÈæ°4Ncël{Qq‡šÌjçñ»
+³3±ÒZ
+d¶¡q…=³ØQô5°õí/ÍÍ´çšÃ†çÒ˜ŽiJs.(2ÊÀònþóŽù¹ŽyãÎ×Óx$À&ÃÄ"`FSÍÐQQüâŸlÅ›xdfBÌ&Ƙ\¨4®ÁðÑ>]iAJÒØ$Ô�F#S×ä&Q¦Jò¡bÀ1uþÙè¸4€ý€ötýhÀ1Áþ‚æ3ÿ=íÍjþÿñâJ&:‡V`„ 5Ý©6C8"Ðí謑耎ˆÂKxÐÑ Ò{“¡À+TØÐ…>S7Ä ;zàÄ¢'záUÄ¡7ú /ú¡?` â1	x
ƒ1‰HÂP$#Ã0¿ÃŒÄ(ŒÆŒÅ8ŒG*&àu¤a"&a2¦`*¦a:Þ «:3‘ŽdÒû߁Ø½øŸãÎà4Îâ]Õ/Q‹ø
+ñ5êp	Áe\Á5\ÅuÜÄ
ÜÁmÜE=faVàm¬Â|lD5Þð°šT`Ž’=XOö“Jj·Œl#ŸíäÙ‹?b3)ÇyÜÂ6,Dz9dùïâ#äa>F9ÃŽ%X€"80sQˆ¿’O©ù¥Ä, ˜ü™Äl|€lä"Ÿ`¶£{P‰Oq�ûqUô	âÇ1†9Xˆµ$›ä\l"³HÉ„©
•ÀÄÑÍ¢«
º‡¡tÞÆÒ“¼JF‘4’N2Éb²’l eÄ`:1"ÓŸ™Æ,gʘÓÌEæs›q2
Ì}–°,˳ÖÆ.d—²o³¥ìZöv[ÁbO±5ì%ö
+{ƒ½Ãê¦tS¶i¡é©Y5_4ÿ`~ı\$׉¹xn7‰›ÉÍáìÜ-î÷”3ZÙy–oÏGóqü@>™˧òSøt>‹ÏåùÅüJBQP…$aŠ-Ø…ÕÂFa«°]ø—ð³ðTŒ£ÅaâXqŠ8M|Cœ!®ˆµâMñ[ñøHl’ …H‘’ )’MŠ•zI½¥¾R¼4XJ‘FIi‰´RZ#­—vKû¤ÒAéˆtRª–!3²Yn%‡ÈmåvrYÙ*ÛäX¹¯<UN—7ÉÉ{å
+ù¨\-×È·(¼¢„)í”H¥£ò²¢(ªÒ]‰Uú)	Ê%Y¦ŒTF+Ó”,%W)P(+”5Êe›²G9¯èÊ}c	¶DXdKŒ%É2ÝjU¬C­µ*TFm­†«íÕ(µ³jU{¨}ÔÕ¡–¨«ÔwÕµêFu‡z@ý\ýB=©žVÏ©µêõ²zU­W½6³-ÌÖÖ–`K´
µeزmy¶·ºŒŠQcbbòö¾÷8äqÄ/çŸDû_W_7_?_‚o°/É—âï«òýÓg4i|Øø¬ñyÓs£Ñÿ¦_ŽßŒDÍî%½HM&’’EŠI	5³‘‰b„3§˜3wfÐb¦(`f5³žÝÄîb÷³Ul5{Ž­c¯³·Ø¿™`Ê2Í7•š­æCækæŸ8p!ÔŒÀÉ\"7š›Ìepùœƒ»ÏýÄ=k•ÊÞÌGòß›ÄãÇó“ù©ÔLŸÇ;ø%#‚`…ÉB†/”e3åÂCá‘1J”Äbj³™t±D<&^o‹Nñ¡ø5C¤ÖRGI¢fb¨™8jf ”Ðl¦HZ*•H¥Ò.j¦RúŒš9þ3Árj&Rîø3©òtù}ys‹™3ò5j†	˜‰˜yI‰¦fºP3}ZÌŒ˜ÉPr”|e®²H)Q6Ì|©¸šÍ„[$K·3‰ÿÓLj‹™÷ÕrµR=¬£fªÕš€™:jænÀLj&¾ÅL®-¿ÅLéãVC©øˆ/šš‰ñ
 f}ɾá¾TßMßóÆÁÍfJfˆñÔxlxŒ{Æ·†ÓÐŒšÃ4Züù|yÓ
,3’1ÃèJ3cüèÖ´Å8AÏW»Œ2cƒ±ÝXmüž& È?èïW´¬#kéï*ZÞ¡åCZ6ÒŒb£9Çdèô}}u”Ö¡9uù¯¹Û\óׄÆJ¬ükÙÇš™íL3Éy*<;=ežõž"O†gªçu÷÷žXOê±º—{ïBïï<o¡×î-ð¾åÍ÷ÎñÎòæys½ÙÞ,o†7ý^ñ½N/Fu%z'ºâÝÏÜO÷Ïz÷÷:q5¹O¸ž¸º·º·æCË8w²{¨;Ñ=Äýš{«öÐ0ÑÝÛµÔ5Émñ÷Ò¿Ñ/ëgõZý¸~X¯Òwêy´­¨áO@Ã:=¿~?è4»é3ô©zš>A§¥ÑH~!5ÓcõWôîz7]Ð;ëí]O\ßÑq«]G]‡\;][]«]ö†S
ûJxíŠöV«ÓÎh§´ãZ•V©íÒ¶ik´¥Úb­H›§ÍÕ²´éÚ$-M› ¥jã´1Úh@KÑ´^Z[-XrêNÍétÖ8Ï8O;Oº~¬O©O¬7Ï\Ѻ´õدòð¨Š$ÞýÞ¼ùU¿~|V]•	!!	„ÓÈÉ@¸“˜@BÂ}¬Ü‡‚@ ¢ ‡+÷A¹pE„¹D`¹‚ nf{&€DØoñóÛÿ¬ï«~UÕUõªÞÑýë(Ö1&WɃr¥\!—Ëer©\Rò¤Ì"ó	Ó(3B!¨û0Šïý8W/áû檕Xµ°ßØý¨IRá—"Ç*n¡8þyšhqjL×2µ)êúŽâUÚ}¤úRFêãõmú.ÿWsB¿ ÿb³~³ÙlåîÏö{I?¢_Ò¹G¿ñ@¯ÓúY5ž½?º”¶_?ù€ØÃ%nkÊC?_jþ̽óÿ?ÒÇÿ.o÷}–DÛ£¶è;š-Ê7òPÆÃyu…b"xM?’êÁ)ì”Ä“y{žÂSyO×&s·z·ÝÂñ£"Þ•
à¹F£‹á6:­Œ®Fk£ÑÖH4’Œt£¢á0ùZ¾Úˆ7ÚÉF{#ÅH5:ò÷h£±Ñ„¯1ÒŒL#Ãè`t2ºݍžr„-ÇÈñr(EÈQ2_–½eÙWö“ýé9€j¡xO⯨Š(4ÀÛ¨‡šCZ¡bÑyȁhQŽAèOeÐoàuLÅDŒÃr,„óè)™MOËÙUæÑÙ]ö pªN5¨UÀjC£d/IÓéUš‚õ4–Ð|šƒM4›¶ÒFZGïÑJúÛhvÒ:J‡é /èÁn:E'¨ˆ®Òeº€O„%„°‘—~QA<Ny¢¬¨ƒÏE
QMTqøJaµ(…Ø2E
+‹D…Û¨·‡Ú³Ä1F¼ˆ£b¨˜%¦á¤˜‚ïpqEÌoŠ•b™X,ˆ¹bŠÄz±VxÄN±7ñ3ÕE±8,‰bŸØ+ÊAâšÙS\2sÅ9qÚhöÇM»ÉE±øYÜ4+šOš™¦4#ÍÚfu3Ĭl¶5[˜.3Úl`¦˜I–féòˆ<!¿•'å)ùü^ž“çå¿äyQ^’—e‘¼"¯ZÉV{+ÅJµÒ­+Óª-oÈ£V€UÖª$oÉŸ¤×â–iÙ-i…Zu¬+LþhՐ‡å!yL—×åòš<#ÏZ9VW+×Ê“ßXݬîö¡öaöáözU=Xña|›W¯æÇø]ôP?ÞÏQ'‹<u¦P8ß¾YoÌ:\obhl­·±ó©|†žÁÇð±¼€Oä“Ôø
+Çóùx>AÏäoéCžÆßÖ‡ë#ô‘êÜ1WIÍê/+Œ•«ÕóÕ
+6A/à‹øb}_¢ÏÐgòå¶rö!¾SÞC!-¦´ˆb#>À|H[hm¦h<¥|G³èušI3°kð>ÖbþÏð©A"XT¥´”–Ó2*¤Uä¡w±a6ÓnÚIÓ.ú’öÓAúŠ>§}؁íØ‹=ø»p�_àKìÇ×8ˆâÂù=EoÑK´ÍEKÑGð"ŠÁbNãÎáÎâ{|‹c8ãø7ðn‰…ùÒEšX*–ˆb¹X$ÒTñ¡ø@¼!f‹ùbžØ!¶ŠíbVa%®ã\ÃU¢"žÁS¨€'Pã1Á‰*¨ŒFhˆúxÏ!oáMÔE-ÔAmD 5P¡F5„ ­ÑmÐqhæh
+bÐÑx¹èŠld¡:£2ѐŽ¤!ÉHDÚá%ŒÀ‹‰aŒ¡‚øàôCoôEôD7ô@wÌÆÌÂLLÇ«˜†×ð
+&a
+&£�ù˜€ñ‹Ñƒ—±‹±K°�óñ.V`.æàüt²‘AvqÒ´½Œ—ÓV³¿hÄÞº¤øŠïêòi>„6揬óAI,]­ÔürÞmþ•úß¾¦³x–Éþ;e³6ŠDnu‡¾*^‘–­¥ùmêoã¯ù¥�ï•Û~q,šµ+™Ãj±dæÒØïR´ÖÐodÕXM¯òõ¾ðP2>‚Åë…Å·xxñ¿õ•ZÕc-V‹ÂŽ±`Ì“Ù:-Us³ŽÊsÿÚ÷ôµ½wb5ÎÖðx.øë­T¼©øˆ·¾²*4éÝXªæ‹÷G¬f%XÄ¡êŒ`X*ßÍ,ïuÖZõ˜ûpÿ1ÒÚªÁò^ÖŽy£î»³fj?NQ¨¾&ë睧-U7gÙDöˆzGÒŸô?I›®x"sj}øMoßâËų¼õ½	ÞYÅ‘Þ
ŽÁÞáÊÉî½Q|ëÁI,_­!½XK6˜MÓ—¨sbÛÎÚD7uwêØ!3#=59©]bB|Û6­[µlÑ<®YSWlL“ÆÑÏG5jØ þs‘ÏÖ«[£zxXpP•ÊÎJË?Z6à‘2Ò»aÓÕOær6u;<An-ÈîӝYʐuÁíq(SÓÒ>‡Ûïæ(í­<»þÆ3ºÄ3ú®'p4d
ÃÃ.§Ãói¬Ó±ž§'¤*yr¬3Íá¹è—[ûe[_)£”À@áp•Ï‹ux¸Ûáò4˜WàrǪ|…ÒŒqÆä˜áa¬Ð”J”Jò;ûòà(î´`WýBQßm=zWV¶'>!Õ[!00Íoc1þ\{Œþ\Žn¾šÙDGaØ–‚IëXgw¨•íÌÎÊLõèY*¨@wä{ʆzBœ±ž¡§Ë«–s<aÎX—'Ô©’µL¼{î1ª8ELï¼x¡´%ë¶Å^% ˆùD_‹w“š¿#3U›ªPõè«eâúhÖY)žÿð]­¿‰\WüÎ`0€=f<3×€1æ5cÀÆ`l¼¶µÆ¼ñ?XÛU÷áí*U£$u¢(ÝRU»ê‡¶êCé_Ðâô‘Dm¥¨Rû!RÔ¨Š*µê‡|m%G‘"%ŸÖî¹€Ýõj[k<sï=çžó;¿sÎeæ¨\í̴ͽÔH°Ö¢ëDòþ¹„]'’£sÉÅö:IªŠõîõâ¾»u´-„Ɓýöå…äBKã«oïì“çV£‰gf:¼­U[êÔ­n¬Åãhô·êÄ¡¡\mEð½–ç;
+° ¬VÛ[ºÛZŽBÕwº»Z‘âÁ%›õ™@b—«ï!åì“ã	û•‚&Pàh9_±YݽÕ®s»PŸ·„*'¶ÔÐWÃÕFd	[[OÀØöØÞ±=£}®L"×yõB•æ45’-Xfá†óX!]í)Éh>#T)«—®]²·P""
ÙZ(qbMìüýH\S¯·¥Ê–.0uüüOhm( 3O¼d´·°kíù8iÂE×1ìГt–ÎE/t.¬Ñ`¦½D²èZhY¨â®a¨!u¹Jb#\·ó»°ŠÊÕv¶»U²viÖ‘O^Ⱥ£]€œ
rç9mÏçÚó‹iéñü¹XhêñÂj“XÆ]ƒHh甬
+Í9i›èöï,oxvVa¶¹õîÙÑvóXU›÷Šõý)bÏï6ñj5õá­T_á^"îlhZXˇÆáðÉcêaùX¥®nT߳»Îõê1Måk¤úÝû vEa—órm¿Y¯‘ÒFN .ªEá,jÑ8{LÑZSË€ù–çÉzŽ¬ç:ëZ²®ƒ´PNê<œÕê»gï_ŠçùQ>_¹mC}V™¬
+-¡\¼õÁ…l¬VpFÖl‚´	kÄÞS2"^1õGúS¤A:Ôÿk-¥C”û0òa4¦0"㇙z,Ÿ~LúÄ&ÓÍ'/‚¦xöý=ú#x%ãÐ,’UnÖ`¶2š˜ªÁ7Ãõu…sWf††(§('²œ;Ù´¥"6WÊ–ÊEcTVŸða‰uð´K§Õ’§"'’.­Ka:>‘¥“>y(²Óåt°fÎ•H$­VçÂoõ8Í£Òb¿Õzœ
+ŽM9ÒÒÙ…í´k0˜ôpáÁpÞ¿p¾^ÜÞØÀÌFj’<·ß ~ßç’XßèŠ]ò¸ûn³WƇ¢’cÀQàý#SW}£¹˜áW¢8˜Oë­zabL²ãYö^ä[ˆBUàëûðò¬E¶wzLH«¥4=$FF¸ìþ¤Â`¦)ÿm÷õ÷µ7Ÿ,Ñ2ì‰Á‰‹þ3ò jF!“ÑÈ™ô{L/ʝä€Åz"GcÉ.-Z?«ÈY‡™†ïN1>¹øÚf<­d³–Û}bº’½û xín‘JšO#µÂÁf-¿ÏYFç“âáÍôæÆV®1nÁ­¾zQÿo¨R²Ë�Jl2¢¶-§ôOÞ:�º­]†‘’êR–’É„úõƒ%²«‘ìTdž&¨0f°]ÎB¦Â0f¿,dÜî+û×^ÿÆá´ÔoÆéЫô#™kÁðZÎ{úu×&†=|ˆ·~	ÈDøv¹AÿÅQDu÷Ëâ˜[sUöðˆxÄ»å>ñª[Óq›ŠD6 ‡I1¶Pät*]¿~XÓ)RD>àÍØœ.—³M–|þŸè×ד’Ù08.ÝH¬¥<ÒÎÔÕݬ ½o..SØ¢¨;‡_g…ïüTÿYÕÆ\Œ8Äj›S”Ee@J–ü¶Ì”…ÃöH*®ñ•ÐRJüú7áìsê_´™PÅÕááÈD™®céwÄщâ$N²W|º~}Å
+p¢äN:AH'›P0^³ CéÇãO×~ò¼‰6ã¦bJN2ÇJ´g-ãU#\t©]J…ãŠ~ß|§ž-Gí·?×XD»ä[œæßÆa»/=š(ø,t3‘Œ‹³ÂäRøôw@rØÀ1òª›=ŠULc;¶kœ•~PѬçP`þÛe¶;mK
‡¹Í,/MßÌ$å!í¡>÷É|¿™—G&ºßnøKlvo~ÔS13>%(yÉ?ó$à‘Àq7Fªøh˜¾nCn«ûžû#wÏcÛÏm´Ûæ¶i†*F{ݦõd³‹ÏweER%‰d²Ã"m1ßÙ{ù5oas2S:ý.=SL$ú´™|.ßûãríÑë…ý9/ˆSò\uÌÿ3õêBH‚ßê6ýWÄ"^µ:öu«Ö`ªôé(´®Ñp®ÁºÇ•ød
+x,«°Ð[åòÆr<Äð¼wôÕWïS¿ØàW6Ìë}£~qãt¥u¢6¹`}G[qèPÅÔ‰
"‚’h£'ýThPØT´T(”J…éù—ÞÄùú•l}Zôo.î\_ßÞY[ß}áñÙ[¥Ñ@©‘™Ù›OêìOäGœj¶›+6‹q¤B÷êàËA ä"íÍv®Û?,¶·SÜmt@£ÞVÉ•$'¤×âcËøþ¡Óㆢ#‡®\£õ¥`ˆä:·7ï‚O¨?(…Q«c|VVŠAÛòuàux}@[‘9UcÐ_ÑQ=ÇDzŒŒ6
+çE•Á‰úKn1ȸŒýÆA³™CZ¿§é}
ÍJAçé_h=–Î>£þ
a&Ђäzl‚à(G%8ö¡éG&ºf:0ѦÿíÀt-p lo%fä+¬®M<“‚Ö´‘[
+níÚOò¥Œç70vñÐÃíþð?Ò8Åñ”<ÍÞT!u-’Y–u·L±”86ЧgG¸é‰bÀúµ;¡Õ|@óÖ èÐIâàˆÞèÀÉÈH:àt%x³ßg²9ŒÓlè5öý‡ò2®ê*ãøwÏ}	$l¬	”¬„	I ,²“Ob!«•—¶£ÅZÒB‹¤,µÚÃÌÔ:í h+vhµEqtPé‚L­U»0¥¥RlD@Á²<ßyçÅç#)ôÎüçî¹çžåÛÏȱSòšÛ3‚3*8bjøœ×Áw(™$-m@{zfJÿù	‰Cç<x"b•ˆ‹¬°vh£‰Uý##µíëkÖäåfä¤e”W.hÄ&7n\tùT°00?}áB/‘%ª‘âeä9õ¤¤Ú3R&''Z;!{Thú‰ÁäºÉÏËxº¸dø„¢áwÜ^xCùg±‚ËÏ×—g族ò¦\:*/ùübo!s÷ó˜{0f801‰ŒÔ>8#59±¿ãÔå†Eœ×¯4¨ÂOõÕ›³rGå§
z«ëáµ÷ÊÌ
N
f—dÝ”t]p¢wîòoù¥3¥3˳ú©ÊÚ«¸ïæ´ªKŠœyíÎuË,ßÓøÔåiÔXÏkΡ€@r8™ŽÖËÓÎw'µÚÞ˜'u§wVK%žw.Jƒ×)£M«ùþnÉ3Ižì•Ñ^–”‚þÞ£’Å·jù@
+½uROõ¾(ýè+7‚	 ä‚é`*(qß‹u¼þK{˜ê¼’æ¿&åæiI1÷IȐIæÏp;¨¯òþ²„¼tÚ·ÈH³®–?þàû]p¼–¾.öÝÁvK½Ù…¼žcÞÍ’dî–¦EFx“¤E÷'³~)rÓ$OšÑ칃&I™Y¥y¤ÛvN~Nêä\øSdÛ
~'cé·ß;¤”yxÏ”|ï6IeïÕ&ÙœY+5ß—\oŠd!ëYpë«,2äˆrø¨×%…þ÷é’¡`þ;fqÎäUʘÀx®«G¤0¶x«X—3¨]0þ6ÿÉ´{¨”,?{ãÜN¿õ*oP&꺠	äè~L:j’‡ü~2ÞÛ)ù&YÆèwÕ³wÙ4ÉVïäþ½íÈm»L¶rk`Þ’©ºå}ýSù0gÎò·Ë0‡ÉÞiúTǽ [½·;½;xéáÃè}2ü&8eþ†ÎãÁ¾"¶ z…êû0si«Ž{/<)¢óX ï—Ðõøp,j–ã¡ö¬¬zz7K¤Á²žW׌g=»®ß«?èÜzþ¯À*ŸÆk`õÅÃø•=χÌ;G|d|sî‡ÏÀ§ˆF ‡L…ú¡Ú¿úƒ7:ú6…_ZßPßÄ?,ª­ŸLV_åÛ¿"Œ`ï~8$ÉÞ81ªO»‡x~L<ÛvïV·ì9žÕç­ßYŸsïclÀ®`bƒõÏxV[Q}]#Û¸¢¾­ö¥ºÕØ‚dz|ÄYãÖ¶²j’7Õ¿Õ¯ÀwA7x¼
+æGççèzÒákÙ`,¨å Âùf©û65ê« ¨×q¯Ë(ÿa™èü´4ꯠÄôk_н×ôÒ¯}å1ýÁ˜9J5§˜ïs†¤ÅÌ”ló¾¨Ïè9lìè”ñ¼÷j8_$.Îuy¢Î\Ol:@,^ôÿð÷E`çúš´ó7Ø8WäýUF™2ŽµFÓ§í)6•ÑÖ|Ôbå–#•Qñ5ÊrPoãÐÛL°|	ü¨ž¿6‚
à¸{ÜAû_�‡5vÆà¨Í­Ñ¼«1˜œ¥y26i.Ñ<¢¹!6hì·ñ^c8qØÆÞ[Å7籟6–h\L1á‹æ÷RäÅ—îˆÄ.c–!ÏÅœg¹üF¹Ît#·è§&¼ÏÄ؝äÕ¥žü¢J&¿†L1õC%ÿ°ÏÃêÇá_!{ë·äæÉæR( ÝÄ:§mL´>ÆâAÎ<Â[IÌQ_Ü £¾iŽ1n%~÷.öóíg°¥ÎßÞÃÏÚ%©#²½ãœiº­—!f€3YÌ1Ÿ¼­ùöxQ’µÎIH–PàyÐÌžž$o”sŽô—Òþ%¨b›5÷à¯{â͵Ɖ™®¦‰‰ó´pØæš·˜ëö˜8‰›…WÄ6Îƹ|	)nÏ1qy†ÌŽÿÅÈøuzæ‰ÄùѺ'ïÛè9yß~æâOÛÀÒ8,ÎnßpP»¾< îrháýe°Ì�
 Ññë›îß®8V¬R0×ÏÁ‹`»­	µ.‹æÀ(SÚúÌå0­mMv—_wÕ¸Ÿýb™ÝgnŽ°w•ïWç«çì8«¯ïä]êO©rù·®¯|è8§ÏïίÆWØsÔ¯ÆÑ|Ç6.EãÓ§©G?;¨Y[ánp�l‰ÜNl¼[gk*[ŸË{®æÝ,p>~Þ`†Hš~óÞ•TbïD‡iž±bÛ½ô“òÌ<©O¸•<4OÔ¶ø|ž9$•ÔËùÈh¬>é’4ÓLli!Ö£Ãvts’xúœ´iìûœu“´S+ýœñ(ûýïÐW'ÿ,eÌv¬t×Ðn!϶È?c¸ÐñƒË­½œ$~wÛ»SµËƒsù¶Ïý¼
1ó(þÃÙÊö^ÓLì~!gÚƼ‘»˜bš­ã7Ùû\	ëµéš`ˆi“{éíЦð^á<ó¤Ò¢•:¥Õ¾çÁã4——òoUÏ~—Ê,íõ=yœÔڱ̊ƒîk¬ãq1ï¥î>ÙçõŠ“ä‚'ˆAŠèœ]Ò앐§#g›î”½À÷asZWDæk�æ«2ž…ê{ÚEÓêIÑv,ÇCvG¾)+ÂÜ·Ÿ¼¿gޏiÇ=yAõ¹Lwø©ƒ¶Ë¦Ç ¬è}°Ü!:ß.ó6~.ÔÀlEv[ñÅÛö.;Ï| Íp™Í]V'Ap½ùõÜqlÉÝÿüî¨Ciÿ‘ØÅX}öÈ}#0AR™ŒÉ­?ÈÛæ&	P_†¬i£¹Cÿ?*ýu¾@?I¢¿ÀŽUèÇd€æÍ#6Fþ‚¶æ½{iýÁœ~ÙÌ¿¿¥ÿüìÆž¥ýºô'φ̽6äÀãCEÄûNüw¼Ôz{°÷vb	1Ü/"ŽÄ'«éS³ÙKøFmÍk3-×꽏º-ÃÆп#»tê¬&úG!×)Rë7Ðnãß³pL“bÿSðxl8z‡]B|Üc¿•iÔ¼¡÷X­'üvtô9¾1ÆîC÷£kéú³±ó¬Ý!~OÞèL¿,‰Ô.!ö\ke?ó¨#¾cóq-ó‡ìZ%Ô¥¿aÜ&úÇJm ]’ü1¶î,°g‚þlÆ=sócêöIäã3¬×Â|Gè¿™ó×ó²^Æûö±šs¨^ÍãÝüÉ/‰=¼=!+¿9¬äû™Hmän0‘½Ñ_¤^XÅyvIB”Õ¶Ô>¬Žcº3ÿá›ÊXkÕz7*3lÀêáÞÿ$uú¯µ¹"—ï‹bj½h×xÞ,¢Ü³VT.Zë]âüj—ªÇ}Þ{±7Õ¹µyÕ[<»=Z½ü„yÔF±•ÀläyÜúi–½“µŠÆƒ\d²šº2d>ÃØìþG裆x~ß)d?¸ç-¥~ßÆÚ9ä3íÿ!gÕÚ}±³m¯¶”K»‘e	vÝ"UpÿVq—ÿ’_®ÁUUW�^çœ{áÒH" �žAB(Â,´¬Vb§*´°m-EA:¶ˆcku T ŽŠµáUKÐ†"Êé·÷Ù79	'á"üèL|³ö^g?×Y{ïµ´*EϦ²±Xôüi[ªx˜±õ¹T±m¶öŸMr}6ùçѳé(¿ÝMù>â5ÿH|¸­dYgä!è»ZÄ¥(+û¨6ÚOf?Eò
»5wXgîK|¦;ozÞ–t÷ªÓDúâ‹*îìAžÐÓyž|ïÀ=äl¦¾Xzêu,Bªù™Sͧæ²2Ür8bO¢?cFÑã
‘7M¼\‡à(9_{èkÏfm*Ïù»6—°n›Íº÷`Ûľ?ÇžwK¢€ï¬Ã9jþºxŸ�çÖý",…UÐ×C¯=�§
ßÛIO|¶§sŽC)í•]ëÀyšv?¡ßC0	FÂýè>óðlD\–áþÙp	N£kþJ›˜ç�lu°
z”]p~æí/ố¡0–ö¾„3œ~ŸÓöNä!à?ÕÉJÚ¬¥ý|
©ÐݏJ»GmiìÂÞj_Œ®ÙçÚ7nõ?Þâ¹á¾wÐæÉö„:ûà´¥gJׇÈûÚHX›×=‘ñÕ|×;‡&÷›K`¾óOãCGÿf\‹³Z®°›xg—¶Å°@õ¹ÎÔ] ˆÖÕ»¢Î÷<ï¬;CtÿBہö9I;u7¼ê^(åŽ÷ÎûûÎ5þ„Îc3þ_h+삆×�oþOø;ð0´ðÆ?K�Ÿ
‡$Îæ×UlŠcÎyÒ‚<à<S`‚OÂ8h,â~3a.L1õm†xÎè¢í”<­r4ýý^ùýSɍ–­íR`úv….Ё¸h™½ˆx†<Ìz™w?‡xé))°’³Í¥\¢c³|«ßR©"FLGî@B:èvÛ‰;ŸÁ_&£L"G*&—kɽ==/§¬úUðý-îÄ•”2Öi$—É'×J¦“Íý©ÆPßÓݵšToZ²&=Z󪵰öÇÕÌÑÝ™!ÖÒÔY"Ngië4¤Lä„‘»SÍíGí7JÍ} F{÷Xíù.¤Ïj¿Ñ½F÷°GµV×ª~ªÍPìáMð^Dˆ=#ÄBîñA’Ú!):¯Œ°†ï„|-B,!ÏŠ0vDr¡›!MKŽÖ&Þ‡|*÷Þ‘6ÖÞǦ’k}Ì”Ⱦ"’n¥_^’–
+Þt'hзB—ª ü5dœÂ*‘d…ó¤YEîE+ݽÈ=Ÿ¦Y ÍíÔ{ÁÊàÌçÿ™vÄ™OwÝÙºjíôÚÊ<¬%Ø|€6K±“þrÀüA:Þ–4‡ºÓÀ½J–4Mn=ºbtCÑ=@ý`mÎ>l<“¹úÒf
û�ûQ읃n”PVèœ,Iq²¼5à—)š�9n•í»bwÅsè§SÅ”‹µ=ªÚåÒ”õú²ªìlÿž¶fÍÄe)šáèÓ<ˆCÕ8çç\å¿öù
+y@¦nÏÜNcTïWÍGø§ÊâuøF5]àõýw¿ýoô/œ|ûßI}g°NÙŽxÅ£
q[toj¯Ñýš}Z—%Ñšè–è}út•åsă×ÛòL¥-÷Òö÷€Â_öÍ~O:×/"w˜ÈžŸ‚šrjõzx¯d†ÞfîîEÙȺʐân€uF*öù4¼hÊ;§ê-Ùäë³Á×Ç/Â°=ª³;Jg9MŒ|^25eÄ÷W¹SÆò΍•õqu²6Ûô‘×a?̂֐)¦ohieIkºŒ²>áÍŸ)}¸G;óN··;Iª}$k
+u®Us¼!f¼<ÿxRŽõçŽ9 ½É¥:“‹öÂŽ™ü÷<îåfš‰z<Õ_½[9Ö‡ä7Aþ5?øLEõøÉEcχá�<{Œ|Ç°ÂÙi­µ¾ÇšŠ$O“î^–Kî
+Êç‘ÿRž!åc‡Ñ­òÝÍþóê+ÇzNùíÉ›>«· œã+Üùµ¾1”k»_bj¿Â½b
†|÷?Ö2âÚAbk|mnåí¹]ïQÐ;´® ·"ðĪóÞ£sܽç*ý*à>u@ö@÷ºRÊ¥Áï–é»ÜÎv—×u¿½ƒF·ÝNŸ?_÷†¾«Þk˜wÍuóf¼5ÙÕßšÊñ¢o΍tu¬¥–3۵ܷ«lÞ¿R,¡tA÷TPü¤òçXÏT­ç¹ö»HÇA7}/ā뙌mÚ»§7çÆzÞbEuA1f€®ŽË;[ÕuÞÙ7ºjÿ#êŸýk4ÿyt確î”ö3£»áÿî§†4÷Ây'Wqƒ7òè¶Æô–V÷‰ä|þxî¸çýoÊÆ7ÝoªÞoc{‰©o†W}²v½×ï ´/ÃA‰ #ÈVÈVÈ4d2ot+ìËpÐ=Ž<îë•õ‘õ‘-MÿîÈîÈD[Åð^¿Xû·èëü­j™?°(Ní?Îç» ¿ZýÄ-öÿ¿­£¯ñåOOÖ@éŸ51ý“©Üh!,Ð}OKtµÓÉ6r‡ÏÀ·—Äð=Œ€·a1ó1³B$'Rï§"‘®ÜSÍEê“54Cl·o=ùö1d¼ôåS?Ê÷é´½DÛuòü�F@*´7²-Üah}Œ>² Gå:_áŽRw•¾£÷ªºã{÷œ~¢w•9§ìo½Ù;+rß…Õ†™zžÉC÷™Üg7|ÇÈ{T¿3öò¬1ò]˜ß„
+Ó FB!9_oë0ë¾ÊšËÉÑ&KòÁ¾vcl¿%÷ڍˆ%šI.m'úÁ(;A²í2†7e ÝTî"ço·³òí«V~è‰c_«¬.ŒsŸ°ÚÉ$G$NJä[3ΣÁrÝ
+¥·?ô$ï{…ý7˜\Õ¯&ÑñØïoß¹v
+9’a<ô1|‹oŸ#ÇÂpx~ìqí×ðŸ,—àUÒ=l%°ÞÛC+áÚ_ Oå“ dŽ¡©÷2¨q2”½œ"l4–Âc°®@ßâá‡2Ì~zXY0.Á�Ø,Cìä³´›eÆBïä#»Á1ô+³™s—‡ý'ø�®Ãà$3†}eUsë±gÝœßÕœƒáûøŃÈ?Â(0$ûÈ«Áë^xÁ³‡õ+c°*à‚'í8$ìrêåö‰ ïVƒ=ž­,Õ{WRèQi¿Y¾oGh»ùKØ	üë¼YËR³ž3p·a¯GàþÞ†é|¿™´·K|ä™yÂï˜wº†f­[$N×)•$õÝiG]­m
|VÁjc«åÆfݝ(7wÙ£Üñü³Õü¯
+Ù]ã?/5>Xfþ³ò=eß\XTÃßæ!çÕîoÚÏ”o=‚/¨µœ…„ëý*êO¡mÀüN¢$ÙëÑAhõeÆwFWù‘ƒ_8¯Á) ³¶zõÐ\$¾zz@#·¢ÞxoÞ0÷Qß
+=œ†œŠ,…— 7uµê¡%^ûP1zìCûášÑ³ïðEÖò²$9$)Ô:RþT’ƒø–ÊœM€¶õøבöèþN¿}ÞÞÿË~ùÇVu–qüýu퀖¹èÜ°;‡%ÄqnR	cŽØŸ”e]×z”–°zÆ9´wmïiî½mW6èÀÒ°éɲÉÜ A£[âZÊ4$»D£F¦Œˆ8'q‰&ŸábŒõûþ0mpf“?–˜¼7ùœçy¿ïó<ïsΕíBîõ›Ð7{ÇÄgAtø‘¿Ž¶%(¿­mÅ¿ä¾®èsðoëz|ÌqßD…ö¡²ËymÃœ_Xð'÷Sti¿ó¿jª‘±ä ‰O[Á¶Î}ÐQ/p.!m±Ü¡})V‚�ŸÏa¾¿kĵإcJ VÄ48½ û²:ôÿuUÞbtÜqqÈ3lœGžAÉÏCVëØE0 QåÏ�Ü!q¸MÛUÈ÷Ó6p«Ž5gÖÈã&–žÕ¶Rvy
œ5ö}SÇ¥ƒ¾bôg ß4>’wê2ˆQ'mç£_àÐo&›ùoÌÚ¯cZÔ›Ø~Ô¬7>çâHÌ­róYÅU¿]ßA±,‹‘~yñ†9øOôžø˜ŽG€ÐÏAn…Džá/ë;äÀöŽ«ï2Cß'¸àÈcü‡hcðÞØûåyígù¾àO¡îgúÞ¨\�{ˆæ^NB_ù°¶…ºK2^¿kbvv°ñ[}ÿʸRÆÍW
¿@y¹Î/Òæï.þ{Ž<ç ñëJm±	v¸Kaé·cü^“'kßÜy._€<
+Y£c—Ô÷Güö|ý#è;Í<SÞs‚›Ø‘÷�óŠ�¶t®ƒD®ØGÈóÃæn'¤ÌØ‹ø5֐÷è—fN™Ó^¼QŸ‰Ë|ø+•s—
+Ø€¿òROå~ÅÔý:|ÎŽC¾¨û‹µ_¤¯ÔûÜèâsXç)“¿ù*$rÖœ÷ˆÉ™À-‡”ç—¶û9¸ˆ±›Ì¹d¼¼¢ý sº´…sƒö“À{ÏÙmì#óðí¶YßK^¡óˆúÙmú®«¸HužU9z\çÊ«ó¤Óir‹ÌGßC¹F÷U1$çBž'áwä&¶*‘9ß
+޵ΘFžI~ÿ|gyÿçN³Îmâ]¿ß2>~ÇøVî¥à[Cô—yùšËº;ç®ý[ÿáЪÿœÿx`¥W18ßt¼§cßöΏÀðï.o8ƒvø¾/¹ô_ÅY‹Åb±X,‹Åb±X,‹Åb±X,‹Åb±X,‹Åb±X,‹Åb±X,‹Åb±X,–ÿ{(!e/Ñu¤–<IJ#ËÈZÂêÜsÄ•­d	yFIù{h“›QÒº€~Üè.ôÓF_D¶’sèIE)†}‚®2:%ëٝFg¤Œ¥Fç¨ßktý„Ñ]è—Œ¾ˆ|ƒßԐŒä³Ý=E¿ºjÝ¿1ê+¦9¿%Šºý{Šñ¿®¯ÏWí?Ÿ’üP‚ÊöžlÁߝæŠ~4âçÒ¢ÿ@âcd’Ob?›ó£Üˆ?Œ–ál±',úùlš÷’|¶PÈbþt÷¬ÔV×ÞÙÜ’©ë-f‡¶äÓbRè]Ý’ÄÙÁþkiQU¾©«\¸X%v£¢%ò£|‚CugzãÅ|'ýQ¾·ðAû#
$%d„äI–t“R$>©&UdÙ�­®îC]Jr(µ ¡—OîA]LÖ@«C{äüø‚*%	䞺g;Z³ªu·šO®ÔùF s¨‘åÐÛ7k&j–å¬Z=ÂSö6c†Q_Äœ)TcÔR<¥.G÷«õ
+ªVΐbå?SÎÔN:I3Ú2Ð{QŸÅ9¶`ÆTí«€ºÕh•»Ëbõ~„q‚91o„^×2ÃÇ5f¾—U¿Êÿj›JcýØôõ¾:ib|Ý­,½ÐgEh´Dù8ùÙ\ç’¹Ðó~'JkO±=S·¬h:ÍbCâ±ýlhÊ÷f^c£Hµlôä-·6ÕÔÝΆQ\Æúe½$`$dBn'!j{ˆª�dz›¼ß¶¤¶KMöe<ØN<ã9dÛNŒ‘ZÛARÀhãɆUÞÑÐ;¥é¹/zûTÍÞ)ºa
+Mߧëiµª­žª_îÕ-¦
$ •$¤k!WC®‘åÚ¹ðý¿­òþx)öþ2ë{—Á%Œ~û­Ø{î?
ßÞ
ÿü)|zÍ…Ö£¦/ï]º÷‘À{xOàó±—ǘ\ìå0æÐxàMÏŒ³ƒc±7†Šî$ötØÅ^„ò—ÂØ›ø"
|o[[ìµÕûÞÝwÅÞ](75ÆÞf”Am}ÉõMÞ«tä¡ÀûJðhx 
÷ûš}ti°$tz‚^³bNðiAG•*›ÓbFðQqX°VÑ%z•eáâàºpQà†4 á‘2Z[F/—Ñcµû¡º+V5º´Ë¥5.JŸº©iÆ¥.=ìÒÔ¥­.-wiI9¡3ä"™%ü(™ ¬ÅÖ:Kæ›&±ÐJ(:•%!XXÎè»Èf?Ê&ëb)ckesŒM3:Êh+£èÄOSù†ràÈ#¤=Ó|Š¿³µy²ä¾“ôÐäÊmòYÛÖ9éš$açŽí'(}²ãàOŠúæÉŠmÛ§ø±cõÍ“±Ô	ª;
+òWÄo0“™×ïWj!=#«2™ùVÙQ•©|’L†ÊgAõœ×Q¯úê²þ½ ',êed/ÙïÓ÷ÿK€�^£*±
+endstream
endobj
31 0 obj
<</Ascent 1056/CapHeight 711/Descent -271/Flags 34/FontBBox[-416 -271 987 1056]/FontFamily(Roboto Mono)/FontFile2 34 0 R/FontName/YRUVSW+RobotoMono-Italic/FontStretch/Normal/FontWeight 400/ItalicAngle 0/StemV 88/Type/FontDescriptor/XHeight 528>>
endobj
34 0 obj
<</Filter/FlateDecode/Length 6503/Length1 13987>>stream
+H‰”Up”Õ>CH	вÌzw—Jv! <ÝMx”¤Ý…Vv³IH"©R:¶øjJ­ÂX§L-Pìt:"ÞPµêtZ”§’�ò°Ù’ðR*åµÙž“"tt¦½3ßýï9÷ÜsÏwþ{Ï€4x|³æŽÈûèH{¾hN	‚áªPuÃ
+w+�N�Hò…Ÿ^ªnï›ÐcÌÿ®¢zQU´_Àä¡�©¯/Z¼¢bP¤÷p€Ìí¢Ë­,•ÝÌÎÈ�°^û‚JQôºÆ§e‰<¸²jéò¿_ñ†È3�Òÿ°xI8ô[\? §Cöh®
+-¯¶¼›¦�FÕ‰½z"TU^Ò¸zŸÈâ[ª—<µ4^•ô@þs¾úÉòê1?/{ç%òV`c¾�ËzË(Yñ@×—BÁÝ­(žjéÅ”«W<ùHfâ±äÒ˜øN.¥¸a–èŒB‹NØ™™CÉ›ùíFRQÂѳAô”¼Úa%l„-ð6l‡]P-p:1û`Á\œ‹q®ÄU¸7¡Æ+'+¡�ývÓ^:MW™¹'§³“kx
¯åM¬ùCÞËø5²ŒF±1Ë(5–ËŒŒÆ1#j|eAK†%Ó†¶É¶çm_Ø®Ún<ð°JUý•M9T¶ÊU£T¡š ŠÔRµJ½©þ¤¶Ø-öLû�»ÃžmnÌAŽ$Gº£¯c ÃæÈqLwåYû®íìŒÇcñx"i]8„á&a¸vÀn¨‡V¸qÌÀ¾˜Cq$>ŠA¬L0܈ïÛt7Ã]Âð¸0„;Ÿ†/ó:Þ̵üïãƒÂŒl#טjøŒ°Qm,7^2êŒãF“qÍB–>6°M²=kÛhûÒöOa*Sݧ”ʆyj܆›…á[÷0\ÐÍ°Ï]˺ކȸ%.ç(Þ„Ùñ80.ç
+ÓÉC@øõpMp#Þ?Ν×:Ûp¬©êwz *v4öÇØ®X­ôoÆ6ÄÖÇ^oÓâSM‹X¹}ëöu€Ûï¶
+66ÈꞐñ4€s®æÍo4ïoÙ¼÷l4êˆÎŠ>õ6]ŽoêˆæE¹ñ†¼Ã‚e7V6þ0òjãœÆìÈê3Ž,‹<YY	FŠ"îÈ°†])h¾Þx¢¿ëÔNv³³Ý…àÝwKq1|KÃùÝ+¥ÿM·N˜¡äˆÄMÌ´nþ·ºôM~éLþÆ|?ÃX‡õxÁ*Ü‹§ñF°£Ø$÷ôgx›ñ¶`+üVãylÃvìÀxžƒçñ:ÞÀ›xoc^€±Sî&ÁK¸‡wÂ/pÔÀ/a
¤<E£áW”Or¶ÇÒ8*¤ñ4^†_ÓDšD“i
+=HòÂ+ð*Q1M¥i4fÀZXG~¹
? Çh!q?~Š‡ñ-§ôSz†¾Gߧù´�Þ‚-ToS=¤Cr×Þ¡t’@Ó):
µt†"°á/…w©‰ÎÂ{ÔïÃ_éµP+§6j§º�§KtþAa'|ŸH]Ú
{`/]}°ŸGÐ5¨£A=]§t“nÁA8‡)ƹÔ	ŸSŽÈ}E8ÊÇäôœ`¦Ûp’
¶p÷àd¹É)ÐÀ©Ü‹Ó¤ÞµÂyhãÞÐpÓá"\’x…3àîÃ}áK΄«ÜGrèäçûø~þD@Db+çñ d4ÐÂ'yÆLì‡ýq�çsT˜!áF>ÁÇ¥Ö|‡a7ð)t¡›óç<†Çò'¼‡ã>Íg¤âŽäݼópŽÆ|,À1<Ž¥šîãñ<[ù<ïçOq,ŽãÏø�âxœÀÇp"Nâ#|”'ò$žŒ“q
+Ÿã|=å&®ãz>ËÍèå‡x—ðL~˜áYX„ÅRÁq—ãTœÆ¼ˆÛ¸§s%wðøq,Ãr¾ÈpŒÏüÏgû5xÍ|ƒŒB©Aó…²ìŠ·¾xGçô®÷êk‹6
+ãíw¬Ú-»Å®[¾Ç®éoí"›v3vy§Á¥4Ìó”*ù�zÏ.ÑIsçûõh«V¨šy~MY¡“!Âag©Õn×Ðàum“jã
zÜ]Z+Üš\ªLé>mdÏß6S¼Åáâ9üv§ÝZãWÚçóÛõ”€Ué±æhl  j»ŒBez¨¨º%¥sÍù\Ór‡Ï¯$ˆšÒ)>P4ÊœK1Gæ¨ h
«Æœ@À©Áç/Üš]JüY!	ÈâõùµÅéÑIN„ÐtkÃ唸TY­¥Ô£Ì™®ÍÍ^Áâ°æavÑ{Uªßµ¹–,¡5ÛôYCs~g@f§ÌõË”Õ$Õ½³[[\º‡7g›<¢‰Ô$‰èô8%ÅNOHSi…Æ°ì¯-Ãܺ‡K™A¦zÃPªLzJ0`š‹A&»¶õHo±g˜ýN²{ºîM~J—Ì‘$ô¬ *®q†Ì‘ÈXÍlje• ÿ¥æ,g¨¨k‹ÔoY®Ë*°~MíîE½\	BÛRS¸Øo·:íav·NsÕë²P‘[÷v‰¡Rº—÷!s¹œž€N3¥9"¥‰äÖéâ&#‘%˾º·7¨j‚J÷–¤¹u†«äQ­QV¬ÓʝËݺ«d¶¿dn—Òj}fBß×UéÞyþÚôt¯ÆG§ç˜‡TŽ®§¶—Ùý›õj‹i#;Ã眹Ø&ØØ2Î`˜±16Ø\¾a;`BŒ;ÎÅH–\!—ÒÕfwu·»¥iµ©V©Ô¨RÚJ›>TÛqúPUÚ>4í[Ui¥>µo•ªmÕ§>Tmôÿǘ°	ٍVEÈÿwÎ|sþû?3µð£Q+d‚sfóex_ô¢ÚN‡·U±½roÚǝx’ûÓ°ûùT½ exY–!Z	?€§çʬ’2aÉ©¼¶[ŽKImeõ—J ~µ¾ž’:¯”Ê{DE»®Ø@˜,à›Yñhj™¢´BœQÚÔ2‡²I-ó(÷ªee³ZQÚÕ²å>µlDÙ¢–M(;TÉ«Ñ­SKMÑÁÖª­Vù
+6î[ál	lDé�Q�QÊ`#Ê6°¥lDéQºÁF”í`#JU•Âz©yTP[_’ŸRBO´ŠõæU5¢y “º ˆÓÒ2!ÏôÉ8ƾ¥äÑ|[é¡V­«³,ÐÆdÆ:ؽ=2Ï_ö«R¯no�x4ù¼è°•ã>±>ÒGöÈ°ÜWöÓFð¨üƒw¶
+{¦Ï£õª^[Ø£¿Œ
+E8ô¤„X’WJcóB(GWVÒrº=cÆ"ttÒFèïƒ)c…¢™ÊüŠW–¤ð
+œÕÿô²ä­œ¡ñp&°$­„ýÌ?d'Ù2×\ˆã4Â4•u¶œ‚îK<ÛJ%œC•aÏ¥9Yã3sp™%fì€K8ƒž½gL‚Á,§ ‡2hH_ t-pÞJäÊ´ã¡Á!ö”ðÜ©p"zäԍ€ßleÊ=Õ)ÀÀ'‰&¸6c ‡!4ƒú¶f„摤”œFe˜­°2t`3¢d*ï•ÂðlD‹77%´¥rÑ	«ÑíOßJ¢vªàÍÌÈXÆC›$ª©)áãùY«©VeÉ‹QKÁ`¼e/µ@F¶¶³Û·£Ÿgïȉ©ZŸ²ã¡qUëWV@1Xû<ÒâÕ¼@MlUX5ºX\2”ºš¤rÜ
˜á_¡Óÿ¯êCóq¾„e!Ûòí(lÚ˜Ä`TýO¡ÿy3�›~l¹œ—+Í	OwèC³Wë^<ø‚ýQ˜¹ÔbÖz©ZD£–„¸J)x”Uã4®b9j€‡Ô0g�L� «¨¾“ ïL"'	 ‡¯"ÁrL#'àrE‚<r“�p9ŠÈAp9N 'à$rœB‚rÌ 'à4rÌ"ÁrÌ«ÚÀV˜ÏàBtVG@¯éõ‹(,Tmp‹}:û¼Ž}AGH½¨já-ê%\èÔË:Bꢎº¤jC[Ô+¸Ð©Wu„Ôk:Bêuõ¡‰gÕ—§¸¢ç5®-ûõê3Åyn†oÝ·á^$æh½À1Ž„gį§ÆF¨"³rØû«Ÿn\“˜ßÌòAùÞ
+wÃD³ð[ÒFÚ£Nø®å)ãá<®H8n$Cxž*5·Y”zÁ¸Wq8Bð
+z™ÛUÇ†aÎÖÊê8up¯ÍXYsÇÉÜ Q´s½éK“~Ó£š#ï—ç|ïlALœZê݈³O¾ÃvuÏ,Š#Œ)‡/ÇéÜýåcý¯ÝκõÖ¢#öu=ù¿ì‹’d4.Q¡c`%¡Œ,Á qÌ3Ä0»ÍjQä‹`z’{|]JG›¥]2›jó³l×Ý^.d[™ÍºÉqÓ{ËCKÇÀ™=ÉþÁ¹Cþš‡5Ó߸_<v{¶Ë(ø2'{£J=oš~O›=vg¡OxÄÛûóý±‹¹ƒ¡5Z
+ßâºÙØL,XŒ;m‹Ÿè§'€GÙà‡Åð|.j³&ŽÌç|e±…Ó¾ãqeîÑ…èðÉèð¾쐥�d·^¦ÜѶZJx:&PÂQ=
®†3„±!6Þ°§¡¡¡^46+4`9ÙÉ
+P‡ÙÀ]zÜüxpupýF#·ÿwkÿ ¿xÇM?ûþÆÇ4·Ìýu­Ÿ}:€ñvƒ¦_ƒ¦:â*5Ê1=âp…ÑEg„„3 •Ñqˆ{©3›öˆX3
€:3•w1ÙLŸœ¥_ûËšvæÚÆ狳ں ­w²?þ'Ë&XjrüúOÖz™yòw~7Ÿ%^(²htÈPÉ1Ê8
+¥HDŠ³àžÒtÆ@Ay’Œûºz]C¾¡6‹³ÓiÄÚtõ„Dó8,lÏæ™E›Ái
†Bî°™fkF.}fäõB7ÏwOœ¹úFø÷µ¢½o²[y5é¯Y5åoþ`,÷ÝùÓ”‰Ö²¦ÒG}7/M«o¤u 52Ψš½r0ua²OÞM&‚û(µtÆ<4÷zÖM™ïÄ7n˜B—‚
·XqüO´NÍ%”¸§	óêÙÈñ9~’($B¿ÑlÙ|Ô\CE¢‚è ¼ÐdcϏÙõ]úÌn!£½7HPí¤H¡NÒ"•ÂÏ@°"-ÆÆí­þKy£:oÏKžg}Éól/yžxmп‘ŒN&_tfËKqñÜ—;²Pù‹Ö8=n·Óì2íŠyX°Y­¶P€Ó‡‚;œ	zm	¡€hiålPGf—K¯¯·MÎðä¹›Ó·}òGê¦ßýùBð\)·ÿl×Í©äÒt­%r§˜¾x8`
„WZü£=ÇÞõOï;?1ucÚ_Ãö'¾õÖ…¬ÊX"½üß?Ïÿt9ÆÑf_Òs9‘e¬cüBìT$ÎX÷äùå7ÛóS‡Û+¤é?ÓYƼ~û ÖÒqx|&<&&b#žh'x-Áá§3<¢7.+T…KnÀIÞÂÜv!‡ÙAƒÁP°•5ZDƒè¢M¬ù=Ú²öA{gã.½Kþ&wËî°¯kˆX;sïû7ý¥/Âhý¾ö&°~h×(LVþ0̬ñUÔGÇ*ù5ƒ^RÔGHº:BìQ›@y>’ѯ‘mW
+ÑZXÚ‰½ÑÙèÔçKµ‡esµ«ÒÚùÓÁâÑ½¦««WÅ]ÊD¸kz,foõWüàÚG|{)Yº“[Ÿd?LuPº×i[û?�¶þý2­ªˆâø™÷æ½¾.´Öbm´±„E V± õQ‹´b¡”­
ÝØ+¡à—ŠKÆÄ%Ñ€"‚‘T U‹DT¬Æ%¢Aq'"òAѸQ®ÿ3sn{½RZýÖ7ùõ̝;wæÌ9gÎL[ k%rOͶÁšˆé)E|°ëø)(Oå¶ÃÙ)š´«°–ìMG8a
üF«öåÑEÉ=’#8•UZ(ÒsB ÅqЄYû¡XSp}NEvvNÅ%w¾4ò–m»Îï7¥b.Q‰©/%&+µìÆÖ"=¢apáÐ^Ðw3ô}Dçá~ß+šC!7óaæ†ÑRSÓ‚‘sqÆqÎÏRÃI¡>jãžÖM+Oþ¹Y%Œ^üW³Ïˆ#fT胵ÎLù+%FÌ¿”{¦f³üpù‹ÓN4´~w(²ýâÿðU¤ªõc¢øš
¿¿wÈŒãù¿ÖM¶ÆÒ¢ÖBžnËÁÕº)Ðí×¢þ4؃×õ‹ôÚWËó]¨ów)àbÐ<–‚WA=x}PWù¨¯w‚Yx>òÝ䄼
+Ô€lP&€
+	¢VÓ§ô‚ÙÒo:&ýšh.x<Š±Aîi˜/Ü‚úŸà{ÐkÌ‚¬£Dçe käï‡ÈÜ7�î—oëÎÏÒýœßä›±Ý^°
+l÷‚0ú|y%æ¾ÄPo½QgÝoñà,0mXŸÓ"ö…m¯k·€9Ö¦šíÜj<X�ÛyTp¬]ÕW 폁çÀ`¾Ãáùï†äqF€<±Ó�“>¼®>²vØÉ9y=*ml¯ë�ÖDl×RÈ�˜)þ˜+vP`%Þïê5ð2l¿"¨sìµkV):¯uøô�GuÞ‰] }WZ{r­Ÿ=Ö÷Îې}·kPbmîü9ò$ä0MÞq\Á¼ò~°õŸDwŽ!ØŽnSåy˜Øå5‰½g´‰}g'd:Ø):�g;Ø*qÌÏïˆ
®�©Â&‰)¶ÿ8ˆ¾j³/h8(Â3üæ¬G}¼´Aç#;æ™á}[F‚§À9 ,’ñ/—µ‡ðí—òŒ8wöJß«¥õný ¿³¶ß²}q46åXp¾C[¶ûq¦ÔŶÈt¾õ‘ÙÃçIÜäÉ+ÀO	*,¡„@)ØB	'¿Àí™÷Ù‰ÁBa¬Ä[Tü±A|–¸c#¦Ì^'º,›?êÀ±e9¸VÆ
Šm¼»*™—ýÂû{¶€ûƒ= ±þ5~
j»w—Û÷œçL¾céá\Àûî8â6
+d`¾L›[Õƒà¼\ìËûûyHŽoÎ3؏
+9H
Ö&®ö„*ý÷è&m÷Á+ Éö¡{À›àfm÷êËb;äU‡sEƒø+L3´ÍUl?ÞœÇ_°º;Gõû&ÿÀ¼°³bŸ�‰}¥Cä
ç-²6±m|Às»9¾èÁ~©’¶I¢;û)KtàyyÏb\zãþ¨m>Ÿês{^)ÎÝ?€O¬¿ç±ã6ÿø\µ‚YÃtYkµYŸoûp&Ìœ|¦ìµçTG˜uúˆúpÏ,?s}ì[uŸSµ>nð!çÓ¿XõOøl2´cû¥Y×ÒÓÈìP¡9ÿ
+EÎ$ë0ä4Ò=ïÝs÷t’sï{¾pÎ(“wmºY¹ÚÈ=~ðÊst{®òK>[DÎð<ó¹p{¤ÄŽ‘ëÚêŒtÏÈÎä<‘¸Ï˜;Å~¹SȽ†ï~Ég<ŸéæŒç¼ò©…uà½Øf–û˜ïÃÝ—~î÷ÑtŠ±]ŠN1Sã!ûsûó„—I¼zey˜áÃÍ'§âa»7¿¸8CétXªt3Ý9’χ#žûl¡øÍinóß]_“>ìS>‹87
³ã™»ß½8ù¼Û,Ò}W!r˜ÌéÞ…Ý}Äû$OæWýÆHÿ\Ñ+SôÊÝjD¿яóïááºýî»Tb1,ïد÷nʲz™>nüú¥Ä³ùcm|ª·zòÈzñ}»-…<:»ºÜ+ëuï7ãu{Žb›®±¶0g÷z©ûsžì™¶\Å÷‚•–¶ïܱsenWºù½¹rœøR‰
ü’yJ·Å§™Ÿm¹ÌÞ1ø¾×Qnþ¯d—swGÒŸ›;Ê¥I÷‡ÎdWó¦_zò¦G÷ߝxðÊŸrì¯õøÄõ•+yÿybý_²øÿ¢ÁB’¹/7ã]3çbÊ¥á”	úSoçç#ÚOkœc¦§…¦~ªžºúëMµô“ê{ÆezËgí%¨PF·•'¥·Egt—îÒ]ºKwé.Ý¥óBŠ(xŒÖP:=@!
+P	UÐÍ8Ó¿H|œ‚ü–âi±‘èH|10uz†Ôèåpo§T(u…֍RP2}"õ Ú¿•º¦ÕSêaÔÊK'O™8uPi¬*V+Ž-Œ
)ª«¬W}¦ít
ÅhÝ
+íçÑšKu¸ï\Š™/ÁÝ'“Æàmíµ4OE´ª)µQh©…,mûj‰yš9c-Ãßô,GÛdÜ”&ÒT„zŒª@(ÁŒZG•mÆææÐR<Ub”3ýúÿî´9g>ÖæzØû»Þ.-kTjuùVµ#Bª^ÔHáüm4fèš.âz4¡Xˆô‹ôŒÓiGáœpŸiHÈߝVŸ¼'~O(
+¯Ç£%97ÆŽšbZ‚TÐØW­˜P¶5º¢¬1XSÐ؏ŸvFêÑՓʸK9~<öÈÈ€HzœNºh»rîÛªW5ðy¨¦ào�Ž¢ï©
+endstream
endobj
30 0 obj
<</Ascent 1064/CapHeight 711/Descent -271/Flags 34/FontBBox[-758 -271 1016 1064]/FontFamily(Roboto Mono)/FontFile2 35 0 R/FontName/MMXBGU+RobotoMono-BoldItalic/FontStretch/Normal/FontWeight 700/ItalicAngle 0/StemV 136/Type/FontDescriptor/XHeight 528>>
endobj
35 0 obj
<</Filter/FlateDecode/Length 6069/Length1 13295>>stream
+H‰”Up”Õ>CH	PYg¹»K&»^!›ð”ÄîB«»y"©¢@Z|5¥Va¦Î8í�EÛéx“ªÕ–hQž
+ä`³!HxD¨È#›íù7C§Î´wæûÿ{Î=÷Üóÿžó@¬ïÌ9ò·bË¢9%”T«ê—¹Ïà8€8oÉ‹‹U`[j/€«eýwåU*ÃýêÛ�â‡$¾½`á²rﶺ¿¤n°x+Ê‚¥ßþ1Åð@²ØçVˆ"á…žn‘‹D\Q¹xéƒïÑz‘ŸHþÃÂE%Á“×ëw<”(g4U—VY>LuUìÕ³ÁʲAW½	0\üQߪEÏ/ŽVÆ}c7׫ž+«õÂX9;g’È[€Í´,Ë;–a1¨óÍ¡œ ûh�Š¦€šoz1åªeÏ=â3‰/Ž~Å”©�×Í”ly³33‡’7óÝŒ¸Â˜£•™ô”¼Úa9¬‡M°¶ÁN8�Íp:0û`Á,œƒOá\Ž+p
n@m%+"?m¥]´‡NÓuFfîÉÉìäj^Íkxkþ”÷ð~>ÄG4c˜QdÌ4ŠEÆãUc¿qÌßXÐ’bIµ¡m¢íÛ׶ë¶[ƒU‰ª¿²)‡JWY*Gå©qªP-V+Ô»êOj“ÝbOµ°;ìéö‡íO:ÈçHvôutØ™Ž©Ž€£,mïÑh$%­“¡‡0Ü ·ÀvØupÚ Š)ØÓq(ÇÇ1€1†ëñax›îïb¸S†p—áËÂð
^˹†ÿÆ{ù 0#ÝÈ2&^£Ä¨2–¯ŒãF£qÃB–>6°M°­´­·]³ýK‚JU÷)¥Ò„a¶s—áFaøþ=çw1ìӍaiÃvaˆ|‰›£ßÈhÄôèv•{…I‚x! ˆ}z¸!¸íåŽq´©ê(é(€ÊÈÑÈ{‘‘y¾Yy'òšx›lZDzÈ|Hûö›�í¶6
+ÖÉîŸ
+ž•ù€s®¦KM¿oÚ×4¼iÏÙpØž~,<#ìi¼ÛØÎsÃ-¹x‡Kži¨høIè­†Ù
é¡UgþZz1´(´0†Ü¡Œú	ûi-¾ÝxlïVu‚“]ìlÝè^+XŒáÎë²X.Ïßvé„JŽH<Q¾`†à¨ Ypû?=Еÿæ—ÎtâÿÌmø%îÇX‡ñ¬À=xÏ`0ŒR§?dz؄ç°ÏÃ/`^À‹Ø‚­x	/ÃËð
+ÞÄ[xï`;FàUx
;¤6^Çݼ~‰{¡~«i8eS€_ÓHÊ•»=šÆP¥qðü†ÆÓšHù4‰
+ÈoÂ[THE4™¦ÐTšk`-ù¤~LOÒSÀ}øÆ+´”–ÑÏè%z‚~Dóh>¼›è�l¦::H‡¤Ö> t’êAÓ):
5t†BPK
ð
+ÇÔHgá#j‚á¯tŽšé<] ‹ÔB­t	þAWè*ü“.Ãø>—¾´vÃjƒ½°‡Ñ
8@ßBݤ[t›îÀA8‡)ÂYÔ_QŽH½"e‚cr{N0S;œdƒ-Ç=8^*9ê9‘{q’ô»óp.rohV¸ÄÉp®Hlãøšûp_¸Æ©pûñpî<�¢|ßÏð@D$¶r6?ˆŒZø$çðLÅ~ØðHΕ3„CÜÀ'ø¸ôš‡03¹žO¡Ý|˜¿âQ<š?çø0ãÓ|F:îpÞÅ»1spŽÄ\Åc8Oºé^Ëãø<_à}üŽÆ1ü%ïÇ<‹ãøŽÇ	|„òxžÀq"æó9nÆIXÀanä\Çg¹	=üOãé<ƒåÇx&b‘t°C\Êe8§p9/à‹Ü‚S¹‚[ùi~K±Œ/ó%\ÆŸáKÿóÝAÈüyÒ'æʲ+ÚbÌŠ¶vLíü_}ocÑF^´¥Ëjg´Å²Ûð~'ßcw­›7Óîšøk阳ˆl
.¥a®¯È¯ÔôO ÷¬é:nÎ<ŸaÕCýrU=ק)-øi<ÄCI‰³Øj·kðkð8k¥Ûxn.­ånM.Uªôv¯6ÒçÕÅOQIÑìù>»Ón­ö)íõúì:ßoUz´9í÷«šN£`©*ª.Ié,s=Ë´Üîõ)	¢:¨t‚׍2×ÌY®9Ë
X~¿ßª1ÓïwjðúÊü~·f—?FZP²x¼>mqè8g„ï×pkÃ唸Ti¥¸@™+‡›OmŠJ4gØEïQÕªZ|×dYÒ„Ö,_Àk
Îöûœ~YÍŸã“%«Iªëd·¶¸tOf­üDc©‰ÑYà”;‚šŠË5–ÈùÚ’áÖ=\Ê2ÑSò‰ÅÊô ó~Ó$P2ÞUÛ#<Eö»Éîéº7ù	^0SBÐÓª¨Ú4?D,S`5³©•U‚ü.JÍiÎ`aç‰?°]–]`ýžZ÷M½\1Bµ‰	\ä³[v†Ý­“\5DEº4XèÖ½]b¨”îåyÄÜ.g_'™Òl‘’Drëdq“K‰’”ȹº·' ªJ÷–¤¹uŠkúã¾£´Ð?X'•9—ºu×ôY¾és:•V»èScú¾®HöÌõÕ$'{4tr¦yIÿÍzÕƶu•ásν×vÒæËNì|´Éunl'ñµÛ|ÔNÛqâ8nâ4MÒv‹›~$éÇÚnëÇhhYÙ&Œ`B“@HAÙŸê:¥BüAiâÇB¢ÚŸVˆ²Äåy¯í4kS&¢¼~Ÿ{ÎsÏy?Ͻ¥;œÛJ?ø1¸™<S³9
+¼^FziÛN·†ÛJ¸©0O· öi$OÒ°?ÑO§ê)	ÌáeYC´’‹¯àÀ3såÐYŽ‰ÔþY£JVSÆe¹†zVç±ý­êjÎ*Ùððò|ÎnñKþ¦V„©¾9ü£NÏqÒNÄ™´KÏI¤ëõœLºAÏ)¤õœ…t“ž³’Þ¦çl¤·ë¹2Òº4øá€Ñi‚Ão‚—F³ÎŒ
+ÿg°±66cm6’vÃFÒ­°‘´I·ÁFÒØHÚIû`#évØHZ×Õ¨YjÛVÏ«Iäg>i¦í£S½u#à7è¤(â´ú”Lh}cÿ•R
+;×ÓÝƎΜÂëR³8†ÈÁ®‘yrº[Ww™öö€ÇSOn‚ÛtsgΟ™GöH\ëËuó:xÔÿaðæö¢°úÆ.=芌Ðÿ¢¢FJ˜Ó£Õ45/B9¶¼œÖÒèöYë8ÑÑ!Îëj±N'ÿ&Å(KúO,5U.c­þGÓj°°†!cM°Tcžú=1={S¨’ÚtSx¥Æì06œ¦šÉÖFÑ}ÉÇ[ižÎ¡Âa/’óÇ5CJ.Ç´H.4ÏÓôø=0	³6ŠjØa~A™»`½M6Ñ
+§ŒGì”òĪX‘<ò˜FàwªpÊ=Ú)PðIb(Þb´(B3`64ªŽjiÚŒ²5CF#ÊöÏÕ(ždqqP%[J!·xp5¶ñé[HÔf\ÌŒFe+Z,¥fžϏ»XJe\×Ô Ems4Ìy-pp}xjãpâÓìM9CºÑçßtÑaÝè÷/cc*Xû$i	AP“ëVŠ.—†R¢I
+ˍàÐÀþJ1ýÿª>2ŸÎ—¨†#dC¾ÝÙ¢)
+FÉÿQòß­PôcÝå4\®+4'žîèCGÐèE/î~ÊøÎ\^ë0vëF*CQK!®ê(e¥8MèTŽFp¾‚s`€Ø«¯psd
+À™&N
+`†8ö‡À~â8@œ!€gˆCàYâ˜%,q’�‰C`Ž8‡ÀaâŒ!£Ä!0OÄX$cÄ!pœ8NèFd=Ì'éˆ=g¢A Sf=á"‹Óº1°Î>C&ûyûõE݈®SÏÒ…I=g"¢ž7Q/èFlú]˜ÔÏ™ˆ¨MDÔ%ýf™,J/OÃ~Ãvڦ.—ž)¼ÝÙñ!ð>^á+™?Ñ^nåø.ãã_©YEŒE3^+b|ŽJVépÔØ-¶z?w8Ü’æppm‹ÐbÞûO>»¶ºç‹ù¿~=vfluM1Öþ"Zþ=ÅßW×~ ž[;œ?Dß	‚E~$7ÉSLgì[Ã>5{Ÿƒ>Þ­@gÍÁD;“¾ßøyØhµpë1Ø$Ï1YNgʸÅÂæl
+ÌK±‰¦„þtª+J¬x3éÙ„3`¬§+0€þ6»§ÓSnkð»½Þ°ÅâJá¸Òã
+‡‚ÂçµX•¸äjƇ©Åâ²zœ¡pØ×Z)¬–f!nÛ$>xmväÊ\·$uMúü+±ïWXj:â¾Ñ#•ùû–ƒW<}à­sýe™²²:ž—Ó¯Z¯M†¬rukWcWãÀ çé‹»wŸ	cѤ/îwq‘L‰ƒ¯ðqÑ}ô›‡ó;®Dìï‰xèÜÞ1ÒÛl®¦(6æ÷ÉWE?dßÉ
˜³œ[X!tsY©ç’Œµ$e¼ÉœàONd·©ŒbÃ9céS3n©“$1‡0	Ä·
ÇÁ`†cøZ6Qî	ø|‡×jkò;âŠËét…]R¥„ˆú¸pÆEØ°v[,Í’Ñtx½>/âyÂæÎ<ÿúä䁶+Õ‹×Þ=:³ø¬ûË™ÈâDïÖÊþ¯Nï>7½k»ÅÂk$a«õöw$OvÌÔ?9žôYEóÈò«/ìõIœæŸÜ={ãRLâ.}Èÿ“ȐîÁl_"|çô™K¯F[Ò©Á®.úzøïB݂ǿЏ¨žbLº«ü•±í,è„ÇÊœgà,ËÂ÷A³D.ÇÄD»§Õä/wKn«;ìv¸yo\ô„šE]m¥Ð,AÁÛDìßÞ¾zÝÇý/æïðsõþ~·Ú×ÙPß1µYý释%þqk_‡‹×zCî@A«èÏ$2íbÍ„ÝÂþŒºZæ¥,:¨cçÌŽM—:¶)áR¸,#s4Ç6Ìd¸t1—ÃS§™íl
…Ì*w;ŠeÄoO\?}äʨ³ì\þþY¥LêIžñ-ï¶<ðÖäQ!Æ_þÞ¾µ“â»;öô©œ÷w¯æåƒÍ7`ó›°ÙÎNfÌÛR‰e2G›¢ Í+©p•-ì(16'ì/D…‹ò‚õ4#óGÙDg[·”Û,ÌÎ튭ÖÏQ^•ÙÝcKÒ{½'zÆ{O…Þ?!ÿö궶™#§å)^U‘ÿ¨¢Š‹•µ%9²¢ïÚNö^ƒ½7å¼ýlK4pSù8~˜¹9âUSãl.?w…¹›k’G4ˆm<˵µßæÿÎ+øÐØ´¸ÿÉoäîcԝCK¶o¿}´*ú¶Åf¾rÿú^Mô¾|sîÁ½µ;6Õö&¡Î„9»l‹kw+;þà^ÞaSÍu6üIÈ+Dº |/´rò2¤cÿ‚D€¹™…üc
+dxr	r"Az!Èä�äÈ äMðAlÀW!‹äcH‡¼òðt-dRñBÚ‹ëWuºÈŸÙ‹ãcEÍ9!ý7 GŠö¾†µý4|a÷a×
+šýÂå¡BGŠ{Î…lÒ¡ùS­ƒ‡Çƒ‡††oìFÑ~ºï"ää<æïcÛyä$偺C/AÊÁ{½cÃÀ‚¾Œk`ƒþ!„üHákówwÿ‡ýª­²
+ãϹ÷Üy7ÝÄ’©¥9¥fmhS)æGcÎá’±©7]w6ÝÆüX»CW"Aɬa¥!iHF$^k0†å},(ÂĬˆ!R¢/ÍN¿çœç½÷åõΙTÝ{øí9ï{Î{Îsžç÷<ç™c¿©“øæWÈ�Ÿq<pÀÚ$g6`)æòþëÅî·:¿™_ ‡ÍÀw.ó•ø|”œyP
+ð¦ˆíïv¾WSÄÆ
î{j;ÎŽü„9Û€=°9ì¦~ÿŸGsÔ}ðJpNüë\yò
�vê	ÈiÎî¦WÎÁ¶Î„…Sí¢8ƒÚÀr€*e¬B8´8…qÏ.໐ñ{µ@#0`:€ˆ|_™£Àô_p\bòšæ9á
+t2Ç€Ë2þ9úß;Ðːg…·3ˆ!³Nø[Ðd<ïÞ=øŒcÝžVïÜÌ÷IÒã?�ß9?šßd-æt7§e¿%ΆV÷"ùvœpþ3߬ãàœ€Ïò…¬õ©vqÈöªq|¤½�|LwȾŸ‹„ÿlɲŸsKyW^vRÞ_{G(ïÒ.Êûã‚㖍­RáY‘Èq²ÇÇ|ÌùÌùÙœt6䘴߬“ý‘¯ˆc~¸v1~Ÿè\*kNvëÐb±+s¼@Æçj—ºMÀ7ŽæMà¸Ø<¢d¿ýŽV?ú‡˜íô☁;!øZM ‹B+Ž¡×€íÀmx朼Gü‰¸Q.î™×
+|P%èkíòd›ã=¥m®!¶ïãÀ'Úå⇁·µË³ð©á=žw|³9}ðò!±/ûúEírt7çõGvŸ÷E×
è÷:©á,ÐÇìÓ.°íˤÏg®þòúœ7§ÊØñï5O|× üB^µ1×í¸jó#ÖUÇ]ÎS½â+äQBÞR|fpDÁ§!F5úˆU-öäýJd²÷Û€ùÑÁê×ãöà|9lî/ €wg±"€~±Í`ðî(?âÈýtºþÙ3̾ZÚs-¿†¹ßÊbÑ#“lð=³n¹†)ºÇä™äj®	ØwœÓ9ßÞ%sRº9¹ÃJoí€4ïˆê3HŽ¯ý"ô=Ï%™;¯‹Ü–êiå
+ñÁõJ¾Ë:…¤ÓuÍèò]w§[?ò}þ’ëÀ±8l|Î`y�^\ÑÀ+ÖöP–aF…“2ìÌ~ÌðÁ¯—?&ðòI&t»3xùŃÙ)4#…””ëæžOè6gòÕ³Å⯆åwÁÚµGüØ'súEÖÊ|¾_åLõ®Îã¼këJo¬^ä9#s{–N玓áÅeŸ~E2?Ð+_tóø[+úq>X&ã^íËþ чÇ&Ëw£qñóX7'Åß >Ûÿ7嶨&çO¾í}ôµ//}àÓÙÓ…ï\®Ó¼úƒsÁÎQý²WÌÕf¶¦ŠeÈy3©\ÅuÁF‡ÔwÞÚa®;óu:_xµ'¹î«’®–\Úºí¬«×ØÎÖ–Ë¥Þ::xnþ·ä5s÷õÈ`n,—%½ÿ†’Á¼èý¯1”ôåMŸ€­lmÊ1Âœ©ÓµuÏ'â«””ú1Å
¯¾ä÷\ÿ:ð·¦ù¡`ž†)ŸF7QÄ3G©Ÿž4}æ"՚è‰ñSMô_ÿʯ³N7Õƒ6àµP‰´niû²-Û²-Û²-Û²mèFŠ(|‘öP!m¡…h15ÑFÜÍg†ïB€QÊ¥õVb"çÂÀö5ú㥟ƒ^9ÏÖ¹xZAK¥¯ðö ôCT@ç¥Æûߥ¯©\•I?ýÕuuñªše¥±ÄªDW¢.Ñ‘˜Z•hoYص²}MóŽÑ|JP'mÂIÖP­¦.*¢TFÓéôj0šÀûvjÅÓBê fš†Þ<¼i‡Œ¥¾Ú`ŸZ![±ÖcøÛ‚™uhqªÂ:˨ã	Ztu@0£	¬Õ‚Õ»h%zk°¯ÔFâi%V»ÑUþïï®x3kñÞcƒÿWÛG'cñ¤R;¨CQŠRsg’rªz©fæDM%ܯ̫S³£ÅÑÑÃtT^ÔSuNY΄ˆ}‘WuøæÍGrD*Á\¼)¨:Œµ+m³oÂT¼]m]?P¹5ž·T'‹ù©?º\ªÜÚ¼4ÎSñãµçFïŒÓ#Jú”yú€ÞžáóHKõß�hŽc8
+endstream
endobj
28 0 obj
<</BaseEncoding/WinAnsiEncoding/Differences[9/gid00164/gid00052/gid00002/gid00163/gid00041/gid00030/gid00036/gid00047/gid00045/gid00033/gid00029/gid00031/gid00039/gid00048/gid00042/gid00035/gid00001/gid00046/gid00032/gid00034/gid00028/gid00040/gid00010]/Type/Encoding>>
endobj
29 0 obj
<</Ascent 1035/CapHeight 700/CharSet(/gid00164/gid00052/gid00002/gid00163/gid00041/gid00030/gid00036/gid00047/gid00045/gid00033/gid00029/gid00031/gid00039/gid00048/gid00042/gid00035/gid00001/gid00046/gid00032/gid00034/gid00028/gid00040/gid00010)/Descent -262/Flags 32/FontBBox[-162 -262 1179 1035]/FontFamily(Acumin Variable Concept)/FontFile3 36 0 R/FontName/GDVRAG+AcuminVariableConcept/FontStretch/Normal/FontWeight 275/ItalicAngle 0/StemV 48/Type/FontDescriptor/XHeight 500>>
endobj
36 0 obj
<</Filter/FlateDecode/Length 3419/Subtype/Type1C>>stream
+H‰|VkP”ç>»áWÇ]À|jmq*Ër‰ÁÖI¡²&5]±¬€ ¬BÃeÝ],Ng¬¹8Auë­ØhA4
¨­Ø¦fYcC§i%¦Õ]´–L∩ÁeB:DÛqdOŸó±ÎôWÿ|—÷ýÞóžóœçyÞOCQZÒh4ó
+Öç~3¿ª©¾¶a]¥£¶rSmEcC•ÍîR?eiBÙSõãKÇ17êõ¯Ú£Cžé¡C3‚sgÚfR2‚P<Í dšO‹)“–Q>­¤Õ´ž*©–¶Òvz‰vÓÏè( n:O½š­š[j«M¦Ì¥9êÝôTÖäݔϞ|ÏÉœ¼g›"÷¥‘ñ§#÷§"ã‘ï³–EÞ¯‹¼çäFî‘}²#ëL‘ïr"q³ÏGòÊz¼.²¦IÉ2eæ(ùՍ›lÊšíN—­Þ©¬l¨jtØ•.[µQɯ«SŠk·Ô¸œJ±ÍislSUl•Z§b«uÕØJ¥â°m©Åz‡­Zq9*«mõ•Ž•F™ùŸ×Íÿg+KYÛP+ok\t*•
ÕˆÒ¨îRÕØÔàrÔÚœÆËšl·Û”\¥Ú¶™ÐÕ×”$[M¿ÒìдYÚ‘'Þzb8jôüèK1ïÅöÇÞŽ;¿&~8~tÊâ©Ê´–„ N§Ë4¹£B-_ZµLXcî¥êÇŸyx0úa0fü™ñƒÑÝåú‡òþè@¬:>^:Þ§Ž<”Ùñ`L}è]½<«_‡Ä&pxß’\¦âkƒÌ{­z¦lgSai“â*aª	63Å*˜6MqÌÇ´™1ÌãÆæwËš™ï»íÌ]˜ç+.skY0.ùhzS<4†!½Ô≱ĖhæžCÌw
¸Ü“ Ÿv¶0ÿ‘=sÊìeþ"ÑÚʤqw1?ðéR™Ï–{b™'0@³°é
C{˜¦›Çæ0½Ø[ÃôuŸIó$œmìHu3½åÛÉÚ™
+w
+óqSr>ŸÞÇëÅåcîG)c’úe·=nfHì¬@ó�r%wióïöìgާ÷G’_ŠI`z֐Ë¢•éraêZiÁ‚\¯5š©Þ‘†0d.bí÷
+ݹq(ÆÍü¤Œ'Vº$B›WôÅ0YòÕõX”\êgz¡À„PY>/Ó‘Â8¦o¸‡˜œÿ1¦å½ƒq­X2½9¼oIcZ((·wö1}‡€‘µ x‡_½ÖÁtÜ›d`:Š¹mãVæÍ#ýh0¦· ѲfÌmZbgÎ¬CĪ…iê¥ürÓz
jzVR˜ƒ	¾j41_Æ¥pøÏØzr¡Å§‹eÚÊà^îÄS;’âv”Á7¥gs)ò„FÍ^TL‚•š}X:˜%9«½Lèa°ãÔXL+ó`°H
Ú6Îæð+ÆÁØ…5;GÐÍãΠMêLBÀ�vº%ŝˆ×?™‹À™³þÌ~pˆŠÊQèÝ¶š2ÀŠ•ELk“LÀS
+8Á7ÓC“õÑ”@[*SÅ°pä%‚†_kPp½N¸RÓdÇ[Ð
>ÛŠ_Ѹ!€RË¥üµB–£®~¦ýHv!ú¶€U,âyA
+Ÿ…Àš¢‘ù¬­kÊÕOIö J?~ݾ¤övDqX+ÍP1†\D”¡% À“è²æ7Ó°lqÃèeÅiaÇp”oœû×0€Pjï „#ÛÆI†`3ð/J·B=DŸ÷%ý!&3tÂÿîìCu>ÝO™¡dÊ(۞ʚùIˆR/ù<¿r<�¼é ÔŒ|™ë„Ý҈󧊄\ÉvJ}J„\tß©ÑËà<åƒ(”iñ?`ÒR.r©ðJ.gÊò@Iè=Ñßõ`ó°�Iü…ÒË‚®,fOäiš¯*n'¡Ir¿#Ô áÛ?T{Çïoö
+o8|Ãô/®Tì@téZË1Ð’²-m ±å$ô2SØ?·v—%õOƒÑ�ÍaÙcB@œR–‡ÄWŸ°Çî‹À†ŸJUZyuyæŒG1(œ>‡žsG†Ö_„`çDÀˆÉŠ~…WHnüņ1-¦Óâµ|ÙUâ.Þ£Þ±M¹£j�M“²Õ§dp–’,i³As�BÉ2“&Dþ'¶ kY|Ð#æµJZÿ‘ÂQ€B‡Å(ÎËëÈпaƺ{PU¬xïHYÚ¾¨p’’<ñWUåwEq¯;®!ɶ{øô6zŽ³ª–{l�8_?*$7Ðk¥.c«•Ù+q0Ø]�8¯Âù÷â	ÝnJüE¬9öjo•åé9üù=éÉIø~ ¢
+ô–“¥;=‚:D~ÝrRàxb®21WC¬d:ÇY.ÅRs–L¤¨O­I§R#lù\r0ù#§4OÆî;PAù]Sg'†QàÎpwÍfíóæ10uÞˆ‡Ãªúk€Ï“Lâ^ÐAäç~$ì퐲@ä½f¼þVôñ~)$Ð’m 3mË@sÄ
+à"´ÎçO8£÷Ôú#°/èì‹MXÇšœœ“‡¦:þ«¢ß%Þ‚Àùš›pÞŠÇ÷@ùü™~ßßÎøSX³LàúåÆe>�¨ìD~ô}"$—õH’VeLGÍ�’æIBO#Jæþ”\ŸøÇ`Éw|º½rºw¦Þ$äÀ¼ù†®Iÿ |Ù4ÓU2
ý¼Ö$q	kãÕÌm(žß”ƒ¤UÈV#íÜ"ò*a@¸_žA%tL,k­pôÇb܇ÄlÚ¥¯brµb[ÉM‹ß+÷ ?lÅç™âÇäObŸDôHVWE‚ð÷ÂoîÁX·Às%ˆÚ¾‡>R½ôCÈD&¹Êi±¾É.tEU•“t”VDÜx–¯Ĭv/<‰T—‹ÄÖK¤B9^$‚r
+þº´Gåùs¨ô¢fóN,<$tI
+F\øDçå'g@HtSžþ.²öéк´&»Ús1±3#
+;P€S*Eö<¨Âú†<N•Mò¤QaËÔR0xµ�šÃrø”HsŸS›)&‘#†½I„ºÈX4O	ìzT9*ÇdakÒlœ!b„³D@©r¸|W°~NtmÀo»ïˆ·Çˆ#Sùîù3ürò¼X%âo¶ø¡Ýf�Ljlß¼-d÷	ÛæÉÞ°Z:ìÄÄGî!hµ´	PŒˆ“%Ê’Ï„í×ÍE0¾"²»÷éq¯xÓÄeÅÅè¿<—khSgÇOÚÔK¬ØÚhä¤b½0´kééö¡³K[ð²B]gº7Š©à‡¢n[HÕ–îC{„-MµTôCTÆ0Rñ
+&µdlƒ7ÅL&„¡˜!ãÝÿwâÖ~:á¼ç}ßçyþMÞ%ê½êß(S¨x?P’Ê§6j‰7�è¥0«�ð]BÂG-#*^ÇKãJÁ£„©Fõ§v? 1µ¤µÞÃåTŠ,Ì„U°C…;ØΗܩ‹c|F­®Œ«Výà¼1ô‚Íf®tŒ|1F+:£»[yì’t¬&¾º8^ °¶æ$¸_ v–<eáOzÉ\½¶—ÔCA¤%ÀV�Û5sE	™Ÿã­/ç=ûC'tì:\ÍMïÓéP¸Uµ´ÉøÒ6™Ÿy	rÿ ¯ÙLXÏÏ9?-ÿ%âý5¬#ëÄ2kµ÷W$¥oÁ|PwðÎçÄ©n<ÂyŽÑ¨:èëi±A ß8àŸPUùyÉ$™ü4ø=ýIŠ>„ZS@œU8²–S®†¤¼þ¯*¿Þ>ûì‘
+2…?xùÚz¶ž ÝÅ"¥‚ð"u3¼ý¹»4·§›ŒçäÒrUaöÀ§Ð°"±ùšÞôˆÊ^£A¹ý*¡šš»€ó6·öˆÖäñ6el;'Ñw^Sç[XÞýÃiã	ÇÚ¡‡ï&!BùzY´us�º¹Î:MNþ†áßý1èýODkðD¯(dùÀj5§Ý_pMªø£¹OlœÉ¬ÕÕ²†¡è9¹úW7;ÏÆû…Í>^› ݃§ˆêW |o^¦rGX7ç\Cß"U“iåÁ"SÌãHâ´HÊ+ô¼È%tȝ
+ÉZ⫍õ	J"gm²\ÊŒÕ	ßíe2§I”ìŽT—ÕÿLT<47ÀwGZÅŽõ¤†fúP=–€ðŸ¶È9‹)§¦çv”a¡)à3ž9éÿƒew³rð²Ð	•ižáê÷=¿üi›%h¶Hn#‹””§è‹aÖTùeŝ˜Ø
+Ú]#k¶sˆ-4õ
+Lé&¼Éiá	ï(7ží=ÕZØO!¯
+R«^¡ß\"^@2iúT0Óèôq(oCYñçO¢F:čxñû$ƒJ+˜q-}ÈÇr¡|ð͈äçüî`´’lçÆ^_²M¨Š1"eCyF$pœ©jWÜ=YŒ»÷4ÐZ]R+Sg¥;iŠ·•A÷¹Ô×ëØíŽwø c/n*ùбWœoÙtܱWNVõû·ŠØP‰qJ{ÂçÕr'®ïëýN™k·,™_?Ïî‹ïÞ`æÚ#c‘΃óìšÆѶã…ß+ÿ`�OèÍ
+endstream
endobj
16 0 obj
<</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>>
endobj
13 0 obj
[12 0 R 11 0 R 10 0 R 9 0 R]
endobj
37 0 obj
<</CreationDate(D:20190909012612-07'00')/Creator(Adobe Illustrator CC 23.0 \(Windows\))/ModDate(D:20190909012612-07'00')/Producer(Adobe PDF library 15.00)/Title(LayoutSpec)>>
endobj
xref
+0 38
+0000000000 65535 f
+0000000016 00000 n
+0000000192 00000 n
+0000054694 00000 n
+0000000000 00000 f
+0000078655 00000 n
+0000078411 00000 n
+0000078919 00000 n
+0000079243 00000 n
+0000077664 00000 n
+0000077734 00000 n
+0000077805 00000 n
+0000077876 00000 n
+0000111366 00000 n
+0000054746 00000 n
+0000055147 00000 n
+0000111253 00000 n
+0000076022 00000 n
+0000077102 00000 n
+0000077150 00000 n
+0000078295 00000 n
+0000078326 00000 n
+0000078179 00000 n
+0000078210 00000 n
+0000078063 00000 n
+0000078094 00000 n
+0000077947 00000 n
+0000077978 00000 n
+0000106966 00000 n
+0000107252 00000 n
+0000100544 00000 n
+0000093694 00000 n
+0000079623 00000 n
+0000079898 00000 n
+0000093956 00000 n
+0000100812 00000 n
+0000107748 00000 n
+0000111411 00000 n
+trailer
+<</Size 38/Root 1 0 R/Info 37 0 R/ID[<97D202C4A94B874591B5BE50E1DF05AF><C5803DC1F035234DB619BA5F88CA5DE0>]>>
+startxref
+111602
+%%EOF
diff --git a/assignments/layout-img/LayoutSpec.png b/assignments/layout-img/LayoutSpec.png
new file mode 100644
index 0000000000000000000000000000000000000000..d35a62e29abba453847a525fc4eba2956e1d34d2
Binary files /dev/null and b/assignments/layout-img/LayoutSpec.png differ
diff --git a/assignments/layout-img/rotations.png b/assignments/layout-img/rotations.png
new file mode 100644
index 0000000000000000000000000000000000000000..ffb63c5918e3a30b458bc244acdc88a3c7689782
Binary files /dev/null and b/assignments/layout-img/rotations.png differ
diff --git a/assignments/layout-peer-review.md b/assignments/layout-peer-review.md
new file mode 100644
index 0000000000000000000000000000000000000000..ca6f59b669bd85d031274b45698200baae0c2854
--- /dev/null
+++ b/assignments/layout-peer-review.md
@@ -0,0 +1,28 @@
+---
+layout: default
+---
+
+* TOC
+{:toc}
+
+# Layout Peer Review
+
+- For peer review, you will be looking at the *Part 4* submissions for the layout assignment. In particular, you will be evaluating the extent to which a student faithfully reproduces their chosen application layout.
+
+- First, you should check the wireframe to see what layout the student was attempting to create. If you have the app, or have quick access to it, it's also good to download and run that app alongside the student submission for comparison.
+
+# Layout Criteria
+
+## External Criteria
+
+- Layout wireframe is present and filled out.
+
+- Wireframe is representative of both the chosen application, and the running submission.
+
+- Layout is responsive to orientation. If using the emulator, click the device rotation buttons to check this criteria.
+
+- Layout is able to scroll in some clear way.
+
+## Additional Feedback
+
+This is your chance to evaluate the success of the submission. Feel free to offer feedback wherever you think it is relevant -- this is your chance to help out your peers!
diff --git a/assignments/layout.md b/assignments/layout.md
new file mode 100644
index 0000000000000000000000000000000000000000..24e014193fdc62143a83454f625ca6126fbfc82b
--- /dev/null
+++ b/assignments/layout.md
@@ -0,0 +1,423 @@
+---
+layout: assignment
+published: true
+
+title: Layout
+code: as2
+
+assigned: April 10th, 2020
+due:
+ - <strong>Part1-2</strong> April 17th, 2020, 10:00pm
+ - <strong>Part3-5</strong> <del>April 23rd</del> April 24, 2020, 10:00pm
+ - <strong>Part3-5 Lock</strong> April 25th 2020, 10:00pm
+
+revised: 10:00 AM Thursday, April 23th, 2020
+
+objective: Use XML and programmatic constraints to replicate three layouts.
+
+android_goals:
+  - Create a generalizable, reusable layout for any number of images
+  - Understand Android layout GUI and XML
+  - Familiarize with Android programmatic layout API
+  - Understand Android constraints implementation
+  - Handle portrait and landscape orientation correctly
+  - Handle fixed- and variable-size container views
+  - Learn about Inflators
+hci_goals:
+  - Make use of interactor hierarchy
+  - Use constraints to create responsive layouts
+  - Make use of complex built-in layouts
+  - Implement reusable layouts
+  - Understand how scrolling works
+  - Understand how sizes influence layout
+---
+
+* TOC
+{:toc}
+
+# GitGrade links
+
+**Classroom** [Summary](https://gitgrade.cs.washington.edu/student/summary/8723)
+
+<span class="note">Note:</span> this is a 2 part assignment. You will work in the same repo for both, but you must accept part 1-2, turn in part 1-2, then accept part 3-4, then turn in part 3-4
+
+**Part 1-2:** [Accept the Assignment](https://gitgrade.cs.washington.edu/student/assignment/119) / [Turn in the Assignment](https://gitgrade.cs.washington.edu/student/assignment/119/turnin)
+
+**Part 3-4:** [Accept the Assignment](https://gitgrade.cs.washington.edu/student/assignment/120) / [Turn in the Assignment](https://gitgrade.cs.washington.edu/student/assignment/120/turnin)
+
+# Assignment Description
+
+This is the assignment spec for Layout. Scroll down below [Part 5](#part-5-reflection) for some development strategies and tips curated from past students!
+
+On average, students spent about 10 - 12 hours on average on this assignment. It has been modified
+somewhat since then, but make sure you get started early, as this can quickly become one of the more
+time-consuming assignments of the quarter.  
+
+Also an important <span class="note">note</span> : Part 1-2 and Part 3-5 are NOT equivalent in difficulty. Part 1-2 should
+take significantly less time than Parts 3-5. Once you have completed part 1-2, turn it in and
+continue to work on the rest of the assignment. The checkpoint will help you at the end of your
+development cycle to ensure your code is working correctly.
+
+# Introduction to Parts 1 and 2
+
+For parts 1 and 2, you will be building the same layout twice. It must show at least five images,
+be scrollable, and look equally nice horizontally and vertically. Additionally, you must
+use constraints to achieve this, using the  `ConstraintLayout` we provide in `part1.xml`.
+`part1.xml` can be found in the `res/layout` directory in Android Studio once the `layout` project has been opened.
+
+The results should look like this:
+
+![Portrait screenshot for parts 1 and 2](layout-img/1_portrait.png){:width="25%"}
+![Landscape screenshot for parts 1 and 2](layout-img/1_landscape.png){:width="50%"}
+
+
+For part 1, you will use Android Studio's built-in layout editor to create the desired layout, using a combination of XML and the GUI.
+
+For part 2, you will create the same layout programatically, using Java code to construct view
+objects and add them to our activity. In this way you will demonstrate how to make a
+generalizable layout class that can be reused for an arbitrary number of images.
+
+The important part of the interactor hierarchy for parts 1 and 2 is shown below:
+
+<div class="mermaid greenlarge" >
+graph LR
+W(LinearLayout) --> Status[StatusBar]
+W --> R[RelativeLayout]
+R --> S[ScrollView]
+S --> C[ConstraintLayout]
+C --> I1[ImageView: borders: vMargin]
+C --> I2[ImageView: borders: vMargin]
+C --> I3[ImageView: borders: vMargin]
+C --> I4[ImageView: borders: vMargin]
+C --> I5[ImageView: borders: vMargin]
+R --> B[BottomNav]
+
+classDef greenlarge fill:#dbf0db,stroke:#333,stroke-width:2px,font-size:16px,padding:0px,height:50px,top:1px;
+classDef bluelarge fill:#99ccff,stroke:#333,stroke-width:4px,font-size:16px,padding:0px,height:50px,top:1px;
+
+class Status,W,S,R,B greenlarge
+class C,I1,I2,I3,I4,I5 bluelarge
+</div>{:font-size=14px}
+
+We can represent this same interactor hierarchy visually in an _Layout Wireframe_ shown below.
+ Note that you will only be adding things inside the ConstraintLayout.
+
+![Reference image for parts 1 and 2 showing how each image is staked vertically with vMargin space on every side; below; above; and between images](layout-img/LayoutSpec.png){:width="40%"}
+
+You will only be configuring the ImageViews as they relate to ConstraintLayout (shown in blue).
+ Also this is simplified from what you would see in the Layout Inspector
+
+And this video shows parts 1 and 2 in action:
+
+<iframe width="560" height="315" src="https://www.youtube.com/embed/gf5__gtVhY0" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
+
+You may find the following link helpful when working with constraint layouts:
+["Building a Responsive UI with Constraint Layout"](https://developer.android.com/training/constraint-layout) (pay particular attention to the "Set Size as a ratio" section).
+
+## Further details on Part 1
+
+**Tasks**:
+
+* Use the tools provided by Android Studio to build a layout that vertically stacks images.
+
+When it comes to layout, working directly with XML can be a pain, especially when there are several attributes to keep track of on each element. Luckily, Android Studio provides a visual editor that you can use to build your app layout.
+
+For `part1.xml`, you will accomplish the following:
+
+* Familiarize yourself with [how to reference images in res/drawable](https://developer.android.com/guide/topics/graphics/drawables).
+* Use the Visual and XML editor to construct a single, scrollable column of images.
+* You must place a `vMargin` gap between images and their container, as well as between consecutive images. You do not have to ensure that the bottom image has `vMargin` space between it and its parent's bottom. `vMargin` is defined in `res/values/dimens.xml`
+* Your layout must have enough images that you need to scroll (use `animal_0` through `animal_4`)
+* Each image must be scaled so it fits horizontally and is centered *while maintaining its aspect ratio*. This requires you to set some attributes specific to ImageViews (not inherited) which are mentioned in the [ImageView Documentation](https://developer.android.com/reference/android/widget/ImageView)
+* You must use constraints to ensure that an image is adjacent to the previous image (`Top_toBottomOf`) and that its left and right side are constrained to the parent container.
+
+_Related APIs_:
+* [ConstraintLayout](https://developer.android.com/training/constraint-layout)
+* [Linear Layouts](https://developer.android.com/guide/topics/ui/layout/linear)
+* [ImageView](https://developer.android.com/reference/android/widget/ImageView)
+* [ViewGroup.LayoutParams#MATCH_PARENT](https://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html#MATCH_PARENT)
+* [ViewGroup.LayoutParams#WRAP_CONTENT](https://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html#WRAP_CONTENT)
+
+## Further details on Part 2
+
+The `Part2View` starter code can be found in the `cse340.layout` directory in Android Studio.
+
+In `Part2View` we have set up the basic scaffolding necessary to complete the given layout. For this section you will be instantiating the view objects from Part 1 programmatically.
+
+**Tasks**:
+
+* Create the layout from `Part1View` without using an XML file that vertically stacks an
+arbitrary number of images.  That is, you must accomplish
+the layout requirements from Part 1 programmatically, creating Views in Java to accomplish your
+desired layout. Part 2, however, will allow for an arbitrary number of images, not just the ones specified in an XML file.
+
+It may be useful to view the interactor hierarchy using Layout Inspector when Part 1 is
+running to understand how to structure the views you are creating programatically.
+
+# Part 3
+
+<span class="note">Note:</span>  Remember to accept the as-layout-part-3-4 [assignment](https://gitgrade.cs.washington.edu/student/assignment/120) and [turn in the assignment](https://gitgrade.cs.washington.edu/student/assignment/120/turnin) when you are done.
+
+The `Part3View` starter code can be found in the `cse340.layout` directory in Android Studio. We will create a custom Layout in Part3 that can organize an arbitrary series of Views into a Pinterest-like layout. Pinterest is a great example of a high-profile app that can be built with relatively simple layout instructions. For instance, one could imagine breaking the layout into two large vertical columns, then assigning various elements to each one. You will also need to ensure the columns never differ by more than the height of one image.
+
+![Screenshot of pinterest layout](https://newsroom.pinterest.com/sites/default/files/inline-images/2014112502.jpg){:width="50%"}
+
+To determine which column a photo should go in, we will use "pinterest" ordering. You must track
+the height of the images in each column and add the next image to the shorter column (or the
+*left* column if equal). For 20sp we will accept one of two methods for determining the Pinterest order.
+
+- Using the intrinsic height of the `drawables` image to determine which column to make this determination.
+(Please see the explanation on our discussion board for why this is so.) The screen shots for the
+Pinterest order in portrait and landscape are shown below.
+
+![Screenshot of part 3](layout-img/3_portrait.png){:width="30%"} &nbsp;&nbsp; ![Screenshot of part 3 scrolled](layout-img/3_portrait_scrolled.png){:width="30%"}
+
+![Screenshot of part 3, landscape](layout-img/3_landscape.png){:width="45%"} &nbsp;
+![Screenshot of part 3, landscape, scrolled down](layout-img/3_landscape_scrolled.png){:width="45%"}
+
+- NOT using the height of the `drawables` directly, instead you will need to get the *displayed*
+(or measured) height of the image. To do this you need get the measured width of a column, then
+use that to measure the height of each image. It will help to take a look at
+[How Android Draws Views](https://developer.android.com/guide/topics/ui/how-android-draws)
+[View.Measure](https://developer.android.com/reference/android/view/View#measure(int,%20int)) and
+[MeasureSpec](https://developer.android.com/reference/android/view/View.MeasureSpec) for this version
+
+![Screenshot of part 3](layout-img/3_portrait_measured.png){:width="30%"} &nbsp;&nbsp; ![Screenshot of part 3 scrolled](layout-img/3_portrait_measured_bottom.png){:width="30%"}
+
+
+Note that two photos with different resolutions but the same aspect ratio (width to height ratio)
+will both affect the column height identically because they will be scaled to have the same size on-screen.
+
+
+Keep in mind that similar to Part 1 and Part 2, your Part 3 layout should be responsive to device orientation. When rotated your layout should maintain the proper positioning (vMargins, spacing, and aspect ratios should remain the same while images scale to fill the extra space.)
+
+
+Our Pinterest style layout will be achieved both by using Layout Inflation (using a LayoutInflater with a valid XML file).
+A [LayoutInflater](https://developer.android.com/reference/android/view/LayoutInflater.html)
+allows us to accept a valid XML file specifying part of an interactor hierarchy and convert it
+into a View object that can be added to the interactor hierarchy you are constructing.
+This can be seen in practice in the `R.id.action_part_1` case in MainActivity#onCreate(Bundle).
+The XML/visual editor makes it much easier to build our app layouts, so we can use that to create new
+layouts, then use an inflater to convert the XML into an object before programmatically
+appending it to our current app layout.
+
+The interactor hierarchy for Part 3 is shown below. The elements marked in light green must be
+created using inflation (and the `part3_grid.xml` file must do this). The elements shown in
+blue must be created programmatically. Note the switch to `LinearLayout` to hold the images.
+
+<div class="mermaid greenlarge" >
+graph LR
+C[ViewGroup:ConstraintLayout]
+C --> Column1[ViewGroup:LinearLayout]
+C --> Column2[ViewGroup:LinearLayout]
+Column1 --> V1[ImageView:Gumball]
+Column1 --> V2[ImageView:Fox]
+Column1 --> V3[...]
+Column2 --> V4[ImageView:Duckling]
+Column2 --> V5[...]
+
+classDef greenlarge fill:#dbf0db,stroke:#333,stroke-width:2px,font-size:12px,padding:0px,height:50px,top:1px;
+classDef bluelarge fill:#99ccff,stroke:#333,stroke-width:4px,font-size:12px,padding:0px,height:50px,top:1px;
+
+class C,Column1,Column2 greenlarge
+class V1,V2,V3,V4,V5 bluelarge
+</div>{:font-size=14px}
+
+
+**Tasks**:
+
+* Before getting started on this section, try constructing a [LayoutInflater](https://developer.android.com/reference/android/view/LayoutInflater.html) and passing in your `part1.xml` file.
+* Once you are comfortable with inflation, use inflation  to make use of the ConstraintLayout we have provided for you (`cse340.layout.R.layout.part3_grid`)
+* Programmatically create ImageViews based on the information passed in:
+  * Add each image to the bottom of one of the two columns.
+  * Which column an image is added to will depend on the current length of both columns (the image will be added to the bottom of the currently shorter column).
+  * Each image must be `vMargin` from the previous image vertically (or from the top of the column **if it is the first image in that column**).
+  * There must be a `vMargin` gap between the left image and the left side of the screen,
+  between the right image and the right side of the screen, and between the two columns. The
+  center of the `vMargin` gap between the two columns must be in the exact center of the screen.
+  All images must be horizontally scaled to to be wide enough to meet these margins exactly.
+  * The heights of the images must be scaled proportionally based on the constrained width.
+  * The bottom of the last image in the longer column must be flush with the bottom of that
+  column. If the other column is shorter, then of course it will show more margin.
+* Write code that evenly distributes ImageViews between a given set of columns based on the scaled height they will be on screen, not the dimensions from the drawable resource.
+* Note that all of this code must be in the contructor of the `Part3View` (or in a
+  private method called by the constructor.)
+
+*Related APIs:*
+[LayoutInflater](https://developer.android.com/reference/android/view/LayoutInflater.html)
+
+
+# Part 4
+
+The `Part4View` starter code can be found in the `cse340.layout` directory in Android Studio.
+
+For part 4, feel free to explore anything pertaining to layout that we have discussed over
+the last few weeks. You are not limited to only using the types of layout covered in class. Your task is to sketch (wireframe) and re-create an interface from another
+popular app. For instance: Twitter, Facebook, Instagram, etc. (not Pinterest!)
+
+Your layout must meet the following requirements:
+* Your layout must implement a scroll view in some fashion, allowing the user to scroll through
+content on your application.
+* Your layout must be responsive to device orientation. If the user rotates their device, then
+your application must adjust to fit the new orientation.
+* Your interface should be sufficiently similar to the one you're emulating. Don't leave out things like icons & text.
+
+**Tasks**:
+
+* Before you start, sketch the interface you've chosen to mock up as a Layout Wireframe *on a
+piece of paper or using a tablet pen*. This sketch will be turned in as part of your reflection
+in [Part 5](#part-5-reflection).
+* Also draw out the Interactor Hierarchy for the interface. Your Interactor Hierarchy may
+be done with a computer program.
+* Using XML and programatic means, create your version of this interface.
+* Make sure that you create a Part4.xml file and add/commit/push it to your GitLab repository
+ (a similar process to using your own pictures.)
+
+
+# Part 5 (Reflection)
+
+For this part, you will submit your reflection on this assignment to Gradescope. Create a MS
+Word, Google or other type of document and copy the following questions (in italics below) into
+that document. Add your responses below each question. You can have
+more than one answer per page, but if you can, please try to avoid page breaks in the middle of
+a question. Insert page breaks between questions as needed.
+
+1. _Diagrams and images_
+  - _The Layout Wireframe you drew for Part 4._
+  - _The interactor hierarchy you drew for part 4. (Do not turn in a screen shot of the
+    layout inspector for this)._
+  - _A screen shot of your final interface and the the interface you are emulating, both in
+  portrait and landscape mode._
+2. _For every interface there may be multiple ways of laying it out, particularly if they are complicated.
+As you reflect on your design and implementation of part 4, think of another way you could
+wireframe the same interface using different ViewGroups/Layouts._
+3. _This class is part theory, part implementation. As such, lecture and section may not have
+provided you all of the information necessary to complete the layout program. How did you
+approach the independent learning required to complete this assignment? List at least one
+resource you used in your learning that would recommend to a friend taking this class in the
+future._
+4. _Why are responsive designs important, in user interfaces, software development and software engineering, and real life applications?_
+
+# Development Strategies
+
+* You may run into issues when rotating the device. Note, when rotating the emulated device or your personal Android device, that the layout must adjust accordingly. You do not need to readjust the layout of your images when rotating the device, as this must remain the same.
+
+![Rotation buttons on emulated android device](layout-img/rotations.png)
+<p style="text-align: center; color:#808080; font-style: italic; font-size: 10pt;">These buttons will allow you to rotate the emulated device clockwise/counter-clockwise.</p>
+
+* When dealing with the Android documentation: ask as many questions as necessary! The android documentation can be painful to read through, as there are many potential options to choose from. If you need any help parsing it, feel free to ask anyone on the course staff for advice. Additionally, we suggest that you read through the following resources as you develop your apps, to better understand the tools you are utilizing (these are referenced in their respective parts as well):
+  * [An explanation of the ImageView ScaleType attribute](https://thoughtbot.com/blog/android-imageview-scaletype-a-visual-guide) (Part 1)
+  * [Building a Responsive UI with Constraint Layout](https://developer.android.com/training/constraint-layout) (Part 3) Note the "Set Size as a ratio" section here
+  * [What's new in Constraint Layout 1.1.0](https://android.jlelse.eu/whats-new-in-constraint-layout-1-1-0-acfe30cfc7be) (Part 4)
+  * [Adjusting the view size](https://developer.android.com/training/constraint-layout#adjust-the-view-size)
+
+
+# Debugging tips and tricks
+
+* Recall that you can use the Layout Inspector to see where your views are placed in the parent.
+The Layout Inspector is can be found under the _Tools_ menu.
+* If your application stops running (the device displays an alert that says
+  "<application name> has stopped"), you likely have a serious runtime error. Make sure
+  to look at the _Run_ tab at the bottom of the screen. For more
+  information on runtime crashes, see
+  [Crashes](https://developer.android.com/topic/performance/vitals/crash).
+* Your application may crash while inflating if there is a problem with your .xml file.
+* Logging output is especially useful for testing the functionality of sections of code such as `Layout#MainActivity#OnCreate` and other methods. Much like `System.out.print` in Java, Andriod provides its own class for producing output: `Log`. We suggest that you use `Log.i` and create your own custom tag so that you can filter the output for the information you want. Below is an example of how to use the `Log.i` function.
+
+```java
+private static final String TAG = "Layout";
+
+Log.i(TAG, "Hello world!");
+```
+
+  To make full use of Logcat, make sure to configure the priority level (in this case, "Info") and use the correct tag (in this case, "Layout MainActivity"). It's also good to check that you have the correct device/emulator selected.
+
+<span class="note">Note:</span>  Remember to take your `Log.i` debugging calls out of your code before turning it in.
+
+_Related APIs_:
+[Android Log.\*](https://developer.android.com/reference/android/util/Log.html) | [Using Logcat](https://developer.android.com/studio/debug/am-logcat)
+
+
+
+# Turn in
+
+## Code Submission Instructions
+
+<span style="color:red;">We will test layout on emulators with different screen sizes. Please use constraint correctly. Don't just try to match pixels in our sample screenshots.</span>
+
+You will turn in the following files on GitGrade
+- [Part 1-2](https://gitgrade.cs.washington.edu/student/assignment/119/turnin).
+- Make sure you have accepted [Part3-4](https://gitgrade.cs.washington.edu/student/assignment/120) before turning that part in.
+- Continue to work in your same repo
+- [Part 3-4](https://gitgrade.cs.washington.edu/student/assignment/120/turnin).
+
+We are allowing you to turn in Part 1-2 early for a checkpoint to see how closely you match our
+pixel tests. You will get 1 point for turning in code that compiles and passes up to half of the
+tests. If you pass more than half the tests, we will award you 2 points.
+
+Make sure you only edited the following files for submission:
+
+```txt
+─ Part1.java
+- Part2View.java
+─ Part3View.java
+─ Part4View.java
+- res/drawable
+- res/layout/part1.xml
+- res/layout/part3_grid.xml
+- res/layout/part4.xml (optional, or other .xml files for part 4)
+- res/values/strings.xml
+```
+
+Do not edit any of the other files that we have given you, do not delete any of the images in the
+ `res/drawable` folder, and do not delete any existing strings in `res/values/strings.xml`
+ (you may add bitmaps and strings of course.)
+
+If you add your own images in [Part 4](#part-4), please make sure to add and commit them to
+your repository in the `res/drawable` directory before turning in your assignment.
+If your images are not there, your custom layout will not work for others and you will
+NOT get credit for the work you did.
+
+<span class="note">Note:</span>  Large images can be problematic both for running your app and for committing to your
+gitlab repository (there are size limit imposed on school resources). Please make sure to resize
+your high resolution images before using them in your creative application.
+
+## Reflection submission
+
+The reflection will be turned in to Gradescope.
+
+
+# Grading (40pts)
+
+The Layout assignment will be out of 40 points and will roughly (subject to small adjustments) be distributed as:
+
+Part 1-2 checkpoint (2pts)
+<span class="note">Note:</span>  this MUST be turned in on time to receive points. No late assignment
+for part 1-2 will be accepted.
+* Turned in and compiles: 1 pt
+* Passed >1/2 of tests: 1 pt
+
+Final checkpoint (38 pts)
+- Part 3-4 code (26 pts)
+  - Part 1 (6 pts)
+  - Part 2 (7 pts)
+  - Part 3 (9 pts)
+  - Part 4 (4 pts)
+- Reflection (12 pts)
+  - Layout Wireframe, Interactor Hierarchy, and screenshots of part 4 (3 pts total)
+  - Each of the 3 reflection questions is worth 3 points (9 pts total)
+
+
+
+
+
+## IDE Errors/Warnings you can ignore
+
+<span class="note">Note:</span>  DO NOT assume that because an error/warning can be ignored for this assignment, it can be ignored for all assignments. ALWAYS check the spec for each assignment before deciding what is OK to ignore.
+
+* `Button`
+  * Hardcoded Strings
+* `TextView`
+  * Hardcoded Strings
+* `ImageView`
+  * Missing `contentDescription`
diff --git a/assignments/menu-report.md b/assignments/menu-report.md
new file mode 100644
index 0000000000000000000000000000000000000000..c770fd20a687897ad37ed98e038f99827607e883
--- /dev/null
+++ b/assignments/menu-report.md
@@ -0,0 +1,73 @@
+---
+layout: default
+---
+# Report on Menus Assignment
+
+*Comments about what should be in your report can be found in italics. **Please remove the comments
+and replace them with your own words**.*
+
+## Introduction
+*Write two sentences describing the purpose of the experiment. This
+can be the same text you use in your [consent form](consent) under
+`Introduction and Purpose of study (Beneficience)`*
+
+## Method
+
+**Menus:** *Mention that there are three types of menus, Pie, Linear
+and Custom. Then describe your custom menu and include
+an screenshots of your custom menu in both a selected and unselected
+state. Describe some of the design choices you made when you were
+conceiving your custom menu and how your final product match (or didn't)
+your original vision? Be sure to explain clearly how your custom menu
+works and how a user interacts with it?*
+
+**Tasks:** *Describe the 9 conditions of the study. Explain how many
+items were selected per menu, and how many times each item was
+repeated. Describe how many trials each participant completed. This
+should be at most one paragraph*
+
+**Setting:** *What device was used? Was it an emulator? Did they use a
+mouse or a finger? Where did the experiment take place?*
+
+**Participants:** *Describe your participants (without identifying
+them). How were they recruited? How many were there? Were
+they consented? You should also add
+some optional information such as: What was there average age? What
+genders were present? How experienced were they with android?*
+
+**Data Collected:** *What information was collected (time, errors,
+etc)*
+
+## Results
+
+*To analyze your data, you should copy the following [spreadsheet](https://docs.google.com/spreadsheets/d/1JqfKhHugIF-kebs_bVztCnkUe0CizXN8PU_Ar3kXtK4/edit?usp=sharing)
+and paste your data into the `Raw Data` subsheet, replacing the
+contents/data that we placed there. To use this spreadsheet look at
+the `Example Chart` sheet to see a chart of your data (you can click on
+the hamburger menu in the chart to download it as an image).  You can
+also create your own charts if you are
+comfortable working in a spreadsheet.*
+
+The results will be broken into two parts. The first will describe the
+overall data, including how many erroneous selections took place, and
+how fast the user was in each condition.
+
+## Speed Results
+
+*Describe your thoughts about overall speed in different
+conditions. Use at least one chart to illustrate what you say. Here is
+ an example chart generated using our data, when you paste your data
+into the spreadsheet you'll see that it updates to reflect your data*
+
+![Picture of histogram chart showing relative performance of each condition](menus-img/time-chart.png)
+
+
+## Error Results
+
+*Describe what happened in terms of errors -- provide at least one chart showing
+what you learned about errors in different conditions*
+
+# Conclusions
+
+*Describe your conclusions. Do you think we should use pie menus more? normal menus more? or your custom menu?
+What can we conclude from your data?*
diff --git a/assignments/menus-img/atan2math.png b/assignments/menus-img/atan2math.png
new file mode 100644
index 0000000000000000000000000000000000000000..56b796497409477f99dd0a84272a2e9998f45925
Binary files /dev/null and b/assignments/menus-img/atan2math.png differ
diff --git a/assignments/menus-img/device-file-explorer.png b/assignments/menus-img/device-file-explorer.png
new file mode 100644
index 0000000000000000000000000000000000000000..a1910ffdebd8067dafe6aed3aa0dc74ddd16593a
Binary files /dev/null and b/assignments/menus-img/device-file-explorer.png differ
diff --git a/assignments/menus-img/linear.png b/assignments/menus-img/linear.png
new file mode 100644
index 0000000000000000000000000000000000000000..4b5b1fcd68a6d803cea91564521d2127a1018adf
Binary files /dev/null and b/assignments/menus-img/linear.png differ
diff --git a/assignments/menus-img/math_a20.gif b/assignments/menus-img/math_a20.gif
new file mode 100644
index 0000000000000000000000000000000000000000..fc36674d716687db4f25e44f50affd813abe87a2
Binary files /dev/null and b/assignments/menus-img/math_a20.gif differ
diff --git a/assignments/menus-img/menus-stats.png b/assignments/menus-img/menus-stats.png
new file mode 100644
index 0000000000000000000000000000000000000000..a150bde99badc764037bffb103e8fc281b64edff
Binary files /dev/null and b/assignments/menus-img/menus-stats.png differ
diff --git a/assignments/menus-img/pie.png b/assignments/menus-img/pie.png
new file mode 100644
index 0000000000000000000000000000000000000000..19bb3cea94cceca2d283eceafb0f580812c433f4
Binary files /dev/null and b/assignments/menus-img/pie.png differ
diff --git a/assignments/menus-img/time-chart.png b/assignments/menus-img/time-chart.png
new file mode 100644
index 0000000000000000000000000000000000000000..555aa23251015ac371dee7a373980d5e5abd7929
Binary files /dev/null and b/assignments/menus-img/time-chart.png differ
diff --git a/assignments/menus.md b/assignments/menus.md
new file mode 100644
index 0000000000000000000000000000000000000000..e22f3fb93687af7070e681f2d15dca2a53808422
--- /dev/null
+++ b/assignments/menus.md
@@ -0,0 +1,682 @@
+---
+layout: assignment
+published: true
+
+title: Menus
+code: as5
+
+assigned: May 12th, 2020
+due:
+- Part 1-4 (programming part) <BR>
+  -  <strong>Due</strong> May 21th, 2020<BR>
+  -  <strong>Lock</strong> May 22th, 2020
+- Part 5-6 (analysis part)<BR>
+  -  <strong>Due</strong> May 25th, 2020<BR>
+  -  <strong>Lock</strong> May 27th, 2020
+revised: 9:00pm, Sunday, May 10th, 2020
+
+objective: Build and test custom interactors
+
+android_goals:
+  - Further practice using callbacks; `onDraw()`
+  - Further practice with translate
+  - Gain more experience working with callbacks.
+  - Further practice with state machines and event handling
+hci_goals:
+  - Record user study data
+  - Produce plausible experiment results (within expected ranges)
+  - Understand pie menus
+  - Design your own interactor
+  - Collect, parse, and interpret results collected from a study.
+
+---
+
+* TOC
+{:toc}
+
+
+# GitGrade links
+
+[Accept the Assignment](https://gitgrade.cs.washington.edu/student/assignment/126) /
+[Turn-in the Assignment](https://gitgrade.cs.washington.edu/student/assignment/126/turnin) /
+[Review your Submissions](https://gitgrade.cs.washington.edu/student/summary/8723)
+
+
+# Overview of assignment
+
+This assignment has two main components.
+
+First you will be creating three menus -- a linear menu, a pie menu, and a custom menu that you
+design.  The programming re-uses many concepts from [ColorPicker](colorpicker.html), but will
+have more pieces to it. Please start early, and reach out if you find you are spending more than 10
+hours.
+
+After your application is turned in, you will test these menus in an experiment with others. The
+user study will include the following:
+- Write your consent form using our [template](consent). Print it out for participants you see in person, or
+be ready to email it to remote participants;
+- Recruit and consent at least 3 participants to test your app;
+- Send your app (APK) to your participants so they can run the tests;
+- Collect the data from participants who tested your app. If participants do the test on your device or
+emulator you will download the data yourself. If participants test your application remotely they will
+have to download and send you the data they collect for you (details for how to do this are in
+[Part 5](#part-5-conduct-and-write-up-user-study)
+- Import the data into the spreadsheet we provide;
+- Turn in a copy of this data (so we can create a very large data set);
+- Analyze the data and write the report.
+
+**Note:** If you are unable to finish parts 1-4, ~~you can borrow a phone with working code
+installed~~ we will send you an APK after the lock date to finish parts 5-6.
+
+
+## Video of completed assignment
+
+_Note the Toasts (pop up messages) are missing a space between the word "Selected" and the item
+that was selected. This has been fixed in the current version of the code, but the rest of
+the app works substantively the same._
+
+<iframe width="560" height="315" src="https://www.youtube.com/embed/4o_4TAsSe8E" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
+
+# Part 1: Overview
+
+**Tasks**
+
+- Read this spec thoroughly
+- Read through the code of the classes listed below. Note any variables or methods you will be
+using or overriding from parent class.
+- Read and understand the experiment design.
+
+You will be implementing a class that can display a pie menu, a class
+that can display a linear menu, and a custom menu of your design, for
+use in an experiment comparing which is faster for the user to select
+menu items from. By *menu items* we mean the individual items in a
+menu, such as the number 1 in the sample video.
+
+
+## Overview of code structure
+
+**Files that you will be changing**
+* MainActivity.java
+  * Activity that displays the option to navigate between sessions. Also adds the corresponding menu view to the view hierarchy.
+* MenuExperimentView.java
+  * View that can displays and handle input for a menu. This is where you implement the state machine that will work for
+  all of your menus. This is the parent class of `NormalMenuView` and `PieMenuView`
+* PieMenuView.java
+  * View that implements pie menus. This knows how to draw a pie menu, and figure out where input is in it. It inherits from `MenuExperimentView`
+* NormalMenuView.java
+  * View that implements normal linear menus. Similar to `PieMenuView`
+* CustomMenuView.java
+  * View that implements normal linear menus. Similar to `PieMenuView`
+
+**Classes that have functions and fields you may need (your classes inherit from them)**
+* AbstractMenuExperimentView
+  * A lot of very handy helper methods (accessors and mutators) for the menus, as well as the Listener methods.
+  Most of the other methods in this class are abstract and overridden in the child classes.
+* AbstractMainActivity
+  * Methods to handle app creation, switching modes (from test to experiment), and starting experiments.
+* TrialListener
+  * Definition of a listener (callback) interface that is called when a trial is finished.
+
+The structure of this code is represented by the
+[Unified Modeling Language](https://en.wikipedia.org/wiki/Unified_Modeling_Language) (UML)
+diagram shown below.
+
+<div class="mermaid">
+classDiagram
+
+class MenuExperimentView {
+  onTouchEvent()
+  startSelection()
+  endSelection()
+  updateModel()
+  onDraw()
+}
+
+
+AbstractMenuExperimentView <|-- MenuExperimentView
+
+AbstractMainActivity <|-- MainActivity
+AbstractMainActivity <|-- TestActivity
+MenuExperimentView <|-- PieMenuView
+MenuExperimentView <|-- NormalMenuView
+MenuExperimentView <|-- CustomMenuView
+
+class TaskType {
+  LINEAR
+  RELATIVE
+  UNCLASS
+}
+
+class State {
+  START
+  SELECTING
+}
+
+class MenuType {
+  NORMAL
+  PIE
+  CUSTOM
+}
+</div>
+
+**Other files you may want to look at**
+* ExperimentSession.java
+  * Class that sets up all the conditions for the experiment and creates an iterator with all the trials.
+* ExperimentTrial.java
+  * Class that stores all the data for a single trial.
+* TestActivity.java
+  * Activity that app starts out in. Lets you test your menus before running the experiment
+
+
+
+## Overview of Experiment
+
+In this experiment we will have 9 conditions, each of which will include
+the number of trials (where totalTrials = `NUM_REPEATS * ITEM_MAX` trials).
+You can think of this as a three dimensional array
+
+|            | Menus       |             |             |
+|------------|-------------|-------------|-------------|
+| **Tasks**  | `PIE`       | `NORMAL`    | `CUSTOM`    |
+| `LINEAR`   | totalTrials | totalTrials | totalTrials |
+| `RELATIVE` | totalTrials | totalTrials | totalTrials |
+| `UNCLASS`  | totalTrials | totalTrials | totalTrials |
+
+<br>
+The three *menu types* (specified in an `Enum` in the code) are `PIE`
+(round), `NORMAL` (linear) and `CUSTOM` (your custom menu).
+
+The three *task types* (also an `Enum`) are `LINEAR` (menu items
+that have a natural order such as 1,2,4,8,16,32,64,128); `RELATIVE`
+(menu items that have a relationship to each other, such as
+Up/UpRight/Right/Down/etc...); and `UNCLASS` (menu items that
+have no relationship or ordering, such as Print/Cast/Bookmark/etc);
+
+The *trials* are specific combinations of menu item, task type,
+and menu type. So for example, one trial might involve showing the
+user a pie menu, with the numbers 1..128 in it, and asking them to
+select number 4. The participant can select any option, no matter what
+as soon as they complete a selection, the result is recorded and the
+next trial begins.
+
+For any given *session* (one user's worth of trials), each combination
+of menu type, task type, and menu item, will be repeated `NUM_REPEATS`
+times (`NUM_REPEATS` is specified in `ExperimentSession.java`). In
+addition, for any specific combination of menu type and task type, at
+most `ITEM_MAX` items (a total of `ITEM_MAX*NUM_REPEATS` trials) will
+be shown to the user. If you set both of these to 1 for testing, you
+can test all your conditions very quickly. Make sure to set them to
+the required values for user testing:
+`ITEM_MAX` must be at least 4 and `NUM_REPEATS` must be 3.
+
+After the code for this project is submitted, you will recruit at least 3
+family, friends, or other students and have them complete one session each. Thus, you
+will have a total of 3 (participant sessions) * 9 (conditions) *
+`ITEM_MAX * NUM_REPEATS`, or at least 324, data points when you have completed
+this assignment. You will analyze the data from this experiment in
+[Part 5](#part-5-conduct-and-write-up-user-study) of this project.
+
+
+We have implemented in `ExperimentSession` the code for you to generate
+all of the trials from a setup file called `menuContents.csv` found in
+the assets directory. Make sure that you understand the `createTrials()` method
+provided in `ExperimentSession.java` which sets up conditions for the
+whole experiment.  `ExperimentSession` is an iterator, so to run the
+trials for a given session you just use `session.next()` as long as
+`session.getNext()` is true.
+
+**Note:** that we give the user feedback two ways.
+- For updates that the user can ignore, throughout the code, we use something called a `Toast` - a widget
+that appears at the bottom of the screen and shows some announcement text. Toasts are temporarily
+displayed and then disappear. See [Toast](https://developer.android.com/guide/topics/ui/notifiers/toasts)
+and for an example of how it is used look in `AbstractMainActivity.java`
+- For critical experimental information (i.e. what to select in a trial), we give the user
+instructions by changing the contents of the `TextView` at the bottom of the screen (by changing
+the contents of `R.id.instructionTextView`). This is a permanent change that will be visible
+until they finish the trial, so a Toast is not an appropriate choice.
+
+
+
+# Part 2: Implement MenuExperimentView and MainActivity
+
+**Tasks**
+- Implement `onTouchEvent()` in `MenuExperimentView` including
+  - `startSelection()`
+  - `endSelection()`
+  - `updateModel()`
+  - `reset()`
+- Implement `onDraw()` in `MenuExperimentView`
+- Implement `showMenuForTrial()` in `MainActivity` (and set up and implement a `TrialListener`)
+
+For this part, you will be working in `MenuExperimentView.java` and `MainActivity.java`.
+This section will entail defining the functions which power your menu experiment.
+The `MenuExperimentView` class includes several methods that you will need to implement. You
+will implement the state machine logic in `onTouchEvent` (similar to what you've done in ColorPicker).
+
+One tricky thing about context menus -- they can appear anywhere in
+your user interface. To support this, we set things up so that the
+menu view is going to `MATCH_PARENT` width and height (i.e. its
+bounding box is the whole screen). However, the menu itself should
+show up right where the user presses down. To make this easier for your
+menus, you will translate the canvas so that they can draw themselves in
+a logical location given where the finger pressed in `onDraw()`. Then you
+will call `drawMenu()` with this translated canvas, which is what each
+specific menu implements to draw itself properly.
+
+**Handling Touch Events**
+
+You will handle touch input by implementing the `onTouchEvent` method.
+This is the event handler that is invoked when a touch occurs in this
+view. The state machine defined in `onTouchEvent` should work, without
+changes, for every menu you implement. The only menu-specific code is
+in `essentialGeometry()` (it finds the current index). Thus
+`onTouchEvent()` is implemented in the parent class,
+`MenuExperimentView` and *is not changed* in the child classes.
+
+`MenuExperimentView`'s implementation of onTouchEvent makes
+use of your menu's `essentialGeometry()` function to determine the
+relative position of the user's finger. Essential geometry will be
+passed the finger's position relative to the menu's `(0,0)`, i.e.
+where the user pressed. You must implement your linear menu
+so this is its top left corner, and your pie menu so that the user's finger is in
+the center of the pie.
+
+You **MUST NOT** perform any assignments within `essentialGeometry()`, as it violates the utility
+of that method. Instead, `essentialGeometry()` will return the index associated with the desired
+view, allowing the calling method to act on that value.
+
+You need to keep track of two main states: `START` and
+`SELECTING`. When in the `SELECTING` state you need to distinguish
+between the event type to determine if the user has selected an option
+or if they are still in the middle of making a choice.
+
+Relevant touch events include `ACTION_DOWN`, `ACTION_MOVE`, and
+`ACTION_UP`; think about how these touch events relate to the change
+and how the UI must respond to these events.
+
+More details about `essentialGeometry()`, specific to each menu, are in descriptions for those
+menus in [Part 3](#part-3-implement-pie-and-normal-menus).
+
+<div class="mermaid">
+graph LR
+S((.)) --> A((Start))
+A -- "Press:startSelection()" --> I(Selecting)
+I -- "Release:endSelection()" --> E[End]
+I -- "Drag:updateModel()" --> I
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+class S invisible
+class A start
+class E finish
+class I normal
+</div>
+
+Details for `startSelection()`, `endSelection()` and `updateModel()` can be found in
+`MenuExperimentView`. Note that there are no guards (boolean logic regarding the essential geometry)
+on these transitions -- any click inside the `MenuExperimentView` causes a menu to appear, and once
+a menu appears, dragging causes `updateModel()` to be called no matter where the finger is.
+Similarly, the menu must be removed when selection ends, and the trial recorded, no matter
+where the finger is. You do not need to check whether the user clicked on the
+correct menu item when you call `endTrial()`. This data will be recorded automatically
+by `ExperimentSession`.
+
+**Drawing your Menu**
+
+Your menu must **ONLY BE VISIBLE** when you are in the `SELECTING` state. You can check this in
+`onDraw()`. In addition, it needs to redraw whenever something important changes (like the selected
+item). Be sure to call `invalidate()` in the appropriate methods of the state machine to make this happen.
+
+For `onDraw()`, your will do some setup that will allow your
+subclasses to draw properly. First, you will need to check if you are
+in the proper state to draw (you must only draw when in the `SELECTING`
+state).
+
+Next, you really want to draw from the `(0,0)` location of the menu,
+rather than the `(0,0)` of the parent. But remember that your width and
+height are set using `MATCH_PARENT`. To fix this, we need to translate
+the coordinate system of the canvas so that `(0,0)` is at the
+`startPoint` for this interaction.
+
+Finally, since this is an abstract class, we need to call the *real*
+drawing method, which our children will implement. This is called
+`drawMenu()` and must be overridden by `PieMenuView`,
+`NormalMenuView`, and `CustomMenuView`.  Therefore, your `onDraw()` implementation in
+`MenuExperimentView.java` will be pretty short.
+
+**Implementing MainActivity**
+
+In `MainActivity` you will implement part of the method
+`showMenuForTrial(ExperimentTrial trial)`. Your main job is to
+register a callback with it that knows what to do when a trial is
+completed.
+
+`MainActivity` also needs to implement the code to respond to
+`onTrialCompleted()`, a method of the TrialListener interface. In
+particular, this code must always remove the current menu being
+shown. Then it must check if the session is over (remember the
+session is an iterator), and if not call `showMenuForTrial()` with the
+next trial. If the session is over, it must update text of
+`InstructionTextView` to say that the session is completed, and also display a
+`Toast` to the same effect. We have provided a method that you may use to announce
+this message (`AbstractMenuExperimentView#announce(String)`), or you may use the `Toast`
+class directly.
+
+**Note:** This means that until the next session is started, the system should not display
+any menus if the user clicks.
+
+**Related APIs**
+* [Toast](https://developer.android.com/reference/android/widget/Toast)
+
+# Part 3: Implement Pie and Normal Menus
+
+**Tasks**
+
+- `NormalMenuView`: Implement `essentialGeometry()` and `drawMenu()`
+- `PieMenuView`: Implement `essentialGeometry()` and `drawMenu()`
+
+Both `PieMenuView` and `NormalMenuView` extend `MenuExperimentView`. You
+will implement `essentialGeometry()` for each and determine what menu item the
+touch event maps to. You'll have to come up with the math logic to map
+from touch event to an item index.
+
+You will also implement `drawMenu()` which at a minimum draws the menus as shown in
+the screenshots. If you want to do something different, you may, as
+long as the size and position of each menu item does not change. For
+example, you can  override the paint properties defined in
+`MenuExperimentView`, position the text differently, or draw more
+decorations on the menus.
+
+Be sure to check the `AbstractMenuExperimentView` starter code for any additional
+values that you must use when creating your menus. Also make sure you are not "shadowing"
+variables (redefining variables already defined in super class).
+
+## NormalMenuView
+
+The Normal Menu will appear where the user touches the screen (as the top/left corner of the menu)
+and extend down and to the right.
+
+For the `NormalMenuView`, `essentialGeometry()` will return -1 if the
+pointer is outside the bounds of the menu in any direction or has
+moved less than `MIN_DIST` (inherited from
+`AbstractMenuExperimentView`) since interaction started. Otherwise
+it must return the "item number" (position in the list) corresponding to
+the menu item that the pointer is currently inside of.
+
+The width of each item in the normal menu is `CELL_WIDTH` and the height is
+`CELL_HEIGHT`.
+
+**Some additional hints for the normal menu**
+- The menu should display on the screen when the user first touches the screen.
+- The indication of the selected menu item should be drawn after entire menu has been drawn. 
+
+## PieMenuView
+
+The Pie Menu will appear centered where the user touches the screen.
+
+For the `PieMenuView`, `essentialGeometry()` will return -1 if the pointer
+has moved less than `MIN_DIST` since selection started, and
+otherwise it will return the  "item number" (position in the list) corresponding to
+the menu item currently being selected. In the case of the Pie menu, the item number is the
+menu item that a ray from the center of the menu to the pointer intersects, with the first
+item being at the top of the pie and increasing as you go clockwise around the circle.
+The pie menu has no maximum diameter, so anything
+outside of the radius `MIN_DIST` around the finger will return a selection.
+
+For PieMenuView, the given `RADIUS` corresponds to the outer radius. The inner radius
+is defined by `RADIUS - TEXT_SIZE * 2`.
+
+**Some additional hints for the pie menu**
+- The menu should display on the screen when the user first touches the screen.
+- The indication of the selected menu item should be drawn after entire menu has been drawn.
+- `drawArc()` will draw a pizza-pie shaped arc, so you can do things
+  like highlight a menu item with a single method call.
+- You will need a rotational offset to ensure the top menu item is at
+  the top of the pie (both when drawing and in essential geometry)
+  because angle is traditionally measured from cardinal east. You can
+  add this in radians before converting from angle to index.
+- Just as in ColorPicker, you should look at the `atan` or `atan2` function to help you calculate
+  your pie menu's `essentialGeometry()` function.
+  - Remember that `atan`/`atan2` return a value between 0..Math.PI or 0 .. -Math.PI. 0
+  being cardinal east and Math.PI or -Math.PI at cardinal west. Also remember that the `y`
+  direction is positive pointing down the canvas, not pointing up
+  like a traditional cartesian coordinate system. This may impact the
+  values returned from trigonometric functions.
+
+  ![:img clarification of atan2](menus-img/math_a20.gif) &nbsp; ![:img clarification of atan2](menus-img/atan2math.png)
+- Your pie menu text does not need to be centered -- as long as it
+  is contained within the outer ring of the pie menu, you are fine.
+
+
+**Related APIs**
+* [Canvas](https://developer.android.com/reference/android/graphics/Canvas): See documentation on `drawArc()` and `drawText()`.
+* [Path](https://developer.android.com/reference/android/graphics/Path): For adding text along a curve
+* [atan2](https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/lang/Math.html#atan2(double,double))
+
+
+# Part 4: Implement a Custom Menu
+
+Create a new menu! Working off of the provided `MenuExperimentView` interface, build your
+own third menu. This menu must be different from the Pie/Normal menus. You are encouraged to
+explore user interactions here, and you will receive credit as long as your code shows
+significant effort. Your menu does not have to be great here -- if you choose, you can
+aim to create the "worst menu ever" for this submission. Alternatively, you can aim to
+outcompete our provided menu views!
+
+Be sure to make use of the same abstractions (`essentialGeometry()` and a state machine)
+in this implementation.
+
+# Part 5: Conduct and Write Up User Study
+
+_(not due at the same time as the code portion)_
+
+**Tasks**
+- Conduct user study
+  - Run a trial on yourself
+  - Create a final consent form from [this sample](consent)
+  - Recruit 3 participants
+  - Consent the participants, including having them sign your consent form
+  - Send your APK to any participants who are testing your app remotely
+  - Have them complete a session with `ITEM_MAX` set to at least 4 and
+   `NUM_REPEATS` set to 3.
+  - Download the recorded data
+- Analyze recorded data
+- Write a report
+
+**Conduct User Study**
+
+Start by testing your own program as a participant so you know how long it takes to run a session
+(this information is needed for your consent form). This is also a good time to double check that
+your data is not lost when you download it.
+
+Make a copy of the [consent form](consent) form template and modify it in all of the places marked as
+such (in italics). The language used in your consent form is key, so ensure that it does not come
+off as forceful or coercive.
+
+
+**Recruit participants and have them sign your consent form**
+
+Recruit your 3 participants from family and friends who can safely use your
+app on your device or your emulator in person (co-present), or from the
+random group you have been assigned from class. Please see
+[this document](https://docs.google.com/document/d/11nsEWs3TubV5Zy0zOIGguqZJohkS34uizIrDv-bgnYs/edit)
+for your group members.
+
+Consenting your participants will be very similar whether they are co-present or remote. First, set up
+a time when can speak to your participant (in person, over the phone, or over a Zoom or other
+video conferencing call).
+
+- For a co-present tester: print out two copies of the consent form for each
+participant -- one for them and one for you. Hand them a copy of the consent form before describing the
+study.
+- For remote testers: send a copy of the consent form to the participant prior to your phone call
+or video meeting.
+
+Briefly explain what your user study is about, and ensure they understand
+their participation in the study is voluntary. Do not *coerce* anyone into participating in your
+study. Make sure they know they have a choice, and have read the consent form.
+
+Your participants must acknowledge their consent by "signing" via the Google form (linked
+at the bottom of the consent form template). This form should send you an anonymized copy of their
+consent in email, which you can save and turn in with the rest of your report and reflection.
+
+**Collect data**
+
+Once your participant has been consented, allow them to test the app.
+
+Our implementation uses the ExperimentSession object to create, manage, and record experiment data
+to a `.csv` file that is stored on the phone or emulator. If you are interested, check out the
+`recordResult` function `ExperimentSession.java` to understand how this is being stored.
+
+Testing can happen on either a phone or other native Android device or on an emulator. If on an
+emulator, the participant may use a mouse, trackpad or touch display to interact with the app.
+When collecting data, you should inform users that all interactions
+will begin with tapping on the center of the screen. This should help
+avoid cases where your menu is unusable due to the screen format.
+
+
+_Co-present Testing_
+
+- Use the hamburger menu to select `Clear Result CSV`
+before starting your study so any prior sample testing data does not contaminate your results.
+**Make sure that you do not clear the results between submissions for a co-present study!**
+This will erase your trial data.
+- Ensure the app is in Experiment mode and a new session has started.
+- You will likely want to point out what they are to select is written at the bottom of the screen.
+- If you are doing 3 co-present tests in a row, the app will move to the next session automatically and
+store all of the data sequentially in the `TestResults.csv` file saved to your device. However, this
+data will be erased if you switch back to test mode, so be sure to download any data before you do that.
+
+_Remote Testing_
+- Send your APK to the participant so they can load it onto their own device or into their own
+emulator (as we did with Doodle earlier this quarter). In your
+menu project in Android Studio, select the *Build -> Build Bundle(s)/APK(s) -> Build APK(s)* menu item.
+When the *Build APK(s)* message popup appears in the lower right hand corner, click the *locate* link
+to find the `app-debug.apk`.
+- Send the APK to your participant. Unfortunately you can't email your APK through UW's servers,
+instead we recommend you upload the APK to your Google Drive or One Drive and send your participant
+a link to download it for testing.
+- Have your participant use the hamburger menu to select `Clear Result CSV` before starting
+your study so any prior sample testing data does not contaminate your results, then run one
+experiment session.
+- Once the user study is complete, your participant will need to download their study data from their device
+and send it back to you for analysis.
+- Combine the three participants' data into one common .csv file.
+
+
+Once *all* participants are done and you have one `.csv` file with all of the data,
+it should have at least `ITEM_MAX * NUM_REPARTS * NUM_PARTICIPANTS` (324) data points.
+You will be turning in this file (through Canvas) as part of your final report.
+
+
+*Downloading user testing data*
+
+You can use the Android Studio
+[Device File Explorer](https://developer.android.com/studio/debug/device-file-explorer) to access the file.
+This allows you to directly access the files on your Android device (emulated or physical) through a
+GUI window. Detailed instructions on getting the data off your device can be found on
+[this page](../docs/android_files/).
+
+The data will likely be in `/storage/emulated/0/CSE340_Menus/TestResult.csv`
+or `/sdcard/CSE340_Menus/TestResult.csv`.
+
+Note that each user is given a participant ID when the session is running. These are randomly
+generated numbers from 0-9999. You may renumber these to identify your participants by the order
+in which they tested (1, 2, 3) when you retrieve the downloaded `.csv` file(s).
+
+**Write a Report**
+
+Complete the user study by writing up brief report. We have provided a
+[template](menu-report) for you to use here. Please reference this template as
+necessary, but the information in the report must be your own descriptions.
+
+Your report will require you to attach screen captures of your menu in both an unselected and
+selected state. You can capture a screenshot of the menu in action in one of two ways:
+- On a phone: Touch the screen to display a custom menu with one hand. With your other hand
+ [capture a screenshot](https://support.google.com/android/answer/9075928?hl=en). How you do this
+ may depend on the device. The resulting screenshot will be stored in the File Manger on your phone.
+- On the emulator: Touch the screen to display a custom menu with one hand. With your other hand
+press the control-S (for Windows) or command-s (for Mac). The resulting screenshot should be found
+on your desktop.
+
+# Part 6: Reflection
+
+Your reflection should be done as Microsoft Word, Google or other type of document.
+Copy the following questions (in italics below) into your refelction document and add
+your responses below each question. You can have more than one answer per page, but if
+you can, please try to avoid page breaks in the middle of
+a question. Insert page breaks between questions as needed.
+
+1. _Attach two screenshots of your custom menu, one where it is in a selected state and one where
+it is in an unselected state. These images may be the same as the ones you included in this report.
+Then re-read our Properties of People Design Tips for [Vision](../slides/wk02/people-vision.html#71)
+and [Motor](../slides/wk06/people-motor.html#65). Which of these design tips did you employ/not employ
+when creating your Custom menu? List at least one Visual design tip and one Motor design tip and be
+specific in describing what part(s) of your menu's operation utilized these tips._
+
+2. _Given the structure of our Pie/Normal menus, how would you create an accessible menu when
+working with the MenuExperimentView class? What could make ensuring the menu is accessible
+difficult? (Rephrasing that last question: "If you were trying to ensure that your
+menu is accessible, what aspects would be difficult?")_
+
+3. _As written, these menus can potentially appear all or partially off the phone screen.
+When would this case happen, how might that appear, and how could you account or prevent this
+from occurring? Would your solution work for all three types of menus?_
+
+# Submission Instructions
+
+You will change ONLY the following files. These will be submitted to GitGrade.
+
+Part 1-4:
+- MainActivity.java
+- MenuExperimentView.java
+- NormalMenuView.java
+- CustomMenuView.java
+- PieMenuView.java
+
+Part 5-6:
+
+Your reflection and report will be uploaded to Gradescope. This will include:
+
+- TestResult.csv
+- Sample consent form
+- Evidence of three "signed" consent forms (either three scanned forms with the "sun signature" or
+copies of the three auto reply emails you get from the google form consent acknowledgement.)
+- Report
+- Reflection
+
+Your participants must also fill out the on line (Google)
+[consent form](CSE 340 20sp Menus User Study Consent) acknowledging that they agree to
+be a participant and identifying you as a tester.
+
+You must also turn in your combined csv file so we can create one large data set.
+This .csv will be turned in through Canvas and *NOT* be put turned in with the rest of your report.
+
+## Grading Rubric
+
+This HW will be out of 68-70 points and will roughly (subject to small adjustments) be distributed as:
+
+Code portion (33-35 points)
+- State machine implementation works: (12 pts)
+- Normal menu draws correctly (3 pts)
+- Pie menu draws correctly (3 pts)
+- Normal & Pie menus correctly implement essential geometry (5 pts)
+- Custom menu works (2 pts)
+- Trials & callbacks handled correctly (4 pts)
+- onDraw translates correctly (1 pt)
+- Code quality (3 pts)
+
+Experiment Portion (35 points)
+- Reasonable CSV output: 1pt
+- Consent form: 2pt
+- Three participants consented via form: 1pt
+- Report:
+  - Introduction: 1pt
+  - Description of study process: 6 pts
+  - Demonstrate understanding of results: 5pts
+  - Makes appropriate/good use of charts: 4pts
+  - Draw appropriate conclusions about linear vs. pie menu vs custom menu: 5pts
+- Reflection (10pts)
diff --git a/assignments/reflection.md b/assignments/reflection.md
new file mode 100644
index 0000000000000000000000000000000000000000..6c1f666860944635bdd06b6e54ade5eff4121bd6
--- /dev/null
+++ b/assignments/reflection.md
@@ -0,0 +1,28 @@
+---
+layout: default
+---
+
+# What is a Reflection
+
+
+A running theme in this course will be reflecting on our work and our work practices.
+
+**Reflection** is a way to examine the present while critically looking at the past in order to
+inform the future. It is also a vital part of the engineering process, and will be a vital part of
+you honing your skill as a Programmer, Computer Scientist, and/or Engineer.
+
+In general, what does it mean to reflect well:
+
+- First and foremost, the reflection answers any guiding questions given.
+- Specific details of the experience(s) being reflected upon are described clearly and
+concisely and in such a way that a non-expert (in this field) reader can understand. This does not
+mean you must explain it so that a novice reader can understand the problem deeply, just a
+non-expert (someone who knows the field but is not an expert in the field.) **Note** that a
+reflection is NOT just a factual recounting of a situation or situation(s).
+- There is a “depth” to the reflection. There are a number of ways to make a reflection deep, thoughtful and thorough.
+  - The reflection elaborates what the significance and meaning are of the given examples and why they are particularly important.
+  - The reflection includes a personal reaction to the events or examples described. Reactions are
+   open and honest and indicate the writer's ability to appraise what is presented.
+  - The reflection describes connections between these details and other events,
+  examples, ideas or concepts from the past or present.
+  - The reflection may raise questions or have implications on future work.
diff --git a/assignments/sensing.md b/assignments/sensing.md
new file mode 100644
index 0000000000000000000000000000000000000000..9673a2d86b42a00243dada6cf399df68bf36c9bd
--- /dev/null
+++ b/assignments/sensing.md
@@ -0,0 +1,300 @@
+---
+layout: assignment
+published: draft
+
+title: Sensing
+code: EX5
+
+assigned: <!-- Tuesday, May 28, 2019 -->
+due: <!-- 11:59 PM Friday, May 31, 2019 -->
+revised: <!-- 10:08 PM Thursday, May 30, 2019 -->
+
+objective: Access Android sensors as the preparation to build context aware application.
+
+android_goals:
+  - Learn Android Awareness APIs
+  - Load sensor data
+  - Understand how and when to use Snapshot or Fence
+---
+
+- TOC
+{:toc}
+
+This is part 1 of a group assignment. You should get this working on
+your own, but then work as a group to make an app that uses sensed
+data. Every group will have one person with an android phone, or
+access to an android phone, and you should work together to make sure
+individual group members can all test their part 1 code using the
+group phone.
+
+Tasks:
+- Add snapshot support for the following sensors:
+  - Headphone
+  - Location
+  - User Activity
+- Use fence support to listen for changes to the following sensors:
+  - Location (detect whether in CSE)
+  - Activity (detect whether walking)
+- Create an app that responds to implicit data (i.e. reacts to a change in context)
+
+Context awareness capabilities enable mobile phones to sense their physical environment and adapt their behavior accordingly. You can practice how to load and react to data from different sensors in this exercise, as the preparation to build context aware app in the final assignment.
+
+According to Google, "[The Awareness API](https://developers.google.com/awareness/) unifies 7 location and context signals in a single API, enabling you to create powerful context-based features with minimal impact on system resources."
+
+It supports combining and working with 7 signals including time, location, places, beacons, headphones, activity and weather.
+
+There are two ways to get context from sensors: `Snapshot` and `Fence`
+- Snapshot will return the most recent (may not be realtime) information from sensor.
+- Fence will be triggered when the sensor data changes (based on the signal conditions you set). You may also combine multiple conditions to create a smarter fence.
+
+We already provide example code to get weather, using snapshot, and headphone state, using fence. Your job will be to add additional sensors
+
+# Preparing to run the app
+You will need to set some things up
+
+## 1) Get your API Key and put it in the app Manifest.xml
+
+Follow the ["Quick Guide"](https://developers.google.com/places/web-service/get-api-key)
+To use this guide, you will be asked at some point about whether you want to create a new app (the answer is yes, name it something like cse340-LaughingChipmunks, or whatever your repository name is, the names have to be unique).
+
+You'll be asked to set up a billing account. However, for the minor use in this class, it shouldn't cost you anything. If this is a problem at all (e.g. you don't have a credit card), please reach out privately on Ed.
+
+When the interface gives you your API key **copy it and don't lose it**. That is the only time you'll ever see it for security reasons, you'll have to create a new app if you lose it.
+
+When you have your API key, go to your android manifest and paste it in between the quotation marks labeled `YOUR_KEY_HERE`.
+
+```xml
+        <meta-data
+            android:name="com.google.android.awareness.API_KEY"
+            android:value="YOUR_KEY_HERE"/>
+        <meta-data
+            android:name="com.google.android.geo.API_KEY"
+            android:value="YOUR_KEY_HERE"/>
+```
+
+If you have a hard time with this, contact us on Piazza, and we will
+provide you with a key. However it should be used for this assignment
+only, not for future android programming, and not shared with anyone
+else.
+
+## 2) Prepare a virtual device that is based on Oreo (API v. 26)
+
+## 3) Run your app and update things
+
+1) Allow location permissions
+
+<!-- TODO: Why do these use px dimensions? They should use [:img alt, XX%] for better mobile support -->
+![Screenshot of enabling sensing](sensing/enable-sensing.png){:width="200px"}
+
+2) Click on 'User Activity Snapshot'. This will cause an error telling
+you that play needs to be enabled as shown here. If it goes away (it's
+a notification), just click the same button again.
+
+![Screenshot of enabling play request](sensing/enable-play.png){:width="200px"}
+
+3) When you click on the notification, it will take you to a sign in
+screen for play store. Sign in using your google account. Agree to the
+terms of service; you don't have to agree to back up to google drive
+though (just turn that off by moving the slider and then press agree)
+
+4) When it sends you back to your app, press on the square button at
+the bottom of the screen and switch back to google play services.
+
+![Screenshot of switching](sensing/switching.png){:width="200px"}
+
+Android will show a big 'Update' button or you can just wait and it will
+download and update, as shown here:
+
+![Screenshot of play updating](sensing/play-updating.png){:width="200px"}
+
+5) Switch back to your app again and press 'User Activity
+Snapshot'. Wait patiently. Rejoice when you see the following (or
+something similar)
+
+![Screenshot of activity results](sensing/activity.png){:width="200px"}
+
+## For advanced awareness things (optional)
+
+You'll need to enable one more API than the automated quick guide does for you. This is the *awareness api*. To enable it, search for it in the search bar as shown here:
+
+![Screenshot of awareness search](sensing/apisearch.png)
+
+Click on the search result, and select **Enable.** You'll then need to click on the **Create Credentials** button and create credentials. Again, you'll get an API string which you'll need to add to your manifest, in the other API KEY meta data (just below the geo one).
+
+
+## What the app looks liken
+
+Here are sample screenshots for sensor results:
+
+<span style="color: red;">Note: the weather screenshots display `&#x2103` where they should display °</span>
+
+![Screenshot of sensor list](sensing/1.png){:width="200px"}
+![Screenshot of headphone snapshot](sensing/2.png){:width="200px"}
+![Screenshot of location snapshot](sensing/3.png){:width="200px"}
+![Screenshot of weather snapshot](sensing/5.png){:width="200px"}
+![Screenshot of detected activity snapshot](sensing/6.png){:width="200px"}
+![Screenshot of headphone fence](sensing/7.png){:width="200px"}
+![Screenshot of location fence](sensing/8.png){:width="200px"}
+![Screenshot of detected activity fence](sensing/9.png){:width="200px"}
+
+Here is a [link to a video of it in
+use](https://youtu.be/oF0i2lL4EUE).
+
+<span style="color: red;">Note: the video does not exhibit the updated behavior of fences prepending text to the beginning of the existing text</span>
+
+## Simulating input if using an emulator
+Although we ask that the group member with the phone donate phone time
+for testing, you should start by testing your code with the emulator,
+and should be able to  reproduce this video.
+
+To test your app, first use the
+[simulation
+capabilities](https://developer.android.com/studio/run/emulator#extended)
+built into the emulator. You bring it up by clicking on the "..."
+shown in red in the bottom right of the below image. Note that this is
+buggy -- it doesn't always work, sometimes it is slow, and it doesn't
+always update when you want. According to the [Awareness Fence Troubleshooting
+page](https://developer.android.com/training/location/geofencing#Troubleshooting),
+
+*Alerts can be late. The geofence service doesn't continuously
+query for location, so expect some latency when receiving
+alerts. Usually the latency is less than 2 minutes, even less when the
+device has been moving. If Background Location Limits are in effect,
+the latency is about 2-3 minutes on average. If the device has been
+stationary for a significant period of time, the latency may increase
+(up to 6 minutes).*{:.quote}
+
+Location changes are generally only
+registered if you switch to maps in the emulator, and then back to
+your app. Otherwise you will get a timeout error for location, and
+weather (which depends upon location).
+
+Despite all this, the emulator is still useful because it can help you make sure your code
+doesn't crash.
+
+### Location Simulation
+![Screenshot of emulator with simulator running](sensing/simulator.png){:width="400px"}
+
+### Headphone Simulation
+![Screenshot of emulator with simulator running](sensing/headphone.png){:width="400px"}
+
+### Weather Simulation
+![Screenshot of emulator with simulator running](sensing/weather.png){:width="400px"}
+
+Using this you can in principal simulate location, either current location or a
+whole route. To simulate a route, you can upload gps traces to
+simulate motion over time. [Here](sensing/Test.gpx) is one that moves in and out of CSE. A good place to download sample traces is
+[OpenStreetMap's traces
+page](https://www.openstreetmap.org/traces/). If you want to double
+check the results of location, here are [instructions on how to find a
+place in google maps using
+lat/long](https://support.google.com/maps/answer/18539?co=GENIE.Platform%3DDesktop&hl=en)
+You can also create your own route by modifing the lat/long in a trace
+(or making your own from scratch using the [GPS exchange
+format](https://en.wikipedia.org/wiki/GPS_Exchange_Format) **HOWEVER**
+we were not able to get this working with the Sensing app and suspect
+a bug in the emulator.
+
+You can also simulate weather (find it in the 'Virtual sensors' part
+of the simulator). **HOWEVER** again this doesn't seem to be reflected
+in the sensing app, potentially due to a bug.
+
+You can simulate headphones in the 'Microphone' tab of the
+simulator. **GOOD NEWS** this should work both for testing your
+headphones snapshot and headphones fence.
+
+We have not found a way to simulate activity.
+
+# Files provided
+The files provided are
+
+```
+Snapshot:
+ActivitySnapshotListener.java
+
+Fence:
+ActivityFenceListener.java
+FenceBroadcastReceiver.java
+```
+
+The files you will implement are:
+
+```
+Snapshot:
+HeadphoneSnapshotListener.java
+LocationSnapshotListener.java
+WeatherSnapshotListener.java
+
+Fence:
+HeadphoneFenceListener.java
+LocationFenceListener.java
+
+MainActivity.java
+```
+
+### Snapshot implementation
+All SnapshotListeners should implement
+ContextActivity.SnapshotListener. They should
+respond to the input received via `onSnapshot(Response response)`,
+by drawing text on the screen in the update
+`TextView`.
+
+The `Response` object will contain the specific information to
+display.
+
+### Fence implementattion
+For fences to work, you will need to implement
+`setupFenceListeners()` in `MainActivity.java`. In addition, you will
+need to complete the implementation of the two `FenceListener`
+classes, `HeadphoneFenceListener.java` and `LocationFenceListener.java`
+
+All fences should inherit from `FenceBroadcastReceiver.java` and
+implement
+`FenceBroadcastReceiver.FenceActivityListener`. They will need to
+implement three methods that respond to fence updates:
+`during(FenceState state)`,
+`starting(FenceState state)` and `stopping(FenceState state)` by updating text on the screen in
+the update `TextView`.
+
+The information to display will depend on the fence state. You will
+have to interpret this based on your knowledge of what you did to set
+up the fence. For instance, the locations given for the location fence
+will result in `state = FenceState.TRUE` in when `duringFence()` is
+called while the user is inside of the CSE building.
+
+There are detailed comments in the code files you will implement that will direct you through the assignment.
+
+# Turn-in
+
+## Submission Instructions
+
+You will turn in the following files [here](https://gitgrade.cs.washington.edu/student/assignment/64/turnin):
+
+```
+- HeadphoneSnapshotListener.java
+- LocationSnapshotListener.java
+- WeatherSnapshotListener.java
+- HeadphoneFenceListener.java
+- LocationFenceListener.java
+- MainActivity.java
+```
+
+You may also change:
+```
+- strings.xml
+- activity_main.xml
+- Any class you create that did not previously exist
+```
+
+## Grading (5pts)
+
+- Get API Keys: 1pt
+- Snapshots all work:
+ - Location: .5pt
+ - Headphone: .5pt
+ - Weather: .5pt
+- Fences all work:
+ - Headphone .5pt
+ - Location .5pt
+- MainActivity sets things up correctly: .5pt
+- Code Organization and Style: 1 pt
diff --git a/assignments/sensing/1.png b/assignments/sensing/1.png
new file mode 100644
index 0000000000000000000000000000000000000000..aa18e9e8127d10337b85787f4c3183c6e260749f
Binary files /dev/null and b/assignments/sensing/1.png differ
diff --git a/assignments/sensing/2.png b/assignments/sensing/2.png
new file mode 100644
index 0000000000000000000000000000000000000000..a856b5246a0993c1989a78ab3674615d17c9f52d
Binary files /dev/null and b/assignments/sensing/2.png differ
diff --git a/assignments/sensing/3.png b/assignments/sensing/3.png
new file mode 100644
index 0000000000000000000000000000000000000000..f60092155f8f517cff64f3ff0cfb0df7ff6f0504
Binary files /dev/null and b/assignments/sensing/3.png differ
diff --git a/assignments/sensing/5.png b/assignments/sensing/5.png
new file mode 100644
index 0000000000000000000000000000000000000000..90cb3d48a591e2f3ea7ba579bfff1e613135efa6
Binary files /dev/null and b/assignments/sensing/5.png differ
diff --git a/assignments/sensing/6.png b/assignments/sensing/6.png
new file mode 100644
index 0000000000000000000000000000000000000000..9ab549f2a54e145edc1c79e91b68afa59e543eb5
Binary files /dev/null and b/assignments/sensing/6.png differ
diff --git a/assignments/sensing/7.png b/assignments/sensing/7.png
new file mode 100644
index 0000000000000000000000000000000000000000..010d628641b10befffdd380ad95f066051d32800
Binary files /dev/null and b/assignments/sensing/7.png differ
diff --git a/assignments/sensing/8.png b/assignments/sensing/8.png
new file mode 100644
index 0000000000000000000000000000000000000000..86efe8c08321b408604e60b492a6f403159a5d3a
Binary files /dev/null and b/assignments/sensing/8.png differ
diff --git a/assignments/sensing/9.png b/assignments/sensing/9.png
new file mode 100644
index 0000000000000000000000000000000000000000..3aaa5c17f5ab1b139f6828dafbd284e4c1c67342
Binary files /dev/null and b/assignments/sensing/9.png differ
diff --git a/assignments/sensing/Test.gpx b/assignments/sensing/Test.gpx
new file mode 100644
index 0000000000000000000000000000000000000000..f7b004877a0c5b8da71e0e55d7c8bb68dfeb2fc9
--- /dev/null
+++ b/assignments/sensing/Test.gpx
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<gpx version="1.1" creator="gpxgenerator.com">
+<wpt lat="47.65379706591215" lon="-122.30192147338511">
+    <ele>15.01</ele>
+    <time>2018-11-14T04:23:56Z</time>
+</wpt>
+<wpt lat="47.653464621123724" lon="-122.30413161361338">
+    <ele>32.43</ele>
+    <time>2018-11-14T04:24:24Z</time>
+</wpt>
+<wpt lat="47.653464621123724" lon="-122.30477534377695">
+    <ele>36.13</ele>
+    <time>2018-11-14T04:24:32Z</time>
+</wpt>
+<wpt lat="47.65352243776071" lon="-122.30546198928477">
+    <ele>36.91</ele>
+    <time>2018-11-14T04:24:40Z</time>
+</wpt>
+<wpt lat="47.6531610827294" lon="-122.30582676971079">
+    <ele>32.73</ele>
+    <time>2018-11-14T04:24:48Z</time>
+</wpt>
+<wpt lat="47.653377896048234" lon="-122.30627738082529">
+    <ele>36.88</ele>
+    <time>2018-11-14T04:24:54Z</time>
+</wpt>
+<wpt lat="47.65395606049759" lon="-122.30653487289072">
+    <ele>38.36</ele>
+    <time>2018-11-14T04:25:05Z</time>
+</wpt>
+<wpt lat="47.65469321088665" lon="-122.30735026443125">
+    <ele>39.41</ele>
+    <time>2018-11-14T04:25:22Z</time>
+</wpt>
+<wpt lat="47.654620941700756" lon="-122.30784379088999">
+    <ele>40.08</ele>
+    <time>2018-11-14T04:25:28Z</time>
+</wpt>
+<wpt lat="47.65453421854566" lon="-122.30876647079111">
+    <ele>42.10</ele>
+    <time>2018-11-14T04:25:39Z</time>
+</wpt>
+<wpt lat="47.65483774895839" lon="-122.30936728561045">
+    <ele>42.50</ele>
+    <time>2018-11-14T04:25:48Z</time>
+</wpt>
+<wpt lat="47.65584950425836" lon="-122.30971060836436">
+    <ele>47.10</ele>
+    <time>2018-11-14T04:26:07Z</time>
+</wpt>
+<wpt lat="47.65648486332888" lon="-122.31038331985474">
+    <ele>47.17</ele>
+    <time>2018-11-14T04:26:21Z</time>
+</wpt>
+</gpx>
\ No newline at end of file
diff --git a/assignments/sensing/activity.png b/assignments/sensing/activity.png
new file mode 100644
index 0000000000000000000000000000000000000000..ceb064ea369c2852230d480971aea80905b32561
Binary files /dev/null and b/assignments/sensing/activity.png differ
diff --git a/assignments/sensing/apisearch.png b/assignments/sensing/apisearch.png
new file mode 100644
index 0000000000000000000000000000000000000000..5189183ebcd008ceefb3981814c528b76490fc70
Binary files /dev/null and b/assignments/sensing/apisearch.png differ
diff --git a/assignments/sensing/emulator.png b/assignments/sensing/emulator.png
new file mode 100644
index 0000000000000000000000000000000000000000..4c13f382bc29aedb06572d3c6f4071787719a33a
Binary files /dev/null and b/assignments/sensing/emulator.png differ
diff --git a/assignments/sensing/enable-play.png b/assignments/sensing/enable-play.png
new file mode 100644
index 0000000000000000000000000000000000000000..a1fba336913b18a4e208b828c57c85d5f08e2966
Binary files /dev/null and b/assignments/sensing/enable-play.png differ
diff --git a/assignments/sensing/enable-sensing.png b/assignments/sensing/enable-sensing.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab41fa31392e7b1ca74e9c2c1911d513f245ff68
Binary files /dev/null and b/assignments/sensing/enable-sensing.png differ
diff --git a/assignments/sensing/headphone.png b/assignments/sensing/headphone.png
new file mode 100644
index 0000000000000000000000000000000000000000..0dcb029d150a4045a1ade3a280260a568521a75f
Binary files /dev/null and b/assignments/sensing/headphone.png differ
diff --git a/assignments/sensing/play-updating.png b/assignments/sensing/play-updating.png
new file mode 100644
index 0000000000000000000000000000000000000000..82aea37305ecdbcddb0c26416ec6a5e742d5a166
Binary files /dev/null and b/assignments/sensing/play-updating.png differ
diff --git a/assignments/sensing/play.png b/assignments/sensing/play.png
new file mode 100644
index 0000000000000000000000000000000000000000..0170d1cd14c5988a3b6bda438badd5c7a27d3314
Binary files /dev/null and b/assignments/sensing/play.png differ
diff --git a/assignments/sensing/simulator.png b/assignments/sensing/simulator.png
new file mode 100644
index 0000000000000000000000000000000000000000..54a4caf41a187e65ea66aa2d09868f8f12eceeb4
Binary files /dev/null and b/assignments/sensing/simulator.png differ
diff --git a/assignments/sensing/switching.png b/assignments/sensing/switching.png
new file mode 100644
index 0000000000000000000000000000000000000000..33ba754479e653b824d319dd4aa1f7888191aa69
Binary files /dev/null and b/assignments/sensing/switching.png differ
diff --git a/assignments/sensing/weather.png b/assignments/sensing/weather.png
new file mode 100644
index 0000000000000000000000000000000000000000..636bfb397f68d178ff671cc5e24fc26e816cf5f2
Binary files /dev/null and b/assignments/sensing/weather.png differ
diff --git a/assignments/undo-img/1stroke.png b/assignments/undo-img/1stroke.png
new file mode 100644
index 0000000000000000000000000000000000000000..74f5c3b15d18628f20ebe94dbfd5653e06c563b6
Binary files /dev/null and b/assignments/undo-img/1stroke.png differ
diff --git a/assignments/undo-img/blank.png b/assignments/undo-img/blank.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b6866045aa154932680bd93a76a35dc684da912
Binary files /dev/null and b/assignments/undo-img/blank.png differ
diff --git a/assignments/undo-img/start-recording.png b/assignments/undo-img/start-recording.png
new file mode 100644
index 0000000000000000000000000000000000000000..74071876de4b175e0924d17b137b47c4dcfe8a46
Binary files /dev/null and b/assignments/undo-img/start-recording.png differ
diff --git a/assignments/undo-img/tab-of-options.png b/assignments/undo-img/tab-of-options.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ae27b1907727b38c63253e1fed5c6c7f7b37956
Binary files /dev/null and b/assignments/undo-img/tab-of-options.png differ
diff --git a/assignments/undo-report.md b/assignments/undo-report.md
new file mode 100644
index 0000000000000000000000000000000000000000..670d72aade8b9cac005c25b86b63b09d47507041
--- /dev/null
+++ b/assignments/undo-report.md
@@ -0,0 +1,44 @@
+---
+layout: default
+---
+# Report on Undo Assignment
+
+*Comments about what should be in your report can be found in italics.
+**Please remove the comments and replace them with your own words**.*
+
+## Introduction
+*Write two sentences describing the Undo drawing app and its core features
+(drawing strokes with different thickness and color, undo and redo).*
+
+*Include a picture of your improvement*
+
+*Write a paragraph describing the additional features that you added to the app. Fully
+explain the improvement, justify why the improvement is based on the principles presented
+in class, and describe how accessibility was addressed (maybe include quoted code that addresses the
+accessibility issue).*
+
+## Report on Heuristic Evaluation of application
+
+*Describe the purpose of the experiment. What do you expect to learn from conducting a Heuristic Evaluation?*
+
+### Tasks
+*Describe the tasks that are being tested in your heuristic evaluation.
+This should summarize all of the steps that are being done for your video*.
+
+### Data
+*How many people provided feedback to you?*
+
+
+*Group like issues; Write up a summary as described in lecture*
+
+*Provide a table of issues and severity. You can group like issues, even though they may be labeled under different issues if it truly is the same thing.*
+
+| Priority | Issue | Good/Bad | Step | Heuristic(s) | Severity: F | B | P | Overall |
+|------|-------|----------|------|---------------|--------------|--------------|--------------|--------------------|
+| |       |          |      |               |              |              |              |                    |
+| |       |          |      |               |              |              |              |                    |
+| |       |          |      |               |              |              |              |                    |
+
+## Overview of what you learned
+
+*Highlight the biggest problem or problems with your interface*
diff --git a/assignments/undo.md b/assignments/undo.md
new file mode 100644
index 0000000000000000000000000000000000000000..9cedfe4d340c7cf85a082802591dc278a5606787
--- /dev/null
+++ b/assignments/undo.md
@@ -0,0 +1,665 @@
+---
+layout: assignment
+published: true
+
+title: Undo
+code: as6
+
+assigned: May 22nd
+due:
+- Programming <br>
+  - <strong>Due</strong> June <del>1</del> 3, 2020, 10:00pm<br>
+  - <strong>Lock</strong> June 3, 2020, 10:00pm
+- Heuristic Evaluation <br>
+  - <strong>Due</strong> June 5, 2020, 10:00pm (no leeway)
+- Reflection <br>
+  - <strong>Due</strong> June 8, 2020, 10:00pm
+
+revised: 9:00pm, Wednesday, May 20th, 2020
+
+objective: Understand Undo Abstractions, practice Heuristic Evaluation
+
+android_goals:
+  - Be able to understand and modify an existing user interface
+  - Learn about floating action buttons
+  - Implement core data structure for Undo
+hci_goals:
+  - Modify and existing app in a consistent fashion
+  - Make your modifications accessible
+  - Make your modifications usable
+  - Use heuristic evaluation to assess an app
+---
+
+* TOC
+{:toc}
+
+# GitGrade links
+
+[Accept the Assignment](https://gitgrade.cs.washington.edu/student/assignment/128) / [Turn-in the Assignment](https://gitgrade.cs.washington.edu/student/assignment/128/turnin) / [Review your Submissions](https://gitgrade.cs.washington.edu/student/summary/8723)
+
+# Overview of assignment
+
+- Handle undo/redo operations (required)
+- Add a new thickness (0) to your app (required)
+- Replace the color menu with a ColorPickerView (required)
+- Make sure the button you add is accessible (required)
+- Improve your app by adding a feature (not thickness, required)
+- Make sure your change is accessible (required)
+- Try to identify at least one usability problem and address it
+  (optional)
+- Provide Heuristic Evaluation feedback to others (required)
+- Reflect on the Heuristic Evaluation feedback you recieved from others in your report (required)
+- Think about how course concepts apply to Undo in your reflection (required)
+
+
+Demo of our solution:
+
+<iframe width="560" height="315" src="https://www.youtube.com/embed/ClIx2wacu8M" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
+
+# Explanation of Codebase
+
+This is one of the more complex programs we are giving you in terms of
+code. Moreover the starter code is already has a couple of fully functional features that
+you will be modifying as part of this assignment.
+
+The initial interactor hierarchy at instantiation is shown below
+(shown at the side is a legend for the visibility status of different
+interactors). Hidden means on screen and drawn but hidden behind
+something else.
+
+The Floating Action Button (FAB) subtrees are the
+menus at the top of the screen (for undo and redo) and bottom (for
+color and thickness), made up of one or more floating
+action buttons. The `DrawingView` is the place where drawing takes
+place. Each new stroke is saved as a separate, new `StrokeView` added
+to the `DrawingView`.
+
+The FABs in this assignment refer to [Floating Action
+Buttons](https://developer.android.com/reference/com/google/android/material/floatingactionbutton/FloatingActionButton.html).
+
+<div class="mermaid">
+graph TD
+M[ReversibleDrawingActivity] --> D[DrawingView]
+M --> FUndo[FAB:Undo]
+M --> FRedo[FAB:Redo]
+M --> FColor[FAB:Color]
+M --> FThick[FAB:Thickness]
+FColor --> Red[Red]
+FColor --> Green[Green]
+FColor --> Blue[Blue]
+FThick --> Thin[Thin]
+FThick --> Med[Med]
+FThick --> Thick[Thick]
+
+Vis[Visible] --> In[Invisible]
+In --> Hid[Hidden]
+
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+
+class M,D,FColor,FThick,Vis start
+class Red,Green,Blue,Thin,Med,Thick,Hid normal
+
+</div>
+
+When the user draws on screen (by clicking and dragging inside the
+`DrawingView`, this adds a new `StrokeView` to the interface. Notice
+that the `Undo` button is now visible instead of invisible because there
+is an action to undo.
+
+<div class="mermaid">
+graph TD
+M[ReversibleDrawingActivity] --> D[DrawingView]
+D --> Stroke1[StrokeView]
+M --> FUndo[FAB:Undo]
+M --> FRedo[FAB:Redo]
+M --> FColor[FAB:Color]
+M --> FThick[FAB:Thickness]
+FColor --> Red[Red]
+FColor --> Green[Green]
+FColor --> Blue[Blue]
+FThick --> Thin[Thin]
+FThick --> Med[Med]
+FThick --> Thick[Thick]
+Vis[Visible] --> In[Invisible]
+In --> Hid[Hidden]
+
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+
+class M,D,Stroke1,FUndo,FColor,FThick,Vis start
+class Red,Green,Blue,Thin,Med,Thick,Hid normal
+
+</div>
+
+The sequence in the interface:
+
+<img src="undo-img/blank.png" alt="Empty drawing program window" height="400">
+<img src="undo-img/1stroke.png" alt="Drawing program window with one red stroke and undo button visible" height="400">
+
+You can play around with the interface to change color and
+thickness. Each new stroke you add adds another `StrokeView` to the interface.
+
+# Codebase Structure
+
+This is a complete codebase for a drawing program. It is designed to
+be as modular as possible and includes support for _Command Objects_ which
+encapsulate changes to the application model.
+
+## Actions
+
+Actions are Command Objects, which encapsulate changes to the
+application model. An `AbstractAction` has a single method, `doAction(view)` which,
+when called, will apply the action to the view (our provided implementation is incomplete)
+
+`AbstractReversibleAction` extends `AbstractAction` to add `undoAction(view)` which,
+when called, reverses the action.
+
+
+<div class="mermaid">
+classDiagram
+
+AbstractAction <|.. AbstractReversibleAction
+AbstractReversibleAction <|.. ChangeColorAction
+AbstractReversibleAction <|.. ChangeThicknessAction
+AbstractReversibleAction <|.. AbstractReversibleViewAction
+AbstractReversibleViewAction <|.. StrokeAction
+
+class AbstractAction {
+  doAction()
+}
+
+class AbstractReversibleAction {
+  +boolean done
+  +undoAction
+}
+
+class AbstractReversibleViewAction  {
+  +invalidate
+}
+
+
+</div>
+
+As with events, `AbstractActions` are part of an inheritance
+hierarchy. `AbstractReversibleAction` has three subclasses --
+`ChangeThicknessAction`, `ChangeColorAction` and `StrokeAction`.
+All of them modify properties of the `DrawingView`
+class. `ChangeThicknessAction` modifies the stroke width, `ChangeColorAction`
+will modify current color of the stroke, and the , and `StrokeAction.`represents
+the creation of a child view object that encapsulates a painted stroke (a `StrokeView`
+that is added to the `DrawingView`).
+
+## Application Code (`/app`)
+
+We've mentioned a `DrawingView` (which is the main canvas for the
+drawing application) and `StrokeView` (which encapsulates a specific
+stroke for the drawing application).
+
+<div class="mermaid">
+classDiagram
+
+AbstractDrawingActivity <|.. AbstractReversibleDrawingActivity
+AbstractReversibleDrawingActivity <|.. ReversibleDrawingActivity
+class AbstractDrawingActivity {
+  DrawingView: "Canvas the user draws on"
+  addMenu()
+  addCollapsableMenu()
+  doAction()
+}
+
+class AbstractReversibleDrawingActivity {
+  +AbstractStackHistory
+  +doAction()
+  +undo()
+  +redo()
+}
+
+class ReversibleDrawingActivity {
+  +onAction()
+  +onColorSelected()
+  +onThicknessSelected()
+}
+
+class StrokeView {
+   Path
+   onDraw()
+}
+</div>
+
+- `AbstractDrawingActivity` is an abstract class for an app that supports
+  drawing without support for Undo. If you changed the manifest to use
+  it (you would need to make it not abstract first), you would see
+  blank canvas that you can draw on with no thickness or color options.
+  *NOTE: if you do this experiment, remember to make it abstract again when you're done!*
+- `AbstractReversibleDrawingActivity` extends `AbstractDrawingActivity` and adds
+  support for undo to it, including both the undo/redo buttons and the
+  history. You can try changing the manifest to use this as well (not
+  abstract). *NOTE: if you do this experiment, remember to make it abstract again when you're done!*
+- `ReversibleDrawingActivity` inherits from
+  `AbstractReversibleDrawingActivity`. It adds support for thickness and color
+  to the undo/redo support in `AbstractReversibleDrawingActivity`. It also
+  adds menus to show them. You can make a drawing application without
+  support for history by changing `ReversibleDrawingActivity` to inherit from
+  `AbstractDrawingActivity` instead.
+- `DrawingView` is the canvas on which drawing takes place. Drawings
+  are made up of `StrokeView` classes which are added to the
+  `DrawingView`. This class also implements a PPS (shown below) which
+  responds to `onTouchEvent()` by creating `StrokeViews`.
+- `StrokeView` is a single stroke. A stroke has a `path` and `paint`
+  object which define it.
+
+<div class="mermaid">
+graph LR
+S((.)) --> A((Start))
+A -- "Press:onDrawStart()" --> I(Drawing)
+I -- "Release:onDrawEnd()" --> E[End]
+I -- "Cancel:onDrawCancel()" --> E[End]
+I -- "Move:onDrawMove()" --> I
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+class S invisible
+class A start
+class E finish
+class I normal
+
+</div>
+
+# Parts 1-5: Programming requirements
+
+There are five parts for the programming portion of this assignment:
+- Part 1: Implement `ChangeThicknessAction`
+- Part 2: Implement history
+- Part 3: Add a thickness 0 FAB to the thickness menu
+- Part 4: Integrate `ColorPickerView`
+- Part 5: Add a new feature to your app. Make sure it is accessible
+
+You can also (optionally) work on improving the usability
+
+## Part 1: Implement `ChangeThicknessAction`
+
+In order to familiarize yourself with Actions and reversible logic, implement
+`ChangeThicknessAction`. This will be very similar to `ChangeColorAction`, you should read and
+ understand that code before implementing your `ChangeThicknessAction`.
+
+## Part 2: History
+
+`Actions` are the objects that are used in the history. An
+`AbstractHistory` simply allows an `AbstractReversibleAction` to be added and supports `undo()`
+and `redo()`. We subclass this with a stack-based history class called `StackHistory` to support
+`undo()` and `redo()`. You will implement the methods to support these features in this `StackHistory` class.
+
+A `StackHistory` has a `capacity` (a max number of actions that it can
+store), a `undoStack` (the history) and a `redoStack` (actions that
+have been undone and can be re-applied). It also supports specific capabilities you must implement (see comments in the code
+for specifically what to do):
+
+- `addAction()` adds an action to the history stack
+- `undo()` undo the top action in the history stack
+- `redo()` redo the top action in the redo stack.
+- `clear()` reset everything
+
+<div class="mermaid">
+classDiagram
+
+AbstractStackHistory <|.. StackHistory
+class AbstractStackHistory {
+  addAction(AbstractReversibleAction action)
+  undo()
+  redo()
+  canUndo()
+  canRedo()
+}
+
+class StackHistory {
+   +capacity: "Max stack size"
+}
+
+
+</div>
+
+__Related APIs__
+
+[Deque](https://developer.android.com/reference/java/util/Deque)
+
+### Undo/Redo behavior
+
+Here is a scenario where the user draws a stroke in the default
+color/thickness (1), changes the color (2), changes the thickness (3), and draws
+another stroke (4) in the original thickness and color, with various
+undos and redos mixed in.
+
+| Action               | Undo Stack | Redo Stack | Interface state |
+| -------------------- | ---------- | ---------- | --------------- |
+| drawstroke (1)       | 1          |            | 1               |
+| change color (2)     | 1,2        |            | 1,2             |
+| undo                 | 1          | 2          | 1               |
+| redo                 | 1, 2       |            | 1, 2            |
+| change thickness (3) | 1, 2, 3    |            | 1, 2, 3         |
+| undo                 | 1, 2       | 3          | 1, 2            |
+| undo                 | 1          | 3, 2       | 1               |
+| drawstroke (4)       | 1, 4       | CLEARED    | 1, 4            |
+| undo                 | 1          | 4          | 1               |
+
+## Requirement 3: Adding a thickness 0 FAB to the thickness menu
+
+There are two main things you will need to do to add one.
+
+First, you find the right place in `thickness_menu.xml` to
+modify. For example, this is the XML in that file for the thickest FAB
+Action Button:
+
+```XML
+<android.support.design.widget.FloatingActionButton
+        android:id="@+id/fab_thickness_30"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|center"
+        android:layout_marginBottom="@dimen/fab_label_margin"
+        android:alpha="0"
+        android:clickable="false"
+        android:contentDescription="@string/thickness_desc"
+        app:fabSize="mini"
+        app:srcCompat="@drawable/ic_thickness_30" />
+```
+
+You must use the `@string` notation for your `android:contentDescription`, meaning you'll
+need to add a string definition to `values/strings.xml`.
+
+Next, you will need to update `onThicknessSelected` to respond when
+your FAB is pressed. It must change the stroke width to 0.
+
+Finally, you will need to make sure that `ReversibleDrawingActivity` is updated to account
+for your new menu item, since all mentions of thickness are currently hard coded to assume there is no 0 thickness.
+
+## Part 4: Integrating color picker
+In addition to adding a thickness, we want to be able to draw strokes of _any_ color instead of
+being limited to 3. You may recall that we have already made a custom interactor that allows
+users to choose any color on the color spectrum in a previous assignment. It is time to wire up a
+`ColorPickerView` into this application! To do this, you'll need to:
+
+1. Copy over the `ColorPickerView.java` file from your color picker assignment. Put this file
+in the same directory as your `ReversibleDrawingActivity.java`
+file. Also be sure to change the package at the top from `cse340.colorpicker`
+to `cse340.undo.app` in your `ColorPickerView.java` file.
+
+2. Add your color picker to your layout. One way to do this is to add xml for your
+`ColorPickerView` to  `drawing_activity.xml`. Be sure it is neither visible
+nor focusable until the user clicks on the color FAB. Be sure to use the correct package name here too.
+
+3. Change the behavior of the color FAB so that, when clicked, it opens up the color picking
+interface instead of opening the collapsible color menu. For reference on how to do this,
+take a look at `ReversibleDrawingActivity.java#onCreate` (**hint:** make sure to take a look at
+what interfaces `ReversibleDrawingActivity.java` implements).
+
+4. Modify `onDraw()` to leave the center circle blank.
+
+When users have the color picker interactor open, they _must not_ be able to access any other
+FABs (undo, redo,  thickness change) so be sure to disable them when you show the color picker
+and visually indicate to the user that they are disabled. This behavior should be very similar
+to the what happens when you try to change the thickness using the collapsible menu. If a color
+change is undone or redone, the color picker must reflect the correct color. Once you set up
+all the listeners to respond correctly, your color picker interactor must allow users to pick
+any stroke color they want!
+
+Finally, you will need to modify `ColorPickerView` so that it only accepts input inside the thin color
+ring. We have provided an AbstractColorPickerView class for you with an
+updated EssentialGeometry enum whose values are now `WHEEL` and `OFFWHEEL` to indicate this change,
+so you will have to update `ColorPickerView#essentialGeometry(MotionEvent)` method to reflect
+this change.
+
+The behavior of the ColorPickerView is must also be modified slightly.
+
+- If the user brings up the interactor, then immediately presses inside the center of the ring
+(which was colored in the ColorPicker app but is blank now), or outside it, you must not leave the start state.
+- If the users brings up the interactor and presses (then moves) inside of the ring, the
+state will leave the the start state and will move to the inside state. The thumb will
+track in the same way it did for the ColorPicker as the user moves around the ring.
+- If the user releases ON the ring, the new color will be chosen and the ColorPicker will become
+invisible.
+- If the user releases when not on the ring you should exit the state machine
+AND not consume the input. To the user this will appear as though the color "snaps back" to the
+previous state (with an opaque thumb) but the color picker stays visible on the screen.
+
+The following PPS diagram describes this new behavior.
+
+<div class="mermaid">
+graph LR
+S((.)) --> A((Start))
+A -- "Press:WHEEL-A" --> I((Inside))
+I -- "Release:WHEEL-B" --> E[End]
+I -- "Release:OFFWHEEL-E" --> E[End]
+I -- "Drag:WHEEL-C" --> I
+I -- "Drag:OFFWHEEL-D" --> I
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+class S invisible
+class A start
+class E finish
+class I normal
+
+</div>
+
+where
+- A is updateModel();invalidate()
+- B is invokeColorChangeListeners();invalidate()
+- C is updateModel();invalidate()
+- D is doNothing() // although not really a method
+- E is resetColor();invalidate()
+
+To implement the new `ColorPickerView#resetColor()` method you will need to store the current color
+of the wheel before you change it using `updateModel()`. You can use this stored color to reset
+the wheel if the user releases when not in the ring.
+
+NOTE: You **do not need to use bundler** to change the starting color or to store your model for this assignment.
+
+_Related APIs_:
+[View#using-views](https://developer.android.com/reference/android/view/View#using-views)
+
+## Part 5: Improve the application
+
+Create an interesting way the user can interact with the application that **can be undone and redone**. This means that whatever interaction you
+add must have a custom undo and redo function (it might help to take a look at `AbstractReversibleAction#doAction` and `AbstractReversibleAction#undoAction(DrawingView)`).
+
+Whatever you choose to implement, make sure to describe your addition in your report.
+In addition, make sure that the action you add is accessible.
+
+Demo of a new feature: Clear Screen. Note that this solution does not use the ColorPicker, nor
+did it implement undo on this features (but you must do both).
+
+<iframe width="560" height="315" src="https://www.youtube.com/embed/NhUE7GgH-vc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
+
+You will describe this addition and its accessibility in your report (see below).
+
+## Optional addition: Improving usability
+
+Try to identify at least one usability problem and address it
+  (optional). As with adding a feature, there are several options
+  here. Here are some examples of things _I_ think are usability issues. You
+  may not agree, if you choose to do this, you should focus on
+  something _you_ think is a usability issue.
+
+Whatever problems you address, please briefly describe the problems and solutions in your report.
+
+- As a color is selected and after the color is selected, the color FAB
+  should update its background to that color.
+- When a thickness is picked, the thickness FAB should update its icon
+  to indicate the thickness selected.
+- If the user begins drawing with the color or thickness FAB open (sub-icons present) the FAB immediately collapses
+- Some might find the menu items small and hard to select
+- No saving of state between invocations of the application. Could use
+  bundle to do this.
+
+
+# Part 6: Report
+
+In this portion you will be providing Heuristic Evaluation feedback and also reflecting on feedback that others have given you.
+
+## 6.1 Video
+To facilitate the online-only nature of this quarter, you will need to make a video of your final
+solution. To create a video, click on the ... at the bottom of the panel to the right of your
+emulator, then select "screen record" and "start recording" (see images below).
+
+<img src="undo-img/tab-of-options.png" alt="Empty drawing program window" height="400">
+<img src="undo-img/start-recording.png" alt="Drawing program window with one red stroke and undo button visible" height="400">
+
+In addition, you should follow these instructions to make sure that clicks are visible:
+
+<iframe width="560" height="315" src="https://www.youtube.com/embed/yYPZTnmP3Ws" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
+
+
+Your video should have the following sequence which is to demonstrate undoing and redoing
+actions for changing thickness, color, and your new feature. Please DO NOT try to create a
+perfect version with no mistakes! You *will not* lose points for any usability
+issues or mistakes (unless your code isn't working, which will not be affected by
+this video). You *will* get much better feedback and learn more about
+Heuristic Evaluation if your video isn't perfect!
+
+- Step 1: draw something
+- Step 2: undo
+- Step 3: change the thickness
+- Step 4: draw something
+- Step 5: undo
+- Step 6: undo
+- Step 7: change color
+- Step 8: try to redo
+- Step 9: draw something
+- Step 10: use new feature
+- Step 11: draw something in the new feature (if you need to)
+- Step 12: undo drawing (if done)
+- Step 13: undo new feature
+- Step 14: draw something
+- Step 15: use new feature
+- Step 16: undo
+- Step 17: redo
+- Step 18: draw something
+
+Finish as you will (e.g. demonstrate optional usability improvement).
+
+## 6.2 Providing Heuristic Eval feedback
+
+You will be assigned four videos. For each one you should:
+
+- Watch the video
+- While watching, take notes on paper about issues you see.
+- Remember: Make two passes through video as discussed in class:
+   - Inspect flow
+   - Inspect each screen, one at a time against heuristics
+- Fill out the following [google form](https://docs.google.com/forms/d/e/1FAIpQLScDe9k5bOKFikyh4ai32ih1e8waMD4SMECAjZK3yRVl1u-eDQ/viewform)
+with the 3 most severe issues. This will include questions about:
+  - Who are you/ who are you evaluating
+  - Which task step (above)
+  - Which heuristics are violated (primary and secondary)
+  - What severity rating would you give it
+  - Take a picture (a frame of the video) and circle the issue
+  - Describe what happened
+
+You will submit 3 things for each assigned video. At least two should be bad issues, one can be good.
+
+## 6.3 Reflecting on Heuristic Eval feedback and other aspects of this assignment
+
+You will turn in a report describing the feedback you got from the Heuristic Evaluation and answering other questions about the assignment. We have provided a [template](undo-report).
+
+# Part 7: Reflection
+
+Your reflection should be done as Microsoft Word, Google or other type of document.
+Copy the following questions (in italics below) into your reflection document and add
+your responses below each question. You can have more than one answer per page, but if
+you can, please try to avoid page breaks in the middle of
+a question. Insert page breaks between questions as needed.
+
+1. _Review the Heuristics from [lecture](https://courses.cs.washington.edu/courses/cse340/20sp/slides/wk10/heuristic.html).
+Which of the heuristics fit mobile application design? Which of the heuristics are less relevant?
+What problems did the heuristics not capture?_
+
+2. _Relate the heuristics to the gulf of evaluation and the gulf of execution:_
+  * _Pick at least one heuristic that you believe captures a problem relating to the gulf of
+  evaluation. Explain why._
+  * _Pick at least one heuristic that you believe captures a problem relating to the gulf of
+  execution. Explain why._
+
+3. _How secure is the Undo app? What security issues could arise with this app?
+List the security principals presented in lecture and categorize
+them as (1) violated, (2) met, (3) not relevant in the Undo app. Defend your
+reasoning._
+
+4. _How would you add context-aware computing in your Undo drawing app? Pick one of the types of
+sensing-based apps (capture and access; adaptive services; novel interaction; behavioral imaging;
+data collection & response) and discuss how it could enhance the app. Describe a case where this
+new feature could be problematic and relate it to the Sensing lecture._
+
+5. _Think back to all of the assignments you have done, and the design principles we have learned from
+Properties of People I and II, Application Design, Accessibility, and Security, been used i
+n your assignments? List and define in your own words 5 Interaction Programming design
+tips from these lectures. Also give an example of which, if any, of the assignments did
+you see that concept used (you can do this even if it was not explicitly named in the learning
+objectives we gave). Please explain your answer_
+
+6. (1pt Extra Credit) Instructor note: Usually on an exam I like to have a fun, 1 pt, extra credit
+problem where student can draw something or write a poem. We're not having traditional exam, but I feel the
+tradition of the fun extra credit must go on. _In an number of sections this quarter the TAs
+created a [Kahoot!](https://kahoot.com/) to help students study for the examlets. (For those of you
+who could not make section, Kahoot! is an on line game that allows participants to answer
+timed, fun questions. ). You can earn your extra credit point by authoring a Kahoot! question
+(and answer(s)) that we could potentially use in our CSE 340 offering. This can be a serious or
+fun question, but school appropriate please!_
+
+
+# Turn-in
+
+## Submission Instructions
+
+You will turn in the following files via GitGrade. It will accept:
+
+- `history/StackHistory.java`
+- `app/ReversibleDrawingActivity.java`
+- `app/ColorPickerView.java`
+- `actions/ChangeThicknessAction.java`
+- Any additional classes you create in `cse340.undo` for your new action
+- `layout/*_menu.xml`
+- `layout/drawing_activity.xml`
+- `drawable/*`
+- `values/{colors,dimens,strings}.xml`
+
+
+You will turn in the following files via our [google form](https://docs.google.com/forms/d/e/1FAIpQLScAh5Zux4YMp2mZzYjurVhzdrFESL1MRHdHeMZP2cExOxL47w/viewform):
+- Your video
+
+You will turn in your reflection and report (separately) on Gradescope
+
+## Grading
+
+This HW will be out of 50 points and will roughly (subject to small adjustments) be distributed as:
+
+Implementation (20 pts)
+- Part 1: Implement ChangeThicknessAction (2pts)
+- Part 2: StackHistory (7pts)
+- Part 3: Adding thickness to FAB thickness menu (3pts)
+- Part 4: Integrating ColorPickerView (7pts). Includes correct interactive behavior,
+and correct interaction with the stack.
+- Code Organization, and Style: (1 pt)
+
+Heuristic Evaluation & Reflection (35 pts)
+- Part 5: Improvement (3 pts). Evaluated through video of application. Improvement
+is evident, significant and can be done, undone, then done again.
+- Part 6:
+  - Video order is correct (3pts)
+  - Heuristic Evaluation Form filled out (based on form) (3pts)
+  - Report (11pts) includes Introduction and detailed description of your improvement,
+  including a justification of your design based on principles and accessibility support,
+  Purpose, Task, Data, and Lessons learned
+- Part 7: Reflection (15 pts). Includes the following reflection questions:
+  - How well do the heuristics fit mobile application design? (3 pts)
+  - Relate the heuristics to the gulf of evaluation and the gulf of execution (3 pts)
+  - How secure is the Undo app? (3 pts)
+  - How would you use context-aware computing in your drawing app? (3 pts)
+  - How have Properties of People I and II been used in your assignments? (3 pts)
+  - End of class picture (1 pt extra credit)
diff --git a/diagrams/Jan 2020 University of Washington Intro to Accessibility and Inclusive Design.pptx b/diagrams/Jan 2020 University of Washington Intro to Accessibility and Inclusive Design.pptx
new file mode 100644
index 0000000000000000000000000000000000000000..1f9bbf92e1df9d51e700796c0a71dc41da15168d
Binary files /dev/null and b/diagrams/Jan 2020 University of Washington Intro to Accessibility and Inclusive Design.pptx differ
diff --git a/diagrams/diagrams.pptx b/diagrams/diagrams.pptx
new file mode 100644
index 0000000000000000000000000000000000000000..88318c778d4292cc07239815fa908eca17c15a14
Binary files /dev/null and b/diagrams/diagrams.pptx differ
diff --git a/diagrams/diagrams/mvc.png b/diagrams/diagrams/mvc.png
new file mode 100644
index 0000000000000000000000000000000000000000..d8461c69af23ceebca4b045b0b1356db5049e4d2
Binary files /dev/null and b/diagrams/diagrams/mvc.png differ
diff --git a/diagrams/layout.pptx b/diagrams/layout.pptx
new file mode 100644
index 0000000000000000000000000000000000000000..2cfddb1d2ab829e0415ec3d43e843b49f90330d3
Binary files /dev/null and b/diagrams/layout.pptx differ
diff --git a/docs/android_files/AndroidStudio_Device_Manager_1.png b/docs/android_files/AndroidStudio_Device_Manager_1.png
new file mode 100644
index 0000000000000000000000000000000000000000..102912e1b51be70337948e78dd1d94f89744241b
Binary files /dev/null and b/docs/android_files/AndroidStudio_Device_Manager_1.png differ
diff --git a/docs/android_files/Device_Manager_File_Structure_2.png b/docs/android_files/Device_Manager_File_Structure_2.png
new file mode 100644
index 0000000000000000000000000000000000000000..5c69e91aac44d2e3107b53ae7c29b96dc86acf69
Binary files /dev/null and b/docs/android_files/Device_Manager_File_Structure_2.png differ
diff --git a/docs/android_files/Saving_CSV_3.png b/docs/android_files/Saving_CSV_3.png
new file mode 100644
index 0000000000000000000000000000000000000000..ca70ae3572e74b3299a9187a61cdca25cac716ce
Binary files /dev/null and b/docs/android_files/Saving_CSV_3.png differ
diff --git a/docs/android_files/index.md b/docs/android_files/index.md
new file mode 100644
index 0000000000000000000000000000000000000000..87ce28e47cb0c3c6a7a33e2a33fd6373bcfc2d25
--- /dev/null
+++ b/docs/android_files/index.md
@@ -0,0 +1,22 @@
+---
+layout: default
+---
+
+* TOC
+{:toc}
+
+# Retreiving Data from an Android Device or Emulator
+
+1. When you open Android Studio to your as5-menus project, you will see a "Device File Explorer" tab in the lower right corner:
+
+    ![Arrow to Android Studio's Device File Explorer Tab, 30%](AndroidStudio_Device_Manager_1.png){:width="max-width"}
+
+2. When you click this tab (make sure your emulator is already running or physical device is plugged in) you will see the file structure of your emulator:
+
+    ![Highlighting TestResult.csv in Android Studio's Device File Explorer Tab](Device_Manager_File_Structure_2.png){:width="50%"}
+
+3. Once you have found TestResult.csv under `/storage/emulated/0/CSE340_Menus/TestResult.csv` or `/sdcard/CSE340_Menus/TestResult.csv` you can right-click to save it to your computer:
+
+    ![Right-Clicking for "Save As" on TestResult.csv](Saving_CSV_3.png){:width="max-width"}
+
+4. Now that you have the file saved to a location on your computer you can right-click to open it in Microsoft Excel or upload it to Google Sheets to process the data.
\ No newline at end of file
diff --git a/docs/dev_mode/About_Settings_Section.png b/docs/dev_mode/About_Settings_Section.png
new file mode 100644
index 0000000000000000000000000000000000000000..c16b524e6d48410f9e48e24636caaa1ab801ed4b
Binary files /dev/null and b/docs/dev_mode/About_Settings_Section.png differ
diff --git a/docs/dev_mode/Build_Number.png b/docs/dev_mode/Build_Number.png
new file mode 100644
index 0000000000000000000000000000000000000000..919fdf4d839a16965bad9fbdb1d2d56144f8708a
Binary files /dev/null and b/docs/dev_mode/Build_Number.png differ
diff --git a/docs/dev_mode/Developer_Options.png b/docs/dev_mode/Developer_Options.png
new file mode 100644
index 0000000000000000000000000000000000000000..b40d373ef468155b281853984890841ae5e49470
Binary files /dev/null and b/docs/dev_mode/Developer_Options.png differ
diff --git a/docs/dev_mode/Settings_Icon.png b/docs/dev_mode/Settings_Icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..60a024802f43f4b9a832e10c8ca9be936bf25539
Binary files /dev/null and b/docs/dev_mode/Settings_Icon.png differ
diff --git a/docs/dev_mode/System_Settings.png b/docs/dev_mode/System_Settings.png
new file mode 100644
index 0000000000000000000000000000000000000000..b93d0f0372f01ecd426311f7e509b49cd172dfb1
Binary files /dev/null and b/docs/dev_mode/System_Settings.png differ
diff --git a/docs/dev_mode/USB_Debugging.png b/docs/dev_mode/USB_Debugging.png
new file mode 100644
index 0000000000000000000000000000000000000000..8299c76c5a9f768fb21d0e241a69344001e553fc
Binary files /dev/null and b/docs/dev_mode/USB_Debugging.png differ
diff --git a/docs/dev_mode/index.md b/docs/dev_mode/index.md
new file mode 100644
index 0000000000000000000000000000000000000000..b39ceee0ac2cdec079e0010dca29a0f3067a263a
--- /dev/null
+++ b/docs/dev_mode/index.md
@@ -0,0 +1,44 @@
+---
+layout: default
+---
+
+* TOC
+{:toc}
+
+# USB Debugging on Android
+
+If you have a personal device that you wish to use with Android Studio, enabling USB debugging is an important step in getting feedback sent from your phone to your PC. Setting this up, however, requires you to enable **Developer Mode** on your device.
+
+1. Open the `Settings` app on your device.
+
+    ![Clicking on Settings App in Android Appdrawer, 30%](Settings_Icon.png){:width="30%"}
+
+2. Scroll down to the `About Phone` submenu within the `Settings` app. This may be nested in a syntactically similar menu, such as `System`, and/or have a slightly different name.
+
+    ![Clicking on 'About' in Android System Settings, 30%](About_Settings_Section.png){:width="30%"}
+
+3. Scroll down to `Build Number` in the `About Phone` submenu.
+
+    ![Clicking on 'Build Number' in About Phone, 30%](Build_Number.png){:width="30%"}
+
+4. Tap `Build Number` several times. After a few taps, a Toast should appear notifying you that you are now a developer.
+
+5. Back out of the `About Phone` submenu. You should now see a `Developer Options` submenu on your device, somewhere in the same category as `About Phone`.
+
+    ![Clicking on 'Developer Options' in System Settings, 30%](Developer_Options.png){:width="30%"}
+
+6. In the `Developer Options` submenu, you should have the option to enable USB debugging.
+
+    ![Clicking on 'USB Debugging' in Developer Options, 30%](USB_Debugging.png){:width="30%"}
+
+Once you have done that, you will be able to debug your applications directly from your device.
+
+# Debugging Strategies
+
+- As with JGRASP, you can set breakpoints in your code by clicking to the right of a given line number. Then, by clicking the "debug" button to the right of the "run" button in the upper-right toolbar, you can have your app pause at the breakpoint, allowing you to inspect the state of your application.
+
+- The Logcat window can be difficult to parse, as the device tends to print out a lot of information that isn't necessarily relevant to your debugging process. However, Logcat provides a host of tools for pruning the errors that are displayed. You can limit console output by priority, or use the search tab to find the most relevant errors.
+
+- The Log class in Android Studio allows you to create custom sortable log statements. By importing `android.util.Log`, you gain access to a host of logging commands intended to display the state of your application quickly. Combining these with Logcat's search tools can be a good way to ensure that your function calls are running properly.
+
+- If you're curious about the implementation of core Android classes, you can use the tools provided by the IDE to view the inner workings of them. Android Studio will display an icon to the right of the line number to provide information on overriding methods for instance.<!--  -->
diff --git a/docs/index.md b/docs/index.md
index ea2cc08d70bfb4a9eb85e26effc60fb32ca97d4b..d891e481764276ed5fff787aaad0965b75baf6d4 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -20,3 +20,10 @@ slowly and will continue to be added to.
 - [How to Write a Reflection]({{site.baseurl}}/assignments/reflection.html)
 - [How to use the remote virtual lab machines](https://vdi.cs.washington.edu/) (e.g. to run Android Studio)
 
+**Handy Programming Resources**
+
+- [Debugging]({{site.baseurl}}/docs/dev_mode)
+- [Android File Explorer]({{site.baseurl}}/docs/android_files)
+- [Java 101]({{site.baseurl}}/docs/java/java.html)
+- [Advanced Java]({{site.baseurl}}/docs/java/java-advanced.html)
+- [Java example code]({{site.baseurl}}/docs/java/JavaRefresher.zip)
diff --git a/docs/java.html b/docs/java.html
new file mode 100644
index 0000000000000000000000000000000000000000..acc8c49f915240cbc2be0220ffc1fc33eec126af
--- /dev/null
+++ b/docs/java.html
@@ -0,0 +1,332 @@
+---
+layout: presentation
+title: Lab 1 Slides
+description: Lab project--Hello World--
+class: middle, center, inverse
+---
+
+# SSUI Mobile Lab ({{site.quarter}})
+## Week 1: Java Refresher
+
+.title-slide-logo[
+  ![Android Logo](java/android-logo.png)
+]
+
+---
+
+# Quick Java Refresher
+
+---
+
+## What is Java?
+--
+
+- Strongly, statically typed language
+
+  - Every variable has a type
+  - This type is decided at compile time (mostly)
+
+--
+
+- Compiled, class-based, Object-oriented
+
+--
+
+- Platform agnostic
+
+  - __Write once__, _run anywhere_ without recompilation
+  - Especially useful for Android
+
+---
+
+## Java Basics: Primitive Types
+
+--
+- Boolean
+
+```java
+boolean hasClassStarted = true;
+boolean isClassOver = false;
+```
+
+--
+- Integer
+
+```java
+int numStudents = rand.nextInt(30);
+```
+
+--
+- Float
+
+```java
+float gradePointAverage = 3.2f;
+```
+
+--
+- Double
+  - Higher precision than float
+
+```java
+double examScore = 97.362;
+```
+
+--
+- Byte, Short, etc.
+
+---
+## Java Basics: Text
+
+--
+- Characters
+
+```java
+char section = 'B';
+```
+
+--
+- Strings
+
+```java
+String instructor = "Jennifer Mankoff";
+```
+
+--
+All non-primitives types inherit from `Object` class
+  - Including `String`; note the capitalization
+
+---
+## Java Basics: Visibility Modifiers
+
+```java
+public final String COURSE = "CSE 340";
+///...
+private final String SSN = "123-45-6789";
+```
+
+--
+- `private`
+  - Kept secret, can only be read/written by `self`
+  - Cannot be accessed by subclasses
+
+--
+- `package private`
+  - This is the default access if no modifier is specified
+  - Accessible by all classes in the same package.
+
+--
+- `protected`
+  - Access restricted to `self`, subclasses, and package
+
+--
+- `public`
+  - The world can read/write (fields) or call (methods)
+
+---
+## Java Basics: Visibility Modifiers
+
+--
+  - Generally, you want to be as restrictive as possible
+    - Usually, this means `private`
+
+--
+
+  - Create getter/setter methods to modify the member variables
+
+--
+
+  - .red[__Almost never use__ `public`] for fields
+    - Except for constants
+
+---
+## Java Basics: `final`
+
+--
+- Prevent value from changing after initialization
+
+```java
+final double courseGrade = 95.0; // local variable cannot be modified ever!
+```
+
+--
+- Prevent subclassing
+
+```java
+  public final class Person {
+      // can't subclass (for example to make a Student class)
+      // ...
+  }
+```
+
+--
+- Prevent overriding
+
+```java
+  public final int getValue() { // can't override!
+      return 0;
+  }
+```
+
+---
+## Java Basics: `static`
+
+--
+- Use for constants or variables are shared by all instances of a particular class
+
+```java
+final static double SALES_TAX_RATE = 0.07; // Class Constant (never changes)
+static double mTotalAmount = 3.56;          // Class variable can change
+```
+
+--
+- Methods that can be called without an class instance (instantiating an object)
+
+```java
+static String toString(int i);
+// For example Integer.toString(100) => "100";
+```
+
+---
+# Naming Conventions
+
+   - class names are PascalCased
+   - local variables and method names are camelCased
+   - class or instance variables begin with a 'm' (for member), such as mTotalAmount
+   - constants are UPPER_SNAKE_CASED
+
+---
+## Java Basics: Methods
+- Methods in Java typically follow this format:
+
+```java
+{visibility} [static] [final] returnType methodName(paramType paramName, ...) {
+    // ...
+}
+```
+
+--
+- `static` and `final` are optional, special modifiers
+- `visibility` is one of `public`, `private`, `protected`, or empty for package private
+
+---
+## Java Basics: Method Example
+
+Summing two numbers and returning the answer as a string
+
+```java
+public String getSumOfTwoNumbersAsString(int first, int second) {
+  int sum = first + second;
+  return Integer.toString(sum);  // could also return "" + sum
+}
+```
+
+---
+## Java Basics: Declaring a class
+
+```Java
+{visibility} class ClassName {
+  // Field declarations
+
+  // Method definitions
+}
+```
+
+---
+
+## Java Basics: Constructing a Class
+
+```java
+public class Student {
+
+  // Class (static) variables -
+  public static final String STUDENT_KEY = "STUDENT";
+  private static final String ID_PREFIX = "S";
+
+  // Instance Variables
+  private String mIdNumber;
+  private String mName;
+
+  // Constructors - used to create an instance
+  Student(String name, String idNumber) {
+    this.name = mName;
+    this.idNumber = mIdNumber;
+  }
+
+  // Methods
+  public String getPrefixedIdNumber() {
+    return ID_PREFIX + mIdNumber;
+  }
+```
+
+---
+## Java Basics: Constructing a Class cont.
+```java
+  // Getter
+  public String getName() {
+    return mName;
+  }
+
+  // Setter
+  public void setName(String newName) {
+    if (newName == null || newName == "") {
+      newName = "Unknown";
+    }
+
+    mName = newName;
+  }
+
+  // ... etc.
+
+}
+```
+
+---
+# Enums
+
+An enum type is a special data type that enables for a variable to be a set of predefined constant
+
+```java
+public enum EssentialGeometry { INSIDE, OUTSIDE };
+
+...
+EssentialGeometry where = EssentialGeometry.INSIDE;
+```
+---
+# Switch Statements
+
+A form of a conditional with different execution paths
+
+```java
+public enum EssentialGeometry { INSIDE, ON_EDGE, OUTSIDE };
+
+...
+EssentialGeometry where = EssentialGeometry.INSIDE;
+
+switch (where) {
+  case ON_EDGE:
+    // do the edgy things
+    break;
+  case INSIDE:
+    // do the inside things but also fall through
+    // and do the OUTSIDE things because no break statement;
+  case OUTSIDE:
+    // do the outside things
+    break;
+  default:
+    // do default things
+    // automatically falls through
+}
+
+```
+
+
+---
+## More Java Resources
+
+- Java Documentation (https://docs.oracle.com/en/java/javase/13/docs/api/)
+
+- __Online Java Practice Problems__:
+
+  - http://codingbat.com/java
+
+  - https://practiceit.cs.washington.edu/problem/list
diff --git a/docs/java/JavaRefresher.zip b/docs/java/JavaRefresher.zip
new file mode 100644
index 0000000000000000000000000000000000000000..25f27c4c6f164f4fa2ad7b747dc793d0083ec75d
Binary files /dev/null and b/docs/java/JavaRefresher.zip differ
diff --git a/docs/java/android-logo.png b/docs/java/android-logo.png
new file mode 100755
index 0000000000000000000000000000000000000000..cebec75001ab25dc397065f193797d5ebd0cb38d
Binary files /dev/null and b/docs/java/android-logo.png differ
diff --git a/docs/java/java-advanced.html b/docs/java/java-advanced.html
new file mode 100644
index 0000000000000000000000000000000000000000..2b1e57a58736db7a29c7dcc9bfc41f7f73d0cd24
--- /dev/null
+++ b/docs/java/java-advanced.html
@@ -0,0 +1,219 @@
+---
+layout: presentation
+title: Advanced Java 
+description: Advanced Java Slides
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+
+# CSE 340 ({{site.quarter}})
+## Advanced Java
+
+---
+layout: false
+
+# Roadmap
+- Inheritance
+- Generics
+- Anonymous Inner Classes
+- Lambdas (and `::` notation)
+
+---
+# Inheritance
+
+.left-column50[
+Interfaces: a promise that you will implement these methods
+- Interfaces can only implement other interfaces
+- A class can implement many interfaces
+- Examples: Comparable interface
+
+Regular class: fully defined behaviors that you want to add to
+- All functions in the parent class have been implemented and are inherited
+- Usually would use this to add more specific behavior by changing implementation or adding new methods
+]
+.right-column50[
+Abstract classes: like interfaces but has some fully implemented methods as well
+- Can have abstract functions that are only defined in subclasses like interfaces
+- Also allows you to define shared member variables and functions for all subclasses
+- Examples: Pets all have a name (inherited member variable), are adopted the
+same way (function defined in abstract class) but eat different foods (abstract function defined only in subclasses)
+
+.small.red[https://courses.cs.washington.edu/courses/cse331/20wi/lectures/lec12-subtyping.pdf]
+]
+
+---
+# Inheritance common errors and tips
+Be careful:
+- Make sure not to redefine a variable you inherited from a parent class 
+- Check and make sure that you are using the same method signature (return types and parameter types) when overriding inherited methods, otherwise this is actually overloading 
+- These might lead to undefined and weird behaviors! :( 
+
+Remember:
+- You can only subclass one class, but you can implement as many interfaces as you want
+- Subclasses are able to access and change public and protected member variables of parent
+- You must implement interface methods and all abstract superclass methods 
+
+---
+# Switch Statements
+
+A form of a conditional with different execution paths
+
+```java
+public enum EssentialGeometry { INSIDE, ON_EDGE, OUTSIDE };
+...
+EssentialGeometry where = EssentialGeometry.INSIDE;
+switch (where) {
+ case ON_EDGE: // do the edgy things
+   break;      // and skip everything after this
+ case INSIDE:  // do the inside things but also fall through
+               // and do the OUTSIDE things because no break statement;
+ case OUTSIDE: // do the outside things
+   break;      // and skip everything after this
+ default:      // do default things
+               // automatically falls through
+}
+```
+---
+# Private class fields are often labelled with a lowercase “m” at the front 
+
+This notation comes from AOSP<br>
+(Android Open Source Project) [Code Style Guidelines for Contributors](http://source.android.com/source/code-style.html#follow-field-naming-conventions)
+
+Follow Field Naming Conventions
+- Non-public, non-static field names start with ‘m’.
+- Static field names start with ‘s’.
+- Other fields start with a lower case letter.
+- Public static final fields (constants) are `ALL_CAPS_WITH_UNDERSCORES`.
+
+For example:
+- `private float mCircleRadius, mThumbRadius;`
+- `private final Paint mPaintStart, mPaintEnd;`
+
+
+---
+# Enums
+
+An enum type is a special data type that restricts a variable to be a set of predefined constant
s
+
+```java
+public enum EssentialGeometry { INSIDE, OUTSIDE };
+...
+EssentialGeometry where = EssentialGeometry.INSIDE;
+```
+---
+# Generics
+
+Basically, abstraction over types
+```java
+Point<Integer>, Point<Double>
+
+// Type abstraction: abstract over element type
+Interface List<E> {       // Lets us use types such as:
+	Boolean add(E n);     //   List<Integer>
+	E get(int index);     //   List<String>
+}                         //   List<List<Double>>
+
+```
+---
+# Anonymous Inner Classes (1/3)
+
+In Java, Anonymous Inner Classes are inner classes (or a non-static class that’s nested inside another class)
+
+- Anonymous classes don’t have a name and are often used to make an instance of an object that has slightly different methods of another class or interface. 
+- This way, you don’t have to actually make a subclass of a class.
+- You’re going to see this type of class in some of our homework when implementing something called “listeners”
+
+---
+# Anonymous Inner Classes (2/3)
+
+```java
+public class ExActivity extends AppCompatActivity {
+	private View.OnClickListener mClickListener = new View.OnClickListener() {
+		public void onClick(View v) {
+			if (mButton!=v) {
+				return;
+			}
+		}
+	}; // remember to end this statement with a semicolon
+}
+
+```
+---
+# Anonymous Inner Classes (3/3)
+
+Digging deeper: Creating an anonymous inner class <br>
+`private View.OnClickListener mClickListener = new View.OnClickListener() {`
+
+.left-column50[
+
+`private` -- it's only available inside the class that contains it (e.g. `ExampleActivity`)
+
+`View.OnClickListener` -- the variable type ([Documentation](https://developer.android.com/reference/android/view/View.OnClickListener)), a nested class in `View`
+
+`mClickListener` is the variable name which is being set to...
+]
+.right-column50[
+a `new View.OnClickListener` which is an anonymous object from an abstract class
+- For those of you who have not taken 331, that means there are methods that have not been implemented in the class
+- The one method that you MUST implement (in order to create a new object of this type) is `onClick`, which overrides the abstract method
+]
+---
+# Lambdas
+
+What are Lambda expressions in Java?
+- Block of code that can be passed around to execute
+- Instances of functional interfaces
+- Think of it as using code as data
+- Useful for anonymous classes and functional interfaces, allows compact instances of one method classes
+- This will come up later in the course when dealing with callbacks!
+- Once instantiated, you can re-use it! Treat it is as a function 
+
+---
+# Lambda Simple Example
+.left-column50[
+An example functional interface
+```java
+interface FuncInter1
+   {
+     int operation(int a, int b);
+     int multiplication(int a, int b);
+   }
+
+...
+
+// Implementing interface w/ lambda function
+FuncInter1 add = (int x, int y) -> x + y;
+
+
+```
+]
+.right-column50[
+
+You can reuse this now!
+- `add.operation(2, 3)` returns 5
+- `add.multiplication(2, 3)` return 5
+]
+---
+# Another Lambda Example using `::` operator
+
+`::` is a method reference, same as using lambda but even shorter and readable 
+
+Syntax of `::` operator `<Class name>::<method name>`
+
+Lambda Example
+
+`numList.forEach(e -> System.out.print(e));`
+
+This does the same thing!
+
+`numList.forEach(System.out::print)`
+
+---
+
+
+
+
+
diff --git a/docs/java/java.html b/docs/java/java.html
new file mode 100644
index 0000000000000000000000000000000000000000..eddb432302a41d8567436d1eb4970c212352869d
--- /dev/null
+++ b/docs/java/java.html
@@ -0,0 +1,404 @@
+---
+layout: presentation
+title: Java Refresher
+description: Java Refresher Slides
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+
+# CSE 340 ({{site.quarter}})
+## Java Refresher
+
+---
+layout: false
+
+# What is Java?
+
+- Strongly, statically typed language
+
+  - Every variable has a type
+  - This type is decided at compile time (mostly)
+
+--
+
+- Compiled, class-based, Object-oriented
+
+--
+
+- Platform agnostic
+
+  - __Write once__, _run anywhere_ without recompilation
+  - Especially useful for Android
+
+---
+
+## Java Basics: Primitive Types
+
+--
+.left-column50[
+- Boolean
+
+```java
+boolean hasClassStarted = true;
+boolean isClassOver = false;
+```
+]
+---
+
+## Java Basics: Primitive Types
+
+.left-column50[
+- Boolean
+
+```java
+boolean hasClassStarted = true;
+boolean isClassOver = false;
+```
+
+- Integer
+
+```java
+int numStudents = rand.nextInt(30);
+```
+]
+---
+
+## Java Basics: Primitive Types
+
+.left-column50[
+- Boolean
+
+```java
+boolean hasClassStarted = true;
+boolean isClassOver = false;
+```
+
+- Integer
+
+```java
+int numStudents = rand.nextInt(30);
+```
+- Float
+
+```java
+float gradePointAverage = 3.2f;
+```
+]
+
+--
+.right-column50[
+- Double
+  - Higher precision than float
+
+```java
+double examScore = 97.362;
+```
+]
+--
+.right-column50[
+- Byte, Short, etc.
+]
+---
+## Java Basics: Text
+
+--
+- Characters
+
+```java
+char section = 'B';
+```
+
+--
+- Strings
+
+```java
+String instructor = "Jennifer Mankoff";
+```
+
+--
+All non-primitives types inherit from `Object` class
+  - Including `String`; note the capitalization
+
+---
+## Java Basics: Visibility Modifiers
+
+```java
+public final String COURSE = "CSE 340"; 
+...
+private final String SSN = "123-45-6789";
+```
+
+--
+.left-column50[
+- `package private`
+  - This is the default access if no modifier is specified
+  - Accessible by all classes in the same package.
+]
+---
+## Java Basics: Visibility Modifiers
+
+```java
+public final String COURSE = "CSE 340"; 
+...
+private final String SSN = "123-45-6789";
+```
+
+.left-column50[
+- `package private`
+  - This is the default access if no modifier is specified
+  - Accessible by all classes in the same package.
+- `private`
+  - Kept secret, can only be read/written by `self`
+  - Cannot be accessed by subclasses
+]
+--
+.right-column50[
+- `protected`
+  - Access restricted to `self`, subclasses, and package
+]
+---
+## Java Basics: Visibility Modifiers
+
+```java
+public final String COURSE = "CSE 340"; 
+...
+private final String SSN = "123-45-6789";
+```
+
+.left-column50[
+- `package private`
+  - This is the default access if no modifier is specified
+  - Accessible by all classes in the same package.
+- `private`
+  - Kept secret, can only be read/written by `self`
+  - Cannot be accessed by subclasses
+]
+.right-column50[
+- `protected`
+  - Access restricted to `self`, subclasses, and package
+- `public`
+  - The world can read/write (fields) or call (methods)
+]
+---
+## Java Basics: Visibility Modifiers
+
+--
+  - Generally, you want to be as restrictive as possible
+    - Usually, this means `private`
+
+--
+
+  - Create getter/setter methods to modify the member variables
+
+--
+
+  - .red[__Almost never use__ `public`] for fields
+    - Except for constants
+
+---
+## Java Basics: `final`
+
+--
+.left-column50[
+- Prevent value from changing after initialization
+
+```java
+// local variable cannot be modified ever!
+final double courseGrade = 95.0; 
+```
+]
+---
+## Java Basics: `final`
+
+.left-column50[
+- Prevent value from changing after initialization
+
+```java
+// local variable cannot be modified ever!
+final double courseGrade = 95.0; 
+```
+
+- Prevent subclassing
+
+```java
+  // can't subclass 
+  // (for example to make a Student class)
+  public final class Person {
+	...
+  }
+```
+]
+--
+.right-column50[
+- Prevent overriding
+
+```java
+	// can't override!
+	public final int getValue() { 
+      return 0;
+  }
+```
+]
+---
+## Java Basics: `static`
+
+--
+- Use for constants or variables are shared by all instances of a particular class
+
+```java
+final static double SALES_TAX_RATE = 0.07; // Class Constant (never changes)
+static double mTotalAmount = 3.56;          // Class variable can change
+```
+
+--
+- Methods that can be called without an class instance (instantiating an object)
+
+```java
+static String toString(int i);
+// For example Integer.toString(100) => "100";
+```
+
+---
+# Naming Conventions
+
+   - class names are PascalCased
+   - local variables and method names are camelCased
+   - class or instance variables begin with a 'm' (for member), such as mTotalAmount
+   - constants are UPPER_SNAKE_CASED
+
+---
+## Java Basics: Methods
+- Methods in Java typically follow this format:
+
+```java
+{visibility} [static] [final] returnType methodName(paramType paramName, ...) {
+    ...
+}
+```
+
+--
+- `static` and `final` are optional, special modifiers
+- `visibility` is one of `public`, `private`, `protected`, or empty for package private
+
+---
+## Java Basics: Method Example
+
+Summing two numbers and returning the answer as a string
+
+```java
+public String getSumOfTwoNumbersAsString(int first, int second) {
+  int sum = first + second;
+  return Integer.toString(sum);  // could also return "" + sum
+}
+```
+
+---
+## Java Basics: Declaring a class
+
+```Java
+{visibility} class ClassName {
+  // Field declarations
+
+  // Method definitions
+}
+```
+
+---
+
+## Java Basics: Constructing a Class
+
+```java
+public class Student {
+  // Class (static) variables -
+  public static final String STUDENT_KEY = "STUDENT";
+  private static final String ID_PREFIX = "S";
+
+  // Instance Variables
+  private String mIdNumber;
+  private String mName;
+
+  // Constructors - used to create an instance
+  Student(String name, String idNumber) {
+    this.name = mName;
+    this.idNumber = mIdNumber;
+  }
+
+  // Methods
+  public String getPrefixedIdNumber() {
+    return ID_PREFIX + mIdNumber;
+  }
+```
+
+---
+## Java Basics: Constructing a Class cont.
+```java
+  // Getter
+  public String getName() {
+    return mName;
+  }
+
+  // Setter
+  public void setName(String newName) {
+    if (newName == null || newName == "") {
+      newName = "Unknown";
+    }
+
+    mName = newName;
+  }
+
+  ... // etc.
+
+}
+```
+
+---
+# Enums
+
+An enum type is a special data type that enables for a variable to be a set of predefined constant
+
+```java
+public enum EssentialGeometry { INSIDE, OUTSIDE };
+
+...
+EssentialGeometry where = EssentialGeometry.INSIDE;
+```
+---
+# Switch Statements
+
+A form of a conditional with different execution paths
+
+```java
+public enum EssentialGeometry { INSIDE, ON_EDGE, OUTSIDE };
+...
+EssentialGeometry where = EssentialGeometry.INSIDE;
+switch (where) {
+  case ON_EDGE:
+    // do the edgy things
+    break;
+  case INSIDE:
+    // do the inside things but also fall through
+    // and do the OUTSIDE things because no break statement;
+  case OUTSIDE:
+    // do the outside things
+    break;
+  default:
+    // do default things
+    // automatically falls through
+}
+
+```
+
+
+---
+## More Java Resources
+
+- Java Documentation (https://docs.oracle.com/en/java/javase/13/docs/api/)
+
+- __Online Java Practice Problems__:
+
+  - http://codingbat.com/java
+
+  - https://practiceit.cs.washington.edu/problem/list
diff --git a/docs/javaRefresher_slides.pdf b/docs/javaRefresher_slides.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..107410aa62897b3d35570973d845b596ddecf37a
Binary files /dev/null and b/docs/javaRefresher_slides.pdf differ
diff --git a/docs/pps.md b/docs/pps.md
new file mode 100644
index 0000000000000000000000000000000000000000..da46a2e2b14ad0e048ecf7d0d501f86b8c48f9df
--- /dev/null
+++ b/docs/pps.md
@@ -0,0 +1,104 @@
+---
+layout: default
+---
+
+
+* TOC
+{:toc}
+
+
+# How to turn the Propositional Production System (PPS) for a button  into code
+
+The code implementation should spiritually follow the PPS; that is, your code should only take
+action when moving from state to state (along the arrows in the PPS). This behavior is best
+represented by a `switch` statement, where each `case` represents a state in our PPS.
+Within each `case`, there can be nested `if` statement to handle transitioning to another state.
+
+Each `case` should be broken out of and should properly handle input, propagating input to later
+views or stopping the input propagation as necessary. We typically do this through the
+`onTouchEvent` method. In `onTouchEvent`, returning `true` will stop the input propagation to
+views below it, while returning `false` allows views below it to handle the event.
+
+## Button Examples
+
+Given the essential geometry for this button is:
+- Inside
+- Outside
+
+and methods for that will be used are:
+
+- `indentButton()` (when button is pressed, also invalidate() the view)
+- `normalButton()` (when button is not pressed, also invalidate() the view)
+- `invokeAction()` (when the user releases in the button)
+- `cancelAction()` (when the user releases outside the button)
+
+The PPS for this interaction is as follows:
+
+<div class="mermaid">
+graph TD
+S((.)) --> START((START))
+START -- "DOWN:Inside?indentButton()" --> PRESSED((PRESSED))
+PRESSED -- "MOVE:Outside?normalButton()" --> PRESSED
+PRESSED -- "UP:Outside?cancelAction()" --> END[END]
+PRESSED -- "UP:Inside?invokeAction()" --> END
+PRESSED -- "MOVE:Inside?indentButton()" --> PRESSED
+
+linkStyle 0 stroke-width:2px;
+linkStyle 1 stroke-width:2px;
+linkStyle 2 stroke-width:2px;
+linkStyle 3 stroke-width:2px;
+linkStyle 4 stroke-width:2px;
+linkStyle 5 stroke-width:2px;
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF;
+
+class S invisible
+class START start
+class PRESSED normal
+class END finish
+</div>
+
+The code is generated thusly
+
+
+```java
+@Override
+public boolean onTouch(MotionEvent e) {
+  EssentialGeometry geometry = essentialGeometry(event);
+  switch (state) {
+    case State.START:
+      if (geometry == Geometry.INSIDE && e.getAction() == MotionEvent.ACTION_DOWN) {
+         indentButton();
+         state = State.PRESSED;
+         return true;
+      }
+      break;
+    case PRESSED
+      if (e.getAction() == MotionEvent.ACTION_MOVE) {
+        if (geometry == Geometry.INSIDE) {
+          indentButton();
+    	  } else {
+          normalButton();
+        }
+        return true;
+      }
+      else if (e.getAction() == MotionEvent.ACTION_UP) {
+        state = State.START; // note we don't actually use the END state
+        if (geometry == Geometry.INSIDE) {
+          invokeAction();
+        } else {
+          cancelAction();
+        }
+        return true;
+      }
+      break;
+    default:
+      break;
+  }
+  return false;
+}
+
+```
diff --git a/docs/ppsscroll.md b/docs/ppsscroll.md
new file mode 100644
index 0000000000000000000000000000000000000000..f710c9fdda4edc477c607114e8d859a4e3306401
--- /dev/null
+++ b/docs/ppsscroll.md
@@ -0,0 +1,88 @@
+---
+layout: default
+---
+
+
+* TOC
+{:toc}
+
+
+# How to turn the PPS for a Scroll bar into code
+
+The code implementation should spiritually follow the PPS; that is, your code should only take
+action when moving from state to state (along the arrows in the PPS). This behavior is best
+represented by a `switch` statement, where each `case` represents a state in our PPS. Within each
+`case`, there can be nested `if` statement to handle transitioning to another state.
+
+Each `case` should be broken out of and should properly handle input, propagating input to later
+views or stopping the input propagation as necessary. We typically do this through the
+`onTouchEvent` method. In `onTouchEvent`, returning `true` will stop the input propagation
+to views below it, while returning `false` allows views below it to handle the event.
+
+## Volume example
+
+<div class="mermaid">
+graph LR
+S((.)) --> A((Start))
+A -- "Press:insideBar? A" --> I((Inside))
+I -- "Release:B" --> E[End]
+I -- "Drag:insideBar? C" --> I
+I -- "Drag:outsideBar? D" --> I
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+class S invisible
+class A start
+class E finish
+class I normal
+
+</div>
+
+where
+- A is updateVolume();updateThumbPosition();updateThumbAlpha();
+- B is updateThumbAlpha();invokeVolumeChangeListeners()
+- C is updateVolume();updateThumbPosition();invalidate()
+- D is doNothing()
+
+```java
+@Override
+public boolean onTouchEvent(MotionEvent event) {
+    EssentialGeometry geometry = essentialGeometry(event);
+    switch(mState) {
+        case START:
+            if (event.getAction() == MotionEvent.ACTION_DOWN && geometry == EssentialGeometry.BAR) {
+                mState = State.INSIDE;
+                updateThumbPosition();
+                updateThumbAlpha();
+                updateVolume();
+                invalidate();
+                return true;
+            }
+            break;
+        case INSIDE:
+            if (event.getAction() == MotionEvent.ACTION_MOVE && geometry == EssentialGeometry.BAR) {
+                updateThumbPosition();
+                updateVolume();                
+                invalidate();
+                return true;
+            } else if (event.getAction() == MotionEvent.ACTION_UP) {
+                mState = State.START;
+                updateThumbAlpha();
+                invokeVolumeChangeListener();
+                invalidate();
+                return true;                   
+            }
+            break;
+        default:
+            break;
+    }
+    return false;
+}
+```
+In the above code snippet, `updateThumb()` would handle determining and setting the opacity of the
+thumb, while `updateVolume()` would similarly update the volume based on the position of your finger.
+Function calls inside the switch cases should be used to break up the logic in complicated situations
+or where the same logic can be used for multiple transitions.
diff --git a/grading.md b/grading.md
new file mode 100644
index 0000000000000000000000000000000000000000..1ab753a48ebb3dcae17e98679e1b870401e1508d
--- /dev/null
+++ b/grading.md
@@ -0,0 +1,4 @@
+---
+layout: default
+---
+
diff --git a/homework.md b/homework.md
new file mode 100644
index 0000000000000000000000000000000000000000..1ab753a48ebb3dcae17e98679e1b870401e1508d
--- /dev/null
+++ b/homework.md
@@ -0,0 +1,4 @@
+---
+layout: default
+---
+
diff --git a/index.md b/index.md
index 56359b06f75c4b13c8605b94e71563ad9658e274..3ebeed3791cc816498544c0dab563f21f53d0507 100755
--- a/index.md
+++ b/index.md
@@ -4,8 +4,8 @@ layout: default
 warning: draft
 ---
 
-<h1> Welcome to Class! </h1>
-Description of class
+<h1> Welcome to Interaction Programming! </h1>
+Interactive technology is changing society. Some of today’s interfaces are used by a billion people at a time. Almost everything we create is created for people to use, through user interfaces. We will learn about interactive systems, including programming paradigms and design of event handling, layout, undo, accessibility and context awareness.
 
 For quick links to key things, check out the navigation bar above and the table of contents here:
 
@@ -16,8 +16,8 @@ For quick links to key things, check out the navigation bar above and the table
 
 See [Canvas]({{site.canvas}}) for all zoom meeting links
 
-**Class Time:**  \\
-**Lab Times:** 
+**Class Time:** M/W/F at 10:30am PDT \\
+**Lab Times:** 9:30am PDT (Section AA) and 10:30 am PDT (Section AB)
 
 # Course staff
 
@@ -30,28 +30,119 @@ See [Canvas]({{site.canvas}}) for all zoom meeting links
 ## TAs
 
 :--: | :---------: | :-- | | :--: | :---------: | :--
-	**Section AA** | ![Taylor Gotfrid](assets/img/staff/gotfrid.jpg){:class="ta-picture"} | Taylor Gotfrid (she/her) | | **Section AB** | | 
-	**Infrastructure** |  |  | | | | 
+	**Section AA** | ![Taylor Gotfrid](assets/img/staff/gotfrid.jpg){:class="ta-picture"} | Taylor Gotfrid (she/her) | | **Section AB** | | David Chen (he/him)
+	**Infrastructure** |  ![Jeremy Zhang](assets/img/staff/zhang.jpg){:class="ta-picture"} | Jeremy  Zhang (he/him) | | | | 
 
 (More information on [Pronouns](https://www.mypronouns.org/))
 
 # Should I take this class?
 
-Why take this class?
+Yes! Some of today’s interfaces are being used by a billion people at
+a time. Almost everything we create is created for people to use, and
+user interfaces are how people interact with anything else you do
+(whether it is a new machine learning algorithm or a database
+system). User interfaces are incredibly important, but they also
+represent a different programming paradigm than you may have learned
+before. This class will teach you
+
+- How to write an event-driven program which reacts to user input and
+  displays output. If you’ve never done this before, the abstractions
+  you will learn are standard in almost any user interface toolkit. Even
+  if you have, too often, without attention to structure, interfaces
+  become impenetrable spaghetti code.
+- How to think about the design of novel interaction techniques. As
+  devices diversify, so too do the ways in which people interact, from
+  voice based interfaces to augmented reality. By understanding the
+  principles of interaction technique design you can do a better job of
+  making interactions that users will want, which improves both the user
+  experience and the business value of what you create.
+- How to avoid common gotchas in the implementation of user
+  interfaces. We will teach you the proper way to create Accessible Interaces and
+  implement features like Undo. We will also touch on other design principles (no
+  modal dialogues; good use of color; inclusion of support for help and
+  so on) that work in any user interface!ß
+
+Taking a class is a big commitment, and you will work hard in this
+class. So we want to help you make sure this is the right class for
+you. Below is some information about prerequisites and expectations.
 
 # Prereqs and expectations
 
-What do I need to know to take this class?
+The only requirement for this class is that you have taken CS 142 and
+143 or an equivalent class, meaning you are comfortable programming in
+Java, and have some experience with data structures. However, if you
+are not comfortable working in an IDE environment, using version
+control, and picking up and working with someone else’s library code,
+you will likely need to plan for extra time with TAs, and possibly
+attend extra tutoring sessions, to keep up with the class.
+Taking CSE 391 just before or concurrently with 340 can help, but our staff
+can also assist where needed.
 
-# Course Modules
+The specific platform and language for this class are Java on Android
+phones (or simulators); using the IntelliJ IDE (Android Studio). While
+Google is switching over to Kotlin, there are good reasons to [start
+learning Android with Java first](https://dzone.com/articles/java-vs-kotlin-which-language-android-developer-sh).
 
-| Module        |  Theory    |  Practice  |
-|---------------|-----------------------------------|-----------------------|
-|         |  |  |
+Note that this class is designed for CS majors, and other students who
+work regularly with information technology and are strong
+programmers. While we will consider applications from outside the
+major, financial and other restrictions may limit
+space for such students.
 
+# Course Learning Goals
+
+The course learning goals focus on five topics: Drawing, Layout, Event Handling, Applications, and Communication.
+
+### Drawing 
+How do I draw things on the screen? Do you know how to control what is shown to the user? 
+
+- Learn to use drawing abstractions such as [https://developer.android.com/reference/android/graphics/Canvas](Canvas) to programmatically draw on screen and use coordinate transformations to move and scale and  orient them. You should be able to place a [https://developer.android.com/reference/android/view/View](View) anywhere onscreen simply by specifying it's upper left x/y coordinates. 
+
+- When creating a new component on screen, it is important to properly size it so it is just big enough to fit its content (text, image, etc). To do this, you will Learn to properly set up bounding boxes so Android knows where to place [https://developer.android.com/reference/android/view/View](View)s even during dynamic events such as resizing or animation. The bounding box should be the smallest possible that surrounds the contents
+
+- Nice interactions often incorporate animation. You should be able to set up an animations using timing options such as slow in/slow out.
+
+### Layout 
+How do I set up an interface so that it looks the way I want and reacts properly to changes in orientation and size? Do you know how to implement a layout, supporting reactivity and so on?
+
+-  Be able to visually represent an interface as an [https://developer.android.com/studio/debug/layout-inspector](Interactor Hierarchy) (and vice versa). Given a picture of an interface, can you draw an interactor hierarchy that has all of the necessary components to be properly rendered as that interface? Similarly, given an interactor hierarchy, can you tell what interface it would be rendered as?
+-  Create reactive layouts that properly position things and handle dynamic events such as resizing or switching from portrait to landscape mode. 
+Also, given an interactor hierarchy, you should be able to point at which interface images it matches, or edit it to add or remove a visual element.
+-  Design and implement your own a layout container that can properly lay out any number of child items, to a spec. For example, can you implement a two column scrolling layout, or the facebook newsfeed which dynamically shows things as you scroll? You will need to properly support dynamic addition and removal of child components, as well as properly reacting to changes in scale or orientation. 
+
+### Events
+Events++ (4 Items)
+How do I handle input from the user, both at the application level and within a specific interactor?  An advanced but important aspect of android programming is implementing your own interactors. This is strongly tied to event handling because they can only be interactive if you know how to deal with events.
+
+-  The most basic and absolutely necessary form of event handling is application callbacks. This is how your application responds when someone presses a button or otherwise interacts, it is the minimum necessary to build a full interface. You should be able to build an application that can respond to callbacks from interactors such as buttons, or custom interactors and properly support separation of concerns between the application and interactors. All information should pass through the callback, and you should be able to update application state in response. You should understand how to use advanced Java programming concepts such as inner classes to support your work. 
+-  If you want to go beyond the default library provided by Android, you need to know how to build an interactor yourself. This involves dealing with lower level events (such as click or keypress events). To do this properly, you need to build an extended finite state machine that knows what state the interactor is in and how to respond to different events depending upon its state. 
+-  Be able to build non-rectangular interactors and other useful interaction techniques. You will learn to use your knowledge of the event handling/bubbling algorithm to properly build non-rectangular interactors, lenses, and other special case input handling. 
+-  Support a class of interaction techninques by building variations on a single interactor that all make use of the same finite state machine controller for their essential behavior. For example, a selection task might be handled as a pie menu or a linear menu. You should be able to accomplish this simply by varying the implementation of essential geometry for your interactor, without needing to modify the state machine underlying your interactor.
+
+### Applications 
+Learn to  build an application that meets basic standards that requiry programmatic support for accessibility, security, and interactivity. 
+
+There are interaction programming concepts that need to be considered at the application level. These may not ever show up in a spec, but are still the responsibility of the implementer to consider. Some examples include making your interface secure; supporting undo; and making it accessible. Human behavior is another essential aspect of interface design you must consider. But how does it interact with interface programming? More specifically, this class will cover the following learning goals
+
+-  You should be able to implement a simple application from scratch. To meet expectations, this should be complete, meaning it includes an interactor hierarchy, event handling and a responsive layout.
+- Fix accessibility problems including adding proper labeling, focus, navigation and contrast. This requires an understanding of how to properly use alt text to describe items on the screen, how to optimize navigation, how to make sure that everything can be accessed by the accessibility tools, that contrast and scaling work properly, and so on and so forth.
+- Be able to assess potential security considerations with an app and fix them, based on android's best practices and information found on sites like PrivacyGrade.org
+- Properly implement Undo in any interface to help users recover from errors. This requires an understanding of how to capture and store information about changes to an interface over time; and memory management so too much history isn't stored.
+
+### Communication about app concerns
+
+You are unlikely to be building an interface in a vacuum -- you will need to be able to read specs that are provided with you, identify potential problems, and advocate for new directions. These are communication tasks that are critical to success whether you are building interfaces or designing them. We will cover a sample of these in this class including:
+
+- You should be able to read, understand, and apply documentation and specs. 
+You should be able to use things you haven't see in the library before such as Canvas, Toasts and Floating Action Buttons; Bundler; Activities and the activity life cycle; and XML specifications including inflation. All of these are Android specific concepts that we will not teach in any detail, but will expect you to master. Some examples include Activities, Inflation, Bundles.
+- Ethics. Although this is a programming course, unexamined decisions can easily lead to major ethics violations. Thus, it is the job of every employeed/creator to search for possible concerns. You will learn examine an application and identify violations of ethics in the domains of behavior change, machine learning, inclusion/accessibility and/or security. This includes accessibility and security, but also other things such as unexamined biases, e.g. assumptions about skin color.
+- Accessibility and Security. Find and describe accessibility/security problems. Part of finding problems is being able to report on them. Such a report might go to someone else who will fix the problems.
+- One critical intersection is in the implementation of a study. You need to properly log behavior and analyze that behavior for a study to run. You should be able to properly consent participants, accurately describe the study process, and clearly describe the results of the study, using charts correctly to illustrate them and to draw  valid conclusions consistent with your data. Further, based on Fitts law, you should be able to predict which interactions will be slow. This can be helpful in finding small issues such as making an interactor that could have infinite width or height smaller.
 
 # Course Structure
 
+Each week, there will be three hours of lecture material (Monday, Wednesday, Friday) and
+one TA-led lab (Thursday). In addition the TAs will host office hours, often in pairs.
 
 ## Zoom
 
@@ -69,10 +160,12 @@ Change their Zoom screen name to a school appropriate screen name that hides any
 identifying information such as their name or
 UW Net ID, and not share their computer audio or video during their Zoom sessions.
 
+
 ## Lectures
 
 Lectures are designed to introduce new material throughout the quarter, motivate key theories and
-concepts, as well as practice.  
+concepts, as well as demonstrate Interface Programming primarily using the Android Studio development
+environment.
 
 The goals in this class center around learning by doing. This
 means that hands on time trying out everything from implementation to
@@ -103,6 +196,12 @@ the material in the course. You will be graded up to 2 points for each practice
 This work will be part of your participation grade for the course.
 
 
+### Lecture examlets and final reflection
+
+There will not be a midterm or final exam this quarter. Instead, there will be 4 quizzes held
+during the last 15-30 minutes of Friday lecture every other week, beginning the third week. The final
+project will incorporate a deeper reflection that covers all course material.
+
 ### Remote Lecture Guidelines and Expectations
 Students are expected to adhere to the below expectations for remote lectures. These guidelines are
 intended to help lecture go more smoothly, facilitate questions and group activities, and foster a
@@ -122,6 +221,11 @@ sense of community within the class.
 
 ## Lab
 
+On Thursdays, you will participate in a weekly lab, held at either 9:30 or 10:30 am PDT. These
+labs will be similar those you may have had in other classes - we will spend the 50 minutes answering
+questions, going over common errors in homework solutions, discussing sample problems in
+more detail than we can in lecture, and completing exercise worksheets with TAs available to help.
+
 ## Remote Lab Guidelines and Expectations
 Students are expected to adhere to the below expectations for remote labs. These guidelines are
 intended to help lab go more smoothly, facilitate questions and group activities, and
@@ -270,7 +374,7 @@ order to request a regrade of a homework (failure to do these two things may res
   - Include a link to the repository in your message and a written summary describing
   why your work should be reexamined.
 
-- Exams and Written Assignments: We will use Gradescope to grade exams and manage regrade requests.
+- Written Assignments: We will use Gradescope to written assignments exams and manage regrade requests.
   - Via Gradescope, you should submit any requests separately for each problem with an
 explanation of why you want this problem regraded.
   - The time limit for such regrade requests will be detailed in the email you receive from Gradescope.
@@ -345,3 +449,55 @@ here are the ones we are aware of:
  The University of Washington acknowledges that we are on sacred land of the first peoples of Seattle, the Coast Salish people, past and present. We honor, with gratitude, the land which touches the shared
  waters of all tribes and bands within the Suquamish, Tulalip and Muckleshoot nations.
 
+
+# Other relevant classes to know about
+
+There are a number of classes on campus that teach related concepts
+which you may wish to consider in addition to this one. As of Spring 2020,
+here are the ones we are aware of:
+
+- CSE 154: Web Programming: [Sp 20](https://courses.cs.washington.edu/courses/cse154/20sp/)
+  This course covers languages, tools, and techniques for developing interactive and dynamic web
+  pages. Topics include page styling, design, and layout; client and server side scripting;
+  web security; and interacting with data sources such as databases.
+- [HCDE 310: Interactive Systems Design &
+  Technology](https://www.smunson.com/teaching/hcde310/a17/) This course is a
+  project based course that teaches how to prototype applications on the
+  web using Python that solve human problems or enable new
+  activities. Includes information about APIs and how people interact with them. It
+  differs from CSE 340 in its choice of platform. Additionally, it
+  doesn’t cover the theory of UI programming, nor issues such as
+  accessibility, undo, and so on.
+- [INFO 343: Client side web
+  development](https://canvas.uw.edu/courses/1118282) This is a
+  programming course, and there will be significant overlap between the
+  courses, as INFO 343 also touches on event based programming, output,
+  and accessibility. [CSE 154: Web
+  Programming](https://courses.cs.washington.edu/courses/cse154/20sp/)
+  also covers some related
+  material. However, both are about programming on the web using
+  JavaScript instead of on Android, using Java. In addition, CSE 340
+  covers more of the theory of UI programming and design, similar to
+  HCID 520.
+- [CSE 440: Introduction to
+  HCI](http://courses.cs.washington.edu/courses/cse440/); [441: Advanced HCI](http://courses.cs.washington.edu/courses/cse441/) This is an advanced series of courses for undergraduate
+  seniors. The focus of 440 is less on programming and more broadly on
+  methods for designing, prototyping, and evaluating user interfaces to
+  computing applications, while 441 is an open ended capstone
+  course. These are excellent follow on courses to 340, for a student
+  who wants to go deeper into how to make usable, enjoyable effective
+  interfaces, and how to solve interesting problems with HCI. Related is
+  [CSE 510](http://courses.cs.washington.edu/courses/csep510/), the HCI
+  course for the professional masters program.
+- HCID 520: User Interface Software +
+  Technology ([Wi 17](http://uwdata.github.io/hcid520/17wi/), [Wi 16](http://faculty.washington.edu/ajko/hcid520/) [Wi 19](https://canvas.uw.edu/courses/1256337))
+  This course
+  teaches about user interfaces, including what they are, how they are
+  built, and some inventions in user interface software and
+  technology. There are many similarities between these classes. However HCID 520
+  is only open to [MHCI+D students](https://mhcid.washington.edu/) Masters students.
+- [HCID 521: Prototyping](https://canvas.uw.edu/courses/1128377/assignments/syllabus)
+  This class is for the [MHCI+D students](https://mhcid.washington.edu/)
+  only and focuses on prototyping techniques, not implementation. It
+  covers everything from paper prototyping to physical interfaces to 3D
+  printing.
diff --git a/schedule.md b/schedule.md
index 735bdbce938cd35a91ab8c8575ac0fa0ab28f434..b7d88ac67a301a817be522a5d4aeefdbf402c2a9 100644
--- a/schedule.md
+++ b/schedule.md
@@ -10,13 +10,491 @@ warning: draft
 <!-- ********* Week 1 ********* -->
 
 {: .week}
-# Week 1: title
+# Week 1: What's in an Interface
 
-{: .lecture} date: title
-: **Learning Goals** 
+{: .lecture} Monday 3/30: Why take this course? What is HCI?
+: **Learning Goals** Relevance of class to all of CS
 : **Readings**
+- Watch the video and read section 4.1 [The CS Field Guide to Human Computer Interaction Introduction](https://csfieldguide.org.nz/en/chapters/human-computer-interaction/)
+- Take the class [survey](https://catalyst.uw.edu/webq/survey/bricker/387508)
+
 : **Slides** {% include slide.html title="Introduction to course" loc="wk01/intro.html" %}
 
-{: .lab} Example lab
-: **Learning Goals** 
+{: .lecture} Wednesday 4/1: What is a toolkit?
+: **Learning Goals**  Toolkit User Types; Basic structure of a user interfaces; How this looks in Android; Introduction of Doodle Assignment
+: **Readings**
+
+- [Widget Toolkit](https://en.wikipedia.org/wiki/Widget_toolkit)
+- Watch Engelbart, Cronkite and other videos from {% include slide.html title="Introduction to course" loc="wk01/intro.html" %}
+
+**Slides** {% include slide.html title="Interface Toolkits" loc="wk01/toolkits.html" %}
+
+**Assigned** AS1 [Doodle]({{site.baseurl}}/assignments)
+
+
+{: .lab} Thursday, 4/2: Setting Up Doodle
+: **Learning Goals** Android project structure; Our development environment (Git/GitGrade), Doode
+
+**Preparation for Lab**
+
+* Android Basics:
+  * Download [Android Studio](https://developer.android.com/studio) and [install it](https://developer.android.com/studio/install)
+  * Select the Tools->SDK Manager and make sure you have Android 7.0 or 7.1.1 (Nougat) installed. This is the version of the Android SDK we will use for this class.
+  * Follow [this tutorial](https://developer.android.com/training/basics/firstapp) to create an Android Application.
+  * Continue with the tutorial to also
+  [run your app](https://developer.android.com/training/basics/firstapp/running-app)
+  either on an emulator or on an Android Device.
+
+* Git Setup: [macOS](https://courses.cs.washington.edu/courses/cse154/19au/resources/assets/atomgit/macosx/), [win](https://courses.cs.washington.edu/courses/cse154/19au/resources/assets/atomgit/windows/) (ignore pieces about Atom as we use Android Studio)
+  * Make sure you have git setup on your computer, follow above instructions
+  * If you have never used git before read through [this]({{site.baseurl}}/docs/git.html)
+  and [this (Android Studio ≈ Intellij)](https://courses.cs.washington.edu/courses/cse331/20sp/tools/version-control.html)
+  * Ensure that you can clone from CSE GitLab, (we recommend cloning via SSH
+    but you'll need to [generate a key](https://docs.gitlab.com/ee/ssh/))
+* Supporting Material [Java Refresher]({{site.baseurl}}/docs/java.html); [Git]({{site.baseurl}}/docs/git.html); [331's
+Git resource](https://courses.cs.washington.edu/courses/cse331/20sp/tools/version-control.html)
+* [Java refresher code]({{site.baseurl}}/docs/JavaRefresher.zip)
+* [Java Refresher slides]({{site.baseurl}}/docs/javaRefresher_slides.pdf)
+
+**Day Of**
+
+* **Slides** {% include slide.html title="Getting Started With Android" loc="l01/hello.html" %}
+* **Slides** {% include slide.html title="GitGrade" loc="l01/gitgrade.html" %}
+* **Slides** {% include slide.html title="Doodle" loc="l01/doodle.html" %}
+
+
+{: .lecture} Friday, 4/3: Drawing on the Screen
+: **Learning Goals** How does Android support drawing on the screen; Drawing abstractions; clipping and other transformations
+: **Readings**
+
+* [Using Android Resources](https://www.tutorialspoint.com/android/android_resources.htm)
+* Look at the following Android Documentation
+  * [ImageView](https://developer.android.com/reference/android/widget/ImageView)
+  * [Drawables](https://developer.android.com/guide/topics/graphics/drawables)
+  * [Canvas](https://developer.android.com/reference/android/graphics/Canvas)
+* [Drawing on the Canvas](https://android.jlelse.eu/android-canvas-for-drawing-and-custom-views-e1a3e90d468b)
+* What is a Bounding Box?
+  * Description [Minimum bounding box](https://en.wikipedia.org/wiki/Minimum_bounding_box)
+  * Exercise: [Bounding box in coordinate geometry](https://www.mathopenref.com/coordbounds.html)
+* A beginners guide to implement Android Animations — [Part 1](https://medium.com/@shubham08gupta/a-beginners-guide-to-implement-android-animations-part-1-2-part-series-b5fce1fc85) (2 part series)
+
+**Slides** {% include slide.html title="Drawing Components & Animation" loc="wk01/drawing.html" %}
+
+
+<!-- ********* Week 2 ********* -->
+
+{: .week}
+# Week 2: Output to Me
+
+{: .lecture} Monday, 4/6:  Drawing Interfaces; Animation
+: **Learning Goals** Role of interactor in drawing on the screen, how to use animation to move interactors
+: **Readings and Watchings**
+
+- There is a lot in there and it is a bit of a preview for Friday, but make sure you watch from 6:00-7:00 [Measure Layout Draw](https://youtu.be/4NNmMO8Aykw?t=368) -
+- Transformations in Android (video coming soon)
+- [Introduction to Animation](https://developer.android.com/training/animation/overview)
+- [Property Animation Overview](https://developer.android.com/guide/topics/graphics/prop-animation)
+
+**Slides**: {% include slide.html title="Drawing the interface" loc="wk02/interface-drawing.html" %}
+
+{: .lecture} Wednesday, 4/8: Properties of People I: Visual Perception
+: **Learning Goals** Design implications of people's visual capabilities
+
+**Readings and Watching**
+- [5 Visual-Design Principles in UX](https://www.nngroup.com/articles/principles-visual-design/)
+- [Visual Design Basics](https://www.usability.gov/what-and-why/visual-design.html)
+- [Gestalt Principles](https://www.interaction-design.org/literature/article/the-law-of-similarity-gestalt-principles-1)
+- Theresa-Marie Rhyne - SIGGRAPH University [Applying Color Theory to Digital Media and Visualization"](https://www.youtube.com/watch?v=KJv1N8akoUs) - at least the first 11 minutes or so
+
+**Slides** {% include slide.html title="Properties of People I: Vision" loc="wk02/people-vision.html" %}
+
+{: .lab} Thursday, 4/9: Debugging, Peer Evaluation, Doodle Help
+: **Learning Goals** Support for Creative Work on Doodle; Discussion of and practice evaluating (toy example)
+: **Slides** {% include slide.html title="Debugging, Peer Evaluation and Animation" loc="l02/animation.html" %}
+**Resources**:
+ - [Animation Demo (movie)](slides/l02/img/animationDemo.mov)
+ - [AnimationDemo.zip](slides/l02/animationPractice.zip)
+
+**Due** (10pm) AS1 [Doodle]({{site.baseurl}}/assignments) code
+
+{: .lecture} Friday 4/10: Introduction to Layout
+: **Learning Goals** Relating layout to the interactor hierarchy
+: **Readings**
+
+- [Layouts (Overview)](https://developer.android.com/guide/topics/ui/declaring-layout)
+- [Building a Responsive UI](https://developer.android.com/training/constraint-layout)
+- [Android - UI Layouts](https://www.tutorialspoint.com/android/android_user_interface_layouts.htm)
+
+**Worksheet** [Layout 1](https://docs.google.com/document/d/1hhFPJBZATrAgWb0pD7S2VZtA6aE2wGKM4wFDISk56sA/edit?usp=sharing)
+: **Slides** {% include slide.html title="Layout" loc="wk02/layout.html" %}
+
+**Assigned**  AS2 [Layout]({{site.baseurl}}/assignments)
+: **Assigned** Quiz 1 (due Sunday): Canvas Practice quiz containing sample questions covering key concepts from Doodle, Properties of People I: Vision, and readings
+
+
+<!-- ********* Week 3 ********* -->
+
+{: .week}
+# Week 3: Present to Me
+{: .lecture} Sunday, 4/12: Peer Evaluation
+: **Assigned** AS1 [Doodle]({{site.baseurl}}/assignments) peer reviews released (look for emails)
+: **Due** Quiz 1
+
+{: .lecture} Monday, 4/13:  Layout II - more layout details
+: **Learning Goal** How is layout accomplished? What is the difference between using XML vs creating
+Views and adding them to the parent?
+
+: **Readings and Watchings**
+- [Android ImageView ScaleType: a Visual Guide](https://thoughtbot.com/blog/android-imageview-scaletype-a-visual-guide)
+- See readings from 4/10
+
+
+: **Slides** {% include slide.html title="More on Layout in Android" loc="wk03/layout-ii.html" %}
+
+{: .lecture} Tuesday, 4/14
+
+: **Due** Peer evaluation of [Doodle]({{site.baseurl}}/assignments)
+
+{: .lecture} Wednesday, 4/15:   Layout: Implementation and Theory
+: **Learning Goals** Under the hood: How is layout accomplished?
+
+: **Readings and Watchings**
+
+- Watch or re-watch: [Measure Layout Draw](https://youtu.be/4NNmMO8Aykw?t=368)
+- Read one of
+  - [How Android Draws Views](https://developer.android.com/guide/topics/ui/how-android-draws)
+  - [Measure… Layout… Draw!](https://medium.com/@britt.barak/measure-layout-draw-483c6a4d2fab)
+  - Deeper details: [https://cheesecakelabs.com/blog/understanding-android-views-dimensions-set/](https://cheesecakelabs.com/blog/understanding-android-views-dimensions-set/)
+
+**Slides** {% include slide.html title="Layout in Android" loc="wk03/layout-algorithm.html" %}
+
+**Due** [Doodle]({{site.baseurl}}/assignments) Reflection
+
+{: .lab} Thursday, 4/16: Support on Layout
+: **Learning Goals** Work through constraint based layout
+
+: **Slides** {% include slide.html title="Layout" loc="l03/layout.html" %}
+
+{: .lecture} Friday, 4/17: AMA, Examlet 1
+: **Examlet 1** Assess your knowledge on Android development and drawing on the canvas
+
+**Slides** {% include slide.html title="AMA, Examlet" loc="wk03/examlet.html" %}
+
+**Due** AS2 [Layout]({{site.baseurl}}/assignments) part 1-2 (for pixel tests)
+
+<!-- ********* Week 4 ********* -->
+
+{: .week}
+# Week 4: Include Everyone
+{: .lecture} Monday, 4/20:  Accessibility
+: **Learning Goals** Learn about the history of accessibility, why it is important, and what problems exist
+: **Readings**
+- [Android Accessibility Overview](https://developer.android.com/guide/topics/ui/accessibility/)
+- [Android Accessibility Guides](https://developer.android.com/guide/topics/ui/accessibility/apps)
+- [Proper Alt Text Writing](https://webaim.org/techniques/alttext/)
+- [Material Design: Assistive Technology](https://material.io/design/usability/accessibility.html#assistive-technology)
+
+: **Slides** {% include slide.html title="Accessibility" loc="wk03/accessibility-and-inclusive-design.pdf" %}
+
+{: .lecture} Wednesday, 4/22: Guest Lecture (Venkatesh Potluri & Anne Ross): Android Accessibility
+: **Learning Goals** Learn about how to make Android apps accessible
+: **Readings** See Monday
+: **Slides**
+  - {% include slide.html title="Accessibility in Practice" loc="wk04/accessibility.html" %}
+  - [340AccessibiltyScanner](340AccessibiltyScanner.pdf)
+
+**Assigned**: AS3 [Accessibility]({{site.baseurl}}/assignments)
+
+
+{: .lab} Thursday, 4/23: Finish Layout & Start Accessibility
+: **Learning Goals** Use the Accessibility Checker
+
+: **Slides**  {% include slide.html title="Layout and Accessibility" loc="l04/accessibility.html" %}
+
+{: .lecture} Friday, 4/24: Event Handling I: Where Events Come from
+: **Learning Goals** Basics of event handling including event types and listeners (callbacks)
+: **Readings**
+- [Comparators](https://tech.willhaben.at/sorting-objects-working-with-java-comparator-5302ab38c21f)
+- [UI Events in Android](https://developer.android.com/guide/topics/ui/ui-events)
+- [Model-View-Controller](https://medium.com/upday-devs/android-architecture-patterns-part-1-model-view-controller-3baecef5f2b6)
+
+**Slides** {% include slide.html title="Event Handling I: Callbacks, Model View Controller, and Events" loc="wk04/events.html" %}
+**Supplemental Files** [person.zip]({{site.baseurl}}/slides/wk04/person.zip)
+
+**Assigned** Quiz 2 (due Sunday): Sample questions covering key concepts from layout
+
+**Due** AS2 [Layout]({{site.baseurl}}/assignments) part 3-5 (code + reflection)
+
+
+<!-- ********* Week 5 ********* -->
+
+{: .week}
+# Week 5: React to me
+{: .lecture} Sunday 4/26:
+: **Due** Quiz 2
+
+{: .lecture} Monday 4/27: Event Handling II: Where Events Go
+: **Learning Goals** How events are dispatched to interactors, importance of interactor hierarchy
+: **Readings**
+- [UI Events](https://developer.android.com/guide/topics/ui/ui-events)
+- [4 Ways To Implement OnClickListener On Android](https://medium.com/@CodyEngel/4-ways-to-implement-onclicklistener-on-android-9b956cbd2928)
+
+
+: **Slides** {% include slide.html title="Event Handling II: Delivery of Events in the Interactor Hierarchy" loc="wk05/event-delivery.html" %}
+**Supplemental Files** [Counter.zip]({{site.baseurl}}/slides/wk05/Counter.zip)
+
+{: .lecture} Wednesday, 4/29: Event Handling III: How Interactors use Events
+: **Learning Goals** Learn how to handle input; How to properly implement a finite state machine in an interactor; Implementation Strategies for Interactors to Handle Events
+: **Readings and Prework**
+- [Custom View Components](https://developer.android.com/guide/topics/ui/custom-components)
+- Download [Counter.zip]({{site.baseurl}}/slides/wk05/Counter.zip) and read through it.
+- Informational only: [Original PPS paper](https://dl.acm.org/doi/abs/10.1145/97243.97252)
+
+: **Slides** {% include slide.html title="Essential Behavior and the use of finite state machines to implement it" loc="wk05/pps-geom.html" %}
+
+{: .lab} Thursday, 4/30: Implementing Interactors
+: **Learning Goals** Get comfortable with finite state machines' implementation in interactors
+
+: **Slides**  {% include slide.html title="State Machines" loc="l05/state.html" %}
+
+**Due**: AS3 [Accessibility]({{site.baseurl}}/assignments)
+
+{: .lecture} Friday, 5/1: Examlet 2, Event Handling IV: Essential Geometry
+: **Learning Goals** ColorPicker intro, Create a non-rectangular interactor, Essential Geometry and Essential Behavior
+: **Reading**
+
+- [Custom View Components](https://developer.android.com/guide/topics/ui/custom-components)
+
+<!-- - **Slides** {% include slide.html title="Review Slides Touching on Key Concepts from Prior Weeks" loc="wk05/review.html" %} -->
+**Slides** {% include slide.html title="Summary of Toolkit Architecture" loc="wk05/whole-toolkit.html" %}
+
+**Examlet 2** Assess your knowledge on layout theory and practice in Android
+
+**Assigned** AS4 [Color Picker]({{site.baseurl}}/assignments)
+
+
+<!-- ********* Week 6 ********* -->
+
+{: .week}
+# Week 6: Beyond Touch: The Larger World
+
+{: .lecture} Monday, 5/4: Context Awareness - Jen Mankoff, Guest Lecture
+: **Learning Goals** Assumptions about phone use and examples of context aware applications
+: **Readings**:
+- [Calm Tech, Then and Now](http://www.johnseelybrown.com/calmtech.pdf)
+- [The Coming Age of Calm Technology](https://pdfs.semanticscholar.org/ed7f/cec667281ab1f4ca4ac10239582cb4345e0a.pdf?_ga=2.248923214.838018675.1588119518-1260861436.1586456410)
+
+: **Slides** {% include slide.html title="The Sensing Phone" loc="wk06/context.html" %}
+
+{: .lecture} Wednesday, 5/6: Physical Computing
+: **Learning Goals** Learn a little about 3D Printing and extending phones for sensing
+: **Readings and Watchings**
+- Lisa Harouni Ted Talk: [A Primer on 3D Printing](https://www.ted.com/talks/lisa_harouni_a_primer_on_3d_printing)
+- [Powder Printing](https://www.youtube.com/watch?v=kBHsfNDsbCs&feature=youtu.be&t=29s)
+- [Liquid Printing](https://www.popsci.com/new-liquid-based-3d-printer-takes-minutes-not-hours/)
+
+: **Slides** {% include slide.html title="Physical Computing" loc="wk06/3dprinting.html" %}
+
+{: .lab} Thursday, 5/7: Bundling + Color Picker help
+: **Learning Goals** What're bundles? What do they do? Let's find out!
+
+: **Slides**  {% include slide.html title="How to use Bundle" loc="l06/bundling.html" %}
+
+{: .lecture} Friday, 5/8: Properties of People II: Motor Behavior
+: **Learning Goals** Learn the theory driving good interactor design; Motor behavior basics and
+ implications for design including Fitts' law and Guiard's theory of bimanual input
+: **Readings**
+- [Fitts' Law](https://en.wikipedia.org/wiki/Fitts%27s_law)
+- [Video](https://www.youtube.com/watch?v=kly2QA1bFc8)
+
+: **Slides** {% include slide.html title="Properties of People II: Motor Control" loc="wk06/people-motor.html" %}
+
+**Assigned** Quiz 3 (due Wednesday 5/13): Sample questions covering key concepts from accessibility and color picker assignments
+
+
+<!-- ********* Week 7 ********* -->
+
+{: .week}
+# Week 7: Design Principles
+
+{: .lecture} Monday, 5/11:Predicting and Evaluating Interactor Efficiency
+: **Learning Goals** Apply design tips we've discussed to comparing the efficiency of different variations on interactors; Learn about wide variety of solutions for selection; Learn about Qualitative and Quantitative ways of testing theories
+
+: **Slides** {% include slide.html title="Predicting and Evaluating Interactor Efficiency" loc="wk07/menus.html" %}
+
+**Assigned** AS5 [Menus]({{site.baseurl}}/assignments)
+
+**Due** AS4 [Color Picker]({{site.baseurl}}/assignments) code and reflection
+
+{: .lecture} Wednesday, 5/13: Application Design Principals
+: **Learning Goals** Mental models, gulf of execution, gulf of evaluation
+**Readings**:
+- [Mental Models](https://www.nngroup.com/articles/mental-models/)
+- [The Two UX Gulfs: Evaluation and Execution](https://www.nngroup.com/articles/two-ux-gulfs-evaluation-execution/) (also a short article [here](https://www.educative.io/edpresso/gulf-of-execution-and-gulf-of-evaluation))
+- [The Seven Stages of Action](https://www.guerillagirl.de/2017/03/18/seven-stages-of-action-don-norman/).
+At least watch these two videos
+  - [The Seven Stages of actions](https://youtu.be/n4fCHYbRcKw&feature=emb_logo)
+  - [It's not you. Bad Doors are everywhere](https://www.youtube.com/watch?v=yY96hTb8WgI&feature=emb_logo)
+
+: **Slides** {% include slide.html title="Application Design Principals" loc="wk07/interaction.html" %}
+
+**Due** Quiz 3
+
+{: .lab} Thursday, 5/14: Designing Menus
+: **Learning Goals** Help with Menus Assignment; Revisiting key concepts
+
+: **Slides**  {% include slide.html title="Getting started with Menus" loc="l07/menus-lab.html" %}
+
+{: .lecture} Friday, 5/15: Examlet 3, Reasoning from Data
+: **Learning Goals** Principals of and Problems with Behavior Change
+**Readings**
+- [Dopamine, Smartphones & You: A battle for your time](http://sitn.hms.harvard.edu/flash/2018/dopamine-smartphones-battle-time/)
+- [Science Of Persuasion](https://www.youtube.com/watch?v=cFdCzN7RYbw) (Optional)
+
+: **Slides** {% include slide.html title="Behavior Change with Mobile Devices" loc="wk07/behavior-change.html" %}
+
+**Examlet 3** Assess your knowledge on key concepts from accessibility and color picker
+
+
+
+<!-- ********* Week 8 ********* -->
+
+{: .week}
+# Week 8: Understand Me
+
+{: .lecture} Monday, 5/18:  Studying People
+: **Learning Goals** Understand concepts in data pipeline in an applied fashion including what is
+our hypothesis, how this translates into study design and method, considerations when interacting
+with users, data collection cleaning and analysis, some statistical methods, and how we draw conclusions
+**Readings**
+- [Some Social Scientist Are Tired of Asking for Permission](https://www.nytimes.com/2017/05/22/science/social-science-research-institutional-review-boards-common-rule.html)
+
+: **Slides** {% include slide.html title="Quantitative Study Design/Running" loc="wk08/studies.html" %}
+
+
+
+{: .lecture} Wednesday, 5/20: Using data to influence people
+: **Learning Goals** Data analysis and how charts and statistics can be used and misused
+
+: **Slides** {% include slide.html title="Analyzing Data" loc="wk08/studies2.html" %}
+
+**Assigned** AS5 [Menus]({{site.baseurl}}/assignments) part 5-6
+
+{: .lab} Thursday, 5/21: Sample Menu Data Analysis
+: **Learning Goals** Evaluating Human Subjects Experiments
+
+: **Slides** {% include slide.html title="Menus Data Analysis" loc="l08/menus-data.html" %}
+
+**Due** AS5 [Menus]({{site.baseurl}}/assignments) part 1-4
+
+
+{: .lecture} Friday, 5/22: Undo
+: **Learning Goals** Theory and implementation of Undo
+
+: **Slides** {% include slide.html title="Undo" loc="wk08/undoSlides.html" %}
+
+**Assigned** AS6 [Undo]({{site.baseurl}}/assignments)
+: **Assigned** Quiz 4 (due <del>Sunday</del>Monday): Covering important concepts from interactor implementation, accessibility and Fitts' Law
+
+<!-- ********* Week 9 ********* -->
+
+{: .week}
+# Week 9: Undo Me
+
+{: .lecture} Monday, 5/25
+: **Due** Quiz 4
+
+{: .holiday} Monday, 5/25: Memorial Day
+: **Due** AS5 [Menus]({{site.baseurl}}/assignments) part 5-6
+
+{: .lecture} Wednesday, 5/27:  Interaction Programming in Web Development
+: **Learning Goals** See how Web Development follows many of the same Interaction Programming principles we've been learning all quarter!
+**Readings**
+- [Spot the Heron Case Study](https://gitlab.cs.washington.edu/cse340-20sp-students/cse340-spottheheron)
+- [What is HTML?](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Getting_started)
+- [What is CSS?](https://developer.mozilla.org/en-US/docs/Learn/CSS/First_steps/How_CSS_works)
+- [Intro to Javascript](https://javascript.info/intro)
+- [Difference between JS and Java](https://stackoverflow.com/questions/245062/whats-the-difference-between-javascript-and-java)
+
+: **Slides** {% include slide.html title="Interaction Programming in Web Development" loc="wk09/web" %}
+
+
+{: .lab} Thursday, 5/28: Work on Undo
+: **Slides** {% include slide.html title="Getting started with Undo" loc="l09/undo-lab.html" %}
+
+{: .lecture .tbd} Friday, 5/29: Examlet 4, Machine Learning
+: **Learning Goals** Using Machine Learning in Interactive Systems
+**Readings and Watchings**
+- [The Risk of Machine-Learning Bias (and How to Prevent It)](https://sloanreview.mit.edu/article/the-risk-of-machine-learning-bias-and-how-to-prevent-it/)
+- [The Basics of Machine Learning](https://sloanreview.mit.edu/article/the-risk-of-machine-learning-bias-and-how-to-prevent-it/)
+
+: **Slides** {% include slide.html title="Mobile Machine Learning" loc="wk09/ml.html" %}
+
+**Examlet 4** (Due by 10pm) Assess your knowledge on key concepts menus, application design principles, and properties of people II.
+
+
+<!-- ********* Week 10 ********* -->
+
+{: .week}
+# Week 10: Assess Me
+
+{: .lecture} Monday, 6/1: Interaction Programming in Flutter
+: **Learning Goals** See how Flutter follows many of the same Interaction Programming principles we've been learning all quarter!
+**Readings**
+- [What is Flutter?](https://flutter.dev/docs/resources/technical-overview) up to "try it"
+- Optional additional: the “aggressive composability” [Inside Flutter](https://flutter.dev/docs/resources/inside-flutter)
+
+**Slides** [Interaction Programming in Flutter](https://docs.google.com/presentation/d/18Ma_vUkgWPBHFQ9KWoC3jrcDZhp3f9lzmVYQcl7zHOM/preview?slide=id.p)
+
+
+{: .lecture} Wednesday, 6/3:  Heuristic Evaluation
+: **Learning Goals** Learn about a quick way to get feedback on the quality of your application,
+particularly good for focused tasks on screens.
+**Readings**:
+- [Usability Heuristics](https://csfieldguide.org.nz/en/chapters/human-computer-interaction/usability-heuristics/)
+
+**Slides** {% include slide.html title="Heuristic Evaluation" loc="wk10/heuristic" %}
+
+**Due** [Undo]({{site.baseurl}}/assignments)
+
+{: .lab} Thursday, 6/4:  Heuristic Eval of Undo App
+: **Learning Goals** Execute a Heuristic Eval (start in Lab)
+
+:  **Slides** {% include slide.html title="Heuristic Evaluation" loc="l10/lab-heuristic.html" %}
+
+**Due** (16-Mar): Heuristic Eval Reflection
+
+{: .lecture} Friday 6/5:Guest Lecture: Implementing Secure & Private Mobile Apps
+: **Learning Goals** Implementing Secure & Private Mobile Apps
+**Readings**
+- [Android Security Tips](https://developer.android.com/training/articles/security-tips)
+- [Cryptography](https://developer.android.com/guide/topics/security/cryptography)
+
+
+: **Slides** {% include slide.html title="Secure Android Application Development" loc="wk09/cse340-guestlecture-june5.pdf" %}
+**Assigned** Quiz 6 (due Sunday): Sample questions covering key concepts from undo and heuristic evaluation
+
+<!-- ********* Finals Week ********* -->
+
+{: .week}
+# Week 11: Final-ly
+
+{: .exam} 6/8: Final Reflection Due (in lieu of Final Exam)
+
+: **Due** [Undo]({{site.baseurl}}/assignments/undo) final reflection
+: **Due** Quiz 6
+
+<!-- Things cut from the course that could be added back: -->
+
+<!-- {: .lecture} TBD Augmented Reality -->
+<!-- : **Slides** {% include slide.html title="Augmented Reality on the phone" loc="wk08/ar.html" %} -->
+<!-- some key things you need to do to implement Sensing, discussion of the context awareness assignment -->
+
+<!-- Deeper introduction to Animation -->
+
+<!-- Advanced Layout Concepts -->
+<!-- : **Learning Goals** Using tabs, lenses, and so on); How to make use of the Android Layout Libraries Effectively -->
+<!-- : {: .tbd} **Slides**: Advanced Layout -->
 
+<!-- : **Learning Goals** Using machine learning to reason from mobile data -->
+<!-- : **Slides** {% include slide.html title="Machine learning on mobile devices" loc="wk10/ml.html" %} -->
diff --git a/slides/l01/doodle.html b/slides/l01/doodle.html
new file mode 100644
index 0000000000000000000000000000000000000000..f6897cd621f3f475706e17c1daa9afb168725947
--- /dev/null
+++ b/slides/l01/doodle.html
@@ -0,0 +1,309 @@
+---
+layout: presentation
+title: Introduction to Doodle Assignment
+description: Introduction to Doodle Assignment
+class: middle, center, inverse
+---
+# CSE 340 Lab 1: Doodle (Spring 2020)
+
+## Introduction to Doodle
+
+.title-slide-logo[
+![:img Android Logo](img/android-logo.png)
+]
+---
+
+.left-column[
+## **Library** (and Inheritance Hierarchy)
+<br>
+<br>
+<br>
+<div class="mermaid">
+    graph LR
+    Activity[Activity]
+    Activity -->|...| Doodler[Doodler]
+    Doodler --> Part1[Part1]
+    Part1 --> Part1Activity[Part1Activity]
+    Part1 --> Part2Activity[Part2Activity]
+
+    classDef yellow font-size:19px,text-align:center
+    classDef green font-size:19px,text-align:center
+
+    class Part1,Part1Activity,Part2Activity yellow
+    class Activity,Doodler green
+</div>
+]
+
+.right-column[
+## Android Classes we are using in Doodle and how they relate
+
+- Doodler (which you don't edit) *extends* [Activity](https://developer.android.com/reference/android/app/Activity)
+- Part1 *extends* Doodler. It implements *helper methods* for Part1Activity and
+Part2Activity.
+- Part1Activity and Part2Activity both extend Part1
+]
+---
+layout:none
+
+.title[Running Sample Code]
+.body[
+When you accept the assignment on GitGrade, a repository containing the starter code is generated for you on CSE
+GitLab. You **MUST** work within this assignment, as it will be turned in via GitGrade when it is due.
+
+Please clone and use the repository and commit and push your work regularly.
+Not only will doing so protect your code, but it will also allow course staff
+to look at your code and it will allow you to easily pull any changes we make
+to the assignment source.You can find instructions on setting up and maintaining
+a forked repository [here](https://help.github.com/en/articles/working-with-forks).
+]
+---
+## Cloning Doodle
+
+.left-column[
+You can find your unique repo by the notification email or by going to [GitLab](https://gitlab.cs.washington.edu) or via
+the [GitGrade](https://gitgrade.cs.washington.edu) interface.
+]
+
+.right-column[
+![:img Android Studio splash screen, 30%](img/doodle-clone-1.png)
+![:img Android Studio clone dialog, 30%](img/doodle-clone-2.png)
+]
+
+---
+.title[Open project in Android Studio]
+.body[
+- Run configurations should be automatically imported from Gradle
+- If not, `build` should trigger an import
+- Run with â–º
+- Connect an android device by USB or create a new virtual device
+- If by USB, debugging must be enabled on the device
+]
+---
+.title[Implementing `addImage`]
+.body[
+```java
+private ImageView addImage(FrameLayout doodleView, String imageName, Float x, Float y, int size);
+```
+
+### Params:
+- `doodleView`: Canvas in which to render the image.
+- `imageName`: Filename of image to draw in `res/drawable`.
+]
+--
+.body[
+- `x`: Horizontal distance from top-left corner of canvas to top-left of image.
+- `y`: Veritcal distance from top-left corner of canvas to top-left of image.
+- `size`: Width and height of rendered image, in pixels.
+]
+
+---
+.title[Implementing `addImage`]
+.body[
+### Returns:
+- An `ImageView` which has been added to the canvas.
+]
+
+---
+.title[Implementing `addImage`]
+--
+.body[
+Break down into component steps, look up documentation, and implement
+
+1) Create `ImageView`
+]
+--
+.body[
+2) Add new view to canvas
+]
+--
+.body[
+3) Position and set view size
+]
+--
+.body[
+4) Set view contents
+]
+---
+.title[Implementing `addImage`]
+.body[
+```java
+private ImageView addImage(FrameLayout doodleView, String imageName, Float x, Float y, int size) {
+// Create ImageView and add it to doodleView.
+ImageView image = new ImageView(this);
+// Add image to doodleView
+// Set image size and position
+// Set image contents using filename
+return image;
+}
+```
+]
+---
+.title[Implementing `addImage`]
+.body[
+```java
+private ImageView addImage(FrameLayout doodleView, String imageName, Float x, Float y, int size) {
+// Create ImageView and add it to doodleView.
+ImageView image = new ImageView(this);
+// Add image to doodleView
+doodleView.addView(image);
+
+// Set image size and position
+
+// Set image contents using filename
+return image;
+}
+```
+]
+---
+.title[Implementing `addImage`]
+.body[
+```java
+private ImageView addImage(FrameLayout doodleView, String imageName, Float x, Float y, int size) {
+// Create ImageView and add it to doodleView.
+ImageView image = new ImageView(this);
+// Add image to doodleView
+doodleView.addView(image);
+
+// Set image size
+image.getLayoutParams().height = size;
+image.getLayoutParams().width = size;
+
+// Set image position ?
+
+// Set image contents using filename
+return image;
+}
+```
+]
+
+---
+.title[Breakout Room Discussion]
+.body[
+
+<iframe src="https://embed.polleverywhere.com/multiple_choice_polls/d8jYLjVJq9Lp6MlCMl0XZ?controls=none&short_poll=true" width="800" height="600" frameBorder="0"></iframe>
+
+]
+
+<!--
+.title[Implementing `addImage`]
+.body[
+```java
+private ImageView addImage(FrameLayout doodleView, String imageName, Float x, Float y, int size) {
+// Create ImageView and add it to doodleView.
+ImageView image = new ImageView(this);
+doodleView.addView(image);
+
+image.getLayoutParams().height = size;
+image.getLayoutParams().width = size;
+image.setX(x);
+image.setY(y);
+
+// Set image contents using filename
+return image;
+}
+```
+]
+-->
+
+---
+.title[Implementing `addImage`]
+.body[
+```java
+private ImageView addImage(FrameLayout doodleView, String imageName, Float x, Float y, int size) {
+// Create ImageView and add it to doodleView.
+ImageView image = new ImageView(this);
+// Add image to doodleView
+doodleView.addView(image);
+
+// Set image size
+image.getLayoutParams().height = size;
+image.getLayoutParams().width = size;
+
+// Set image position ?
+
+// Set image contents using filename
+int resID = getResources().getIdentifier(imageName, "drawable", getPackage());
+image.setImageResource(resID);
+return image;
+}
+```
+]
+
+---
+.title[Android Debugging Tips]
+.body[
+
+Resource: [https://developer.android.com/studio/debug](https://developer.android.com/studio/debug)
+
+]
+
+<!---
+## `ValueAnimator`
+
+- Keeps track of the animation's timing (how long its been running and current value of property)
+
+- Contains a `TimeInterpolator` that defines the type of interpolation for the value over time
+
+- Contains a `TypeEvaluator` that figures out how to calculate values for the property being animated
+
+```java
+ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
+animation.setDuration(1000);
+// Starts the animation
+animation.start();
+// TODO: need to listen for updates to get the returned value
+```
+-->
+<!--
+.title[How do we use pacing functions for this?]
+.body[
+![:img Picture of a curve transforming motion over time to create a pacing
+effect, 40%](img/pacing.png)
+
+- Time normalized with respect to animation interval (0...1)
+- Normalized time is transformed by pacing function (0…1)
+- Paced value is then fed to curve function to get final value
+
+] -->
+<!--
+.title[XML shown in class]
+.body[
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <objectAnimator android:propertyName="x" android:valueTo="100" />
+</set>
+```
+]
+-->
+<!--
+```java
+package com.example.myapplication;
+//imports...
+
+public class MainActivity extends AppCompatActivity {
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+super.onCreate(savedInstanceState);
+ImageView view = new ImageView(this);
+setContentView(view);
+
+Bitmap bitmap = Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888);
+view.setImageBitmap(bitmap);
+Canvas c = new Canvas(bitmap);
+Paint p = new Paint();
+c.drawCircle(10,10,5,p);
+
+ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f);
+anim.setDuration(2000);
+anim.start();
+
+Animator anim2 = (Animator) AnimatorInflater.loadAnimator(this,
+R.animator.sample);
+anim2.setTarget(view);
+anim2.setDuration(2000);
+anim2.start();
+}
+}
+```
+-->
\ No newline at end of file
diff --git a/slides/l01/gitgrade.html b/slides/l01/gitgrade.html
new file mode 100644
index 0000000000000000000000000000000000000000..a6c9f64a35133b1599bedcf121e5a557f53b2b55
--- /dev/null
+++ b/slides/l01/gitgrade.html
@@ -0,0 +1,48 @@
+---
+layout: presentation
+title: Lab 1 GitGrade Slides
+description: Introduction to GitGrade and accepting the first assignment
+class: middle, center, inverse
+---
+
+# CSE 340 Lab 1: GitGrade (Spring 2020)
+
+## Introduction to course infastructure
+![:img GitGrade Logo, 20%](img/gitgrade_square.png)
+
+---
+## What is GitGrade?
+
+GitGrade is the software we use to manage and grade programming assignments.
+
+## Why is it relevant to you?
+
+Because you will use GitGrade to `accept` the assignment, in order to generate a GitLab repository with starter code.
+
+You will also `turn-in` the assignment using GitGrade by registering a commit as your submission.
+
+---
+## What are we doing with it today?
+
+We're going to `accept` the first assignment (`as1-doodle`) and clone the generated repository.
+
+Start by navigating to
+[https://gitgrade.cs.washington.edu/student/assignment/116](https://gitgrade.cs.washington.edu/student/assignment/116).
+This link is available on the course website, on the `Doodle` assignment page.
+
+You will need to login with your CSE GitLab credentials.
+---
+## Accepting the assignment
+
+Accept the assignment, and navigate to the generated GitLab repository of the name
+`cse340-20wi-students/as1-doodle-NETID`
+
+![:img screenshot of GitLab accept assignmet page with a large button labeled "Accept Assignment",
+90%](img/accept-screencap.png)
+
+---
+## Turning in the assignment
+- Through GitGrade, link on the Doodle page on the course website (accept link + `/turnin`)
+- Recommended to visit the turnin page ahead of time to read the **nuances and details**
+- Late Day Policy: 3 late days, no partial usage. Applied whenever something is turned in late until you run out.
+- If something is late, and you have no late days: `score -= (10% * unexcused days late)`
\ No newline at end of file
diff --git a/slides/l01/hello.html b/slides/l01/hello.html
new file mode 100644
index 0000000000000000000000000000000000000000..46a2d2e3d1c0c31bf37ff6dc7127ebf1a703e268
--- /dev/null
+++ b/slides/l01/hello.html
@@ -0,0 +1,216 @@
+---
+layout: presentation
+title: Lab 1 Slides
+description: Lab project--Hello World--
+class: middle, center, inverse
+---
+
+# CSE 340 Lab 1 (Spring 2020)
+## Week 1: Getting Started With Android Development
+
+.title-slide-logo[
+![Android Logo](img/android-logo.png)
+]
+
+---
+
+## Course Objectives
+- Practical applications for learnings in lecture
+
+
+- Understand design considerations when making mobile apps
+
+
+- Design and implement basic Android applications
+
+
+- Debugging in Java and for Android
+
+---
+
+## Lab 1 Objectives
+
+- Introduce the building blocks of Android applications
+
+
+<!-- - Obtain the course repository -->
+
+
+- Explore an Android project folder
+
+
+- Getting the first part of the Doodle started
+
+
+- Show some basic Android debugging techniques
+
+---
+## Android Applications
+
+__Components__
+
+- Activity
+- Service
+- Broadcast Receiver
+- Content Providers
+
+__Intents__
+
+- Launch components (and provide them with data)
+- Not limited to components of the same app
+- Meaning: your components can be started by intents from other applications
+
+
+---
+## Activity
+[`android.app.Activity`](https://developer.android.com/reference/android/app/Activity)
+
+- Represents a single interface
+
+- Example: Activities for Gmail App
+- Inbox, Message Compose, Spam Folder, etc.
+
+- Activities can be started by other applications, if desired
+- E.g., sharing a photo by email starts Gmail's Message Compose activity
+
+---
+## Activity
+
+.center[
+![:img Activity Lifecycle, 40%](img/activity_lifecycle.png)
+]
+
+---
+## Service
+[`android.app.Service`](https://developer.android.com/reference/android/app/Service)
+
+
+- Entry point for background processes
+
+
+- Example: Spotify's player activity uses a service to play music
+- Could be done by activity alone
+
+- Use of a service allows music to continue when player activity is no longer in the foreground
+
+- Services may be killed and restarted as required by the OS
+- A persistent service such as music playback may use a persistent notification to prevent this
+
+---
+## Broadcast Receivers
+[`android.content.BroadcastReceiver`](https://developer.android.com/reference/android/content/BroadcastReceiver.html)
+
+
+- Entry point for events outside of regular userflow
+
+
+- Example: Alarms
+- Application schedules callback with OS in 10 minutes
+
+- In the meantime, the application can be killed
+
+- 10 minutes later, the OS broadcasts the callback event to the app
+
+- App begins playing sound; vibrating
+
+---
+## Content Providers
+[`android.content.ContentProvider`](https://developer.android.com/reference/android/content/ContentProvider)
+
+
+- Persistent storage of data
+
+
+- Supports multiple backends, depending on app permissions
+- Local filesystem, web, SQLite DB, etc.
+
+- Can permit access to other applications
+- Contacts can be read and written to by other apps, depending on permissions
+
+<!---
+## Obtaining the Course repository
+
+- After [accepting the assignment](https://courses.cs.washington.edu/courses/cse340/20sp/slides/l01/gitgrade.html#1), go to Gitlab
+
+- If you do not have SSH set up with Gitlab, just download the zip for now
+
+- Later: ['Set up an SSH key with
+Gitlab'](https://gitlab.cs.washington.edu/help/ssh/README#generating-a-new-ssh-key-pair)
+
+- Once you have SSH set up, clone the repository -- will show after section -->
+
+---
+## Android Project Structure
+
+.center[
+![:img Android Project Structure, 30%](img/android_project_structure.png)
+]
+
+---
+
+## Android Project Structure
+
+`app/src/main/AndroidManifest.xml`
+
+- Describes application at a high level for both compilation and running
+- Includes app package, components, permissions, and hardware features
+
+
+
+`app/src/main/java/com.example.myapp/MainActivity.java`
+
+- The main activity activated when application launches
+
+
+
+`app/build.gradle`
+
+- Android build tool configuration file
+- Includes target and min SDK versions and dependencies
+
+
+`app/src/main/res/layout/activity_main.xml`
+
+- Declares the views and layout of the main activity
+
+---
+## Android Project Structure
+
+`drawable-<density>/`
+
+  - Images at various pixel densities to accommodate various display resolutions
+  - Keep filenames consistent between folders
+
+
+`layout/`
+
+  - Layout XML description files for application activities
+
+
+`mipmap/`
+
+  - Launcher icons for your application at various sizes and shapes
+
+
+`values/`
+
+  - A good place to store constants
+  - Density-independent pixel values (sizes)
+  - Color
+  - Good for string localization as well
+  - Storing strings here makes it much easier to add additional languages in the future!
+
+---
+
+  ## Resources
+
+  - Vogella Tutorials -
+  - Android Animation - http://www.vogella.com/tutorials/AndroidAnimation/article.html
+
+  - Android Developer
+  - View Animation - https://developer.android.com/guide/topics/graphics/view-animation.html
+  - Property Animation - https://developer.android.com/guide/topics/graphics/prop-animation.html
+
+  - Relevant supplemental material is provided on the course website
+  - Listed in the schedule
+  - This week's supplemental material reviews Java, covers Android animation
\ No newline at end of file
diff --git a/slides/l01/img/accept-screencap.png b/slides/l01/img/accept-screencap.png
new file mode 100644
index 0000000000000000000000000000000000000000..d4c9bd30025ebc9f8cde44d3caacb229b3934d7e
Binary files /dev/null and b/slides/l01/img/accept-screencap.png differ
diff --git a/slides/l01/img/activity_lifecycle.png b/slides/l01/img/activity_lifecycle.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab0921a717d184442c96c1b8863018d46920a67c
Binary files /dev/null and b/slides/l01/img/activity_lifecycle.png differ
diff --git a/slides/l01/img/android-logo.png b/slides/l01/img/android-logo.png
new file mode 100755
index 0000000000000000000000000000000000000000..cebec75001ab25dc397065f193797d5ebd0cb38d
Binary files /dev/null and b/slides/l01/img/android-logo.png differ
diff --git a/slides/l01/img/android-versions-oct2018.png b/slides/l01/img/android-versions-oct2018.png
new file mode 100644
index 0000000000000000000000000000000000000000..0317a23481dd904945e70c60790755ac28b2ae69
Binary files /dev/null and b/slides/l01/img/android-versions-oct2018.png differ
diff --git a/slides/l01/img/android_project_structure.png b/slides/l01/img/android_project_structure.png
new file mode 100644
index 0000000000000000000000000000000000000000..60efcf057b7240f6c29e09b5e09edcad52b64174
Binary files /dev/null and b/slides/l01/img/android_project_structure.png differ
diff --git a/slides/l01/img/doodle-clone-1.png b/slides/l01/img/doodle-clone-1.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab06ba85fc07a7ff070816ce3d8cdae25163eac5
Binary files /dev/null and b/slides/l01/img/doodle-clone-1.png differ
diff --git a/slides/l01/img/doodle-clone-2.png b/slides/l01/img/doodle-clone-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..1fc9275e26732ebb178c482500cfb16d21d1eac6
Binary files /dev/null and b/slides/l01/img/doodle-clone-2.png differ
diff --git a/slides/l01/img/gitgrade_square.png b/slides/l01/img/gitgrade_square.png
new file mode 100644
index 0000000000000000000000000000000000000000..300617b81c276855f685524efb55670492c4ac7a
Binary files /dev/null and b/slides/l01/img/gitgrade_square.png differ
diff --git a/slides/l01/img/instagram-example.png b/slides/l01/img/instagram-example.png
new file mode 100755
index 0000000000000000000000000000000000000000..0094d142321dde64b7a627634d2e619e8cca0e1f
Binary files /dev/null and b/slides/l01/img/instagram-example.png differ
diff --git a/slides/l01/img/mvp-design-pattern.png b/slides/l01/img/mvp-design-pattern.png
new file mode 100755
index 0000000000000000000000000000000000000000..9dd87a7f4c12553e619856dd300b307ae9e7b449
Binary files /dev/null and b/slides/l01/img/mvp-design-pattern.png differ
diff --git a/slides/l01/img/pacing.png b/slides/l01/img/pacing.png
new file mode 100644
index 0000000000000000000000000000000000000000..3997cf6fd6aeee192b83ddd549982c9fb8c857a2
Binary files /dev/null and b/slides/l01/img/pacing.png differ
diff --git a/slides/l01/notes-sp19.txt b/slides/l01/notes-sp19.txt
new file mode 100644
index 0000000000000000000000000000000000000000..978318b631574c4e5e832b3e276016df849eb000
--- /dev/null
+++ b/slides/l01/notes-sp19.txt
@@ -0,0 +1,146 @@
+Introduction - 2 minutes
+   - Welcome to CSE 340
+   - Over the duration of this course, you will be applying your learnings from
+   lecture in a very practical way
+      - This means
+         - not only understanding what to consider when building mobile apps
+         - but also designing and implementing your own Android apps
+   - With that goal in mind, we will use our time in lab today to start exploring
+   Android app development
+      - I will introduce you to the building blocks of Android applications
+      - After obtaining the course repository
+         - we will explore the android project folder
+         - I will show some basic Android debugging techniques
+
+
+
+
+Android Application Components - 7 minutes
+- Applications are comprised of a variety of components.
+   - These components are activities, services, broadcast receivers, and content providers
+
+- Components are activated with objects called intents
+   - These intents provide the components with data. 
+   - Intents are not limited to components of the same application,
+   so your components can actually be activated by intents from other applications.
+      - Personal example: for an internship I was kicking off a workflow
+      on an Amazon Echo where we would play a series of audio pieces, record them,
+      and then analyze them. For that, I defined the intent in the Android manifest,
+      and then supplied the intent over a command line with arguments like which audio
+      files to play, how long to record for, etc.
+
+- Activities represent single screens with a user interface
+   - Gmail has different activities for composing your message, looking at your inbox,
+   accessing your settings, etc.
+   - <Walk through example workflow>
+      - This diagram is a toolkit architecture.
+
+- Services are components that perform operations in the background that don't provide
+a user interface.
+   - For example, Spotify's player activity is where you select what music to play,
+   but its player service is what actually places the music. This is why you can
+   navigate your phone freely when you use Spotify.
+   - In my project, the Intent kicked off a service that would fetch audio from the cloud,
+   play it, and calibrate it. There was no user interface because the device was an Amazon Echo.
+   - Of course, it's the OS's prerogative to impact the life of a service instance. 
+
+- Broadcast Receivers are entry points for events outside of the regular user workflow.
+   - Registers system or application events using the publish-subscribe model.
+   - When an interesting event happens, a broadcast is sent.
+   - Individual apps can register to receive specific broadcasts.
+   - For example, an alarm app can register a callback with the OS for x time. Then,
+   when the time comes, the OS sends a broadcast to the alarm app to wake it up, and the
+   alarm starts ringing.
+   - Think of it as a messaging system between apps outside of the user workflow.
+
+- Content Providers are the interfaces for managing persistent data.
+   - For example you could have a Content Provider manage writing data to the local filesystem
+   or the cloud.
+   - You can manage other applications' interactions with your data.
+      - For example, the messenger app interacts with a content provider to look at your
+      contacts list on your phone if you give it permission. 
+
+
+
+
+
+Obtaining the Course Repository - Give them 5 minutes to obtain and peruse
+the repository
+
+- Make it private
+
+
+
+
+
+Ask two people if they noticed any files that stood out in particular
+and why those files stood out - 3 minutes
+
+
+
+
+
+
+Move through important files together - 5 minutes
+
+- The Android Manifest describes the application at a high level.
+   - Identifies the name of the application package
+   - Describes all the components of the app.
+   - Lists any permissions the application would need, as well
+   as any hardware or software the app depends on to compile and run
+      - For example, if the app needs permission to write to the disk,
+      that information would be here
+      - Notice that the Part1Activity activity is described here as accepting
+      intent for the Main action with category Launcher. This means that this
+      activity is the main activity that is activated when launching the app.
+
+- The MainActivity java file sets the behavior of the main acitivity of the
+application. For us, the Main activity is Part1Activity.java
+   - Here in Doodler we see the OnCreate method, which is run whenever an Activity
+   is launched.
+      - Our OnCreate calls other methods, like addText, addLine, and addImage, that you
+      will implement.
+
+- The build.gradle file configures the build for the application
+   - Describes the minimum SDK versions and technical dependencies the project will depend on.
+
+- The resources folder contains additional files and static content that the code will use.
+   - Things like images, static data files, and even activity layouts and global
+   constants can be described here.
+      - One interesting thing about Android development is that depending on your needs
+      you can implement functionality either in your code files or in your resources folder.
+
+- The activity_main.xml file declares the views and the layout of the main activity.
+   - Layouts in Android are in XML. 
+      - If you've ever done HTML development, this should
+      be familiar to you. 
+      - Components in your view are structured like a tree, where each
+      component is described relative its parent.
+         - In Doodle, we see that right now our outermost container is ConstraintLayout,
+         and inside that is a FrameLayout whose height and width are set to match the parent.
+
+- The drawable folders contain the images for the application.
+   - The different folders are for accomodating various display resolutions.
+
+- The layout folder holds the XML files describing the layouts of the different
+activities in the program.
+   - In our application, there's only the main activity's xml layout, but additional
+   layouts can go here as well.
+
+- The mipmap folders contain the launcher icons for the application for a variety
+of screen sizes and shapes.
+
+- The values folder is a good place to store global static constant values
+   - e.g. strings
+
+
+- Go over debugging - 5 minutes
+   - Breakpoints, the android studio debugger
+   - Logging
+
+
+- 22 minutes - work on Doodle
+   - Working on Doodle addImage
+
+Discussion in general:
+   - Learning a toolkit is hard - need to explore
\ No newline at end of file
diff --git a/slides/l01/notes-wi20.txt b/slides/l01/notes-wi20.txt
new file mode 100644
index 0000000000000000000000000000000000000000..22ebd968d757c5f51f95d5bd51ae5d5ea02304d4
--- /dev/null
+++ b/slides/l01/notes-wi20.txt
@@ -0,0 +1,45 @@
+TODO:
+ - update assignment accept link in gitgrade slides
+ - add assignment accept and turn-in links to assignment page
+
+Issues:
+ - not sure how doable the addImage without handholding the entire thing / showing them the code
+
+ total structured time: 37min
+ total unstructured time: 23min
+
+Introduction - 10 minutes
+   - Welcome to CSE 340
+   - Introduce ourselves!
+   - notes on how section works, teachers changing
+
+   - Talk about nametags, hand out nametags
+   - Plug Java Refresher Lab 5.30 @ CSE1 403
+
+   - Over the duration of this course, you will be applying your learnings from
+   lecture in a very practical way
+      - This means
+         - not only understanding what to consider when building mobile apps
+         - but also designing and implementing Android apps
+   - With that goal in mind, we will use our time in lab today to start exploring
+   Android app development
+      - We'll accept the first assignment, Doodle
+      - Clone the repository to our local devices
+      - Explore the structure and pieces of an Android project
+      - Complete the first part of the assignment
+
+Android apps happen on phones, if you want to get a phone instead here are our recommendations
+(Sophie, 7min)
+
+GitLab Intro (using the GitLab deck) - 10min
+
+Intro to Doodle
+    - open the assignment spec and walk through it quickly: 5min
+    - open the repo in Android Studio and talk through important files: 5min
+        - activities
+        - layouts
+    - talk through the addImage line: 5min
+    - let students work on Doodle for remaining time
+
+
+
diff --git a/slides/l02/animation.html b/slides/l02/animation.html
new file mode 100644
index 0000000000000000000000000000000000000000..3141f5ddcce3009b19e38047aba60d1bfb885afb
--- /dev/null
+++ b/slides/l02/animation.html
@@ -0,0 +1,157 @@
+---
+layout: presentation
+title: Lab 2 Slides
+description: Lab project--Doodle--
+---
+
+# CSE 340 Lab 2 (Spring 2020)
+## Week 2: Get Help with Doodle
+
+.title-slide-logo[
+  ![Android Logo](img/android-logo.png)
+]
+
+---
+
+# Doodle Timeline
+
+- Doodle Due: Thursday, April 9 @ 10:00pm (**Today!**)
+
+- Lock: Saturday, April 11 @ 10:00pm (If you are using late days)
+
+- Peer Eval: Sunday, April 12 - Tuesday, April 14 @ 10:00pm
+
+- Reflection: Wednesday, April 15 @ 10:00pm
+
+---
+
+# Lab 2 Objectives
+
+- Go through peer evaluation and reflection
+
+
+- How to debug in Android
+
+
+- Android Animation
+
+---
+
+# Lab 2 After Implementation
+
+- Peer evaluation - fill the survey that we send out
+
+- The best ones will show off in class
+
+
+- Part 3: Turn in reflection on Gradescope after peer evaluation
+
+---
+# Peer Evaluation
+- Why?
+  - Chance to externalize your work
+  - Get user feedback (the user experience is after all the point of HCI)
+
+- What to expect  
+  - Your grade won't be determined by peer evaluating alone
+  - You get credit for **doing** the peer evaluation
+  - Questions about spec requirements -- no room for interpretation
+  - Questions that prompt about subjective feedback
+    - Provide constructive feedback
+  - Anonymous to your peers (but not to the teaching staff)
+
+- Your feedback on the exercise! (be honest)
+
+---
+
+# Peer Evaluation Practice
+
+- Download the apk file: https://tinyurl.com/wdgjkcu
+
+- Google form: https://tinyurl.com/DoodleTestEval (Please use your UW Net ID)
+
+---
+
+# Peer Evaluation Instructions
+
+.right-column-staff[
+- You will be assigned to peer grade 3 assignments via email
+- If you have an Android phone
+  - Click on the download link to install the app on your phone
+- If you don't have a phone
+  - Download the APK files
+  - Open the APK file in Android Studio and run the app in the emulator
+- Fill out the google form for each APK file
+]
+
+.left-column-staff[
+<img src="./img/wizard.png" alt="screenshot of Android Studio Wizard" width="40%" height="50%"/>
+]
+---
+
+# Android Debugging
+
+- Select a device to debug your app on
+- Set breakpoints in your Java, Kotlin, and C/C++ code
+- Examine variables and evaluate expressions at runtime
+
+
+- How to use Debugger: https://developer.android.com/studio/debug#java
+- Helpful tool (Logcat): https://developer.android.com/studio/debug/am-logcat#java
+
+
+---
+# Animation on Android
+
+- _Property Animation_ - preferred method; more flexible
+
+- _View Animation_ - simple setup; the old way (but you have to deal with xml...)
+
+- _Drawable Animation_ - load `Drawable` resources and display them one frame after the other (it is like a gif)
+
+
+---
+# Property Animation
+
+- Define an animate that changes on object's _property_ (a field in an object) over _a length of time_
+
+## `ValueAnimator`
+
+- Keeps track of the animation's timing (how long its been running and current value of property)
+
+```java
+ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
+animation.setDuration(1000);
+// Starts the animation
+animation.start();
+// TODO: need to listen for updates to get the returned value
+```
+
+---
+
+# `ObjectAnimator` (the one you need in this assignment)
+
+- Rather than listening for a value, we can simply directly animate a property on an object
+
+- **However**: the property that you are animating must have a setter function (in camel case) in the form of set<propertyName>() for this to work (_setDuration()_)
+
+```java
+ObjectAnimator anim = ObjectAnimator.ofFloat(textView, "alpha", 0f, 1f);
+anim.setDuration(1000);
+anim.start();
+```
+
+---
+
+# Resources
+
+- Vogella Tutorials - http://www.vogella.com/tutorials/AndroidAnimation/article.html
+
+- Android Developer
+  - View Animation - https://developer.android.com/guide/topics/graphics/view-animation.html
+  - Property Animation - https://developer.android.com/guide/topics/graphics/prop-animation.html
+
+- Relevant supplemental material is provided on the course website
+  - Listed in the Doodle assignment
+  - Don't stress out :) this isn't required
+
diff --git a/slides/l02/animationPractice.zip b/slides/l02/animationPractice.zip
new file mode 100644
index 0000000000000000000000000000000000000000..f61898caee6a923d2664759343babc271aa24ce7
Binary files /dev/null and b/slides/l02/animationPractice.zip differ
diff --git a/slides/l02/img/activity_lifecycle.png b/slides/l02/img/activity_lifecycle.png
new file mode 100755
index 0000000000000000000000000000000000000000..879f51f6e8fafe75d267984680ef63f85b118dc5
Binary files /dev/null and b/slides/l02/img/activity_lifecycle.png differ
diff --git a/slides/l02/img/android-logo.png b/slides/l02/img/android-logo.png
new file mode 100755
index 0000000000000000000000000000000000000000..cebec75001ab25dc397065f193797d5ebd0cb38d
Binary files /dev/null and b/slides/l02/img/android-logo.png differ
diff --git a/slides/l02/img/animation/android-animate.gif b/slides/l02/img/animation/android-animate.gif
new file mode 100755
index 0000000000000000000000000000000000000000..0fb1d08fd616979b31c4390966e7c2e3410b2c4f
Binary files /dev/null and b/slides/l02/img/animation/android-animate.gif differ
diff --git a/slides/l02/img/animation/animation-linear.png b/slides/l02/img/animation/animation-linear.png
new file mode 100755
index 0000000000000000000000000000000000000000..08bd9fc3dc2ce5d151294b1d2b695a490f2e5f00
Binary files /dev/null and b/slides/l02/img/animation/animation-linear.png differ
diff --git a/slides/l02/img/animation/valueanimator.png b/slides/l02/img/animation/valueanimator.png
new file mode 100755
index 0000000000000000000000000000000000000000..6cc2a13bbfca142b090c3fec00ddf410ca82eeb5
Binary files /dev/null and b/slides/l02/img/animation/valueanimator.png differ
diff --git a/slides/l02/img/animationDemo.mov b/slides/l02/img/animationDemo.mov
new file mode 100644
index 0000000000000000000000000000000000000000..a6869d9aea9806463e59f8fd6266d3b48a8819f7
Binary files /dev/null and b/slides/l02/img/animationDemo.mov differ
diff --git a/slides/l02/img/animationPractice.zip b/slides/l02/img/animationPractice.zip
new file mode 100644
index 0000000000000000000000000000000000000000..f61898caee6a923d2664759343babc271aa24ce7
Binary files /dev/null and b/slides/l02/img/animationPractice.zip differ
diff --git a/slides/l02/img/anydo-example.png b/slides/l02/img/anydo-example.png
new file mode 100755
index 0000000000000000000000000000000000000000..ad9958b541d2a3cce7890b7f8156ebf84bb7cfd0
Binary files /dev/null and b/slides/l02/img/anydo-example.png differ
diff --git a/slides/l02/img/first-android-project-structure.png b/slides/l02/img/first-android-project-structure.png
new file mode 100755
index 0000000000000000000000000000000000000000..8a63e70e71075cbd6963baa58fc9eb4e52bbe1ea
Binary files /dev/null and b/slides/l02/img/first-android-project-structure.png differ
diff --git a/slides/l02/img/instagram-example.png b/slides/l02/img/instagram-example.png
new file mode 100755
index 0000000000000000000000000000000000000000..0094d142321dde64b7a627634d2e619e8cca0e1f
Binary files /dev/null and b/slides/l02/img/instagram-example.png differ
diff --git a/slides/l02/img/wizard.png b/slides/l02/img/wizard.png
new file mode 100644
index 0000000000000000000000000000000000000000..8ecaad5256c117e6ab7c93b93e5b61818a57950f
Binary files /dev/null and b/slides/l02/img/wizard.png differ
diff --git a/slides/l03/img/LayoutSpec.png b/slides/l03/img/LayoutSpec.png
new file mode 100644
index 0000000000000000000000000000000000000000..d35a62e29abba453847a525fc4eba2956e1d34d2
Binary files /dev/null and b/slides/l03/img/LayoutSpec.png differ
diff --git a/slides/l03/img/android-linear.png b/slides/l03/img/android-linear.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b252da67203bb2e57a21a65c2b442d1e7e14a9d
Binary files /dev/null and b/slides/l03/img/android-linear.png differ
diff --git a/slides/l03/img/constraint-editor.png b/slides/l03/img/constraint-editor.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb898264dbb375ea8f1fe36aa38180cf76f5ceee
Binary files /dev/null and b/slides/l03/img/constraint-editor.png differ
diff --git a/slides/l03/img/design-view.png b/slides/l03/img/design-view.png
new file mode 100644
index 0000000000000000000000000000000000000000..76f63830d1dbd0e0388c6ce7f57bd2b3d7618db9
Binary files /dev/null and b/slides/l03/img/design-view.png differ
diff --git a/slides/l03/img/exam-q-sol.png b/slides/l03/img/exam-q-sol.png
new file mode 100644
index 0000000000000000000000000000000000000000..047f349edee6bc6236c21e774ef2d7febef9ff0e
Binary files /dev/null and b/slides/l03/img/exam-q-sol.png differ
diff --git a/slides/l03/img/interactor-hierarchy.png b/slides/l03/img/interactor-hierarchy.png
new file mode 100644
index 0000000000000000000000000000000000000000..bd0a91b5f82c8810b45ea4c661fe9fda6e68e311
Binary files /dev/null and b/slides/l03/img/interactor-hierarchy.png differ
diff --git a/slides/l03/img/pinterest-android.png b/slides/l03/img/pinterest-android.png
new file mode 100644
index 0000000000000000000000000000000000000000..b07ff8eb6c83c79e5b44007a16da7d1b47c88536
Binary files /dev/null and b/slides/l03/img/pinterest-android.png differ
diff --git a/slides/l03/img/watch3.png b/slides/l03/img/watch3.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce7134c4b0c57883931335e40fef086a366e7294
Binary files /dev/null and b/slides/l03/img/watch3.png differ
diff --git a/slides/l03/img/xmlvsjava.png b/slides/l03/img/xmlvsjava.png
new file mode 100644
index 0000000000000000000000000000000000000000..62b80b16d6c1c2cb1779fc42a1928e42e1aa7aaa
Binary files /dev/null and b/slides/l03/img/xmlvsjava.png differ
diff --git a/slides/l03/layout.html b/slides/l03/layout.html
new file mode 100644
index 0000000000000000000000000000000000000000..0b49a4fe99589f60d698eaea59b0257965b83584
--- /dev/null
+++ b/slides/l03/layout.html
@@ -0,0 +1,278 @@
+---
+layout: presentation
+title: Lab 3 Slides
+description: Lab project--Layout--
+---
+
+# CSE 340 Lab 3 (Spring 2020)
+## Week 3: Layout
+
+.title-slide-logo[
+  ![Android Logo](img/android-linear.png)
+]
+
+---
+
+# Layout Timeline
+
+- Layout part 1-2 due: Tomorrow @ 10:00pm (No late days allowed)
+
+- Layout part 3-4 and Reflection due:  Next Thursday, April 23 @ 10:00pm
+  - Lock: Saturday, April 25 @ 10:00pm (If you are using late days)
+
+
+<!-- # Reflection?
+
+- What did you learn from doing Part4?
+
+- Was there anything that was surprisingly easy or hard?
+
+- Include your diagram of the interactor hierarchy and the corresponding interface. -->
+
+---
+
+# Instruction for turning in Layout part 3-4
+
+- **(Important!)** You will have to accept the Layout Part 3-4 at Gitgrade before you turn in
+
+- Track your acceptance/ submission of all assignments: https://gitgrade.cs.washington.edu/student/summary/8723
+
+- Work in the same repo as Part 1-2
+
+---
+# Section 3 Objectives
+
+- User Interfaces on Android
+  - ConstraintLayout
+  - Interactor Hierarchy
+
+- `LayoutInflater`
+  - XML vs. Programmatic (Java)
+
+- Previous exam problem of Layout
+  - Worksheet: https://tinyurl.com/cse340lab3
+
+
+---
+# User Interfaces on Android
+.left-column-half[
+- Views
+  - Base class for __all__ UI elements
+  - Interactors (e.g buttons, labels, image views, etc)
+- ViewGroups
+  - Encapsulates one or more views (e.g. Android Components, **Layouts**)
+  - Can define specific **layout** properties
+- Layout
+  - Defines the structure for the user interface (UI) of your app
+  - View and ViewGroup objects live within Layouts
+  - We will use the word *Components* to include both layout components and interactors (Views) since you don't generally "interact" with layouts
+]
+
+.right-column-half[
+<div class="mermaid">
+graph TD
+W(ViewGroup) --> V[ViewGroup]
+W --> V1[View]
+W --> V2[View]
+V --> V3[View]
+V --> V4[View]
+V --> V5[View]
+
+classDef blue font-size:14pt,text-align:center
+classDef darkblue font-size:14pt,text-align:center
+
+class W,V darkblue
+class V1,V2,V3,V4,V5 blue
+</div>]
+
+---
+# Layout in Android
+Where we left off: "Many layout and other attributes for components. You should explore!"
+
+![:img Picture of the whole android layout interface showing the possible components that can be added; the component tree (interactor hierarchy; and the attributes for the Save Button; which is selected, 90%](img/design-view.png)
+
+---
+# Layout Types in Android
+
+- [FrameLayout](https://developer.android.com/reference/android/component/FrameLayout.html) - good for position views on
+top of each other, or encapsulating a bunch of views. Used in [Doodle](/assignments/doodle).
+
+- [__LinearLayout__](https://developer.android.com/reference/android/component/LinearLayout.html) - places views one after
+the other in order according to the orientation (Horizontal or Vertical). Used in [Layout](/assignments/layout).
+
+- [__RelativeLayout__](https://developer.android.com/reference/android/widget/RelativeLayout) - Positions of the children
+are desribed in relation to one another
+
+- [__TableLayout__](https://developer.android.com/reference/android/component/TableLayout.html) - Rows and columns style
+way of declaring a layout
+
+- [GridLayout](https://developer.android.com/reference/android/component/GridLayout.html) - Uses
+an [*adapter*](https://developer.android.com/reference/android/interactor/Adapter.html) that provides items to display in
+a grid
+
+- [ConstraintLayout](https://developer.android.com/reference/android/component/ConstraintLayout.html) Let's you use constraints to specify how things should lay out. Used in [Layout](/assignments/layout).
+
+
+- More on https://developer.android.com/guide/topics/ui/declaring-layout.html
+
+<!--
+
+
+# What is LayoutInflater? -->
+
+---
+# Constraint Layout
+.left-column-half[
+
+![:img A simple layout on an android watch with a textview and two
+buttons (save and discard) and the constraints highlighted,70%](img/constraint-editor.png)
+]
+.right-column-half[
+- ConstraintLayout is a ViewGroup that allows you to position widgets in a flexible way
+- Useful for building responsive interfaces in Android.
+- You can see little lines connecting the `textView` to its container and it's sibling (the `linearLayout`).
+  - This specifies how it's attached (can change type by clicking on right)
+  - If you were to change the interface (e.g. a different sized screen), it would stay attached and keep filling the space
+  - All ends up in XML you can explore too
+]
+
+
+---
+# What are  Constraints?
+.left-column[
+![:img A simple layout on an android watch with a textview and two
+buttons (save and discard) and the constraints highlighted,110%](img/watch3.png)]
+.right-column[
+
+- Very general
+- Can reproduce most other things
+- Can operate on multiple axes
+- Can enhance other layout options
+
+]
+
+---
+
+# Worksheet: Interactor Hierarchy
+
+What would be the Component Tree for the Layout Part 1-2 program?
+
+.left-column-half[
+  ![:img diagram of the interactor hierarchy shown on the next slide in graphic form, 50%](img/LayoutSpec.png)
+]
+
+
+--
+.right-column-half[
+<div class="mermaid" style="font-size: small;">
+graph TD
+LL(LinearLayout) --> S[StatusBar]
+LL --> RL[RelativeLayout]
+RL --> SV[ScrollView]
+RL --> BN[BottomNav]
+SV --> CL[ConstraintLayout]
+CL --> V2[ImageView]
+CL --> V3[...]
+CL --> V4[ImageView]
+
+
+class LL,RL,SV,CL darkblue
+class S,SV,BN,V2,V3,V4 blue
+</div>
+]
+
+---
+
+# LayoutInflater
+
+- Accepts a valid XML file and converts it into a `View` object or interactor hierarchy.
+
+- In Part 3 you will code part of it in an XML file and the rest programmatically (Java).
+
+- Why? (Discuss about pros and cons of constructing layout with XML and programmatically)
+
+---
+
+# XML vs. Programmatic (Java)
+
+.left-column-half[
+- XML is easier setting up the Layouts
+
+- XML shows the Layouts directly
+
+- XML can be inflated many times
+]
+
+.right-column-half[
+![XML vs Programmatic Java](img/xmlvsjava.png)
+]
+---
+
+# XML vs. Programmatic (Java)
+
+- Programmatic is easier adding items to the Layouts
+
+- Programmatic can use loops
+
+- Sample solution of adding items into Layout in Part 1 (XML) has 55 lines
+
+- Sample solution of adding items into Layout in Part 2 (Java) has 17 lines
+
+
+---
+
+# How do we use the LayoutInflater?
+
+1. Setting up the LayoutInflater
+```java
+// Obtains the LayoutInflater from the given context
+LayoutInflater.from(Context context)
+```
+
+2. Inflate
+```java
+// Inflate a new view hierarchy from the specified XML resource
+inflate(int resource, ViewGroup root)
+```
+
+---
+# Worksheet: Quick Exercise
+
+Construct a LayoutInflater and pass in the `part1.xml` file.
+
+---
+
+# Quick Exercise Solution
+
+```java
+public Part1View(Context context, List<String> imageNames, int vMargin) {
+// Obtain the inflater from the context
+LayoutInflater inflater = LayoutInflater.from(context);
+
+// Inflate R.layout.part1 
+View newView = inflater.inflate(R.layout.part1, null); // newView is at the root of the inflated tree
+
+// Add it to this view
+this.addView(newView);
+}
+```
+
+---
+
+# Previous Exam Question
+
+---
+
+# Solution
+
+**What is the basic idea you have for how to fix it?**
+
+> Constrain the top of the scroll to the bottom of the text view.
+
+**Which view would you need to modify (provide the value you would set `android:id` to)?**
+
+> `@+id/scrollView`
+
+**What one line of XML would you add? Pseudocode ok here, you don't have to use exact names.**
+
+> `app:layout_constraintTop_toBottomOf="@id/textView"`
diff --git a/slides/l04/accessibility.html b/slides/l04/accessibility.html
new file mode 100644
index 0000000000000000000000000000000000000000..9f6f39b0cbf4891b646bcc8ad8bca50d2f2f780d
--- /dev/null
+++ b/slides/l04/accessibility.html
@@ -0,0 +1,110 @@
+---
+layout: presentation
+title: Lab 04 Slides
+description: Layout and Accessibility
+class: middle, center, inverse
+---
+# CSE 340 Lab 4 (Spring 2020)
+
+## Week 4: Accessibility
+
+.title-slide-logo[
+  ![Accessibility Logo](img/cover.jpg)
+]
+
+---
+
+# Assignment Timeline
+
+- Layout part 3-4 and Reflection due: ~~Today, April 23~~ Tomorrow, April 24 @ 10:00pm
+  - Lock: Saturday, April 25 @ 10:00pm (If you are using late days)
+
+- No peer evaluation for this assignment
+
+- Accessibility assignment out: Yesterday, April 22 - due: Next Thursday, April 30
+
+<!--
+
+# Reflection
+
+- Include a screen shot of the interface you are emulating in your reflection
+
+- Include a screenshot of the result of your implementation in your reflection
+
+- Also include your diagram of the interactor hierarchy and the corresponding interface.
+
+- Tell us: What did you learn from doing Part 4?
+
+- Tell us: Was there anything that was surprisingly easy or hard? -->
+
+---
+# Section 4 Objectives
+
+- Get ready for Accessibity Assignment
+- What is Alt Text?
+- Accesibity in designing technology
+- Discussion: What does inclusion mean to you?
+
+
+---
+
+# Get ready for Accessibity Assignment
+
+- Install Accessibility Scanner on Emulator (through Google Play)
+  - https://play.google.com/store/apps/details?id=com.google.android.apps.accessibility.auditor&hl=en_US
+
+---
+
+# Alt Text
+
+- What is alt text, and why is it important?
+
+- Adding Accessibility Features to Apps for Blind and Visually-Impaired Users: https://youtu.be/1by5J7c5Vz4
+- Introduction to Alternative Text: https://webaim.org/techniques/alttext/#intro
+
+---
+
+.title-slide-logo[
+  ![Exmaple photo of Purple flowers with a fuzzy center surrounded by green leaves](img/flower.png)
+]
+
+---
+
+## Bad alt text:
+
+- This picture of flowers was taken at the Chihuly Glass Gardens
+
+## Better alt text:
+
+- Purple flowers with a fuzzy center surrounded by green leaves
+
+---
+
+# Who can alt text help? 
+
+- Not only visually impaired individuals!
+
+---
+
+# Are the captions we used in the lectures enough? 
+
+- Why?
+
+---
+
+.left-column-half[
+# ASL Gloves
+
+- Why are technologies like this harmful?
+
+- You could build bias into technology if you are not careful
+
+]
+
+.right-column-half[
+![:img These “SignAloud” gloves developed by UW sophomores Navid Azodi and Thomas Pryor translate American Sign Language into speech and text, 90%](img/asl_gloves.png)
+]
+
+---
+
+# What does inclusion mean to you?
diff --git a/slides/l04/agenda.txt b/slides/l04/agenda.txt
new file mode 100644
index 0000000000000000000000000000000000000000..76f136a1a969625bd527f42c7144e567dc3b5c16
--- /dev/null
+++ b/slides/l04/agenda.txt
@@ -0,0 +1,27 @@
+- reminder for layout assignment
+- timeline
+- layout reflection (10 mins)
+
+- alt text  (10 mins)
+- what is alt text, and why is it important?
+- who can screen reader help?
+
+- brain storm: other than alt text, what we can do for other disabilities? for example, deaf   (5-10 mins)
+-- caption: help non-native speakers
+-- captions in this class - not enough. why?
+- please do not call us "hearing impaired" (brifly explain my identity. since they call blind "visual impaired")
+- disabilities varies (i am deaf, and i dont represent blind people, i dont represent the D community)
+
+- some mindsets i have noticed in HCI:   (10 mins)
+-- asl glove (why does it hurt the community?)
+-- how to be an "ally" (please, dont say its my job to fight. Fight with me if you consider yourself an ally)
+
+- what does "inclusion" mean?   (10 mins)
+-- it mean view us as who we are
+- technology shows a mindset. And the mindset is the core. Thus, you are not only learning the technology in this class. We want you to learn the mindset as well.
+- you could build bias in technology if you are not careful
+- accessibility is always an inherent feature, not a nice addition, it should not be something you implement the last
+
+
+- ask prob questions and encourage students
+- divide groups
\ No newline at end of file
diff --git a/slides/l04/img/asl_gloves.png b/slides/l04/img/asl_gloves.png
new file mode 100644
index 0000000000000000000000000000000000000000..15e1c51fe2af35f02817cf2df4afe182189eff1a
Binary files /dev/null and b/slides/l04/img/asl_gloves.png differ
diff --git a/slides/l04/img/cover.jpg b/slides/l04/img/cover.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..0ab996615cbaba6c49d6ee41e20e0c02689a4d67
Binary files /dev/null and b/slides/l04/img/cover.jpg differ
diff --git a/slides/l04/img/flower.png b/slides/l04/img/flower.png
new file mode 100644
index 0000000000000000000000000000000000000000..acd6bc12862d864b1bedcb114d79627d59de644d
Binary files /dev/null and b/slides/l04/img/flower.png differ
diff --git a/slides/l05/img/eventDiagram.png b/slides/l05/img/eventDiagram.png
new file mode 100644
index 0000000000000000000000000000000000000000..6a73ac5e20901d48a503f43375824925b58cb921
Binary files /dev/null and b/slides/l05/img/eventDiagram.png differ
diff --git a/slides/l05/img/layout.png b/slides/l05/img/layout.png
new file mode 100644
index 0000000000000000000000000000000000000000..b6ff09630cff8240594e1550a96aa75bbd25f707
Binary files /dev/null and b/slides/l05/img/layout.png differ
diff --git a/slides/l05/img/smq.png b/slides/l05/img/smq.png
new file mode 100644
index 0000000000000000000000000000000000000000..66c0e1367260f1845bf068fe07aa5f6d5dbd959e
Binary files /dev/null and b/slides/l05/img/smq.png differ
diff --git a/slides/l05/img/smrecap.png b/slides/l05/img/smrecap.png
new file mode 100644
index 0000000000000000000000000000000000000000..9757ee308e1388fb9e687fa08d4c6d0df195c247
Binary files /dev/null and b/slides/l05/img/smrecap.png differ
diff --git a/slides/l05/img/statemachine.png b/slides/l05/img/statemachine.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d0038d95b01e30c67f13a3f5daf3f7cd9d9239c
Binary files /dev/null and b/slides/l05/img/statemachine.png differ
diff --git a/slides/l05/state.html b/slides/l05/state.html
new file mode 100644
index 0000000000000000000000000000000000000000..41717d5e47c53952a73bc56303f92ebe1a5b5421
--- /dev/null
+++ b/slides/l05/state.html
@@ -0,0 +1,105 @@
+---
+layout: presentation
+title: Lab 5 Slides
+description: State Machine
+class: middle, center, inverse
+---
+
+# CSE 340 Lab 5 (Spring 2020)
+## Week 5: State Machine
+
+.title-slide-logo[
+  ![State Machine Logo](img/statemachine.png)
+]
+
+---
+# Timeline
+- Accessibility assignment due: Today, April 30 @ 10:00pm
+  - Lock: Saturday, May 2 @ 10:00pm (if you are using late days)
+
+---
+# Section 5 Objectives
+
+- Understanding State Machine
+- Practice with PPS and State Machine
+  - Worksheet: https://tinyurl.com/340section5
+- Questions
+
+---
+# State Machine 
+
+- State Machines are used to respond to incoming events and allows for us to store state between events.
+- Start state - indicated with incoming arrow
+- End state - indicated with double-layered shape
+- Transition States - indicated with single-layered shape
+- Event Arrows - indicated with an arrow between states, represent different actions taken up states.
+
+![:img State Machine Diagram Recap, 50%](img/smrecap.png)
+
+---
+# Propositional Production System (PPS)
+
+- State machine is just the start, stop and interim states with arrows with nothing on them.
+- State machine with:
+  - ? (Boolean gates)
+  - action calls 
+  - extra conditions required to fire
+  on the arrows is called PPS.
+
+  ![:img State Machine Diagram Question, 50%](img/smq.png)
+
+---
+# State Machine Practice
+Discussion: What is the behavior of this State Machine/PPS?
+
+![:img State Machine Diagram Question, 60%](img/smq.png)
+
+---
+# Worksheet: State Machine Practice
+- Link: https://tinyurl.com/340section5
+
+---
+# Worksheet Solutions
+
+Problem 1:
+
+1. updateThumbPosition()
+2. updateVolume()
+3. INSIDE
+4. EssentialGeometry.BAR
+5. updateThumbPosition()
+6. updateVolume()
+7. State.START
+8. updateThumbAlpha()
+
+
+Read more: [How to turn the PPS into code](https://courses.cs.washington.edu/courses/cse340/20sp/docs/pps)
+
+
+---
+# Worksheet Solutions
+Problem 2:
+
+
+<div class="mermaid" style="font-size: 14pt">
+  graph TD
+  S((.)) --> A((Start))
+  A -- "DOWN:insideBar? updateButtonPosition(); 
+  updateButtonAlpha(); invokeScrollAction();
+  invalidate();" --> I((PRESSED))
+  A -- "DOWN:insideButton? updateButtonAlpha(); 
+  invokeScrollAction(); invalidate();" --> I((PRESSED))
+  I -- "UP:updateButtonAlpha(); invalidate();" --> E[End]
+  I -- "MOVE:updateButtonPosition(); invokeScrollAction(); invalidate();" --> I
+  
+  classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+  classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+  classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+  classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+  
+  class S invisible
+  class A start
+  class E finish
+  class I normal
+  
+  </div>
diff --git a/slides/l06/android-logo.png b/slides/l06/android-logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..cebec75001ab25dc397065f193797d5ebd0cb38d
Binary files /dev/null and b/slides/l06/android-logo.png differ
diff --git a/slides/l06/bundling.html b/slides/l06/bundling.html
new file mode 100644
index 0000000000000000000000000000000000000000..02c58fd4310c4c0f0110991b2c6541cd19a927f6
--- /dev/null
+++ b/slides/l06/bundling.html
@@ -0,0 +1,122 @@
+---
+layout: presentation
+title: Lab 6 Slides
+description: Bundling
+class: middle, center, inverse
+---
+
+# CSE 340 Lab 6 (Spring 2020)
+## Week 6: Bundles? Bundles!
+
+.title-slide-logo[
+  ![Android Logo](android-logo.png)
+]
+
+---
+# Timeline
+- Color Picker and Reflection due: Next Monday, May 11 @ 10:00pm
+  - Lock: Wednesday, May 13 @ 10:00pm (if you are using late days)
+
+- Practice quiz for Accessibility and Color Picker will be out: this Friday, May 8
+  - Due: Next Wednesday, May 13 @ 10:00pm
+
+- **Reminder:** Please fill out this [form](https://docs.google.com/forms/d/e/1FAIpQLSdQrpZx-gexgDcKEF1SRp4egObimDP9qqVwLD56w0V2sYJDpw/viewform) by tomorrow night, so we can plan for our next assignment - Menus.
+---
+# Section 6 Objectives
+
+- Solicit some anonymous feedback and questions
+- Bundles
+  - What're they?
+  - Why they're important
+  - How we use them (for the assignment and otherwise)
+- Questions and work time on Color Picker
+
+---
+
+# Feedback
+
+Form link: https://forms.gle/A7BBRGQGvF6J1aJ1A
+- Any questions you have about assignment/ examlet
+- Any feedback you have on section
+  - What can we do better? What is going well? 
+  - We want this to be a good use of time for you.
+
+---
+
+# Bundles: So you got lots of apps..
+
+And they all want to use _tons_ of memory, but they don't **need** that memory all the time.
+
+  - Android: You get no/minimal memory when you're not actively being used.
+  - Apps: But then how do we remember stuff when we are being used if we can't save it in memory
+  - Android: Use this `bundle`
+
+_(In truth the app could write/read its state to disk whenever it is being closed/opened but that is time consuming and would delay the OS launching new things)_
+
+---
+
+# What is a Bundle?
+
+- First what happens when the user closes the application? Does it die?
+  - No!
+
+- Where does it go then?
+  - Think about it as **hibernation**
+  - All of it's memory is cleared, so all of your variables are _GONE_ 😲.
+  - **But** Android lets you save some variables to a `bundle` right before your memory is cleared, and gives you your `bundle` back when you get the memory space back.
+
+- What's in the bundle? 
+  - You decide, entirely up to the application developer (you).
+
+_(Your bundle is destroyed if the user force quits the app through multitasking, or if the phone is turned off. There is also a max size of the bundle and likely not something you will run into)_
+
+---
+
+# Bundles & Code
+
+- Bundle management is occuring at the `activity` layer, not to be confused with any individual `view`.
+
+- When the user closes the app, right before it closes and its memory is cleared, Android invokes `onSaveInstanceState(Bundle outState)` on the activity, providing a reference to the activity for the app to save values into.
+
+- Then when the user opens the app again, Android invokes `onRestoreInstanceState(Bundle savedInstanceState)` returning the same bundle from earlier.
+
+- You can think of the `bundle` as a `Map<String, Object>` that only supports certain types of objects (they must be `Serializable` which includes all primitives and `String`)
+
+_(Read more [here](https://developer.android.com/topic/libraries/architecture/saving-states))_
+
+---
+
+# Bundles: Code Example
+
+```java
+public abstract class MainActivity extends AppCompatActivity {
+
+  @Override
+  public void onSaveInstanceState(Bundle outState) {
+      super.onSaveInstanceState(outState);
+
+      outState.putString("OUR_KEY", "bundles? bundles!!!");
+  }
+
+  @Override
+  protected void onRestoreInstanceState(Bundle savedInstanceState) {
+      super.onRestoreInstanceState(savedInstanceState);
+      
+      String whatWeSaved = savedInstanceState.getString("OUR_KEY");
+      // whatWeSaved would contain "bundles? bundles!!!"
+  }
+}
+```
+---
+# Discussion: Using Bundles in Color Picker 
+Not in this assignment but you could store the state of the Color Picker view directly into the bundle instead of storing the state of the application. 
+- Think about the model of the application
+- Think about the model of the color picker view/interactor
+- Is it better to store the state of the application or the view? 
+
+---
+
+# Work time on Color Picker
+
+- Color-Angle conversion [hints](https://docs.google.com/document/d/1p97w2eoDe8hhmhDgE9fgkO5emimfKPy-eqGvzyaeUUQ/edit?usp=sharing)
+
diff --git a/slides/l07/img/callbacks2.png b/slides/l07/img/callbacks2.png
new file mode 100644
index 0000000000000000000000000000000000000000..37eeff1f958d4f711faf7ce2af0ceb9736121957
Binary files /dev/null and b/slides/l07/img/callbacks2.png differ
diff --git a/slides/l07/img/callbacks3.png b/slides/l07/img/callbacks3.png
new file mode 100644
index 0000000000000000000000000000000000000000..c7c5e1de7d5c73ca13b8e95df99735ce5aeec7fa
Binary files /dev/null and b/slides/l07/img/callbacks3.png differ
diff --git a/slides/l07/img/listener.png b/slides/l07/img/listener.png
new file mode 100644
index 0000000000000000000000000000000000000000..30ad3eea628489302baae48acddf0b7c59ecbbab
Binary files /dev/null and b/slides/l07/img/listener.png differ
diff --git a/slides/l07/img/menus.png b/slides/l07/img/menus.png
new file mode 100644
index 0000000000000000000000000000000000000000..ae04e3b7be46c18e69c93a2b1eaa5a584d406f4f
Binary files /dev/null and b/slides/l07/img/menus.png differ
diff --git a/slides/l07/img/menussm.png b/slides/l07/img/menussm.png
new file mode 100644
index 0000000000000000000000000000000000000000..0baadcf1c31e35a4e89954c65ad3b42262832d21
Binary files /dev/null and b/slides/l07/img/menussm.png differ
diff --git a/slides/l07/img/smrecap.png b/slides/l07/img/smrecap.png
new file mode 100644
index 0000000000000000000000000000000000000000..9757ee308e1388fb9e687fa08d4c6d0df195c247
Binary files /dev/null and b/slides/l07/img/smrecap.png differ
diff --git a/slides/l07/img/tips.png b/slides/l07/img/tips.png
new file mode 100644
index 0000000000000000000000000000000000000000..6a7406ab1d2f992e5352885127fb7aa5ebe23ee3
Binary files /dev/null and b/slides/l07/img/tips.png differ
diff --git a/slides/l07/img/translate.png b/slides/l07/img/translate.png
new file mode 100644
index 0000000000000000000000000000000000000000..37fa3326c7b96cefe9e0d17c89c4fb45bf122030
Binary files /dev/null and b/slides/l07/img/translate.png differ
diff --git a/slides/l07/menus-lab.html b/slides/l07/menus-lab.html
new file mode 100644
index 0000000000000000000000000000000000000000..38438b5de4eafab0484bd7a515f23675c356cf69
--- /dev/null
+++ b/slides/l07/menus-lab.html
@@ -0,0 +1,166 @@
+---
+layout: presentation
+title: Lab 7 Slides
+description: Menus
+class: middle, center, inverse
+---
+
+# CSE 340 Lab 7 (Spring 2020)
+## Week 7: Getting started with Menus
+
+
+
+.title-slide-logo[
+  ![:img Menu Types, 50%](img/menus.png)
+]
+
+---
+
+# Menus Timeline
+
+- Programming part (Part 1-4) due: Next Wednesday, May 20 @ 10:00pm
+  - Lock: Friday, May 22 @ 10:00pm (if you are using late days)
+
+- Analysis part (Part 5-6: Report and Reflection) out: Wednesday, May 20
+  - Due: Monday, May 25 @ 10:00pm
+
+- **Examlet 3 is tomorrow!** Friday, May 15
+
+---
+
+# Section 7 Objectives
+
+- Thank you for filling out the mid-quarter section feedback form!
+- Review key concepts for Menus assignment
+  - Translate
+  - Callbacks
+  - State machine ([Lab 5](https://courses.cs.washington.edu/courses/cse340/20sp/slides/l05/state.html#1))
+- Examlet review with Kahoot 
+- Work time on Menus assignment
+- Questions
+
+---
+
+# Translate
+
+- Move origin (and everything else) in x and y
+![:img a large moon and a large moon moved to the right a few pixels, 15%](img/translate.png)
+   
+    ```java
+    translate(float dx, float dy)
+    ```
+- How do we use _translate_ in Menus?
+---
+
+# Callbacks
+
+Callbacks handle application response to events
+  - Update Application Model
+    
+    ![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface and a do_action() call
+happening below the line in response to a button_pressed(), 45%](img/callbacks2.png)
+
+
+---
+
+# Callbacks
+
+Callbacks handle application response to events
+  - Best implemented using custom listeners:
+    - Let you execute code when your view's model has changed
+    - No other way to know that has happened
+    
+    ![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface with do_action() replaced
+with an actionListener, 45%](img/callbacks3.png)
+
+---
+# Example in ColorPicker
+
+We setup the Custom View side for you
+
+```java
+    // Currently registered ColorListener instance or null.
+    // A set of listener in Color picker vs. One listener in Menus
+    private List<ColorChangeListener> mColorChangeListeners;
+
+    // Class which defines a listener to be called when a new color is selected.
+    public interface ColorChangeListener {
+        void onColorSelected(@ColorInt int color);
+    }
+
+    // Registers a new listener
+    public final void addColorChangeListener(@NonNull ColorChangeListener colorChangeListener) {
+        mColorChangeListeners.add(colorChangeListener);
+    }
+```
+---
+# Example in ColorPicker
+
+You implemented this
+.left-column-half[
+`// TODO: Register callback to update {color,label} View when color changed.`
+
+- What method do we call to register the callback?  
+  - `addColorChangeListener()`
+
+- What do we usually do in a callback? 
+  - update application (`MainActivity`) model
+]
+.right-column-half[
+![:img listener relationship diagram in color picker, 100%](img/listener.png)
+]
+
+---
+# Custom Listener in Menus
+
+You need to do this yourself in Menus
+
+```java
+// TODO: register a new listener with the menu so that the application knows when a selection is made
+
+// TODO: implement the listener. When the user completes a trial, the menu listener should store
+// the results of the trial, and setup for the next trial
+```
+
+
+---
+# Android Studio Tips
+
+- [Keyboard shortcuts](https://developer.android.com/studio/intro/keyboard-shortcuts)
+- Structure tab
+
+![:img android structure tab, 50%](img/tips.png)
+
+
+
+---
+# Work time on Menus
+
+
+
+<div class="mermaid">
+  classDiagram
+  
+  class MenuExperimentView {
+    onTouchEvent()
+    startSelection()
+    endSelection()
+    updateModel()
+    onDraw()
+  }
+  
+  
+  AbstractMenuExperimentView <|-- MenuExperimentView
+  
+  AbstractMainActivity <|-- MainActivity
+  AbstractMainActivity <|-- TestActivity
+  MenuExperimentView <|-- PieMenuView
+  MenuExperimentView <|-- NormalMenuView
+  MenuExperimentView <|-- CustomMenuView
+  
+  
+  </div>
+
+
diff --git a/slides/l08/.gitkeep b/slides/l08/.gitkeep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/slides/l08/menus-data.html b/slides/l08/menus-data.html
new file mode 100644
index 0000000000000000000000000000000000000000..9fa2d81cd917c4b84a7b7e9d9ea498d77fd6a1dd
--- /dev/null
+++ b/slides/l08/menus-data.html
@@ -0,0 +1,78 @@
+---
+layout: presentation
+title: Lab 8 Slides
+description: Menus Data Analysis
+class: middle, center, inverse
+---
+
+# CSE 340 Lab 8 (Spring 2020)
+## Week 8: Menus Data Analysis
+
+
+.title-slide-logo[
+  ![:img Data Analysis, 40%](menus_data.png)
+]
+
+---
+
+# Menus Timeline
+
+- Programming part (Part 1-4) due: ~~yesterday~~ Today, Thursday, May 21 @ 10:00pm
+  - Lock: Friday, May 22 @ 10:00pm (if you are using late days)
+
+- Analysis part (Part 5-6: Report and Reflection) due: Monday, May 25 @ 10:00pm
+    - Lock: Wednesday, May 27 @ 10:00pm (if you are using late days)
+---
+
+# Section 8 Objectives
+
+- Data analysis
+  - In-class demo
+- Remote testing
+- Menus help & questions
+
+---
+
+# Data Analysis
+
+In-class demo
+
+- Getting Menus data from an Android device or Emulator ([instructions here](https://courses.cs.washington.edu/courses/cse340/20sp/docs/android_files/))
+
+- Working with data: [sample spreadsheet](https://docs.google.com/spreadsheets/d/1JqfKhHugIF-kebs_bVztCnkUe0CizXN8PU_Ar3kXtK4/edit#gid=1104722579)
+
+
+---
+
+# Remote Testing
+
+1. Still looking for participants? Find your group members [here](https://docs.google.com/document/d/11nsEWs3TubV5Zy0zOIGguqZJohkS34uizIrDv-bgnYs/edit)
+  - You can ask us/the course staff too 😊
+2. Create an APK:  
+  - In your menu project in Android Studio, select the *Build -> Build Bundle(s)/APK(s) -> Build APK(s)*.
+  - When the *Build APK(s)* message popup appears in the lower right hand corner, click the *locate* link to find the `app-debug.apk`.
+3. Send a copy of the consent form (Word/Google Doc) to the participant
+4. Set up your phone call or video meeting
+  - Briefly explain the study
+  - Have the participant "sign" [this Google form](https://bit.ly/20sp-Menus-Consent) as written consent
+
+---
+
+# Remote Testing (cont.)
+5\. Send your APK - Have the participant test your menus:
+- **Highly recommend** to create a shared Google folder/drive with your participant where:
+  - you upload your APK
+  - your participant can later upload their .csv data file 
+
+**Notes**:
+- Participants please make sure to `Clear Result CSV` prior testing and complete a full session
+- Developer please make sure you have 108 data points from each participant
+
+Read more: [Menus Spec](https://courses.cs.washington.edu/courses/cse340/20sp/assignments/menus#part-5-conduct-and-write-up-user-study)
+
+
+---
+
+# Questions
+
+
diff --git a/slides/l08/menus_data.png b/slides/l08/menus_data.png
new file mode 100644
index 0000000000000000000000000000000000000000..e94e349ff2398ebc099de80f1ae9072e0fcd6395
Binary files /dev/null and b/slides/l08/menus_data.png differ
diff --git a/slides/l09/img/abridged_undo_view_tree.png b/slides/l09/img/abridged_undo_view_tree.png
new file mode 100644
index 0000000000000000000000000000000000000000..deafa50f428c05705f4edb5c7ae21fc34edab58b
Binary files /dev/null and b/slides/l09/img/abridged_undo_view_tree.png differ
diff --git a/slides/l09/img/draw-app.jpg b/slides/l09/img/draw-app.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..6cc42303aa32f5f7533bb42a2159ced7a96b27f9
Binary files /dev/null and b/slides/l09/img/draw-app.jpg differ
diff --git a/slides/l09/outline.md b/slides/l09/outline.md
new file mode 100644
index 0000000000000000000000000000000000000000..cb33e127f340aa299b9a3cb1af3a067cab482d69
--- /dev/null
+++ b/slides/l09/outline.md
@@ -0,0 +1,13 @@
+### lab outline
+
+- Intro
+  - Hi I'm Adam!
+  - Welcome to color picker
+  - you got emails for GitLab repos for assignment 3, clone them as we'll be working with them today
+- Visually introduce color picker (3min)
+- Talk through stub/spec (7min)
+  - Reminder of api references
+  - Radian math quick refresh
+- Convert unconstrained xy coords to a color (10min)
+- Work in small groups over examples of possible interaction flows, ask about potential outputs (2 + 5)
+- work on state machine implementation (23min)
diff --git a/slides/l09/undo-lab.html b/slides/l09/undo-lab.html
new file mode 100644
index 0000000000000000000000000000000000000000..d6cd5e3e832707f52d2d610e5ab07ac79ec5febd
--- /dev/null
+++ b/slides/l09/undo-lab.html
@@ -0,0 +1,250 @@
+---
+layout: presentation
+title: Lab 9 Slides
+description: Getting Started With Undo
+class: middle, center, inverse
+---
+# CSE 340 Lab 9 (Spring 2020)
+## Week 9: Getting started with Undo
+
+.title-slide-logo[
+  ![:img Drawing App, 40%](img/draw-app.jpg)
+]
+
+---
+# Undo Timeline
+
+- Programming part due: Next Monday, June 1 @ 10:00pm
+  - Lock: Wednesday, June 3 @ 10:00pm (if you are using late days)
+
+- Heuristic Evaluation due: Friday, June 5 @ 10:00pm
+- Reflection due: Monday, June 8 @ 10:00pm
+
+- **Examlet 4 is tomorrow!** Friday, May 29
+
+---
+# Section 9 Objectives
+
+- Understanding Undo assignment
+- Examlet review with Kahoot
+- Work time/ Questions on Undo assignment
+
+---
+# The Undo feature
+
+- Incredibly useful interaction technique
+
+- Reverts the application to an older state
+
+  - Mistakes can easily be undone
+
+  - *"Ugh...that was definitely not right, but manually erasing all this work is going to take forever"*
+---
+# The Redo feature
+
+- Inverse to the Undo feature
+- "Undoes" an undo
+
+  - Work previously undone is reapplied
+
+  - *"Huh, maybe I made the right decision after all..."*
+---
+# Codebase: Application
+.left-column60[
+- `ReversibleDrawingActivity`, class contains the entire interactor hierarchy
+  - Floating Action Buttons (FAB), buttons that allow for actions supported by AbstractReversibleDrawingActivity
+  - References DrawingView in AbstractDrawingActivity 
+
+- `AbstractReversibleDrawingActivity`, abstract class that extends AbstractDrawingActivity
+  - adds support for undo/redo
+  - includes buttons for undo/redo
+  - `doAction()`, `undo()`, `redo()`]
+
+.right-column30[
+<div class="mermaid">
+classDiagram
+
+AbstractDrawingActivity <|.. AbstractReversibleDrawingActivity
+AbstractReversibleDrawingActivity <|.. ReversibleDrawingActivity
+class AbstractDrawingActivity {
+  DrawingView: "Canvas the user draws on"
+  addMenu()
+  addCollapsableMenu()
+  doAction()
+}
+
+class AbstractReversibleDrawingActivity {
+  +AbstractStackHistory
+  +doAction()
+  +undo()
+  +redo()
+}
+
+class ReversibleDrawingActivity {
+  +onAction()
+  +onColorSelected()
+  +onThicknessSelected()
+}
+</div>]
+
+---
+# Codebase: Application
+
+.left-column60[
+- `AbstractDrawingActivity` - abstract class for app that supports drawing without history
+
+  - Wrapper around a `DrawingView`
+
+  - `doAction()`
+
+  - Contains methods for adding menus and changing visibility]
+
+  .right-column30[
+  <div class="mermaid">
+  classDiagram
+  
+  AbstractDrawingActivity <|.. AbstractReversibleDrawingActivity
+  AbstractReversibleDrawingActivity <|.. ReversibleDrawingActivity
+  class AbstractDrawingActivity {
+    DrawingView: "Canvas the user draws on"
+    addMenu()
+    addCollapsableMenu()
+    doAction()
+  }
+  
+  class AbstractReversibleDrawingActivity {
+    +AbstractStackHistory
+    +doAction()
+    +undo()
+    +redo()
+  }
+  
+  class ReversibleDrawingActivity {
+    +onAction()
+    +onColorSelected()
+    +onThicknessSelected()
+  }
+  </div>]
+---
+# Codebase: DrawingView
+.left-column-half[- `AbstractDrawingActivity` is a wrapper around a `DrawingView`
+  - Sets behavior for how strokes are drawn 
+
+- DrawingView, a drawing canvas that handles strokes
+  - Strokes are just `StrokeView`'s in the `DrawingView`
+  - `onTouchEvent()` implements a PPS that describes lifetime of a stroke being created]
+
+.right-column40[
+<div class="mermaid">
+  classDiagram
+  
+  class AbstractDrawingActivity {
+    DrawingView: "Canvas the user draws on"
+    addMenu()
+    addCollapsableMenu()
+    doAction()
+  }
+
+  class StrokeView {
+     Path
+     onDraw()
+  }
+  </div>
+]
+---
+
+# Codebase: Actions
+.left-column-staff[
+- `AbstractAction` abstract class defines basic behavior any Action should have
+- `AbstractReversibleAction` abstract class defines interface for actions that can be undone
+- `doAction()` chain: `AbstractReversibleDrawingActivity.doAction()` âž¡`AbstractDrawingActivity.doAction()` âž¡`AbstractAction.doAction()`
+- `AbstractReversibleDrawingActivity`'s `undo()` and `redo()` call methods on `AbstractReversibleAction` to undo/redo]
+
+.right-column55[
+<div class="mermaid">
+  classDiagram
+  
+  AbstractAction <|.. AbstractReversibleAction
+  AbstractReversibleAction <|.. ChangeColorAction
+  AbstractReversibleAction <|.. ChangeThicknessAction
+  AbstractReversibleAction <|.. AbstractReversibleViewAction
+  AbstractReversibleViewAction <|.. StrokeAction
+  
+  class AbstractAction {
+    doAction()
+  }
+  class AbstractReversibleAction {
+    +boolean done
+    +undoAction
+  }
+  class AbstractReversibleViewAction  {
+    +invalidate
+  }
+  </div>
+]
+
+---
+
+# Codebase: Actions
+.left-column-staff[
+- Actions:
+  - `ChangeColorAction`
+  - `ChangeThicknessAction`, implement for homework
+  - `StrokeAction`
+  - And more, create your own action!]
+
+.right-column55[
+<div class="mermaid">
+  classDiagram
+  
+  AbstractAction <|.. AbstractReversibleAction
+  AbstractReversibleAction <|.. ChangeColorAction
+  AbstractReversibleAction <|.. ChangeThicknessAction
+  AbstractReversibleAction <|.. AbstractReversibleViewAction
+  AbstractReversibleViewAction <|.. StrokeAction
+  
+  class AbstractAction {
+    doAction()
+  }
+  class AbstractReversibleAction {
+    +boolean done
+    +undoAction
+  }
+  class AbstractReversibleViewAction  {
+    +invalidate
+  }
+  </div>
+]
+
+---
+
+# Codebase: History
+
+.left-column60[The `AbstractReversibleDrawingActivity` uses an StackHistory interface to manage the undo/redo history
+  - You will implement the concrete `StackHistory` which implements `AbstractStackHistory`  
+  - Think: What data structures are used? Why does this make sense?
+    - What happens to the redo history if you take a new action after undoing a couple times?
+    - What happens to the undo history if you redo an action?
+    - What happens to the redo history if you undo an action?]
+
+.right-column30[
+<div class="mermaid">
+  classDiagram
+  
+  AbstractStackHistory <|.. StackHistory
+  class AbstractStackHistory {
+    addAction(AbstractReversibleAction action)
+    undo()
+    redo()
+    canUndo()
+    canRedo()
+  }
+  
+  class StackHistory {
+     +capacity: "Max stack size"
+  }
+  
+  
+  </div>
+]
+
diff --git a/slides/l09/undo_exam_question.pdf b/slides/l09/undo_exam_question.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..c739bea3b80736a3f299a8fe2818586cea2d853a
Binary files /dev/null and b/slides/l09/undo_exam_question.pdf differ
diff --git a/slides/l09/undo_lab_notes.txt b/slides/l09/undo_lab_notes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2f0debf2ecaf43158114a00571e79969f9313cc7
--- /dev/null
+++ b/slides/l09/undo_lab_notes.txt
@@ -0,0 +1,104 @@
+Today we will spend lecture exploring and building an understanding of the
+Undo assignment.
+
+The Undo feature is an incredibly useful interaction technique. It allows the user
+to revert the application to an older state, enabling mistakes to be easily undone.
+
+The Redo feature is also very useful, and is the inverse to the Undo feature.
+It "undoes" an undo. Work previously undone is reapplied.
+
+[DEMO]
+Let's begin by looking at the app in action. There are two different
+menus - one for changing the thickness of the drawn stroke and the other
+for changing the color of the drawn stroke. Changing the thickness, changing
+the color, or changing the stroke are the three types of actions the user can
+take, and the user can undo or redo any of these actions using buttons that
+only appear when they're relevant. Undo only appears when there is an action to
+undo, and redo only appears when there is an action to redo.
+
+[CODEBASE EXPLORATION]
+
+[ACTIVITY FILES]
+Let's dive into the codebase.
+
+The MainActivity in this app is a concrete implementation of the ReversibleDrawingActivity
+and in turn DrawingActivity abstract classes. Important methods include `onColorSelected()`
+and `onThicknessSelected()`
+
+DrawingActivity is an abstract class for an app that supports drawing without support for Undo or Redo.
+An important method to read is doAction().
+
+The ReversibleDrawingActivity extends DrawingActivity and adds support for undo/redo to it, 
+including both the undo/redo buttons and the history. Important methods to read
+include doAction(), undo(), and redo().
+
+The MainActivity class inherits from ReversibleDrawingActivity. It adds support for thickness
+and color to the undo/redo support in ReversibleDrawingActivity. It also adds menus to show 
+the thickness/color options. Important methods to read include onColorSelected() and onThicknessSelected().
+
+[DRAWING VIEW]
+The DrawingActivity is a wrapper around a DrawingView. The DrawingView sets the 
+behavior for how strokes are drawn. Strokes are just StrokeView objects drawn against
+the DrawingView. The onTouchEvent() should look 
+familiar. It implements a PPS that describes the lifetime of a stroke being created.
+
+There's a useful diagram that visualizes the code's structure. You should also look
+at the layout files. Chances are you'll want to update them to add new features. 
+
+[ACTIONS]
+
+We're building a drawing app. Whenever the user interacts with the app, he/she
+is taking some sort of Action. The Action abstract class defines the basic behavior
+any Action should have. The DrawingActivity's doAction() calls the doAction() implementation
+ in Action's subclasses. 
+
+There's another abstract class called ReversibleAction that extends Action. This represents an action
+that is reversible. The ReversibleAction abstract class extends the Action abstract class 
+and adds an undoAction() method to undo the particular Action. 
+All three of the actions we've defined in the app are reversible. If for your extra feature you define a 
+new action, it may extend ReversibleAction, or it may just extend Action - it's up to you.
+
+The three actions we've defined are ChangeColorAction, ChangeThicknessAction, and StrokeAction.
+The ChangeColorAction, when applied, stores the DrawingView's Paint's old color and sets a new color.
+When undone, it sets the color on the DrawingView's paint to its previous color. 
+The ChangeThicknessAction does something similar, except it alters the thickness of the
+DrawingView's paint. The StrokeAction creates a StrokeView that represents the View of the
+stroke drawn and adds it to the DrawingView.
+
+[HISTORY]
+
+Your first goal with this assignment is to implement StackHistory. StackHistory extends the
+AbstractHistory abstract class. It is the fundamental data structure that will allow your
+users to undo and/or redo actions on the app, and it is used in the ReversibleDrawingActivity.
+
+[ADDITIONAL RESPONSIBILITIES]
+Your second goal with this assignment is to add a new FAB that adds a thickness 0 stroke.
+
+Your third goal with this assignment is to add an additional feature to the app. The simplest
+thing to do is to add a new FAB to one of the existing menus, like a FAB that allows you to draw 
+in a new color. If you want to challenge yourself, you could allow users to use your ColorPicker wheel
+to select a color or allow a user to change a stroke location.
+
+That was a lot. I'm actually going to help you out and show you how to add one of the
+additional features, but before I get to that - any questions?
+
+[ADDING COLOR FAB]
+
+I'm going to show you how to add a Color FAB. This is one of your options for additional
+features. It's also very similar to adding the Thickness 0 FAB.
+
+The first thing I'm going to do is go to color_menu.xml, because I know this
+is the layout file that contains all the color FABs. I'm just going to copy
+and paste one of the other color FABs. Then I'm going to update it's id, contentDescription,
+and backgroundTint attributes. 
+
+To be consistent with the style here, I'm going to define the string for the contentDescription
+in the strings.xml file.
+
+Next I'm going to look at MainActivity because I know that's the class that adds
+the color and thickness buttons. I noticed that the other color buttons are stored 
+in COLOR_MENU_ITEMS array. I add my grey FAB to the array. addCollapsableMenu adds
+the button and sets its on click listener automatically, so you don't have to worry 
+about it showing up correctly on your app or registering a listener. All you have to
+do now is go to onColorSelected, which is the listener function for the color buttons.
+I add my own case for the grey fab, do a ChangeColorAction, and I'm done.
\ No newline at end of file
diff --git a/slides/l10/10-heuristic-1.png b/slides/l10/10-heuristic-1.png
new file mode 100644
index 0000000000000000000000000000000000000000..fb0ccf3ae0d1ab2153ac19709c2ed58797225d7d
Binary files /dev/null and b/slides/l10/10-heuristic-1.png differ
diff --git a/slides/l10/10-heuristic-2.png b/slides/l10/10-heuristic-2.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe13cfe4b255e278e7089fad3912a3e59a2f41ad
Binary files /dev/null and b/slides/l10/10-heuristic-2.png differ
diff --git a/slides/l10/10-heuristic.png b/slides/l10/10-heuristic.png
new file mode 100644
index 0000000000000000000000000000000000000000..30d63b8b69588d725642697ec7196b52e6befd71
Binary files /dev/null and b/slides/l10/10-heuristic.png differ
diff --git a/slides/l10/lab-heuristic.html b/slides/l10/lab-heuristic.html
new file mode 100644
index 0000000000000000000000000000000000000000..90f246e614d237015e11a5008e69baee68d55f49
--- /dev/null
+++ b/slides/l10/lab-heuristic.html
@@ -0,0 +1,73 @@
+---
+layout: presentation
+title: Lab 10 Slides
+description: Getting started with Heuristic Evaluation
+class: middle, center, inverse
+---
+# CSE 340 Lab 10 (Spring 2020)
+## Week 10: Heuristic Evaluation
+
+.title-slide-logo[
+  ![:img 10 Heuristic Evaluation Principles, 45%](10-heuristic.png)
+]
+---
+
+# Undo Timeline
+
+- Heuristic Evaluation due: Friday, June 5 @ 10:00pm
+
+- Report and Reflection due: Monday, June 8 @ 10:00pm
+
+---
+
+# Section 10 Objectives
+
+- Heuristic Evaluation instruction
+
+- CSE 340 Farawell Kahoot
+
+- Questions/Feedback
+
+
+---
+
+## Heuristic Evaluation
+
+- You should have received an email with the [survey link](https://docs.google.com/forms/d/e/1FAIpQLScDe9k5bOKFikyh4ai32ih1e8waMD4SMECAjZK3yRVl1u-eDQ/viewform) and videos
+
+- We will complete a heuristic evaluation on one submission in section today
+    - You must complete the remaining 3 evaluations by the due date
+
+- What should you do?
+
+    - Two passes through the interface: one to inspect flow, another to inspect each screen against heuristics
+    - For each video, submit 3 things: At least two should be bad issues, one can be good.
+    - Write a Usability Action Report ([template](https://courses.cs.washington.edu/courses/cse340/20sp/assignments/undo-report) provided)
+---
+
+![:img 10 Heuristic Evaluation Principles, 60%](10-heuristic-1.png)
+
+- **H1. Visibility of system status** -- Are users informed about what is going on in the app?
+
+- **H2: Match between the system and the real world** -- Does the app use concepts, language, and conventions that would be familiar to users?
+
+- **H3: User control and freedom** -- Does it allow users to do what they want to?
+
+- **H4: Consistency and standards** -- Does the app use the same conventions in all its components? Is it consistent with other apps on the same platform?
+
+- **H5: Error prevention** -- Is the app defensive? Does it have a design that protects users from making mistakes?
+
+---
+
+![:img 10 Heuristic Evaluation Principles, 60%](10-heuristic-2.png)
+
+
+- **H6: Recognition rather than recall** -- Are the objects/actions/options of the app easily accessible to newcomers, or do they require memory?
+
+- **H7: Flexibility and efficiency of use** -- Can users customize the app to their needs?
+
+- **H8: Aesthetic and minimalist design** -- Is the app cluttered? Does it contain only relevant components?
+
+- **H9: Help users recognize, diagnose, and recover from errors** -- When users run into any problem, will it be easy for them to fix it?
+
+- **H10: Help and documentation** -- Is help easy to find and navigate? Is the information given even helpful?
diff --git a/slides/unused/3dmodeling.html b/slides/unused/3dmodeling.html
new file mode 100644
index 0000000000000000000000000000000000000000..0bb6b2e4aa3487f77eedff6336861cd55b3306c1
--- /dev/null
+++ b/slides/unused/3dmodeling.html
@@ -0,0 +1,149 @@
+---
+layout: presentation
+title: Basic Intro to 3D modeling
+description: Description of how to create a 3D model in OpenSCAD
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse-
+---
+# Physical Computing
+
+Jennifer Mankoff
+
+CSE 340 Winter 2020
+---
+layout:false
+
+[//]: # (Outline Slide)
+.title[Today's goals]
+.body[
+- Introduce OpenSCAD
+- Talk about elements of 3D modeling
+]
+
+---
+.title[OpenSCAD: A language for 3D modeling]
+.body[
+[Beginner's
+tutorial](http://edutechwiki.unige.ch/en/OpenScad_beginners_tutorial)
+
+Comments and variables similar to what you are used to
+
+```
+//Name Tag - Customizable
+Name = "Jen Mankoff";
+Length = 90 ;
+c = 20;
+```
+]
+---
+.title[OpenSCAD concepts: solids]
+.body[
+Primitive Solids such as `cube([2,3,4]);` make up your designs
+
+Also `sphere` `cylinder` `polyhedron` 
+]
+---
+.title[OpenSCAD concepts: transformations]
+.body[
+Same as 2D transformations
+
+- `rotate([x,y,z]) [solid]`
+- `translate([x,y,z]) [solid]`
+- `mirror([x,y,z]) [solid]`
+- ...
+]
+---
+.title[OpenSCAD concepts: CSG modeling]
+.body[
+- Union: `union() { [transformations/solids/etc] }` combines children
+- Difference: `difference() {}` subtracts everything from first child
+- Hull: `hull() {}` combines all the children within a convex hull 
+
+]
+
+---
+.title[OpenSCAD concepts: 2G geometry + linear extrusion]
+.body[
+- `linear_extrude (height=XX)` and then define a polygon to extrude,
+  e.g., `polygon(points=[[0,0],[100,0],[0,100],[15,15],[65,15],[15,65]], paths=[[0,1,2],[3,4,5]]);`
+
+makes what? 
+]
+--
+.body[
+![:img Picture of a triangle extruded to a depth of 16,30%](img/modeling/extruded-polygon.png)
+
+]
+---
+.title[Other things to extrude]
+.body[
+
+- Can import a DXF file and extrude, just put this after `linear_extrude`: `import (file = "file.dxf");`
+
+- text: 
+
+```
+content = "Text rocks";
+font = "Liberation Sans";
+
+translate ([-30,0,0]) {
+   linear_extrude(height = 3) {
+       text(content, font = font, size = 10);
+     }
+ }
+```
+]
+---
+.title[Other features]
+.body[
+[Cheat sheet](http://www.openscad.org/cheatsheet/index.html)
+
+- `%` shows something transparently so you can find out what would
+  happen
+- `$fn` sets resolution (can speed things up by making this low during design)
+- Can create functions (`module name() {}` )
+- Can use for loops 
+- Can use [other peoples' libraries](https://github.com/mtu-most/most-scad-libraries)
+]
+---
+.title[Let's try it]
+.body[
+- Open OpenSCAD
+- Before you begin modeling, go to View>>Show Axes. This will make it
+  easier to see where the parts of your model are being placed.
+- Click and drag to change viewing angle
+- Right click and drag to move origin
+
+
+]
+---
+.title[sample program]
+.body[
+
+```
+//Name Tag
+Name = "Jen Mankoff";
+Length = 90 ;
+c = 20;
+
+linear_extrude(height = 5)
+translate([0, 5, 0])
+text(Name);
+
+difference(){
+    hull(){
+        cylinder(h=2,d=40);
+        translate([Length,0,0])
+        cylinder(h=2,d=40);
+    }
+    translate([Length,0,0])
+    cylinder(h=2,d=14);
+
+}
+```
+]
+---
+# End of Deck
diff --git a/slides/unused/activity-events.html b/slides/unused/activity-events.html
new file mode 100644
index 0000000000000000000000000000000000000000..81970bc95a0da05dd108ee195b871a3edbc6a69e
--- /dev/null
+++ b/slides/unused/activity-events.html
@@ -0,0 +1,40 @@
+---
+layout: presentation
+title: Background on how Activities Generate Events
+description: Activity state changes generate events. Here's how
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+template: inverse
+
+# Interaction Programming Lab (Spring 2019)
+## Activity State Change Event Handling
+---
+layout: false
+---
+
+## Activity.red[*]
+
+- Application component providing a screen for users to interact
+
+--
+
+- Typically fills whole the screen (though it doesn't have to)
+
+--
+<br><br>
+![:img Android Calculator App, 20%](img/android-calculator-example.png)
+![:img Android Contacts App, 20%](img/android-contacts-example.png)
+![:img Android Search App, 20%](img/android-search-example.png)
+<br>
+
+--
+
+<br>
+.footnote[
+ More on Activites: https://developer.android.com/guide/components/activities.html
+
+]
diff --git a/slides/unused/ar.html b/slides/unused/ar.html
new file mode 100644
index 0000000000000000000000000000000000000000..fe53f80ac6cfd3916a6d8d2fa0e9009bdd7eac09
--- /dev/null
+++ b/slides/unused/ar.html
@@ -0,0 +1,214 @@
+---
+layout: presentation
+title: Augmented Reality and your Phone
+description: Discussion of the future of mobile AR
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Augmented Reality and your Phone
+
+Jennifer Mankoff
+
+CSE 340 Spring 2019 
+Slides credit: Chauncey Frend, Indiana University
+.footnote[[Frend, Chauncey. ”Augmented Reality & the UITS Advanced Visualization Lab." 30 Sep 2016/28 Feb 2017. Digital Arts & Humanities Workshop Series. Scholars' Commons, Wells Library, Indiana University, Bloomington.](http://hdl.handle.net/2022/21293)
+]
+
+---
+layout: false
+
+.title[What is Augmented Reality?]
+
+.body[
+![:img Continuum, 100%](img/ar/arvr.png)
+]
+.footnote[
+Milgram, Paul, et al. "Augmented reality: A class of displays on the reality-virtuality continuum." Photonics for industrial applications. International Society for Optics and Photonics, 1995.
+[Photo
+Source](http://smartideasblog.trekk.com/augmented-or-virtual-how-do-you-like-your-reality)
+]
+---
+.left-column[
+##        What is AR?
+
+A combination of 
+- a real scene viewed by a user and 
+- a virtual scene generated by a computer that augments the scene with
+  additional information.
+  ]
+.right-column[
+![:img eg, 60%](img/ar/areg.png)
+
+]
+???
+Differences to VR?
+Augmented Reality
+- System augments the real world scene
+- User maintains a sense of presence in real world
+- Needs a mechanism to combine virtual and real worlds
+- Hard to register real and virtual
+
+---
+.left-column50[
+## Brief History
+
+- 1901 Lyman Frank Baum  author of “The Master Key” imagines a kind of AR.
+- 1968 Ivan Sutherland invents first head-mounted display “Sword-of-Damocles” at University of Utah.
+- 1999 ARToolkit was created by Hirokazu Kato at HITLab
+- 2010 Vuforia for AR Mobile Apps was released by Qualcomm.
+- 2013 Google announces Google Glass.
+- 2015 Microsoft announces the HoloLens.
+- 2016 Niantic released Pokémon Go.
+]
+.right-column50[
+![:img History, 100%](img/ar/arhistory.png)
+]
+---
+.title[AR Coloring Book]
+.body[
+![:youtube AR Coloring Book Video, SWzurBQ81CM]
+0:00-0:30
+]
+
+---
+.title[AR Climbing Wall]
+.body[
+![:youtube AR Climbing Wall, rjWcE25s7kQ]
+0:00-0:33
+]
+
+---
+.title[AR 3D Assembly]
+.body[
+![:youtube AR 3D Assembly, CONY3q3OdPA]
+
+0:00-0:33
+
+[Similar example in medical domain](https://www.youtube.com/watch?v=MS3h9_KPoBY&feature=youtu.be)
+]
+
+---
+.title[AR in Retail]
+.body[
+![:img Ikea, 100%](img/ar/ikea.png)
+]
+
+---
+.title[AR in Tourism]
+.body[
+![:img Disney, 100%](img/ar/disney.png)
+]
+
+---
+.title[Human/robot Interaction]
+.body[
+
+![:youtube HRI, mSCrviBGTeQ]
+
+Time: 2:15
+
+]
+---
+.left-column[
+## Building AR experiences]
+.right-column[
+ASSETS
+
+Display
+
+Interface
+]
+---
+.left-column[
+## Building AR experiences: ASSETS]
+.right-column[
+Sources?
+ - 3D Scanning
+ - Photogrammetry
+ - 3D Authoring
+ - 3D Repositories
+  - e.g. Smithsonian X 3D https://3d.si.edu/browser
+  - e.g. Thingiverse
+]
+???
+Other media? 
+---
+.left-column[
+## Building AR experiences: Display Hardware]
+.right-column[
+
+![:img Hololens, 50%](img/ar/hololens.png)
+![:img Phone, 25%](img/ar/mobile.png)
+
+Requirements?
+]
+???
+Camera
+Display
+...
+
+---
+.left-column[
+## Building AR experiences: Interface]
+.right-column[
+![:youtube Pokemon Go, vgfZbgwrbx8]
+
+- 4:00-7:20 
+
+
+]
+.footnote[https://www.geekwire.com/2018/pokemon-go-evolved-remain-popular-initial-craze-cooled/]
+???
+Discussion of interface needs
+---
+.left-column[
+## Combining real and virtual
+ 
+Registering assets with the scene
+
+Tracking objects
+]
+.right-column[
+![:img registration, 50%](img/ar/objectplace.png)
+]
+???
+1st picture - real world
+
+2nd picture - real world with virtual objects and inter-reflections and virtual 
+	shading
+---
+.title[Difficult!]
+.body[
+
+Requires objects to behave in physically plausible manners when manipulated
+- Occlusion
+- Collision detection
+- Shadows
+
+AR systems sensitive to visual errors - virtual object may not be stationary in the
+	real scene or it may be in the wrong place.
+
+Time delays lead to augmented image lagging behind motions in the real scene.
+
+]
+???
+Failures in registration due to:
+Noise
+Position and pose of camera with respect to the real scene
+Image distortions
+Time delays
+In calculating the camera position
+
+
+
+---
+.title[Some tools]
+.body[
+- Unity (Basic package)
+- [Vuforia (AR
+  Plugin)](https://medium.com/quick-code/top-tutorials-to-learn-vuforia-to-develop-ar-applications-274eedc2b18f)
+  
+]
diff --git a/slides/unused/ar/areg.png b/slides/unused/ar/areg.png
new file mode 100644
index 0000000000000000000000000000000000000000..70b9195a640946c8b4ec22aaf79ae5f431f8c933
Binary files /dev/null and b/slides/unused/ar/areg.png differ
diff --git a/slides/unused/ar/arhistory.png b/slides/unused/ar/arhistory.png
new file mode 100644
index 0000000000000000000000000000000000000000..550d9f858b52ecbf1502d503e69f632d16297950
Binary files /dev/null and b/slides/unused/ar/arhistory.png differ
diff --git a/slides/unused/ar/arvr.png b/slides/unused/ar/arvr.png
new file mode 100644
index 0000000000000000000000000000000000000000..de518a47a6de4fb5c7f0b03fda00b08e118cc95a
Binary files /dev/null and b/slides/unused/ar/arvr.png differ
diff --git a/slides/unused/ar/disney.png b/slides/unused/ar/disney.png
new file mode 100644
index 0000000000000000000000000000000000000000..5e648a272f580502a65d94ccf9767fbae62a2f3f
Binary files /dev/null and b/slides/unused/ar/disney.png differ
diff --git a/slides/unused/ar/hololens.png b/slides/unused/ar/hololens.png
new file mode 100644
index 0000000000000000000000000000000000000000..bbb80f5d644bf7208c14aeacb047b7a7487dfaf8
Binary files /dev/null and b/slides/unused/ar/hololens.png differ
diff --git a/slides/unused/ar/ikea.png b/slides/unused/ar/ikea.png
new file mode 100644
index 0000000000000000000000000000000000000000..581b9ca6b395866451e7515eeb86ed0a6d5ce560
Binary files /dev/null and b/slides/unused/ar/ikea.png differ
diff --git a/slides/unused/ar/mobile.png b/slides/unused/ar/mobile.png
new file mode 100644
index 0000000000000000000000000000000000000000..bde11ccf0af95bc7ea20eb3d16b2a239f7445a77
Binary files /dev/null and b/slides/unused/ar/mobile.png differ
diff --git a/slides/unused/ar/objectplace.png b/slides/unused/ar/objectplace.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f5dbe56678158c3c657ed14c73a772c1daf4a56
Binary files /dev/null and b/slides/unused/ar/objectplace.png differ
diff --git a/slides/unused/cartoon2.png b/slides/unused/cartoon2.png
new file mode 100644
index 0000000000000000000000000000000000000000..44d9f443c8702ee6e65fec7b12378c8c9545ce27
Binary files /dev/null and b/slides/unused/cartoon2.png differ
diff --git a/slides/unused/dev-demo.html b/slides/unused/dev-demo.html
new file mode 100644
index 0000000000000000000000000000000000000000..ff90862930ac559bd82463d2db65cafa80252eb2
--- /dev/null
+++ b/slides/unused/dev-demo.html
@@ -0,0 +1,121 @@
+---
+layout: presentation
+title: Hello World Slides--Week 1, Lab-- 
+description: Lab project--Hello World--
+class: middle, center, inverse
+---
+
+# SSUI Mobile Lab (Spring 2020)
+## Week 1: Development Environment Setup
+
+.title-slide-logo[
+  ![:img Android Logo, 100%](img/android-logo.png)
+]
+
+---
+
+# Overview
+- ## Android Studio Installation
+
+- ## Android SDK Installation
+
+- ## Exercise: Hello World
+---
+
+layout: false
+## Development Environment Setup
+
+--
+
+- Download + Install
+
+  - __Android Studio__:  
+    https://developer.android.com/studio/index.html
+--
+
+  - __Genymotion Android Emulator__ *(Optional)* :   https://www.genymotion.com/thank-you-freemium/
+--
+
+- Android Set-up
+--
+  - Open Android Studio
+
+---
+
+template: inverse
+## Android Studio Walk-through
+
+---
+
+### Starting Android an Android Project
+![:img Select `Start a new Android Studio Project`, 70%](img/lab-00-hello-01.png)
+
+---
+
+### Project Configuration
+
+![:img Project Configuration, 70%](img/lab-00-hello-02.png)
+
+---
+
+### Targeting Android Devices
+
+![:img Targeting Android Devices, 70%](img/lab-00-hello-03.png)
+
+---
+
+### Adding an Activity
+
+![:img Adding an Activity, 70%](img/lab-00-hello-04.png)
+---  
+
+### Customizing the Activity
+
+![:img Customizing the Activity, 70%](img/lab-00-hello-05.png)
+
+---
+
+### Viewing your Activity's Code
+
+  ![:img Viewing your Activity's Code, 70%](img/lab-00-hello-06.png)
+
+---
+
+### Running your Application
+  ![:img Running your Application, 70%](img/lab-00-hello-07.png)
+
+
+---
+### Selecting a Deployment Target
+  ![:img Selecting a Deployment Target, 70%](img/lab-00-hello-08.png)
+
+---
+### Configuring a Virtual Device (Install Marshmallow)
+  ![:img Install Marshmallow, 70%](img/lab-00-hello-09.png)
+
+
+---
+### Let the Installer Run (Grab some Coffee)
+  ![:img Let the Installer Run - Grab some Coffee, 70%](img/lab-00-hello-10.png)
+
+
+---
+### Configuring a Virtual Device - Select a Phone
+  ![:img Configuring a Virtual Device - Select a Phone, 70%](img/lab-00-hello-11.png)
+
+
+---
+### Configuring a Virtual Device - Naming your Device
+  ![:img Configuring a Virtual Device - Naming your Device, 70%](img/lab-00-hello-12.png)
+
+
+---
+
+### Selecting a Deployment Target
+  ![:img Selecting a Deployment Target, 70%](img/lab-00-hello-13.png)
+
+
+---
+### Start your Application!
+  ![:img Start your Application, 70%](img/lab-00-hello-14.png)
+
diff --git a/slides/unused/final-exam-review.html b/slides/unused/final-exam-review.html
new file mode 100644
index 0000000000000000000000000000000000000000..c1f6509f21a203f963c7763427d3cf8b3ea77bd0
--- /dev/null
+++ b/slides/unused/final-exam-review.html
@@ -0,0 +1,113 @@
+---
+# Example long answer question
+
+##Which is better and which laws explain it?
+
+| #A | #B | 
+|--|--|
+|![:img Picture of the Graffiti gesture recognition alphabet from the Palm Pilot, 50%](img/whole/Grafitti.png)|.right-column50[![:img Picture of the Edgewrite gesture recognition alphabet, 100%](img/whole/Edgewrite.png)]|
+
+--
+- Fitts Law ( distance and sized;  expert errorless behavor)
+- Steering Law (distance and size over a path)
+- Cognitive modeling (expert behavior)
+- Gestalt Psychology (will they see it at all?)
+- **Errors (will they be reduced)**
+
+---
+.left-column-half[
+# Fitts Law
+
+![:img Picture of graph of fitts law data collected when I did the
+experiment. Y axis is time and x is index of difficulty. It's fairly
+noisy because fitts law is designed to measure multiple
+people. However it does fit a line., 80%](img/whole/timeoverid.png)
+
+Fitts' law only applies to *error-free, expert* behavior
+]
+.right-column-half[
+.jax[$$MT = a + b*log_2({Dist \over Size} + 1)$$
+]
+
+where
+- *MT* is movement time
+- *ID/MT* is the *Throughput* of a device in bits/second
+- *a* and *b* are empirically derived constants 
+- ID is the *Index of Difficulty* (ID, in bits) of a movement
+.jax[$$log_2({Dist \over Size} + 1)$$]
+
+
+]
+???
+This is just a line
+
+Fitts’ law tells us about difficulty for pointing and selection tasks
+- Time to move the hand depends only on relative precision required
+- MT increases as __distance__ from target increases
+- MT decreases as __size__ of target increases
+- Diagram this
+
+Fitts' law only applies to expert behavior
+
+---
+.title[Design tips derived from motor principals]
+.body[
+Design Tip #1: Make small targets larger
+
+Design Tip #2: Put commonly used things close together
+
+Design Tip #3: Make use of Edges: They are Infinite
+
+Design Tip #4: Use pie menus instead of context menus for expert tasks
+
+Design Tip #5: Use snapping to minimize distance<br> when likely
+targets are known
+
+Design Tip #6: Separate Motor Size from Visible Size
+
+]
+---
+.title[Use of two handed input]
+.body[
+
+2 Handed input principles
+- Non preferred leads
+- Sets frame of reference
+- Preferred does fine movement
+]
+--
+.title[Lenses]
+.body[
+Use: Display hidden, context-specific interaction
+
+Implementation
+]
+---
+.title[Study design]
+.body[
+Know your terms (participant, session, trial, condition)
+
+Know the important information about ethics
+- Beneficence -->
+ - Value of research higher than risks
+ - Do no harm
+- Respect for Persons -->
+ - Fully informed of intent and purpose
+ - Informed consent
+ - May opt out at any time, for any reason
+- Justice
+ - equitable, representative selection of participants
+]
+
+---
+.title[Study Analysis]
+.body[
+
+Basic statistics: Max, Min, Mean, Mode
+
+Bar chart: Compares conditions (means)
+
+Histogram: Shows number of results in each part of a range (distribution)
+
+Correlation != Causation
+]
diff --git a/slides/unused/img/Edgewrite2.png b/slides/unused/img/Edgewrite2.png
new file mode 100644
index 0000000000000000000000000000000000000000..d667210ad2a378b2158d5ed08c97edb01efec834
Binary files /dev/null and b/slides/unused/img/Edgewrite2.png differ
diff --git a/slides/unused/img/Grafitti2.png b/slides/unused/img/Grafitti2.png
new file mode 100644
index 0000000000000000000000000000000000000000..af6a460e7db587130d59a195b06160ceadbbef9d
Binary files /dev/null and b/slides/unused/img/Grafitti2.png differ
diff --git a/slides/unused/img/akkarh.jpg b/slides/unused/img/akkarh.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..9ea23e5b7e5f4cc5603d8323973622dceb5b3033
Binary files /dev/null and b/slides/unused/img/akkarh.jpg differ
diff --git a/slides/unused/img/amber.png b/slides/unused/img/amber.png
new file mode 100644
index 0000000000000000000000000000000000000000..dc1ee2f038baeef5c20a0ccc3d8a1c0f8dd94774
Binary files /dev/null and b/slides/unused/img/amber.png differ
diff --git a/slides/unused/img/android-calculator-example.png b/slides/unused/img/android-calculator-example.png
new file mode 100755
index 0000000000000000000000000000000000000000..f5921e2da2941d95e3d6eafc39fade76ec14c266
Binary files /dev/null and b/slides/unused/img/android-calculator-example.png differ
diff --git a/slides/unused/img/android-contacts-example.png b/slides/unused/img/android-contacts-example.png
new file mode 100755
index 0000000000000000000000000000000000000000..86239c1cdfab7abde795a4d01567cede0dd7accd
Binary files /dev/null and b/slides/unused/img/android-contacts-example.png differ
diff --git a/slides/unused/img/android-logo.png b/slides/unused/img/android-logo.png
new file mode 100755
index 0000000000000000000000000000000000000000..cebec75001ab25dc397065f193797d5ebd0cb38d
Binary files /dev/null and b/slides/unused/img/android-logo.png differ
diff --git a/slides/unused/img/android-search-example.png b/slides/unused/img/android-search-example.png
new file mode 100755
index 0000000000000000000000000000000000000000..ba5e27882923910ebee1e758760360e943c670d8
Binary files /dev/null and b/slides/unused/img/android-search-example.png differ
diff --git a/slides/unused/img/animation.png b/slides/unused/img/animation.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab4004c764f33b6a9e74806206a1262f835a17c2
Binary files /dev/null and b/slides/unused/img/animation.png differ
diff --git a/slides/unused/img/area.png b/slides/unused/img/area.png
new file mode 100644
index 0000000000000000000000000000000000000000..09a62b05a8402bccfb0d2dd1d6d5e3fae53f00ff
Binary files /dev/null and b/slides/unused/img/area.png differ
diff --git a/slides/unused/img/ascent.png b/slides/unused/img/ascent.png
new file mode 100644
index 0000000000000000000000000000000000000000..bd3570da5f06b32335df6fe44627c6ed7b8b62e8
Binary files /dev/null and b/slides/unused/img/ascent.png differ
diff --git a/slides/unused/img/background-paper.png b/slides/unused/img/background-paper.png
new file mode 100644
index 0000000000000000000000000000000000000000..fab891a842afc9228f4eaa8098b56252c11a3398
Binary files /dev/null and b/slides/unused/img/background-paper.png differ
diff --git a/slides/unused/img/bad-defaults.gif b/slides/unused/img/bad-defaults.gif
new file mode 100644
index 0000000000000000000000000000000000000000..e2a3c38c8184eb2a8468f6609171355e7da5dee4
Binary files /dev/null and b/slides/unused/img/bad-defaults.gif differ
diff --git a/slides/unused/img/buttons.png b/slides/unused/img/buttons.png
new file mode 100644
index 0000000000000000000000000000000000000000..26675f540854d26ee061fb0f9f81a46d9766ca14
Binary files /dev/null and b/slides/unused/img/buttons.png differ
diff --git a/slides/unused/img/cartoon.png b/slides/unused/img/cartoon.png
new file mode 100644
index 0000000000000000000000000000000000000000..5f76a447e8897a2b5a527df6f715c18dce15ed38
Binary files /dev/null and b/slides/unused/img/cartoon.png differ
diff --git a/slides/unused/img/colordodge-both.png b/slides/unused/img/colordodge-both.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa80aafc9aa29f8f656020a8aa2bf175de96c88c
Binary files /dev/null and b/slides/unused/img/colordodge-both.png differ
diff --git a/slides/unused/img/colordodge-diagram.png b/slides/unused/img/colordodge-diagram.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec409e17117c3e56ec8aa2826d5bafea6e3c87b7
Binary files /dev/null and b/slides/unused/img/colordodge-diagram.png differ
diff --git a/slides/unused/img/colormeter-highlights.png b/slides/unused/img/colormeter-highlights.png
new file mode 100644
index 0000000000000000000000000000000000000000..4bf4ad68b9d61b7fcebf9dcc9c675fc456983e75
Binary files /dev/null and b/slides/unused/img/colormeter-highlights.png differ
diff --git a/slides/unused/img/combined2.png b/slides/unused/img/combined2.png
new file mode 100644
index 0000000000000000000000000000000000000000..c40330a24baefe21cc51e412404416ab7b0d9fe2
Binary files /dev/null and b/slides/unused/img/combined2.png differ
diff --git a/slides/unused/img/dest.png b/slides/unused/img/dest.png
new file mode 100644
index 0000000000000000000000000000000000000000..89def8fa8bacee63b6568bdd908fafd714555d04
Binary files /dev/null and b/slides/unused/img/dest.png differ
diff --git a/slides/unused/img/destatop-diagram.png b/slides/unused/img/destatop-diagram.png
new file mode 100644
index 0000000000000000000000000000000000000000..8de5e7f261e925749c8c0870569e32fddc64ae74
Binary files /dev/null and b/slides/unused/img/destatop-diagram.png differ
diff --git a/slides/unused/img/destatop.png b/slides/unused/img/destatop.png
new file mode 100644
index 0000000000000000000000000000000000000000..a2db0db76f516e56ff70d3a7bf8aa6c60b2884b0
Binary files /dev/null and b/slides/unused/img/destatop.png differ
diff --git a/slides/unused/img/diagram.png b/slides/unused/img/diagram.png
new file mode 100644
index 0000000000000000000000000000000000000000..5437f18cc73929e005672147a1da65fa821abff5
Binary files /dev/null and b/slides/unused/img/diagram.png differ
diff --git a/slides/unused/img/diaz.png b/slides/unused/img/diaz.png
new file mode 100644
index 0000000000000000000000000000000000000000..59c95dc4ecde1bc5b966fd09364892eb27a14418
Binary files /dev/null and b/slides/unused/img/diaz.png differ
diff --git a/slides/unused/img/download-projects.png b/slides/unused/img/download-projects.png
new file mode 100644
index 0000000000000000000000000000000000000000..2c14bd2aafc9317983c230fd4af3ef1279707b0e
Binary files /dev/null and b/slides/unused/img/download-projects.png differ
diff --git a/slides/unused/img/drawing-interface.png b/slides/unused/img/drawing-interface.png
new file mode 100644
index 0000000000000000000000000000000000000000..25ca6afba81ee996baa56de1ef507751b13cf107
Binary files /dev/null and b/slides/unused/img/drawing-interface.png differ
diff --git a/slides/unused/img/echeverra.png b/slides/unused/img/echeverra.png
new file mode 100644
index 0000000000000000000000000000000000000000..cd9317cfb4c036141df5d4299a7262863ffe7c9e
Binary files /dev/null and b/slides/unused/img/echeverra.png differ
diff --git a/slides/unused/img/ex1.png b/slides/unused/img/ex1.png
new file mode 100644
index 0000000000000000000000000000000000000000..2900bc8d9e002acb4ef7d670c5036468a723fe74
Binary files /dev/null and b/slides/unused/img/ex1.png differ
diff --git a/slides/unused/img/ex2.png b/slides/unused/img/ex2.png
new file mode 100644
index 0000000000000000000000000000000000000000..2b5f42516128abe09cb980dc36fc55c84fcba7bd
Binary files /dev/null and b/slides/unused/img/ex2.png differ
diff --git a/slides/unused/img/expanded.png b/slides/unused/img/expanded.png
new file mode 100644
index 0000000000000000000000000000000000000000..4907f94f175c3c32c81aabd86688ca1157c5b013
Binary files /dev/null and b/slides/unused/img/expanded.png differ
diff --git a/slides/unused/img/gmail-snapping.gif b/slides/unused/img/gmail-snapping.gif
new file mode 100644
index 0000000000000000000000000000000000000000..66a17084941a6d03ad02d2dfa7b62446ec755b1d
Binary files /dev/null and b/slides/unused/img/gmail-snapping.gif differ
diff --git a/slides/unused/img/goodviz.png b/slides/unused/img/goodviz.png
new file mode 100644
index 0000000000000000000000000000000000000000..b42f09a9f43ddc6d05dcd1c0e3e287da291c78a3
Binary files /dev/null and b/slides/unused/img/goodviz.png differ
diff --git a/slides/unused/img/hello-01.png b/slides/unused/img/hello-01.png
new file mode 100644
index 0000000000000000000000000000000000000000..6c057df55e13c28a81228aa2fae3d0edf5cac700
Binary files /dev/null and b/slides/unused/img/hello-01.png differ
diff --git a/slides/unused/img/hello-02.png b/slides/unused/img/hello-02.png
new file mode 100644
index 0000000000000000000000000000000000000000..b86dea59e9823022af4b81bef09fdfba55b89074
Binary files /dev/null and b/slides/unused/img/hello-02.png differ
diff --git a/slides/unused/img/hello-03.png b/slides/unused/img/hello-03.png
new file mode 100644
index 0000000000000000000000000000000000000000..abe5ea1efe366c816202d3cefd4b0d6acacdbc2f
Binary files /dev/null and b/slides/unused/img/hello-03.png differ
diff --git a/slides/unused/img/hello-04.png b/slides/unused/img/hello-04.png
new file mode 100644
index 0000000000000000000000000000000000000000..6f97bb0cba2987998e50f8636db525c7079cb9e2
Binary files /dev/null and b/slides/unused/img/hello-04.png differ
diff --git a/slides/unused/img/hello-06.png b/slides/unused/img/hello-06.png
new file mode 100644
index 0000000000000000000000000000000000000000..170e81c7f423939618e0f2aa03125e3fad7c64c2
Binary files /dev/null and b/slides/unused/img/hello-06.png differ
diff --git a/slides/unused/img/hello-07.png b/slides/unused/img/hello-07.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb177cec3a40e92916564d2c41aad6be4f458238
Binary files /dev/null and b/slides/unused/img/hello-07.png differ
diff --git a/slides/unused/img/hello-08.png b/slides/unused/img/hello-08.png
new file mode 100644
index 0000000000000000000000000000000000000000..335d752558aef8183444ccdb34c9f59de9781895
Binary files /dev/null and b/slides/unused/img/hello-08.png differ
diff --git a/slides/unused/img/hello-09.png b/slides/unused/img/hello-09.png
new file mode 100644
index 0000000000000000000000000000000000000000..9c8722d48a4c63fe23597091479a5b6b441d3614
Binary files /dev/null and b/slides/unused/img/hello-09.png differ
diff --git a/slides/unused/img/hello-10.png b/slides/unused/img/hello-10.png
new file mode 100644
index 0000000000000000000000000000000000000000..880f6e86a28a16eede427735bc4a3b120a923bcd
Binary files /dev/null and b/slides/unused/img/hello-10.png differ
diff --git a/slides/unused/img/hello-11.png b/slides/unused/img/hello-11.png
new file mode 100644
index 0000000000000000000000000000000000000000..cbb3f57b2bb8a8370f2add7d9bad0930ffb88b44
Binary files /dev/null and b/slides/unused/img/hello-11.png differ
diff --git a/slides/unused/img/hello-12.png b/slides/unused/img/hello-12.png
new file mode 100644
index 0000000000000000000000000000000000000000..ba1580140041d190f4f459230234b9006f892d26
Binary files /dev/null and b/slides/unused/img/hello-12.png differ
diff --git a/slides/unused/img/hello-13.png b/slides/unused/img/hello-13.png
new file mode 100644
index 0000000000000000000000000000000000000000..93e377d4922b592f763057a4eb21019884b3016f
Binary files /dev/null and b/slides/unused/img/hello-13.png differ
diff --git a/slides/unused/img/hello-14.png b/slides/unused/img/hello-14.png
new file mode 100644
index 0000000000000000000000000000000000000000..bf0f8d9f48d01391031e8ac57ebcc16ceffdd0e5
Binary files /dev/null and b/slides/unused/img/hello-14.png differ
diff --git a/slides/unused/img/history.png b/slides/unused/img/history.png
new file mode 100644
index 0000000000000000000000000000000000000000..137e7e1cf9c1d15a26db157570135dcec876de84
Binary files /dev/null and b/slides/unused/img/history.png differ
diff --git a/slides/unused/img/input-example.gif b/slides/unused/img/input-example.gif
new file mode 100755
index 0000000000000000000000000000000000000000..6aaadb863a3f3f120edd35cd05b6e507dfab7bbb
Binary files /dev/null and b/slides/unused/img/input-example.gif differ
diff --git a/slides/unused/img/linear.png b/slides/unused/img/linear.png
new file mode 100644
index 0000000000000000000000000000000000000000..4b5b1fcd68a6d803cea91564521d2127a1018adf
Binary files /dev/null and b/slides/unused/img/linear.png differ
diff --git a/slides/unused/img/lorem-content.png b/slides/unused/img/lorem-content.png
new file mode 100644
index 0000000000000000000000000000000000000000..6182fca44d5142386b8c5ad8546821e642cc96c4
Binary files /dev/null and b/slides/unused/img/lorem-content.png differ
diff --git a/slides/unused/img/meanchart.png b/slides/unused/img/meanchart.png
new file mode 100644
index 0000000000000000000000000000000000000000..1a1d40eef2f2772506de97382338e6209ff904e7
Binary files /dev/null and b/slides/unused/img/meanchart.png differ
diff --git a/slides/unused/img/menu2.png b/slides/unused/img/menu2.png
new file mode 100644
index 0000000000000000000000000000000000000000..355420f9062a0e8a0820a8910d1f563bb2df9703
Binary files /dev/null and b/slides/unused/img/menu2.png differ
diff --git a/slides/unused/img/messenger-bubble.gif b/slides/unused/img/messenger-bubble.gif
new file mode 100755
index 0000000000000000000000000000000000000000..77defd497891e79a775a6ca3593cf33e02d2c890
Binary files /dev/null and b/slides/unused/img/messenger-bubble.gif differ
diff --git a/slides/unused/img/midterm/histogram.png b/slides/unused/img/midterm/histogram.png
new file mode 100644
index 0000000000000000000000000000000000000000..fc38781aa5657281643b358b01f25f7839f11df2
Binary files /dev/null and b/slides/unused/img/midterm/histogram.png differ
diff --git a/slides/unused/img/midterm/qs.png b/slides/unused/img/midterm/qs.png
new file mode 100644
index 0000000000000000000000000000000000000000..90f6c7b5fb6d60cd832473aa12388b79cd0b32c0
Binary files /dev/null and b/slides/unused/img/midterm/qs.png differ
diff --git a/slides/unused/img/minimalist-app.png b/slides/unused/img/minimalist-app.png
new file mode 100644
index 0000000000000000000000000000000000000000..eb7b7a7cb0f47ff93eedf376ba0b4eb9c61ffe19
Binary files /dev/null and b/slides/unused/img/minimalist-app.png differ
diff --git a/slides/unused/img/modeling/extruded-polygon.png b/slides/unused/img/modeling/extruded-polygon.png
new file mode 100644
index 0000000000000000000000000000000000000000..4e4502d0aa41d80333e032d005348aa05c7750d4
Binary files /dev/null and b/slides/unused/img/modeling/extruded-polygon.png differ
diff --git a/slides/unused/img/mvc.png b/slides/unused/img/mvc.png
new file mode 100644
index 0000000000000000000000000000000000000000..15f6beea7a9cb9b94b00200db17b6ef4b9366307
Binary files /dev/null and b/slides/unused/img/mvc.png differ
diff --git a/slides/unused/img/p21-rettig.pdf b/slides/unused/img/p21-rettig.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..4b519982b782ecb9367304c831de8190db6dc27d
Binary files /dev/null and b/slides/unused/img/p21-rettig.pdf differ
diff --git a/slides/unused/img/p21-rettig.png b/slides/unused/img/p21-rettig.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb5bc0b0c021dd5cd656314a8aa1071cf552511b
Binary files /dev/null and b/slides/unused/img/p21-rettig.png differ
diff --git a/slides/unused/img/palplates.png b/slides/unused/img/palplates.png
new file mode 100644
index 0000000000000000000000000000000000000000..ceb494c18ba7e5fdf03a9408d85c21269a2539e1
Binary files /dev/null and b/slides/unused/img/palplates.png differ
diff --git a/slides/unused/img/paper-prototype-example.jpg b/slides/unused/img/paper-prototype-example.jpg
new file mode 100755
index 0000000000000000000000000000000000000000..804f888d1cc5f29981d291864c0b72e1df11751d
Binary files /dev/null and b/slides/unused/img/paper-prototype-example.jpg differ
diff --git a/slides/unused/img/paper.png b/slides/unused/img/paper.png
new file mode 100644
index 0000000000000000000000000000000000000000..a9ddd75d2abb12320c8b63a578985f5ddc42e0dc
Binary files /dev/null and b/slides/unused/img/paper.png differ
diff --git a/slides/unused/img/pie.png b/slides/unused/img/pie.png
new file mode 100644
index 0000000000000000000000000000000000000000..19bb3cea94cceca2d283eceafb0f580812c433f4
Binary files /dev/null and b/slides/unused/img/pie.png differ
diff --git a/slides/unused/img/q2.png b/slides/unused/img/q2.png
new file mode 100644
index 0000000000000000000000000000000000000000..1c7d316f8ea6be349057428ec713c53be8a36987
Binary files /dev/null and b/slides/unused/img/q2.png differ
diff --git a/slides/unused/img/red.png b/slides/unused/img/red.png
new file mode 100644
index 0000000000000000000000000000000000000000..7dbe46c9c00ca3be4021c908e057dcd2738fdad5
Binary files /dev/null and b/slides/unused/img/red.png differ
diff --git a/slides/unused/img/redsat.png b/slides/unused/img/redsat.png
new file mode 100644
index 0000000000000000000000000000000000000000..e7d2519666e7434e6cd0558fde9b4ed18ef29bf1
Binary files /dev/null and b/slides/unused/img/redsat.png differ
diff --git a/slides/unused/img/redval.png b/slides/unused/img/redval.png
new file mode 100644
index 0000000000000000000000000000000000000000..307cac41cdd5c32453b8eb984b193c5fdf42d8c3
Binary files /dev/null and b/slides/unused/img/redval.png differ
diff --git a/slides/unused/img/reference.png b/slides/unused/img/reference.png
new file mode 100644
index 0000000000000000000000000000000000000000..378521989824e2f5e14c0c0964f88143e1c3e679
Binary files /dev/null and b/slides/unused/img/reference.png differ
diff --git a/slides/unused/img/reverse.png b/slides/unused/img/reverse.png
new file mode 100644
index 0000000000000000000000000000000000000000..b802283dba1c4ce186b23e2f2e81501dd126bb97
Binary files /dev/null and b/slides/unused/img/reverse.png differ
diff --git a/slides/unused/img/scrollbar-p2.png b/slides/unused/img/scrollbar-p2.png
new file mode 100644
index 0000000000000000000000000000000000000000..d77624497279e1529dd5b4c9e3440e657592f643
Binary files /dev/null and b/slides/unused/img/scrollbar-p2.png differ
diff --git a/slides/unused/img/scrollbar-p3.png b/slides/unused/img/scrollbar-p3.png
new file mode 100644
index 0000000000000000000000000000000000000000..aee4764b651e30f17952d8b6fcbe7b131a773dbb
Binary files /dev/null and b/slides/unused/img/scrollbar-p3.png differ
diff --git a/slides/unused/img/select-colors.png b/slides/unused/img/select-colors.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe0aaec670e8e9070320f328b2ce1e343274689b
Binary files /dev/null and b/slides/unused/img/select-colors.png differ
diff --git a/slides/unused/img/select-shapes.png b/slides/unused/img/select-shapes.png
new file mode 100644
index 0000000000000000000000000000000000000000..14c3341a45c65f2962d5995880ccb96e4960a187
Binary files /dev/null and b/slides/unused/img/select-shapes.png differ
diff --git a/slides/unused/img/sensing/aware-study.png b/slides/unused/img/sensing/aware-study.png
new file mode 100644
index 0000000000000000000000000000000000000000..f2f4fa24d33e4340774d383feeb610bcf9d03655
Binary files /dev/null and b/slides/unused/img/sensing/aware-study.png differ
diff --git a/slides/unused/img/sensing/aware_overview1.png b/slides/unused/img/sensing/aware_overview1.png
new file mode 100644
index 0000000000000000000000000000000000000000..e8c605485445b1d5d1cd0a38771b71814b976fd9
Binary files /dev/null and b/slides/unused/img/sensing/aware_overview1.png differ
diff --git a/slides/unused/img/sketch-styled.png b/slides/unused/img/sketch-styled.png
new file mode 100644
index 0000000000000000000000000000000000000000..b7280859cec521e6ae8bc5981904f00f187310d6
Binary files /dev/null and b/slides/unused/img/sketch-styled.png differ
diff --git a/slides/unused/img/snapping.gif b/slides/unused/img/snapping.gif
new file mode 100644
index 0000000000000000000000000000000000000000..e716fad939bd04ed7868a3376239cb412ceed2eb
Binary files /dev/null and b/slides/unused/img/snapping.gif differ
diff --git a/slides/unused/img/source.png b/slides/unused/img/source.png
new file mode 100644
index 0000000000000000000000000000000000000000..05d2d1e4836a77cfd3b37501f0e364130790b5f9
Binary files /dev/null and b/slides/unused/img/source.png differ
diff --git a/slides/unused/img/spectrum.png b/slides/unused/img/spectrum.png
new file mode 100644
index 0000000000000000000000000000000000000000..c89c3b4fec26db2544598bf4e552fb843483b816
Binary files /dev/null and b/slides/unused/img/spectrum.png differ
diff --git a/slides/unused/img/static-interactive.png b/slides/unused/img/static-interactive.png
new file mode 100644
index 0000000000000000000000000000000000000000..8080782000520e0199b0d574ad08ad3dc8d921fc
Binary files /dev/null and b/slides/unused/img/static-interactive.png differ
diff --git a/slides/unused/img/timeoverid.png b/slides/unused/img/timeoverid.png
new file mode 100644
index 0000000000000000000000000000000000000000..a633d97047b1974ec59e5811c2c768ebac148502
Binary files /dev/null and b/slides/unused/img/timeoverid.png differ
diff --git a/slides/unused/img/trueblue.png b/slides/unused/img/trueblue.png
new file mode 100644
index 0000000000000000000000000000000000000000..b318d002f47f0a680bfb96d6b867f48f6c572dd6
Binary files /dev/null and b/slides/unused/img/trueblue.png differ
diff --git a/slides/unused/img/visual-eg.png b/slides/unused/img/visual-eg.png
new file mode 100644
index 0000000000000000000000000000000000000000..08029b57adb2d300013caf369af485ca7a3b5480
Binary files /dev/null and b/slides/unused/img/visual-eg.png differ
diff --git a/slides/unused/l04-state.html b/slides/unused/l04-state.html
new file mode 100644
index 0000000000000000000000000000000000000000..71a506b109bed2994b449d1bd5ff89866aae1b83
--- /dev/null
+++ b/slides/unused/l04-state.html
@@ -0,0 +1,376 @@
+---
+layout: presentation
+title: Lab 04 Saving State in Android --Week 4, Thursday--
+description: Introduction to state management in Android
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+template: inverse
+
+# Interactivity Lab (Fall 2018)
+## Week 3: State
+
+Instructor: TBD
+_{email}_
+
+Slides online: xxxTODO url
+
+---
+layout: false
+
+# Goals for Today
+
+---
+layout: false
+
+# Goals for Today
+
+- Understanding more about __Activities__
+- Learn about __State and Data Persistence__
+---
+template: inverse
+
+# Saving State
+---
+layout: false
+
+.left-column[## Activity Lifecycle]
+.right-column[![:img Android activity lifecycle, 50%](img/activity_lifecycle.png)]
+
+
+---
+
+.left-column[## When to save state? (1/3)]
+.right-column[![:img Android activity state diagram, 50%](img/android-activity-states-01.png)]
+
+
+---
+
+.left-column[## When to save state? (2/3)]
+.right-column[![:img Android activity state diagram -- process killed, 50%](img/android-activity-states-02.png)]
+
+---
+
+.left-column[# When to save state? (3/3)]
+.right-column[
+- Activity `A` spawns Activity `B`
+  - E.g. Typing a Facebook post, then you select 'Add a Location'
+]
+--
+.right-column[
+- Android kills `A` to reclaim resources while the user is interacting with `B`
+]
+--
+.right-column[
+- User finishes with `B`, returns to `A` but the post is gone!
+]
+---
+
+# Maintaining Activity State
+
+- We can fix it by saving the state in a `Bundle` before Android closes the `Activity`
+
+- We then restore the state when we return to the `Activity` later
+
+---
+
+# Bundle it up
+
+- `Bundle`: A hash map (dictionary) of String keys to Primitive, Parcelable, Serializable values
+
+--
+
+- Used to:
+  (1) Save/restore state
+  (2) Transfer data between different `Activity` in an app
+
+--
+
+- Primitive are `int`, `float`, `boolean`, `double` (the usual suspects)
+
+--
+
+- Custom objects that implement the `Serializable` or `Parcelable` interfaces
+  - You will need to make any custom classes that you want to save into a `Bundle` implement the `Parcelable` interface
+
+---
+
+# Parcelable vs. Serializable
+
+- Both are for the same purpose of saving but `Serializable` makes implementations much easier...
+
+--
+
+- **EXCEPT, .red[you should almost always use `Parcelable`]**
+
+
+--
+
+- Why?
+  - `Serializable` uses introspection ==> more memory, and CPU cycles
+  - `Parcelable` **is optimized for mobile devices**
+
+---
+## Implementing `Parcelable` (1/3)
+
+-- You are required to implement the following methods for the `Parcelable` interface:
+
+```java
+public class MyPersonModel implements Parcelable {
+    private int mAge;
+
+    // Required for the interface
+    public int describeContents() {
+        return 0;
+    }
+
+    // Required for the interface
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mAge);
+    }
+    // Continued on next slide...
+```
+
+---
+
+## Implementing `Parcelable` (2/3)
+
+```java
+
+    // Required for the interface
+    // CREATOR is an object that can remark
+    public static final Parcelable.Creator<MyPersonModel> CREATOR
+            = new Parcelable.Creator<MyPersonModel>() {
+        public MyPersonModel createFromParcel(Parcel in) {
+            return new MyPersonModel(in);
+        }
+
+        public MyPersonModel[] newArray(int size) {
+            return new MyPersonModel[size];
+        }
+    };
+
+    // Required for the interface
+    // Private constructor for Android to use with your CREATOR
+    private MyPersonModel(Parcel in) {
+        mAge = in.readInt();
+    }
+}
+```
+---
+
+## Implementing `Parcelable` (3/3)
+- **Note**: .red[the order of the values when writing and reading them matters!]
+
+  - When you write to the parcel using `write*()` methods in `writeToParcel`,
+
+  - The write order __MUST BE__ the same as when you read them in the private constructor
+
+- For more details on implementation:
+  https://developer.android.com/reference/android/os/Parcelable.html
+
+---
+
+# Saving in the Bundle
+
+- Methods for _saving_ items out of a Bundle
+
+  - Ints: `putInt(String key, int value)`
+
+  - Floats: `putFloat(String key, float value)`
+
+  - Characters: `putChar(String key, char value)`
+
+  - Strings: `putString(String key, String value)`
+
+  - Serializable Objects: `putSerializable(String key, Serializable value)`
+
+  - Parcelable Objects: `putParcelable(String key, Parcelable value)`
+
+  - _Others in the documentation (e.g. Arrays, Bytes, etc).._
+    https://developer.android.com/reference/android/os/Bundle.html
+
+---
+# Retrieving from the Bundle
+
+- Methods for getting items out of a Bundle
+
+  - Ints: `getInt(String key)`
+
+  - Floats: `getFloat(String key)`
+
+  - Characters: `getChar(String key)`
+
+  - Strings: `getString(String key)`
+
+  - Serializable Objects: `getSerializable(String key)`
+
+  - Parcelable Objects: `getParcelable(String key)`
+
+  - _Others in the documentation_ (e.g. Arrays, Bytes, etc)..
+    https://developer.android.com/reference/android/os/Bundle.html
+---
+## Saving Activity State (1/3)
+- Android provides the `onSaveInstanceState(Bundle savedInstanceState)` callback method for you to save the state of an `Activity`
+
+```java
+private static final USERNAME_KEY = "USER_NAME_KEY";
+private static final FIB_SUM_KEY = "FIB_SUM_KEY";
+
+private int mFibSumValue; // Set to 10295 by our user
+private String mUsername; // Set to "Michael" by our user
+
+@Override
+public void onSaveInstanceState(Bundle outState) {
+    // Always call super - your super classes could be saving state for you!
+    super.onSaveInstanceState(outState);
+
+    // Now
+    outState.putInt(FIB_SUM_KEY, mFibSumValue);
+    outState.putString(USERNAME_KEY, mUsername);
+}
+```
+---
+
+## Restoring Activity State (1/4)
+
+- We saved, and now our user goes off to some other app
+
+--
+
+- Android kills our `Activity`
+
+--
+
+- Now how do we get the _saved_ state back?
+
+---
+## Restoring Activity State (2/4)
+
+-  Two ways:
+  - `onCreate(Bundle savedInstanceState)`
+  - `onRestoreInstanceState(Bundle savedInstanceState)`
+
+---
+## Restoring Activity State (3/4)
+
+- Using `onCreate(Bundle savedInstanceState)`...
+
+```java
+private static final USERNAME_KEY = "USER_NAME_KEY";
+private static final FIB_SUM_KEY = "FIB_SUM_KEY";
+
+private int mFibSumValue = 0;
+private String mUsername = null;
+
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+  super.onCreate(savedInstanceState);
+  setContentView(R.layout.activity_main);
+
+  mMainTextView = (TextView) findViewById(R.id.text_main_title);
+  mSumTextView = (TextView) findViewById(R.id.text_sum);
+  // Check if there was a previously saved state to restore to the user
+  // A non-null bundle means there was a state that was saved previously
+  // A bundle is just a Key-Value pairing - its a hash map :)
+  if (savedInstanceState != null) {
+    // There was a previous state - time to restore
+    mFibSumValue = savedInstanceState.getInt(FIB_SUM_KEY);
+    mUsername = savedInstanceState.getString(USERNAME_KEY);
+  }
+  updateMainText();
+  updateFibSumText();
+}
+```
+
+---
+
+## Restoring Activity State (4/4)
+
+- Using `onRestoreInstanceState(Bundle savedInstanceState)`
+
+```java
+private static final USERNAME_KEY = "USER_NAME_KEY";
+private static final FIB_SUM_KEY = "FIB_SUM_KEY";
+private int mFibSumValue = 0;
+
+@Override
+protected void onRestoreInstanceState(Bundle savedInstanceState) {
+  super.onRestoreInstanceState(savedInstanceState);
+  // Check if there was a previously saved state to restore to the user
+  if (savedInstanceState != null) {
+    // There was a previous state - time to restore
+    mFibSumValue = savedInstanceState.getInt(FIB_SUM_KEY);
+    mUsername = savedInstanceState.getString(USERNAME_KEY);
+  }
+  updateMainText();
+  updateFibSumText();
+}
+```
+
+---
+
+### Restoring in `onCreate` vs. `onRestoreInstanceState`
+- `onRestoreInstanceState`
+  - Guarantees you will never have a non-null `Bundle` when called
+  - Lets subclasses override the behavior of restoring the state
+
+- `onCreate`
+  - Lets you focus on doing all of your initialization in one place
+
+- You decide what works best for you :)
+
+- http://stackoverflow.com/questions/36408776/using-oncreate-vs-onrestoreinstancestate
+
+---
+
+## Exercise: Parcelable and Activity State
+
+- Pair up!
+
+- Download the base code here:
+
+- This app lets a user enter a name, age, and favorite food
+
+- It stores this info in a `PersonModel`
+
+- When the app is killed, this information needs to remain edited
+
+- Implement the `Parcelable` interface for the PersonModel
+
+- Then use the Activity's relevant state change callbacks to `PersonModel` when the phone rotates
+
+---
+### Some Notes about `onSaveInstanceState()`
+- .red[Only use to save and restore session variables and the state of the UI]
+
+--
+
+  - Android won't always trigger the method
+
+--
+
+  - It is called when the `Activity` is closed and _expected_ to be restored soon
+
+--
+
+- If your app crashes, or is closed, **the values in the bundle will disappear!**
+
+--
+
+- If you use custom views, you can implement their version of `onSaveInstanceState`:
+
+  Android will call `onSaveInstanceState()` every view in the layout
+
+---
+# Project Work: Add Save State
+
+
+---
+# End of Slides
+    
+---
+
diff --git a/slides/unused/lofi.html b/slides/unused/lofi.html
new file mode 100644
index 0000000000000000000000000000000000000000..67ae041a22de92c24ff14b2931efc4a1ceba3334
--- /dev/null
+++ b/slides/unused/lofi.html
@@ -0,0 +1,138 @@
+---
+layout: presentation
+title: Layout --Week 2, Monday-- 
+description: Description of Layout
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Advanced Interaction Design
+
+Jennifer Mankoff
+CSE 340 Spring 2019 
+---
+layout:false
+
+background-image: url(img/paper.png)
+[//]: # (Outline Slide)
+# Today's goals
+- Problems with lo-fi prototypes
+- Understand user testing
+- Ethical considerations in testing
+- Collection and use of evidence
+---
+.left-column[## Problems with low-fi prototypes?]
+.right-column[
+![:img paper prototype, 20%](img/paper.png)
+]
+???
+-“Computer” inherently buggy
+-Can’t get accurate time measurement
+-Hard to implement some functionality: pulldowns, feedback, drag, viz …
+-Won’t look like final product: sometimes hard to recognize components
+-End-users can’t use by themselves: not in context of user’s work environment
+-Couldn’t measure realistic I/O
+-Lack of interactive feedback: e.g. button highlights
+-“Computer” has to keep track of a lot of paper
+-Users wouldn’t criticize UI
+-Doesn’t map well to what will actual fit on the screen 
+-Couldn’t hold in your hand – different ergonomics from target device
+-Some things could not be simulated (highlighting)
+-Writing on paper not the same as writing on target device / Hard to draw well (-recognition of elements)
+-Appearance unrealistic
+-Dynamic components hard to simulate (pop-ups)
+-Couldn’t give proper affordance that something wasn’t selectable
+-Some items had to be static!
+-Dragging hard to simulate
+---
+.left-column[## High Fi testing]
+.right-column[
+Must test & observe ideas with customers
+
+ - Want to compare and contrast
+ - Want to get more realistic reactions
+
+Paper mock-ups don’t go far enough
+ - How would you show a drag operation?
+ - Not realistic of how interface will be used
+
+Approaches
+ - Can fake it -- good for early
+ - Can implement it
+]
+---
+.left-column[## Review: Testing Goals
+![:img Cartoon of user test, 100%](img/cartoon.png)
+]
+.right-column[
+Choose your focus
+
+Task design:
+- Appropriate scope
+- Predictable outcomes
+- Elicits action
+]
+---
+.left-column[##Kinds of data we can collect?]
+???
+Discuss
+--
+.right-column[
+Video, Descriptions of behaviors, Notes
+Can transcribe and analyze individual users
+Can look for patterns across users
+]
+---
+.left-column[##Goal of data collection?]
+???
+Discuss
+--
+.right-column[
+What went well?
+What went badly?
+What matters (severe, common)?
+]
+---
+.left-column[##Qualitative data collection]
+.right-column[
+Identify Critical Incidents (can be good or bad)
+
+Critical Incidents are Situations that: 
+- Provoke silence 
+- Provoke puzzlement 
+- Provoke user comments 
+
+Capture using Critical Incident reports
+
+]
+---
+.left-column[#Critical Incident Report]
+.right-column[
+Name: System doesn’t treat “1” and “one” interchangeably
+Severity:   High/Medium/Low + Good/Bad
+Frequency:  (expected within system)
+Category: 
+The user accomplishes a goal, but in a suboptimal way OR
+The user expresses some negative affect or says something is a problem.
+Evidence: Report FACTS!
+What the user (s) said: “My destination is One Market Street” “This is not right, I don't think this is what I want to do.” (on “Multiple Search Results” page).
+
+What the user (s) did: After receiving the “no exact match” error message, the user hits the Back button to return to the trip planner and enters “1” instead of “One.”
+
+What the system did: The system presented the user with a “Multiple Search Results” page, with the error message “We found some locations similar to your destination entry, but no exact match.”  After the user returns to the trip planner and enters “1,” the system returns a bus route.
+]
+---
+.left-column[#Quantitative data]
+
+---
+layout: false
+
+.left-column[##Other Menus]
+.right-column[
+Kurtenbach:
+![:youtube Illustration of advantages of marking menus,dtH9GdFSQaw]
+]
+
+---
diff --git a/slides/unused/menus2.html b/slides/unused/menus2.html
new file mode 100644
index 0000000000000000000000000000000000000000..9c519a5bc5029b15097455969c849045d3d3348f
--- /dev/null
+++ b/slides/unused/menus2.html
@@ -0,0 +1,585 @@
+---
+layout: presentation
+title: Predicting and Evaluating Interactor Efficacy
+description: Discussion of Theory and Collection of User Data for assessing Interactor Efficacy
+class: middle, center, inverse
+---
+layout:false
+
+# Why is selection (and testing) important .red[*]
+.left-column50[
+
+![:img Image showing a false alarm in hawaii that led everyone to
+think there wsa a nuclear event, 100%](img/alert1.jpg)
+]
+.right-column50[
+![:img Image showing the screen that led to this error, 100%](img/alert.jpg)
+]
+
+.footnote[.red[*] [Washington Post Article](https://www.washingtonpost.com/news/morning-mix/wp/2018/01/16/that-was-no-wrong-button-in-hawaii-take-a-look/?utm_term=.1848969db923)
+]
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Predicting and Evaluating Interaction Efficacy
+
+Jennifer Mankoff
+CSE 340 Spring 2019 
+---
+layout: false
+
+[//]: # (Outline Slide)
+# Today's Learning goals
+- Introduce key coding concepts for Menus Assignment
+- **Using Properties of People To Predict Design Outcomes**
+---
+.title[Comments on Feedback]
+.body[
+Thanks for the feedback on the class!
+- Quizzes show. Assignments are taking a long time. We will try to post information
+about expected time, please reach out for help if you go beyond that
+
+- Start early (some people are starting ColorPicker today), so you can ask us for help with time to spare!
+
+]
+???
+Feedback from Monday 
+---
+.title[Menus Assignment]
+.body[
+Will compare pie menus to linear menus
+
+Demo
+]
+
+---
+.left-column50[
+## Interface  Structure
+
+<div class="mermaid">
+graph LR
+FrameLayout --> ActionBar[ActionBar]
+ActionBar --> TextView[TextView:Pie/Menu]
+ActionBar --> Hamburger[Hamburger:Next Session/ClearCSV]
+FrameLayout --> MainLayout[MainLayout]
+MainLayout --> MenuExperimentView[MenuExperimentView]
+MainLayout --> InstructionText[InstructionTextView]
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+class FrameLayout,ActionBar,MainLayout,TextView,Hamburger,MenuExperimentView,InstructionText normal
+</div>
+]
+
+.right-column50[
+## Inheritance Structure
+
+<div class="mermaid">
+graph LR
+MenuExperimentView[MenuExperimentView] --> PieMenuView[PieMenuView]
+MenuExperimentView --> NormalMenuView[NormalMenuView]
+</div>
+
+]
+ 
+---
+.title[PPS for assignment]
+.body[
+Implemented in MenuExperimentView
+
+<div class="mermaid">
+graph LR
+S((.)) --> A((Start))
+A -- "Press?drawMenu;startTrial;startPoint=p" --> I((Inside))
+I -- "Release:endTrial;reset();onOptionSelected(trial)" --> E[End]
+I -- "Drag:currentIndex=menuItem" --> I
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+class S invisible
+class A start
+class E finish
+class I normal
+</div>
+
+
+Works in both Menus!
+]
+
+---
+.title[Enums]
+.body[
+
+Group of named constants
+
+- Used for PPS in colorPicker (PPS States; Essential Geometry)
+
+- Used for PPS in Menu assignment *and* for experimental conditions
+
+- Easy to inspect if you want to (we do this in ExperimentSession)
+
+[Documentation](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)
+]
+
+---
+.title[Custom Listeners]
+.body[
+- Used in ColorPicker and Menus. You'll use them lots
+- Why create custom listeners?
+]
+--
+.body[
+ - Let you execute code when your view's model has changed
+ - No other way to know that has happened
+
+]
+
+---
+.title[How to implement]
+.body[
+
+Custom View needs
+- To define the custom interface 
+- To keep track of listeners
+]
+--
+.body[
+Anything using the view needs
+- To implement the interface (specifically, the method that will be called)
+- To register itself as a listener
+]
+---
+.title[Example Custom View -- ColorPicker: We setup the Custom View side for you]
+.body[
+```java
+    /** Currently registered ColorListener instance or null. */
+    protected ColorListener mColorListener;
+
+    /**
+     * Class which defines a listener to be called when a new color is selected.
+     */
+    public interface ColorListener {
+        void onColorSelected(@ColorInt int color);
+    }
+
+    /**
+     * Registers a new listener for the color of this ColorPicker, or replaces
+     * any existing listener.
+     *
+     * @param colorListener New listener or null.
+     */
+    public final void setColorListener(@Nullable ColorListener colorListener) {
+        mColorListener = colorListener;
+    }
+```
+]
+---
+.title[You need to do this yourself in Menus]
+
+.body[
+
+```java
+ /**
+     * You need to create a listener interface so the application
+     * can be notified when a selection is made. This will trigger
+     * the move to the next trial.
+     */
+    protected MenuExperimentViewSolution.MenuListener menuListener;
+```
+]
+---
+.title[Example Custom Listener -- ColorPicker: You need to implement
+this]
+
+.body[
+`// TODO: Register callback to update {color,label} View when color changed.`
+
+What method do we call to register the callback?  setColorListener
+
+What method is called when?
+
+What do we usually do in a callback? update application state
+]
+???
+ Draw a time based diagram 
+---
+.title[Listener in Menus]
+.body[
+`setMenuListener` needs to be implemented, should
+
+- record the result of that trial
+- Update the experiment to show the next menu (or nothing if the
+session is over)
+- Update the instructions to the user
+]
+---
+.title[OnDraw changes to Canvas]
+.body[
+Views `MATCH_PARENT`
+
+Makes drawing tricky
+
+Translate (like a parent view does for kids)
+
+]
+---
+layout: false
+
+[//]: # (Outline Slide)
+# Today's Learning goals
+- Introduce key coding concepts for Menus Assignment
+- **Using Properties of People To Predict Design Outcomes**
+---
+.title[Fitts Law]
+.body[
+Quiz Results to discuss
+]
+
+---
+.title[Other laws we might use to make predictions about what will go better]
+.body[
+- Fitts Law (compare distance and size; check for infinite size)
+- Steering Law (distance and size over a path)
+- Cognitive modeling (complex multi-step model of expert behavior)
+ - Does someone have to 'check' something? More than once?
+ - Do they have to move? More than once
+- Gestalt Psychology (will they see it at all?)
+- Errors (will they be reduced)
+]
+ ---
+#Which is better and which laws explain it?
+.left-column50[
+#A Pie Menu
+![:img Pie Menu, 80%](img/pie.jpg)
+]
+.right-column50[
+#B Pull down Menu
+![:img Traditional Menu inside a web browser, 80%](img/menu.png)
+]
+???
+
+What analysis methods can we use to predict?
+
+- Fitts Law (compare distance and size; check for infinite size)
+- Steering Law (distance and size over a path)
+- Cognitive modeling (complex multi-step model of expert behavior)
+ - Does someone have to 'check' something? More than once?
+ - Do they have to move? More than once
+- Gestalt Psychology (will they see it at all?)
+- Errors (will they be reduced)
+
+---
+# Which is better and which law explains it?
+.left-column50[
+#A Pie Menu
+![:img Pie Menu, 80%](img/pie.jpg)
+]
+.right-column50[
+#B Marking Menu
+![:youtube Video assigned before class, 8c58bN6ajJ4?t=30]
+]
+???
+
+- Fitts Law (compare distance and size; check for infinite size)
+- Steering Law (distance and size over a path)
+- Cognitive modeling (complex multi-step model of expert behavior)
+ - **Does someone have to 'check' something? More than once?**
+ - **Do they have to move? More than once**
+- Gestalt Psychology (will they see it at all?)
+- Errors (will they be reduced)
+---
+.title[Which is better and which laws explain it?]
+
+.body[
+A: Tapping B: Crossing
+![:youtube Video of using crossing for selection, kp2Zl4ONuik]
+]
+
+???
+
+- **Fitts Law (compare distance and size; check for infinite size)**
+- Steering Law (distance and size over a path)
+- Cognitive modeling (complex multi-step model of expert behavior)
+ - Does someone have to 'check' something? More than once?
+ - Do they have to move? More than once
+- Gestalt Psychology (will they see it at all?)
+- Errors (will they be reduced)
+
+---
+#Which is better and which laws explain it?
+.left-column50[
+#A
+![:img Picture of the Graffiti gesture recognition alphabet from the Palm Pilot, 100%](img/Grafitti.png)
+]
+.right-column50[
+#B
+![:img Picture of the Edgewrite gesture recognition alphabet, 50%](img/Edgewrite.png)
+
+]
+???
+
+- Fitts Law (compare distance and size; check for infinite size)
+- Steering Law (distance and size over a path)
+- Cognitive modeling (complex multi-step model of expert behavior)
+ - Does someone have to 'check' something? More than once?
+ - Do they have to move? More than once
+- Gestalt Psychology (will they see it at all?)
+- **Errors (will they be reduced)**
+
+---
+#Which is better and which laws explain it?
+
+.left-column50[
+#A
+![:img Picture of old facebook security page with icons and text mixed
+up,100%](img/facebook.png)
+]
+.right-column50[
+#B
+
+![:img Picture of March 2019 facebook security page with icons and
+text clearly aligned, 100%](img/facebook2.png)
+]
+???
+
+- Fitts Law (compare distance and size; check for infinite size)
+- Steering Law (distance and size over a path)
+- Cognitive modeling (complex multi-step model of expert behavior)
+ - Does someone have to 'check' something? More than once?
+ - Do they have to move? More than once
+- **Gestalt Psychology (group?)**
+- **Errors (will they be reduced)**
+---
+# How do we actually **prove** such theories?
+
+--
+# Collect Data!
+---
+
+.left-column[##Kinds of data we can collect?]
+???
+Discuss
+--
+.right-column[
+- Video
+- Timing/Errors
+- Descriptions of behaviors
+- Notes
+- Can transcribe and analyze interviews with users
+- Can look for patterns across users
+]
+---
+.left-column[##Qualitative data collection to test theory]
+.right-column[
+Identify Critical Incidents (can be good or bad)
+
+Critical Incidents are Situations that: 
+- Provoke silence 
+- Provoke puzzlement 
+- Provoke user comments 
+
+Capture using Critical Incident reports
+
+]
+---
+.left-column[##Quantitative data collection to test theories]
+.right-column[
+Identify Hypothesis
+
+Hypothesis is 
+- Relevant
+- Testable
+
+Capture data that proves or disproves hypothesis
+
+]
+---
+# How do we prove our theories? Hypothesis
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis((Hypothesis))
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+
+
+class S invisible
+class Hypothesis start
+</div>
+
+
+---
+# How do we prove our theories? Method
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis((Hypothesis))
+Hypothesis -- "Study Design" --> Method((Method))
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+
+
+class S invisible
+class Hypothesis start
+class Method normal
+</div>
+
+
+---
+# How do we prove our theories? Data
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis((Hypothesis))
+Hypothesis -- "Study Design" --> Method((Method))
+Method -- "Run Study" --> Data((Data))
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+
+
+class S invisible
+class Hypothesis start
+class Method,Data normal
+</div>
+---
+# How do we prove our theories? Analysis
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis((Hypothesis))
+Hypothesis -- "Study Design" --> Method((Method))
+Method -- "Run Study" --> Data((Data))
+Data -- "Clean and Prep" --> Analysis((Analysis))
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+
+
+class S invisible
+class Hypothesis start
+class Method,Data,Analysis normal
+</div>
+
+---
+# How do we prove our theories? Conclusions
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis((Hypothesis))
+Hypothesis -- "Study Design" --> Method((Method))
+Method -- "Run Study" --> Data((Data))
+Data -- "Clean and Prep" --> Analysis((Analysis))
+Analysis --> Conclusions((Conclusions))
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+linkStyle 4 stroke-width:4px;
+
+
+class S invisible
+class Hypothesis,Conclusions start
+class Method,Data,Analysis normal
+</div>
+
+.left-column50[
+#A
+![:img Picture of the Graffiti gesture recognition alphabet from the Palm Pilot, 100%](img/Grafitti.png)
+]
+.right-column50[
+#B
+![:img Picture of the Edgewrite gesture recognition alphabet, 50%](img/Edgewrite.png)
+
+]
+
+???
+Hypothesis: Errors (will they be reduced)
+Method:?? 
+Data:??
+Analysis??
+Conclusions??
+
+---
+# How do we prove our theories? Conclusions
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis((Hypothesis))
+Hypothesis -- "Study Design" --> Method((Method))
+Method -- "Run Study" --> Data((Data))
+Data -- "Clean and Prep" --> Analysis((Analysis))
+Analysis --> Conclusions((Conclusions))
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+linkStyle 4 stroke-width:4px;
+
+
+class S invisible
+class Hypothesis,Conclusions start
+class Method,Data,Analysis normal
+</div>
+
+.left-column50[
+#A Pie Menu
+![:img Pie Menu, 80%](img/pie.jpg)
+]
+.right-column50[
+#B Pull down Menu
+![:img Traditional Menu inside a web browser, 80%](img/menu.png)
+]
+???
+
+Hypothesis: Errors will be reduced; 
+Hypothesis: Motion will be faster due to low level motor things 
+Hypothesis: fewer cognitive checks needed
+Method:?? 
+Data:??
+Analysis??
+Conclusions??
diff --git a/slides/unused/midterm.html b/slides/unused/midterm.html
new file mode 100644
index 0000000000000000000000000000000000000000..23b1bc0a437338e6db71f3130ed4aeda9394370c
--- /dev/null
+++ b/slides/unused/midterm.html
@@ -0,0 +1,85 @@
+---
+layout: presentation
+title: Midterm Recap
+description: Discussion of some Midterm Questions
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Midterm Recap
+
+Jennifer Mankoff
+
+CSE 340 Spring 2019 
+---
+layout: false
+
+.title[Midterm Histogram]
+.body[
+
+![:img Histogram of Midterm Grades, 100%](img/midterm/histogram.png)
+]
+---
+
+.title[Question Breakdown]
+.body[
+
+<div class="mermaid">![:img Question Breakdown, 90%](img/midterm/qs.png)
+</div>]
+---
+
+.title[Sampling of questions]
+.body[
+Your boss has read up on Fitts’ law, and wants to put all the controls
+at the bottom of the screen so they have infinite width and are easier
+to click on. However, your colleague argues that they should be in a
+pie menu which should pop up wherever the user presses instead. 
+
+- D and W in each case
+- Which is better?
+- Time savings for eyes free (HARD!)
+]
+???
+
+---
+.title[Given an interface draw an interactor hierarchy]
+.body[
+What defines an interactor hierarchy?
+
+]
+
+???
+has a root
+only has views in it
+is a tree
+--
+.body[
+What is damaged? Everything under the damaged region
+]
+---
+.title[Callbacks]
+.body[
+
+You have registered your app to listen for OffRoute callbacks (when the driver’s vehicle deviates from the route, onOffRoute() will be called). Correctly label each method call, based on what object (Application or View) calls it, and where you would put the code to implement it. 
+
+ |                         | Called by application or view? | Implemented in application or view? |
+ |-------------------------|--------------------------------|-------------------------------------|
+ | onOffRoute()            |                                |                                     |
+ | setOnOffRouteListiner() |                                |                                     |
+
+]
+
+???
+view -- app
+app -- view
+---
+.title[Draw a PPS]
+.body[
+Let's do it for a button
+]
+---
+
+
+
diff --git a/slides/unused/paper.html b/slides/unused/paper.html
new file mode 100644
index 0000000000000000000000000000000000000000..9a66d11245cfe4ed14ee353afeb9999ec1c6aadb
--- /dev/null
+++ b/slides/unused/paper.html
@@ -0,0 +1,479 @@
+---
+layout: presentation
+title: Layout --Week 2, Monday-- 
+description: Description of Layout
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# XXX need to cut back on these slides significantly to focus on exercise...
+---
+layout:false
+
+# Marc Rettig’s Problems with Hi-Fi Prototypes
+
+Can you list some?
+???
+Hi-Fi prototypes take too long to build and change
+
+Reviewers and testers tend to comment on detailed, low-level issues rather than big picture
+
+Developers resist change
+
+A prototype in software can set expectations that are hard to change
+
+A single bug in a hi-fi prototype can bring a test to a complete halt
+
+---
+template:inverse
+
+# Quiz
+---
+# Paper Prototyping
+
+![:img Paper Prototyping, 20%](img/paper-prototype-example.jpg)
+
+Jennifer Mankoff
+CSE 340 Spring 2019
+
+---
+# Example of Paper Prototyping
+
+![:youtube Paper Prototyping of video game,9wQkLthhHKA]
+
+---
+layout:false
+
+.left-column[
+![:img Rettig Paper, 100%](img/p21-rettig.png)
+Marc Retting: Prototyping for Tiny Fingers. CACM 1994]
+
+.right-column[Paper prototyping is potentially a breakthrough idea for
+organizations that have never tried it, since it allows you to
+.red[demonstrate the behavior of an interface very early] in
+development, and .red[test designs with real users]...]
+--
+.right-column[
+It is .red[fast], it .red[brings results early] in development (when it is
+relatively cheap to make changes), and allows a team to
+.red[try far more ideas] than they could with high-fidelity
+prototypes. Lo-fi prototyping 
+helps you apply Fudd's first law of creativity: 'To get a good idea,
+get lots of ideas.'
+]
+
+---
+background-image: url(img/background-paper.png)
+
+.left-column[## What is Paper Prototyping?]
+--
+
+.right-column[
+Fast and cheap way to create and test user interfaces]
+
+--
+
+.right-column[
+It's equivalent to storyboarding in the film industry
+]
+
+--
+
+.right-column[
+Focuses on function, less on form
+]
+--
+
+.right-column[
+All you need: pen, paper (and possibly scissors/tape)
+]
+
+---
+.left-column[Paper Prototypes
+
+![:img hand pointing at drawing interface, 100%](img/drawing-interface.png)
+]
+.right-column[
+Show what an interface … 
+- looks like (sort of)
+- flows like (from screen to screen)
+- interacts like (for some things)
+
+Should be… 
+- Fast to build
+- Lo-fi or hi-fi
+
+Support … 
+- Iteration
+- Ideation
+- User testing
+]
+---
+.left-column[Paper Prototypes
+![:img hand pointing at drawing interface, 100%](img/drawing-interface.png)
+]
+.right-column[
+Can uncover what a user ...
+- fill in
+<br>
+<br>
+<br>
+Cannot uncover ...
+- fill in
+]
+???
+
+can uncover:
+- Notices
+- Prefers
+- Finds Accessible
+- Knows
+cannot uncover:
+Interaction
+Load Times
+Context aware (hard)
+---
+## Today's learning goals
+
+Why paper prototypes?
+
+How to make paper prototypes 
+
+Hands-on experience rapidly making a paper prototype
+
+Understand what paper prototyping is and isn’t good for
+
+Begin to understand the role of study design in prototyping
+
+---
+template:inverse
+
+# More Examples
+---
+layout:false
+
+.left-column[## Example Prototype Dimensions
+
+There are other spectrums, but <br> these three are <br> very important
+]
+.middle-column[
+## &nbsp;&nbsp;Faster &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  &nbsp;  &nbsp;  &nbsp;  Slower.red[*]
+![:img skteched vs styled, 70%](img/sketch-styled.png)
+
+The visual look of your prototype is its most salient dimension. If not properly selected, it can sidetrack prototype reviews. Go hi-fi too soon and users will focus on aesthetics like color and font choice, which is not appropriate in early stages.
+]
+ .small[.red[*]Source: [Smashing Magazine](http://www.smashingmagazine.com/2010/06/16/design-better-faster-with-rapid-prototyping/)]
+---
+.left-column[##Visual Dimension
+
+Prototyping the Nintendo Wii UI .red[*]]
+
+.right-column[
+![:img A wii prototype, 70%](img/visual-eg.png)
+
+When a prototype looks like an early design, your users will be more comfortable providing candid—and often more critical—feedback  
+
+]
+
+.small.red[[Source: Gamustra](http://www.gamasutra.com/view/news/181321/Sometimes_paper_is_your_best_prototyping_tool__even_if_youre_Nintendo.php#.UK95NofAd8G)]
+
+???
+http://www.gamasutra.com/view/news/181321/Sometimes_paper_is_your_best_prototyping_tool__even_if_youre_Nintendo.php#.UK95NofAd8G
+
+'Oh, it's made out of cardboard! (laughs)'- Nintendo president Satoru
+Iwata marvels atthe simplicity of an early prototype of the Wii U's
+tablet controller (pictured above).Nintendo is banking on its
+Miiverse -- a sort of mini-Facebook with a layer of console game --
+	 -- makeup -- to draw players to its new Wii U console. It was
+a new concept, running on a new type of game hardware with the
+tablet-like GamePad.
+
+Nintendo contracted fellow Kyoto social media
+company Hatena Co. Ltd. to do a lot of the Miiverse design work. The
+Wii U's tablet-infused GamePad hadn't been finalized yet, but Hatena
+UI designer Kazuyuki Motoyama felt that he needed to know how the
+Miiverse would feel in his hands, so the company developed the basic
+feel of it with this simple cardboard prototype.
+
+'We wouldn't know how it felt unless we could actually hold it, but
+since we didn't have one, the only thing to do was make one,' Motoyama
+explains. 'In the middle of the night, I cut pieces of cardboard and
+glued them together.'
+
+Ithink there's a game development lesson here. You can prototype just
+about anything with the tools available to you, on just about any
+budget. Whether it's paper or an HTML website or even a free copy of
+UDK or Unity, you shouldn't let available technology hold you back
+from trying new ideas.
+
+If paper prototyping is good enough for a feature embedded in millions of Nintendo-made consoles, it's probably good enough for you too. 
+
+---
+.left-column[## Example Prototype Dimensions
+
+There are other spectrums, but these three are very important
+]
+.middle-column[
+## &nbsp;&nbsp;Faster  &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  &nbsp;  &nbsp;  &nbsp;  Slower.red[*]
+![:img skteched vs styled, 70%](img/sketch-styled.png)
+
+![:img static vs interactive, 70%](img/static-interactive.png)
+
+
+Does the prototype reveal how the solution will work (static) or does
+it appear to be fully functional and respond to user input
+(interactive)?   
+
+]
+
+.small[.red[*][Source: Smashing Magazine](http://www.smashingmagazine.com/2010/06/16/design-better-faster-with-rapid-prototyping/)]
+
+---
+.left-column[##Functional Dimension
+
+Prototyping the Nintendo Wii UI .red[*]]
+
+.right-column[
+![:img A wii prototype, 70%](img/visual-eg.png)
+
+Here the screen is made of paper. The controller is made of
+cardboard. But the design is interactive: The user clicks on a
+button and the facilitator updates the resulting paper interface
+
+]
+
+.small[.red[*][Source: Gamustra](http://www.gamasutra.com/view/news/181321/Sometimes_paper_is_your_best_prototyping_tool__even_if_youre_Nintendo.php#.UK95NofAd8G)]
+---
+
+
+.left-column[## Example Prototype Dimensions
+
+There are other spectrums, but these three are very important
+]
+.middle-column[
+## &nbsp;&nbsp;Faster &nbsp; &nbsp; &nbsp; &nbsp;  &nbsp;  &nbsp;  &nbsp;  Slower.red[*]
+![:img skteched vs styled, 70%](img/sketch-styled.png)
+
+![:img static vs interactive, 70%](img/static-interactive.png)
+
+![:img lorum ipsum vs real content, 70% ](img/lorem-content.png)
+
+
+Displaying content? Early on, just squiggly lines, then maybe dummy
+text (though this can distract—be careful), then actual content.]
+]
+---
+.left-column[##'Point of need' Computing .red[*]]
+.right-column[
+![:img Picture of a wall mounted paper interface, 70% ](img/palplates.png)
+
+
+.red[*]
+Supporting knowledge workers beyond the desktop with
+PALPlates. Mankoff, Jennifer, and  Bill Schilit. CHI 1997.
+]
+---
+# Prototyping Concerns
+.left-column[## Choosing your focus]
+.right-column[
+![:img Prototyping Cartoon, 70%](img/cartoon.png)
+]
+---
+# Prototyping Concerns
+.left-column[
+### Task Design
+- Appropriate scope
+- Predictable outcomes
+- Elicits action
+]
+--
+.middle-column[
+### Prototype Design
+
+Each card represents one sub-screen/task element
+- Use a photocopier to make many version
+- Use post-its and notecards for different regions of the screen
+
+Simple is great
+]
+---
+# Prototyping Concerns
+.left-column[## Choosing your focus
+
+### Task Design
+- Appropriate scope
+- Predictable outcomes
+- Elicits action
+]
+.middle-column[
+### Prototype Design
+
+Each card represents one sub-screen/task element
+- Use a photocopier to make many version
+- Use post-its and notecards for different regions of the screen
+
+Simple is great
+]
+.right-column[
+### Roles
+- Real users
+- An observer or video camera
+- A human computer
+]
+
+???
+Computer should be mostly silent
+
+Accurate
+
+Wait for users to act
+
+---
+template:inverse
+
+#Importance of Testing .red[Multiple] Prototypes
+
+---
+layout:false
+.left-column[##Testing Multiple Prototypes
+<br>
+<br>
+Wiklund Thurrot &amp; Dumas<br>
+Human Factors Society 1992
+]
+.right-column[
+We have found subjects reluctant to be critical of designs when they are asked to assign a rating to the design. In our usability tests, we see the same phenomenon even when we encourage subjects to be critical. 
+]
+--
+.right-column[
+We speculate that the test subjects feel that giving a low rating to a
+product gives the impression that they are “negative” people, that the
+ratings reflect negatively on their ability to use computer-based
+technology, that some of the blame for a product’s poor performance
+falls on them, or that they don’t want to hurt the feelings of the
+person conducting the test.
+]
+
+---
+template:inverse
+
+#What are some strategies to combat this problem?
+---
+layout:false
+
+.left-column[##Eliciting Criticism]
+.right-column[
+Test low-fidelity prototypes that look unfinished
+
+Have independent testers (testers not invested in outcome)
+
+Show multiple prototypes/products & have them compare
+]
+---
+template: inverse
+# Exercise
+---
+layout: false
+## Exercise
+- Brainstorming - a To Do List app (7 mins)
+
+--
+
+- Paper Prototype the app in groups of 3 (20 mins)
+
+--
+
+- Come up with Task Scenarios (5 min)
+
+--
+
+- User Test with 2 students from another group (15 min)
+
+--
+
+- Discussion (10 min)
+
+--
+
+Things we would add if we had time!
+- Refine your Prototype (10 min)
+
+--
+
+- User Test with 1 student (10 min)
+
+---
+
+## Discussion
+
+--
+
+- What can and can't you learn from it?
+
+--
+
+- Why is this hard for mobile applications?
+  
+--
+
+  - Context-aware Applications?
+
+--
+
+- What other low-fi techniques can we use?
+---
+Sources:
+Storyboards, Paper Prototypes and Mockups
+Scott Klemmer’s HCI MOOC
+https://www.youtube.com/watch?v=z4glsttyxw8
+
+Paper Prototyping as a Usability Testing Technique
+https://usabilitygeek.com/paper-prototyping-as-a-usability-testing-technique/
+
+
+Also useful: wikipedia.org/wiki/Paper_prototyping
+Google image search: ‘paper prototyping’
+
+
+
+Book: Prototyping: A practitioner’s guide
+https://www.amazon.com/Prototyping-Practitioners-Todd-Zaki-Warfel/dp/1933820217
+
+Book: Paper Prototyping
+https://www.amazon.com/Paper-Prototyping-Interfaces-Interactive-Technologies/dp/1558608702
+
+
+Prototyping for tiny fingers. Rettig, Marc. Communications of the
+ACM 37.4 (1994
+
+Supporting knowledge workers beyond the desktop with
+PALPlates. Mankoff, Jennifer, and  Bill Schilit. CHI 1997.
+
+MoveableMaker: facilitating the design, generation, and assembly of
+moveable papercraft. Annett, Michelle, et al., UIST 2015. 
+
+ 
+---
+# Unused
+
+---
+ Example 1: Travellr
+
+![:youtube Paper Prototyping of travel app,_5FGeSQ7DBU]
+
+Example 2: Game (also video prototyping...)
+![:youtube Paper Prototyping of video game,x48qOA2Z_xQ]
+
+---
+# Complex has its place too .red[*]
+
+![:youtube Paper Prototyping of video game,v=0yh-omblujQ]
+
+[Long video](https://www.youtube.com/watch?v=eujk284JYOE) and [Full talk](https://www.youtube.com/watch?v=NO4Fml1UZA4)
+
+.red[*] Annett, Michelle, et al. MoveableMaker: facilitating the
+design, generation, and assembly of moveable papercraft. Proceedings
+of the 28th Annual ACM Symposium on User Interface Software &
+Technology. ACM, 2015. 
diff --git a/slides/unused/sensing-assignment.html b/slides/unused/sensing-assignment.html
new file mode 100644
index 0000000000000000000000000000000000000000..f59f0f0e0b7cf5db60adfa1faf77b12fa301b74a
--- /dev/null
+++ b/slides/unused/sensing-assignment.html
@@ -0,0 +1,236 @@
+---
+layout: presentation
+title: Sensing Implementation
+description: Implementation of phone sensing
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Sensing with your Phone: Implementation
+
+Jennifer Mankoff
+
+CSE 340 Spring 2019 
+---
+layout: false
+
+.title[Review: Android Awareness API]
+.body[
+Link to overview [Awareness API](https://developers.google.com/awareness/) 
+
+Unfortunately much of the documentation online is not up to date (last
+updated in 2017)
+]
+
+???
+---
+.title[Non-programming requirements]
+.body[
+Emulator requirements: Play store installed
+- Makes it easier to get your app working
+
+Permission requirements: Correct API installed
+
+Follow the “[Quick
+Guide](https://developers.google.com/places/web-service/get-api-key)”
+- Click on 'Get Started'
+- Use your class repo name for your app name (something like
+cse340-LaughingChipmunks) -- competing with all other google apps for namespace
+- You may need a billing account. 
+- DONT LOSE YOUR API KEY or you'll have to start over. 
+]
+---
+.title[Which APIs to enable?]
+.body[
+
+Minimum requirements
+- Awareness API (should be turned on by default
+- [See APis enabled](https://console.developers.google.com/apis/)
+]
+
+---
+.title[Using your API key]
+.body[
+When you have your API key, go to your android manifest and paste it
+in between the quotation marks labeled API_KEY. 
+
+Once you do that, as
+described in the spec, you'll need to accept permissions and update
+play when you run your code.
+
+```xml
+
+        <meta-data
+            android:name="com.google.android.awareness.API_KEY"
+            android:value="YOUR_KEY_HERE"/>
+        <meta-data
+            android:name="com.google.android.geo.API_KEY"
+          android:value="YOUR_KEY_HERE"/>
+```
+	
+]
+---
+.title[Review: Snapshots]
+.body[
+Current info
+
+Requires a single callback: 
+`onSnapshot(Response response)`
+
+Setup the callback in MainActivity (pass in the type of activity)
+`setSnapshotListener(Awareness.getSnapshotClient(this).getDetectedActivity(),`
+`new ActivitySnapshotListener(mUpdate, mResources));`
+	
+Parse the response and act on it in onSnapshot
+]
+---
+.title[What are Snapshots useful for?]
+.body[
+Debugging
+
+Anything else?
+
+]
+---
+.title[Review: [Fences](https://developers.google.com/awareness/)]
+.body[
+Conditional data
+
+3 callbacks: during, starting, stopping
+
+Setup in `MainActivity.java setupFenceListeners()`
+```java
+mActivityFenceListener = new ActivityFenceListener(
+	            // during
+                DetectedActivityFence.during(DetectedActivity.WALKING),
+			    // starting
+                DetectedActivityFence.starting(DetectedActivity.WALKING),
+				// stopping
+                DetectedActivityFence.stopping(DetectedActivity.WALKING),
+                this, this, mUpdate);
+```
+]
+???
+What might we use for a location fence?
+Headphone fence?
+...
+---
+.title[Setting up a fence in `MainActivity.java`]
+.body[
+The rest is pretty boilerplate for everything
+
+```java
+if (((Checkable) v).isChecked() && 
+*    ensureFineLocationAccess()) {
+                mActivityFenceListener.register();
+            } else {
+                mActivityFenceListener.unregister();
+            }
+```
+]
+.footnote[
+`ensureFineLocationAccess()` needs to be checked before anything
+that uses location, e.g. weather]
+
+---
+.title[Setting up a fence in `MainActivity.java`]
+.body[
+
+The rest is pretty boilerplate for everything
+```java
+if (((Checkable) v).isChecked() && 
+     ensureFineLocationAccess()) {
+                mActivityFenceListener.register();
+            } else {
+                 mActivityFenceListener.unregister();
+            }
+```
+]
+.footnote[These are because this is asynchronous]
+---
+.title[Using Places]
+.body[
+Shows you what is nearby
+
+```java
+//In MainActivity:
+setSnapshotListener(
+    Awareness.getSnapshotClient(this).getPlaces(),
+                        new PlacesSnapshotListener(mUpdate, mResources)));
+//In PlacesSnapshotListener
+
+public void onSnapshot(PlacesResponse response) {
+        List<PlaceLikelihood> placeLikelihood = response.getPlaceLikelihoods();
+        if (placeLikelihood != null && !placeLikelihood.isEmpty()) {
+            for (PlaceLikelihood likelihood : placeLikelihood) {
+                addPlace(likelihood.getPlace().getName().toString(), likelihood.getLikelihood());
+            }
+        }
+
+
+        mUpdate.prependText(placeLikelihood.toString());
+    }
+```
+]
+---
+.title[Work on adding a snapshot]
+.body[
+Make sure to download Oreo 27 for emulation (Nougat 25 won't work)
+
+When you run your code, you'll need to update Play store & set permissions
+
+Try to have the base code running by end of class (e.g. everything installed;
+            api keys correct) 
+You can get additional help in office hours
+]
+---
+.title[Context Aware Computing Assignment]
+.body[
+Pick one type of context
+- attach for later
+- automatically execute based on context
+- present info based on context
+]
+---
+.title[System Usability Scale]
+.body[
+1) I think that I would like to keep using this app.
+
+2) I found the system unnecessarily complex.
+
+3) I thought the system was easy to use.
+
+4) I found the use of implicit and explicit data in this app to be well integrated.
+
+5) I thought there was too much inconsistency in this system.
+
+6) I would imagine that most people would learn to use this system very quickly.
+
+7) I found the system very cumbersome to use.
+
+8) I felt very confident using the system.
+]
+---
+.title[Group Project]
+.body[
+Expectations:
+- Work together to decide on a focus
+- Implement your App
+- Make a video
+]
+---
+.title[More Expectations:]
+.body[
+Divide and conquer ok for video, interface implementation,
+  context-aware implementation
+
+Should not look at sensing code by others until yours has been
+  turned in 
+
+Group participation will be assessed
+]
+???
+Questions?
+---
diff --git a/slides/unused/sensing.html b/slides/unused/sensing.html
new file mode 100644
index 0000000000000000000000000000000000000000..5a1790e86793cf7d03ab8931cdee540f95f9bbeb
--- /dev/null
+++ b/slides/unused/sensing.html
@@ -0,0 +1,129 @@
+---
+layout: presentation
+title: Sensing with your Phone
+description: Discussion of practical side of phone sensing
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Sensing with your Phone
+
+Jennifer Mankoff
+
+CSE 340 Spring 2019 
+---
+layout: false
+
+# Types of Input
+
+- Not just touches: clicks, key presses
+
+--
+
+- *Sensors* - GPS, IMU/Accelerometer, humidity, temperature, etc
+
+???
+Sampled or event based?
+--
+  - `Managers` (e.g. `LocationManager`) let us create and register a listener
+
+  - Listeners can receive updates at different intervals, etc.
+
+  - Some Sensor-specific settings  
+    [https://source.android.com/devices/sensors/sensor-types.html](https://source.android.com/devices/sensors/sensor-types.html)
+
+---
+# Other Kinds of Input
+
+- Microphone
+
+- Camera
+
+- Multi-touch
+
+- Connected Devices? 
+---
+.title[
+Aware Framework]
+.body[
+![:img Picture of how AWARE is used](img/sensing/aware_overview1.png)
+[Aware's Many Sensors](https://awareframework.com/sensors/)
+]
+???
+AWARE is an Android framework dedicated to instrument, infer, log and share mobile context information, for application developers, researchers and smartphone users. AWARE captures hardware-, software-, and human-based data. The data is then analyzed using AWARE plugins. They transform data into information you can understand.
+---
+.title[Easy to collect data]
+.body[
+![:img Aware Study Interface, 70%](img/sensing/aware-study.png)
+]
+---
+.title[We'll implement our own version]
+.body[
+Much Simpler
+
+Android only
+
+Uses Android's
+[Task](https://developer.android.com/reference/com/google/android/play/core/tasks/Task)
+API because this may be asynchronous. We do our best to hide this for
+you
+
+Uses Google's [Awareness
+API](https://developers.google.com/awareness/) to provide you access
+to data
+]
+
+???
+---
+.title[Snapshots]
+.body[
+Current info
+
+Requires a single callback: 
+`onSnapshot(Response response)`
+
+Parse the response and act on it! 
+
+`WeatherSnapshotActivity` example
+]
+---
+.title[Subclass ContextSnapshotActivity]
+.body[
+	You'll create activities for multiple sensors
+]
+---
+.title[[Fences](https://developers.google.com/awareness/)]
+.body[
+Conditional data
+
+3 callbacks: during, starting, stopping
+
+From the android docs: 
+```
+if (TextUtils.equals(fenceState.getFenceKey(), "headphoneFenceKey")) {
+            switch(fenceState.getCurrentState()) {
+                case FenceState.TRUE:
+                    Log.i(TAG, "Headphones are plugged in.");
+                    break;
+                case FenceState.FALSE:
+                    Log.i(TAG, "Headphones are NOT plugged in.");
+                    break;
+                case FenceState.UNKNOWN:
+                    Log.i(TAG, "The headphone fence is in an unknown state.");
+                    break;
+            }
+        }
+```
+]
+---
+.title[Subclass FenceActivity]
+.body[
+Again you'll create for multiple sensors
+]
+---
+.title[Simulation Demo]
+.body[
+]
+---
diff --git a/slides/unused/sensing2.html b/slides/unused/sensing2.html
new file mode 100644
index 0000000000000000000000000000000000000000..9a5e82ecfe852f6e8feb84fd1e66e77e9f88f97d
--- /dev/null
+++ b/slides/unused/sensing2.html
@@ -0,0 +1,31 @@
+
+<!-- ---
+# Types of Input
+
+- Not just touches, clicks, key presses
+
+--
+
+- *Sensors* - GPS, IMU/Accelerometer, humidity, temperature, etc
+
+???
+Sampled or event based?
+--
+  - `Managers` (e.g. `LocationManager`) let us create and register a listener
+
+  - Listeners can receive updates at different intervals, etc.
+
+  - Some Sensor-specific settings  
+    https://source.android.com/devices/sensors/sensor-types.html
+
+---
+# Other Kinds of Input
+
+- Microphone
+
+- Camera
+
+- Multi-touch
+
+- Connected Devices? -->
+---
diff --git a/slides/unused/state.html b/slides/unused/state.html
new file mode 100644
index 0000000000000000000000000000000000000000..aceb78df0dc2fc5451c94352c3a323ad861ea2e8
--- /dev/null
+++ b/slides/unused/state.html
@@ -0,0 +1,505 @@
+---
+layout: presentation
+title: Capturing Behavior through State 
+description: Description the use of propositional production systems to describe component behavior (interaction techniques)
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+layout: false
+
+.title[# Hall of Fame/Shame]
+.body[
+![:img Picture of the course website with the mouse clicking on an unresponsive hamburger menu,80%](img/noresponse.png)
+]
+
+---
+class: inverse, center, middle
+
+.title[# From Events to Behavior]
+.body[
+Jennifer Mankoff
+CSE 340 Spring 2019 
+]
+---
+
+[//]: # (Outline Slide)
+.title[# Today's goals]
+.body[
+Review / Quiz 
+
+Introduce interaction techniques
+
+Discuss use of Propositional Production Systems in implementing them
+
+Try creating a PPS 
+]
+---
+.title[What is part of an event?]
+.body[
+![:img Picture of quiz results for the question about events. The question is "Which of these is not an event?" and the most popular answer is "CTRL (key pressed)" but many people also chose "WindowOpen" and "4"., 80%](img/notevent.png)
+]
+---
+.title[When is focus used?]
+.body[![:img Picture of quiz results for the question about focus. The question is "In which of the following situations is focused used during event handling?" and many people correctly chose "When a mouse moves off a scrollbar" but others chose things like "When selecting a word in a text area" and "When clicking on a button", 80%](img/focus.png)
+]
+---
+.left-column[
+## Interaction Technique]
+.right-column[
+A method for carrying out a specific interactive task
+
+Example: enter a number in a range
+
+could use...
+]
+???
+have the class try to think of examples
+--
+.right-column[
+- (simulated) slider
+- (simulated) knob
+- type in a number (text edit box)
+
+Each is a different interaction technique
+]
+---
+.left-column[
+## Example: Specify the end points for a line
+]
+.right-column[
+Could just specify two endpoints – click, click
+- not good: no affordance, <br>no feedback (/ feedforward)
+
+Better feedback is to use “rubber banding”
+- stretch out the line as you drag
+- at all times, shows where you would end up <br> if you “let go”
+]
+???
+Importance of feedback vs application callback
+---
+.left-column[
+## Implementing rubber banding]
+
+.large.right-column[
+```
+Accept the press for endpoint P1; P2 = P1;
+Draw line P1-P2;
+Repeat
+  Erase line P1-P2;
+  P2 = current_position(); Draw line P1-P2;
+Until release event;
+Act on line input;
+```
+]
+???
+Discuss! 
+Not event based
+Not in the basic event/redraw loop
+Potentially locks up the system
+---
+.left-column[
+## Implementing rubber banding]
+.right-column[
+Need to get around this loop <br> absolute min of 5 times / sec
+
+– 10 times better
+
+– more would be better
+]
+???
+aside -- why 5-10 times per second?
+
+---
+.left-column[## Event driven code]
+.right-column[
+Needs to respond to events as they arrive
+
+Needs to maintain state between events 
+
+]
+
+---
+.left-column[
+# Solution: Propositional Production Systems]
+.right-column[
+
+<div class="mermaid">
+graph LR
+S((.)) --> A((A))
+A -- "Event/Callback()" --> B((B))
+B -- "Event2/Callback2()" --> C[C]
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+
+
+class S invisible
+class A start
+class C finish
+class B normal
+</div>
+
+Special circle start state <br> (arrow going into it)
+
+Special circle for 'final state' <br> (really means 'reset to start')
+
+Transitions represent actions (callbacks).
+
+]
+???
+
+---
+.left-column[
+# PPS Example: Rubber Banding
+
+
+Compare to previous implementation: 
+
+```
+Accept the press for endpoint P1; P2 = P1;
+Draw line P1-P2;
+Repeat
+  Erase line P1-P2;
+  P2 = current_position(); Draw line P1-P2;
+Until release event;
+Act on line input;
+```
+]
+.right-column[
+
+- Determine the Events (triggers)
+
+- Determine the States
+
+- Determine the Actions
+
+- Determine the Queries
+]
+---
+.left-column[
+# PPS Example: Rubber Banding
+
+Compare to previous implementation: 
+
+```
+Accept the press for endpoint P1; P2 = P1;
+Draw line P1-P2;
+Repeat
+  Erase line P1-P2;
+  P2 = current_position(); Draw line P1-P2;
+Until release event;
+Act on line input;
+```
+]
+.right-column[
+
+<div class="mermaid">
+graph LR
+S((.)) --> A((Start))
+A -- "Mouse Down:?inView/Start_Line()" --> B((Drawing))
+B -- "Mouse_Move:?inView/Update()" --> B
+B -- "Mouse_Release:?inView/Finish_Line()" --> C[Finished]
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+
+class S invisible
+class A start
+class C finish
+class B normal
+</div>
+
+]
+
+???
+  Means: When you are in Start State, and a Mouse Down event arrives, do
+  the action ```Start_line()``` and go to Drawing State. Then update
+  the line end point position every time the mouse moves. Finally,
+  when it releases (Mouse Release event), finish the line (at this
+  stage a callback to the application might be appropriate)
+
+- translates input sequence into action!
+- How could we provide a better affordance?
+- Does it matter if we are using a mouse or a touch screen?
+
+---
+
+.left-column[##Summary]
+.right-column[
+State machines are very good (for this job) but do have limits
+
+State machines don't handle independent actions very well (state explosion)
+
+Mostly useful for smaller things
+
+- Great for individual components
+- Not so great for whole dialogs
+
+Path of least resistance is rigid sequencing
+ Ask: is this good for what I am doing?
+
+]
+???
+xxx TODO decide whether to keep
+xxx TODO decide how to end this deck and/or what other material needs
+to be covered
+---
+.left-column[## Guards on transitions]
+.right-column[
+Sometimes also use “guards” --> **Propositional Production System**
+
+- predicate (Boolean expr) before event
+
+- adds extra conditions required to fire
+
+- typical notation: pred : event / action
+
+- e.g. button.enabled: press-inside / A
+
+Note: FSM augmented with guards is Turing complete 
+]
+---
+
+.left-column[
+## PPS for Button?
+
+![:img FB Messenger Animation, 100%](img/messenger-bubble.gif)
+
+]
+.right-column[
+- Determine the Events (triggers)
+
+- Determine the States
+
+- Determine the Queries (essential geometry, context)
+
+- Determine the Actions
+]
+
+???
+What constitutes an “event” varies
+
+- may be just low level events, or
+- higher level (synthesized) events
+- e.g. region-enter, press-inside
+
+What is missing? Query fields 
+
+---
+.left-column[
+## Facebook Button Solution
+![:img FB Messenger Animation, 100%](img/messenger-bubble.gif)
+]
+--
+.right-column[
+
+Press:?inside => highlight(), start_animation(), small, active<br>
+AnimateStep ==> update(), active<br>
+AnimateFinish ==> !small, active<br>
+Release:inside,small => unhighlight(), exit()<br>
+Release:inside,!small => add_to_chat(), small, unhighlight(),
+exit()<br>
+
+__rest is unknowable from this animation__
+
+<div class="mermaid">
+  graph LR
+  S((.)) --> A((Start))
+  A -- "Press:?inside/highlight(), start_animation()" --> B((Active))
+  B -- "AnimateStep,update()" --> B
+  B -- "AnimateFinish,!small"--> B
+  B -- "Release,inside:small, unhighlight" -->D(End)
+  B -- "Release,inside:!small,add_to_chat(),unhighlight()" --> D
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+linkStyle 4 stroke-width:4px;
+linkStyle 5 stroke-width:4px;    
+ 
+class S invisible
+class A start
+class D finish
+class B normal
+</div>
+
+]
+
+---
+.left-column[
+## When to use PPSs
+]
+.right-column[
+
+- You're probably already using them, just not intentionally (and maybe
+less well as a result)
+- PPSs are a good way to do control flow in event driven systems
+
+Can do (formal or informal) analysis
+- are all possible inputs (e.g. errors) handled from each state
+- what are next legal inputs: can use to enable / disable
+Can be automated based on higher level specification
+]
+
+---
+.left-column[
+## Implementation of PPS
+]
+
+???
+```
+fsm_transition(state, evt) switch (state)
+
+..case 0: // case for each state
+
+...switch(evt.kind)
+
+...case loc_move: // transition event
+
+....do all the transition actions
+....state = 42 // set the new state
+
+..case 1: // case for next state switch (evt.kind) ...
+
+return state;
+```
+
+---
+layout: false
+
+.title[Exercise: Build your own color picker]
+.body[
+Learning goals: 
+- Create non-rectangle interactor
+- Use a state machine to manage feedback
+- Callbacks: React to events
+- Should handle error cases appropriately
+
+Android learning goals:
+- Save app state
+- Handle touch input properly
+- Understand app lifecycle
+]
+???
+
+---
+.title[Color Picker PPS ]
+
+.body[Work in pairs on this]
+
+---
+.left-column[![:img Picture of a menu with two items pulled down, 105%](img/menu.png)]
+
+.right-column[
+## Another example: Pull-down Menu
+
+How do we manage the drop-down behavior?
+
+FSM controller?
+
+]
+
+--
+.right-column[
+Behavior:
+
+- Body pulls down on press (in arrow)
+
+- Body stays down until release
+
+- Items highlighted while cursor is over them
+]
+---
+![:img Picture of a menu with two items pulled down, 25%](img/menu.png)
+
+<div class="mermaid">
+  graph LR
+  A((Start)) -- "Dn-inside-Top/Drop()" --> N((NotIn))
+  N -- "Enter-Item1/Highlight(1)" --> I((In1))
+  I -- "Enter-Item2/Highlight(2)" --> II
+  N -- "Enter-Item2/Highlight(2)" --> II((In2))  
+  I -- "Exit-Item1/Highlight(none)" --> N
+  II -- "Enter-Item1/Highlight(1)" --> I
+  I -- "Up/Fire-Item(1)" -->E((End))
+  II -- "Up/Fire-Item(2)"-->E((End))
+  II -- "Exit-Item2/Highlight(none)" --> N
+  N -- "Up/UnDrop()" --> F((End))
+</div>
+
+---
+.title[ Summary]
+.body[
+- Interaction technique: involves input AND feedback
+- Propositional Production Systems let us implement feedback
+  - event driven
+  - actions on **transitions**
+  - guards (conditionals) on **transitions**
+]
+---
+#End of Slides / Old material below here
+---
+.left-column[# Discussion of state explosion]
+.right-column[
+Take a button, and a control key (can you draw the state machine for
+the control key?)
+]
+--
+.right-column[Combine them (cross product)]
+
+
+<div class="mermaid" id="simplestate">
+  graph TD
+  A(( )) --> B(( ))
+  B --> A
+</div>
+
+<div class="mermaid">
+  graph LR
+  A(( )) --> B(( ))
+  B --> C(( ))
+  C --> B
+  C --> D(( ))
+  B --> End(( ))
+</div>
+
+---
+.left-column[# Cross product of state diagrams]
+.right-column[
+Replicate the larger one
+
+Once for every state in the smaller one!
+
+At transitions between corresponding states
+
+Correct semantics
+  - Eliminate impossible states
+  - Merge similar ones
+
+
+Now add another independent machine (shift key?)
+
+]
+???
+Totally out of hand -- combinatorical explosion!
diff --git a/slides/unused/unused.html b/slides/unused/unused.html
new file mode 100644
index 0000000000000000000000000000000000000000..8292316c4988413bc4b116286959ff8736a86b1c
--- /dev/null
+++ b/slides/unused/unused.html
@@ -0,0 +1,965 @@
+---
+layout: presentation
+title: Introductory Slides--Week 1, Monday--
+description: Introductory slides for Interaction Programming, CSE 340
+class: middle, center, inverse
+---
+# Text quirks
+
+- Each glyph has a reference point that defines a baseline
+- Each glyph has an advance width (distance to next glyph's reference point)
+
+![:img examples of reference point and advance width,40%](img/reference.png)
+---
+# Text quirks
+
+- Each glyph has a reference point that defines a baseline
+- Each glyph has an advance width (distance to next glyph's reference point)
+- font has standard ascent and descent
+
+![:img letter p with ascent and descent marked,60%](img/ascent.png)
+---
+.title[Text quirks]
+.body[
+- Each glyph has a reference point that defines a baseline
+- Each glyph has an advance width (distance to next glyph's reference point)
+- Font has standard ascent and descent
+- Font has 'leading' (distance between lines)
+]
+--
+.title[Why am I telling you all this?]
+.body[
+- Where is (0,0) of text when you call [drawText()]("https://developer.android.com/reference/android/graphics/Canvas.html#drawText(java.lang.CharSequence,%20int,%20int,%20float,%20float,%20android.graphics.Paint")? 
+- What should you set up in [Paint](https://developer.android.com/reference/android/graphics/Paint)?
+]
+ 
+---
+# Other Paint properties
+
+- Transparency and composition characteristics: Alpha value and `xfermode`([Porter-Duff](https://developer.android.com/reference/android/graphics/PorterDuffXfermode))
+???
+When the alpha channel is 1, the image is fully there, when it is 0,
+the image isn’t there at all, and when it is in between, the image is
+partially there. In other words, the alpha channel describes the shape
+of the image, it does not describe opacity. The way to think of images
+with an alpha channel is as irregularly shaped pieces of cardboard,
+not as colored glass.
+
+--
+<br>![:img source image with triangle on transparent background,10%](img/source.png)
+![:img destination image with & on transparent background,10%](img/dest.png)
+![:img diagram of pixel relationships,10%](img/diagram.png)
+--
+
+- Each type of pixel can be treated differently. 
+
+--
+<br>![:img Both should be blue and source red, 10%](img/destatop-diagram.png)
+![:img result: just part shows,10%](img/destatop.png)
+![:img Both should be pink and source orange and dest red, 10%](img/colordodge-diagram.png)
+![:img result: pink triangle with blue and,10%](img/colordodge-both.png)
+???
+Dest blend mode, atop source, limited to pixels in dest, colors blue and orange
+Color Dodge blend mode, pixels from both kept, colors pink and blue and orange
+
+The general formula is an area weighted average:
+
+Asrcâ‹…[s]+Adestâ‹…[d]+Abothâ‹…B(s,d)
+
+where [s] and [d] are the source and destination colors respectively
+or 0, and B(s,d) can be chosen from a set of formulas
+
+alpha channel is
+Asrcâ‹…[as]+Adestâ‹…[ad]+Abothâ‹…[ab]
+
+where [ab] is determined by the blend mode. 
+
+---
+# How does Canvas work?
+
+  - Handles __clipping__ of drawing boundaries
+
+???
+Clipping is super efficient if limited to a rectangle
+Implications for GUI design
+--
+
+  - Performs __transformations__ on drawn visual elements
+
+---
+# Work through clipping example (bell)
+.left[
+- For draw
+- For redraw
+]
+.right[
+![:img Picture of a very simple interface showing a ringing bell at
+left and an x at right to close the window with the words Google
+Calendar reminder Christian and Anind (Jen Mankoff) is starting at
+12:30pm. Video call between them, 70%](img/interface.png)
+
+]
+---
+# Coordinate Transformations in Android
+
+```java
+  Canvas c = new Canvas();
+
+  // Set the drawing boundary
+  c.setClippingRect(100, 50, 200, 100);
+
+  // Draw the shape
+  c.drawRect(0, 0, 50, 50);
+
+  // Move origin to where shape's top-left corner is
+  c.translate(100, 50);
+
+  // Draw another Rect inside the Rect just drawn
+  c.drawRect(10,10,10,10);
+
+  // Return state back to before the translation & clipping
+  c.restore();
+```
+---
+Which of the following must a parent component do before passing a
+drawable region to the child? [raise your hands]
+
+- [a] Translate (child.x, child.y)
+- [b] Clip(parent.x, parent.y, parent.w, parent.h)
+- [c] Translate (-child.x, -child.y)
+- [d] Clip(0,0,child.w,child.h)
+
+---
+.left-column[
+# Aside: Interactors: Significant Stagnation
+
+- Basic GUI components invented 1970s
+- Windows, Icons, Menus, Pointers (“WIMP”)
+- “Perfected” by Macintosh in 1984
+- Not much change since then (even with web)
+]
+.right-column[
+## Most GUIs still use the same 7-10 interaction techniques
+
+![:img Picture of a very old mac control panel showing typical interactors at the time,80%](img/mvc/interactors1.png)
+]
+???
+- Work well, uniform
+- Good for usability
+- GUI is victim of its own success
+- Opportunities lost by not customizing interaction techniques to tasks
+- Hard for better techniques to get traction
+- Only very recently with mobile devices (touch based) have we seen lots of new techniques get a major foothold
+---
+.title[In class Exercise: Interface Developer]
+.body[
+Let's look at interactors in Android Studio
+![:img A picture of the setup for android study in which we can layout
+components,80%](img/mvc/android-components.png)
+]
+???
+Menu, Button(types), Slider, Scrollbar, Spinner, List box, Icon, Link,
+Text box, Label,
+---
+.title[In class Exercise]
+.body[
+Quick Tour | tutorial
+for [building a ui](https://developer.android.com/training/basics/firstapp/building-ui)
+
+![:img A picture of the setup for android study in which we can layout
+components,80%](img/mvc/android-components2.png)
+]
+
+---
+# Multiple Simultaneous Animations (`AnimatorSet`)
+
+```java
+  // Create animator set
+  AnimatorSet bouncer = new AnimatorSet();
+
+  // Add the good stuff
+  bouncer.play(bounceAnim).before(squashAnim1);
+  bouncer.play(squashAnim1).with(squashAnim2);
+  bouncer.play(squashAnim1).with(stretchAnim1);
+  bouncer.play(squashAnim1).with(stretchAnim2);
+  bouncer.play(bounceBackAnim).after(stretchAnim2);
+
+  // Animate the alpha value from 1->0
+  ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
+  fadeAnim.setDuration(250);
+
+  // Build up a another level of animation sets
+  AnimatorSet animatorSet = new AnimatorSet();
+  animatorSet.play(bouncer).before(fadeAnim);
+
+  // Starts the animations
+  animatorSet.start()
+```
+---
+# Declaring Animations in XML
+
+```
+/res/animator/object_animator_ex.xml
+```
+```xml
+<set android:ordering="sequentially">
+    <set>
+        <objectAnimator
+            android:propertyName="x"
+            android:valueTo="200"/>
+        <objectAnimator
+            android:propertyName="y"
+            android:valueTo="300"/>
+    </set>
+    <objectAnimator
+        android:propertyName="alpha"
+        android:valueTo=".5f"/>
+</set>
+```
+
+.footnote[Can do even *more* with ValueAnimator XML (will let you google this)]
+
+---
+# There's more flexibility... (3/3)
+
+You can then run the animation by doing the following:
+
+```java
+  Animator anim = (Animator) AnimatorInflater.loadAnimator(this,
+      R.animator.object_animator_ex);
+  anim.setTarget(myObject);
+  anim.setDuration(2000);
+  anim.start();
+```
+
+Note that animations xml files should be in the `res/animator/` directory
+
+---
+# Make sure the animation info is inside of:
+```xml
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+<!-- ... -->
+</set>
+```
+
+---
+# An Aside: What is an Inflater?
+
+You will use these often! They give you access to XML data (part of
+the *model* of your application). Just saw an 
+[AnimatorInflater](https://developer.android.com/reference/android/animation/AnimatorInflater)
+in the previous code.
+
+```java
+[Type] [name] = ([Cast to Type]) [Inflator].load...([arguments])
+```
+Will need the *path* to the part of the XML you care about, typically
+something like:
+```
+R.[dirname].[filename]
+```
+Specifics vary from situation to situation (*e.g.,* [LayoutInflater](https://developer.android.com/reference/android/view/LayoutInflater)
+works slightly differently), so you'll need to read the documentation.
+]
+
+
+---
+.title[Interactor (Component) Model]
+.body[
+__Encapsulate interactive components__ (interactors)
+- Component library (button, slider, container)
+- Interface built as a hierarchy of components
+
+__Components drawn by underlying graphics library__
+- Input event generation and dispatch
+- Historically mouse & keyboard, now touch, ...
+
+__Bounds management & damage/redraw__
+- Model geometry, redraw updated regions only
+]
+
+---
+template: inverse
+
+# Saving State
+---
+layout: false
+
+.left-column[## When to save state? (1/3)]
+.right-column[
+- Activity `A` spawns Activity `B`
+  - E.g. Typing a Facebook post, then you select 'Add a Location'
+]
+--
+.right-column[
+- Android kills `A` to reclaim resources while the user is interacting with `B`
+]
+--
+.right-column[
+- User finishes with `B`, returns to `A` but the post is gone!
+]
+---
+.left-column[## Activity Lifecycle]
+.right-column[![:img Android activity lifecycle, 50%](img/viewupdate/activity_lifecycle.png)]
+
+---
+
+.left-column[## When to save state? (2/3)]
+.right-column[![:img Android activity state diagram, 50%](img/viewupdate/android-activity-states-01.png)]
+
+---
+
+.left-column[## When to save state? (3/3)]
+.right-column[![:img Android activity state diagram -- process killed, 50%](img/viewupdate/android-activity-states-02.png)]
+
+---
+.title[ Maintaining Activity State]
+.body[
+- We can fix it by saving the state in a `Bundle` before Android closes the `Activity`
+
+- We then restore the state when we return to the `Activity` later
+]
+---
+
+.title[# Bundle it up]
+.body[
+- `Bundle`: A hash map (dictionary) of String keys to Primitive, Parcelable, Serializable values
+]
+--
+.body[
+- Used to:
+  (1) Save/restore state
+  (2) Transfer data between different `Activity` in an app
+]
+--
+.body[
+- Primitive are `int`, `float`, `boolean`, `double` (the usual suspects)
+]
+---
+.left-column[
+## Saving in the Bundle
+]
+.right-column[
+Methods for _saving_ items out of a Bundle
+
+- Ints: `putInt(String key, int value)`
+- Floats: `putFloat(String key, float value)`
+- Characters: `putChar(String key, char value)`
+- Strings: `putString(String key, String value)`
+- Serializable Objects: `putSerializable(String key, Serializable value)`
+- Parcelable Objects: `putParcelable(String key, Parcelable value)`
+- _Others in the documentation (e.g. Arrays, Bytes, etc).._
+]
+.footnote[[Bundle Documentation](    https://developer.android.com/reference/android/os/Bundle.html
+)]
+---
+.left-column[
+## Retrieving from the Bundle
+]
+.right-column[
+Methods for getting items out of a Bundle
+
+- Ints: `getInt(String key)`
+- Floats: `getFloat(String key)`
+- Characters: `getChar(String key)`
+- Strings: `getString(String key)`
+- Serializable Objects: `getSerializable(String key)`
+- Parcelable Objects: `getParcelable(String key)`
+- _Others in the documentation_ (e.g. Arrays, Bytes, etc)..
+]
+.footnote[[Bundle Documentation](    https://developer.android.com/reference/android/os/Bundle.html
+)]
+---
+.left-column[
+## Saving Activity State (1/3)]
+.right-column[
+- Android provides the `onSaveInstanceState(Bundle savedInstanceState)` callback method for you to save the state of an `Activity`
+
+```java
+private static final USERNAME_KEY = "USER_NAME_KEY";
+private static final FIB_SUM_KEY = "FIB_SUM_KEY";
+
+private int mFibSumValue; // Set to 10295 by our user
+private String mUsername; // Set to "Prabha" by our user
+
+@Override
+public void onSaveInstanceState(Bundle outState) {
+    // Always call super - your super classes could be saving state for you!
+    super.onSaveInstanceState(outState);
+
+    // Now
+    outState.putInt(FIB_SUM_KEY, mFibSumValue);
+    outState.putString(USERNAME_KEY, mUsername);
+}
+```
+]
+---
+.left-column[
+## Restoring Activity State (1/2)
+]
+.right-column[
+- We saved, and now our user goes off to some other app
+]
+--
+.right-column[
+- Android kills our `Activity`
+]
+--
+.right-column[
+- Now how do we get the _saved_ state back?
+]
+---
+.left-column[
+## Restoring Activity State (2/2)]
+.right-column[
+-  Two ways:
+  - `onCreate(Bundle savedInstanceState)`
+  - `onRestoreInstanceState(Bundle savedInstanceState)`
+]
+---
+.left-column[
+## Restoring in `onCreate` vs. `onRestoreInstanceState`
+]
+.right-column[
+- `onRestoreInstanceState`
+  - Guarantees you will never have a non-null `Bundle` when called
+  - Lets subclasses override the behavior of restoring the state
+
+- `onCreate`
+  - Lets you focus on doing all of your initialization in one place
+
+- In the assignment we use onCreate
+]
+.footnote[[Stackoverflow conversation on this](http://stackoverflow.com/questions/36408776/using-oncreate-vs-onrestoreinstancestate)
+]
+---
+---
+# Saving state: advanced material
+---
+
+- Custom objects that implement the `Serializable` or `Parcelable` interfaces
+  - You will need to make any custom classes that you want to save into a `Bundle` implement the `Parcelable` interface
+
+---
+
+# Parcelable vs. Serializable
+
+- Both are for the same purpose of saving but `Serializable` makes implementations much easier...
+
+--
+
+- **EXCEPT, .red[you should almost always use `Parcelable`]**
+
+--
+
+- Why?
+  - `Serializable` uses introspection ==> more memory, and CPU cycles
+  - `Parcelable` **is optimized for mobile devices**
+
+---
+## Implementing `Parcelable` (1/3)
+
+-- You are required to implement the following methods for the `Parcelable` interface:
+
+```java
+public class MyPersonModel implements Parcelable {
+    private int mAge;
+
+    // Required for the interface
+    public int describeContents() {
+        return 0;
+    }
+
+    // Required for the interface
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mAge);
+    }
+    // Continued on next slide...
+```
+
+---
+
+## Implementing `Parcelable` (2/3)
+
+```java
+
+    // Required for the interface
+    // CREATOR is an object that can remark
+    public static final Parcelable.Creator<MyPersonModel> CREATOR
+            = new Parcelable.Creator<MyPersonModel>() {
+        public MyPersonModel createFromParcel(Parcel in) {
+            return new MyPersonModel(in);
+        }
+
+        public MyPersonModel[] newArray(int size) {
+            return new MyPersonModel[size];
+        }
+    };
+
+    // Required for the interface
+    // Private constructor for Android to use with your CREATOR
+    private MyPersonModel(Parcel in) {
+        mAge = in.readInt();
+    }
+}
+```
+---
+
+## Implementing `Parcelable` (3/3)
+- **Note**: .red[the order of the values when writing and reading them matters!]
+
+  - When you write to the parcel using `write*()` methods in `writeToParcel`,
+
+  - The write order __MUST BE__ the same as when you read them in the private constructor
+
+- For more details on implementation:
+  https://developer.android.com/reference/android/os/Parcelable.html
+
+---
+## example code for restoring state
+
+
+```java
+private static final USERNAME_KEY = "USER_NAME_KEY";
+private static final FIB_SUM_KEY = "FIB_SUM_KEY";
+
+private int mFibSumValue = 0;
+private String mUsername = null;
+
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+  super.onCreate(savedInstanceState);
+  setContentView(R.layout.activity_main);
+
+  mMainTextView = (TextView) findViewById(R.id.text_main_title);
+  mSumTextView = (TextView) findViewById(R.id.text_sum);
+  // Check if there was a previously saved state to restore to the user
+  // A non-null bundle means there was a state that was saved previously
+  // A bundle is just a Key-Value pairing - its a hash map :)
+  if (savedInstanceState != null) {
+    // There was a previous state - time to restore
+    mFibSumValue = savedInstanceState.getInt(FIB_SUM_KEY);
+    mUsername = savedInstanceState.getString(USERNAME_KEY);
+  }
+  updateMainText();
+  updateFibSumText();
+}
+```
+---
+## example code for restoring state
+
+```java
+private static final USERNAME_KEY = "USER_NAME_KEY";
+private static final FIB_SUM_KEY = "FIB_SUM_KEY";
+private int mFibSumValue = 0;
+
+@Override
+protected void onRestoreInstanceState(Bundle savedInstanceState) {
+  super.onRestoreInstanceState(savedInstanceState);
+  // Check if there was a previously saved state to restore to the user
+  if (savedInstanceState != null) {
+    // There was a previous state - time to restore
+    mFibSumValue = savedInstanceState.getInt(FIB_SUM_KEY);
+    mUsername = savedInstanceState.getString(USERNAME_KEY);
+  }
+  updateMainText();
+  updateFibSumText();
+}
+```
+---
+---
+## Exercise: Parcelable and Activity State
+
+- Pair up!
+
+- Download the base code here:
+
+- This app lets a user enter a name, age, and favorite food
+
+- It stores this info in a `PersonModel`
+
+- When the app is killed, this information needs to remain edited
+
+- Implement the `Parcelable` interface for the PersonModel
+
+- Then use the Activity's relevant state change callbacks to `PersonModel` when the phone rotates
+
+---
+### Some Notes about `onSaveInstanceState()`
+- .red[Only use to save and restore session variables and the state of the UI]
+
+--
+
+  - Android won't always trigger the method
+
+--
+
+  - It is called when the `Activity` is closed and _expected_ to be restored soon
+
+--
+
+- If your app crashes, or is closed, **the values in the bundle will disappear!**
+
+--
+
+- If you use custom views, you can implement their version of `onSaveInstanceState`:
+
+  Android will call `onSaveInstanceState()` every view in the layout
+
+---
+.left-column[
+## Essential Behavior Quiz question
+PPS Parts?
+- Action	
+- Input modifier
+- Input Event
+- Query field (Condition)
+- State
+]
+.right-column[
+![:img Picture of first quiz question asking "What sort of interaction does this PPS support?" and showing a state machine for drawing a line with updates to the line on every move event. Most people correctly understood a line with rubber banding., 100%](img/viewupdate/quizqs.png)
+]
+
+
+---
+layout: false
+
+# Affordance
+
+Opportunities to act
+- which are readily apparent to the user ... and appropriate to the
+  user’s abilities 
+
+Form “affords” certain actions and makes that apparent
+
+Allows and promotes certain actions
+
+- Door knobs afford turning
+- Handle of hammer affords grasping in a particular way
+]
+
+---
+# Affordance Example: Knurling
+
+.left-column[
+![:img Picture of a knob with ridges around it, 80%](img/interaction/knurling.png)
+
+]
+.right-column[
+Small ridges typically found on knobs
+
+Increases friction
+
+Affords grip
+]
+
+---
+# “Virtual affordances”
+
+.left-column[
+![:img Picture of a digital window corner ridges drawn on it, 80%](img/interaction/virtual-knurling.png)
+]
+
+.right-column[
+Don’t typically have much physical form in a GUI
+
+But, visual appearance can still suggest function
+]
+--
+.right-column[
+Note that you don’t have to know about knurling for this to afford
+“grip” with the mouse
+]
+---
+# Feedback
+
+Response by the system to the actins of the user – Cause and effect
+
+- Essential for forming mental models
+
+Making “system state” visible
+
+---
+# Component design guideline #1
+
+Explicitly design a conceptual model and use affordance and feedback
+(and everything else you have)
+to reinforce it
+
+---
+# Performance properties of people
+
+(Only a very few here) How long will things take?
+
+- e.g., physical movements
+
+How much can people remember? How fast are thing perceived?
+
+---
+#How long will user actions take
+
+Strong models for physical movement
+
+Fitts’ law predicts movements as a function of distance and required accuracy:
+
+T = A log2(D/S + 0.5) + B D – distance to target
+
+S – size of target
+
+A,B proportionality constant and intercept (linear fit)
+
+– Property of user (motor control group)
+
+---
+# Speed Differences Explained
+
+Menu position and design can have a
+significant impact on speed of interaction
+
+Fitts' law is the main
+explanation for this.
+
+---
+# Fitts law –
+
+helps to capture the difficulty of input with different devices]
+
+Time = A + B*log2(Dist/Size + 0.5)
+
+“Index of Difficulty”
+
+- Time is linearly proportional to “index of difficulty” (log of what we would intuitively think of as “difficulty”)
+
+  - Proportionality constants depend on muscle group and device
+
+  - Difficulty determined by distance and required accuracy (size of
+target)
+---
+.left-column[##Fitts’ law]
+.right-column[
+
+Actual numbers from Fitts’ law generally not all that helpful
+
+- That level of detailed analysis is hard
+
+- Very hard to know what exact distances are across
+
+dynamic layout and varied platforms General guideline
+
+- Keep required movements (accuracy & distance) firmly in mind
+ - Avoid device swapping
+ - Avoid disturbing focus of attention
+]
+---
+.left-column[##Fitts’ law]
+.right-column[
+(True) expert performance tends to be closely related to time required for movements
+
+- not that closely related to learning (or performance) of novices
+
+- still need to consider “cognitive load”
+]
+---
+.left-column[##How much can a person remember Short term (working)
+memory]
+.right-column[
+- Famous 7 +/- 2 “chunks” (Somewhat outdated model)
+
+- For us just: “very limited” and “decays quickly” – Has become “worse” with constant multitasking
+
+Long term
+
+– Essentially unbounded
+– But requires effort & may not always work on cue –  Can’t explicitly forget! Even though you try!
+]
+---
+.left-column[##How much can a person remember Novice / expert
+differences]
+.right-column[
+-  Experts have learned items in long term memory to draw on, novices don’t
+
+-  But note that having the ability to operate from recogni2on does not preclude recall
+
+Implication:
+
+- Generally better to rely on recognition (seeing it in front of you)
+than just recall (having to pull it out of long term memory)
+]
+---
+.left-column[##How fast are things perceived?]
+.right-column[
+
+less than ~20ms (1/50 sec) discrete images/flashes merge into con2nuous percep2on
+
+- Image you are looking at flickers 60 times per second
+- Differences in peripheral vision
+  - Sabertooth tigers
+]
+--
+.right-column[
+Don’t ever have to be faster than this for user response!
+
+Get more than 120 million instructions per core (@3Ghz)
+
+(High end GPU theoretically as high as 26 billion instr.)
+ - You can do a lot with that
+ -  (First GUIs had ~20K)
+ -  Not enough? Twice as many cores in 2-3yrs...
+]
+---
+.left-column[##How fast are things perceived?]
+.right-column[
+ ~100ms seems like “instant response”
+
+- Hard to tell response times below this apart
+
+- Upper range of eye saccades
+
+Discrete images into steps instead of apparent motion
+]
+---
+.left-column[##How fast are things perceived?]
+.right-column[
+
+100ms (1/10 sec)
+
+Except some animation, most things don’t need to be faster than this
+
+- Typical target “cycle time”
+
+- 600 million+ machine instructions, ...
+]
+---
+.left-column[##How fast are things perceived?]
+.right-column[
+ 1-2 seconds typically “good response time”
+
+-  Similar times in conversa2onal turn taking protocols
+
+-  Longer delays ~5 sec have to say something to keep conversation alive
+
+(Note: numbers fuzzier as we go out)
+]
+---
+.left-column[##How fast are things perceived?]
+.right-column[
+10-15 sec is typically “bad response time” – STM decay effects
+]
+---
+.left-column[##A liMle about response times]
+.right-column[
+Good vs. bad response time
+is very dependent on expecta2on
+
+-  If you can’t meet the goals, manipulate user expectations!
+
+Consistency of response is very important
+
+- Can be more important than
+time
+]
+---
+.left-column[##How long do other cognitive activities take?]
+.right-column[
+Unfortunate, but...
+
+–  Things known, but overall not as well understood –  Much harder to apply what is understood
+
+–  See other HCI courses for some of this
+]
+---
+.left-column[##We do know essen2ally minimums]
+.right-column[
+“Cycle” times for “Human Processor”
+(Model Human Processor [Card, Moran, Newell])
+
+- Perceptual ~100ms [50-200]
+
+- Cognitive ~70ms [25-170]
+
+- Motor ~70ms [30-100]
+
+Can be used to predict reaction times and highly routine actions
+
+- E.g., it takes at least ~150ms to
+act on something (~250ms more likely)
+
+Harder to use for complex things and/or with learning
+
+]
+---
+.left-column[##When do these rules break down?]
+.right-column[
+-  Novices
+-  Disabled
+ ]
+
+---
+XX add some active learning?
+XX add something about color perception here or earlier?
+
+
+---
+# Case Study: Text Entry Speed on Mobile Devices
+
+.left-column[
+![:img Picture of phone keypad with buttons laid out in rows of "1 2 3 - 4 5
+6 - 7 8 9 - * 0 #", 100%](img/pm/buttons.png)
+]
+.right-column[
+Multi-tap
+```
+77 88 444 222 55 0 22 777 666 9 66 0 333 666 99
+q u i c k _ b r o w n _ f o x
+```
+
+Slow, lot's of overhead
+]
+
+---
+# Case Study: Text Entry Speed on Mobile Devices
+.left-column[
+![:img Picture of phone keypad with buttons laid out in rows of "1 2 3 - 4 5
+6 - 7 8 9 - * 0 #", 100%](img/pm/buttons.png)
+]
+.right-column[
+Multi-tap (~ 20 WPM)
+```
+77 88 444 222 55 0 22 777 666 9 66 0 333 666 99
+q u i c k _ b r o w n _ f o x
+```
+
+T9 - dictionary based disambiguation (~ 20 WPM)
+```
+7 8 4 2 5 0 2 7 6 9 6 0 3 6 9
+q u i c k _ b r o w n _ f o x 843 78425 27696 369 58677 6837 843 5299 364
+the quick brown fox jumps over the jazz dog
+tie stick crown lumps muds tie lazy fog
+vie vie
+```
+]
+???
+Most common word (top) not always right
+---
+# Case Study: Text Entry Speed on Mobile Devices
+
+.left-column[
+![:img Picture of phone keypad with swype enabled and the swype for quick shown, 100%](img/pm/swype.jpg)
+]
+.right-column[
+Method | Speed
+----|----
+Multi-tap | ~ 20WPM
+T9 - dictionary based disambiguation | ~ 20 WPM
+Swype | ~ 55 WPM
+Keyboard | ~ 55 WPM
+Flesky | Up to 80 WPM ([Guinness World Record!](https://www.cnn.com/2014/05/15/tech/mobile/guiness-record-fastest-text/) )
+Speech | ~ 150 WPM
+
+Skeptical? Need to know % errors and time cost of error correction to truly evaluate
+]
+
+???
+Flesky is combination of gestures and automatic error correction
+
diff --git a/slides/wk01/drawing.html b/slides/wk01/drawing.html
new file mode 100644
index 0000000000000000000000000000000000000000..ef29741325c58b757b4616b11ea65b820961d186
--- /dev/null
+++ b/slides/wk01/drawing.html
@@ -0,0 +1,701 @@
+---
+layout: presentation
+title: Drawing On the Screen
+description: Discussion of basic information about how to draw on the screen
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Introduction to Drawing
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout: false
+
+[//]: # (Outline Slide)
+# Today's goals
+
+- Administrivia
+- Warmups
+  - Checks for understanding
+  - Practicing with breakouts, polleverywhere, and Ed
+- Quick view of resources
+- Abstractions for drawing on the screen
+- Drawing in Android
+- Clipping and other transformations
+
+---
+# Administrivia
+
+- Please remember to take the first day [survey](https://catalyst.uw.edu/webq/survey/bricker/387508) if you have not already
+- Ed-iquette
+  - Please tag your posts with the most appropriate tag, e.g., if you are posting about doodle
+  please tag it with as1-doodle
+  - Please search to see if someone has already answered your question before posting! (these tags can help!)
+- Lab videos were posted
+- Important [Ed Post about a change to Part1.java](https://us.edstem.org/courses/381/discussion/24015)
+
+---
+# Trying new things!
+
+1. Breakout rooms
+  - Today I've randomly assigned you to breakout rooms with one TA each.
+  - In the future, we will experiment with a system where you can choose your breakout partners
+  - Goal: Meet other students, answer some questions.
+    - Please turn your cameras on in the breakouts
+    - Introduce yourself, and say what color socks your wearing.
+    - Work together on the question posed....
+2. Warmup 1: pollev.com/docbrick
+   - answer the question
+   - try to think of a one unique answer per person in your breakout
+   - Each person should answer the poll separately
+   - We'll come back together and see the results.
+3. Warmup 2: Ed sway
+  - We'll go back into the breakout rooms and try to work together to answer questions on Sway
+  - Each person should submit their answers.
+
+---
+
+Warmup 1
+
+<iframe src="https://embed.polleverywhere.com/free_text_polls/gmZBJAx5kjHZQkO16zRve?controls=none&short_poll=true" width="800" height="600" frameBorder="0"></iframe>
+
+
+---
+# Quick view of resources
+
+One commong "Good Programming Practice" is to remove "static" resources from your code and
+store them in a resource area to be used by your program. Think of this like the "No Magic Numbers"
+principle you learned early in 142).
+
+- Often used in internationalization or localization
+- Often used in A/B testing in software development
+
+Android resources are stored in `.xml` files in subdirectories of the `app/res` directory may include
+- `drawable` - images you might draw on the screen in various formats
+- `layout` - layouts of various screens
+- `menu` - the menus for your application
+- `values` - might contain `colors.xml` and `strings.xml`
+
+---
+## Developer roles
+
+.left-column[
+
+<div class="mermaid">
+  graph LR
+  ip[Interface Programmer]
+  w[Component Developer]
+  l[Library Extender]
+  a[Architecture Extender]
+  t[Toolkit Builder]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+
+  class t,l,a,w yellow
+  class ip green
+</div>
+]
+
+.right-column[
+From [last class](toolkits.html) we briefly discussed of the roles
+a developer can play in app development.
+
+- Today we're going to focus on being an Interface Developer (adding existing components like
+`ImageView` objects to the `doodleView`)
+- We might get to touch on being a Component Developer and thinking about how to create that new
+`LineView` component
+]
+
+
+---
+# Drawing on the Screen
+
+- Take out your phone. Open an App. What do you see on your screen?
+---
+# Drawing on the Screen
+
+- Take out your phone. Open an App. What do you see on your screen?
+
+.left-column[
+![:img Example poll everywhere mobile presenter application screen, 100%](img/drawing/pollevscreen.jpeg)]
+
+.right-column[
+(this is what I currently see)
+
+What is an app made up of?
+]
+---
+# What is on your screen?
+
+.left-column[
+![:img Example poll everywhere mobile presenter application screen, 100%](img/drawing/pollevscreen.jpeg)
+]
+
+.right-column[
+App is made up of? Interactors
+
+Last class we discussed the "tree" of components.
+
+Think about what this hierarchy might look like.
+- What is at the "root" ?
+- How is this divided up into sections
+- In each section, how are things further divided up?
+
+
+]
+
+---
+# What is on your screen?
+
+.left-column[
+![:img Example poll everywhere mobile presenter application screen, 100%](img/drawing/pollevscreen.jpeg)]
+
+.right-column[
+<div class="mermaid" style="width: 75%">
+graph LR
+W(Window) --> T[Title Bar]
+W --> L[Label: My Folders]
+W --> F[Folders]
+W --> B[Toolbar]
+T --> TA[Icon]
+T --> TB[Label: Activities]
+T --> TC[Button: Search]
+T --> TD[Button: Folder]
+T --> TE[Button: Add]
+F --> F1[Folder 1]
+F --> F2[Folder 2]
+F --> F3[Folder 3]
+F1 --> I[Icon]
+F1 --> N[Folder Name]
+F1 --> C[Activity Count]
+B --> H[Button:Home]
+B --> A[Button: Activities]
+B --> R[Button: Reports]
+B --> P[Button: Profile]
+
+classDef start font-size:12pt,text-align:center
+classDef blue font-size:12pt,text-align:center
+
+class W start
+class T,L,E,F,B,TA,TB,TC,TD,TE,F1,F2,F3,H,A,R,P,I,N,C blue
+
+</div>
+]
+---
+# What is on your screen?
+
+.left-column[
+![:img Example poll everywhere mobile presenter application screen, 100%](img/drawing/pollevscreen.jpeg)
+]
+
+.right-column[
+App is made up of? Interactors
+
+What are Interactors made up of?
+
+]
+
+???
+Should push them down to the lowest level on the screen
+
+App is made up of? Interactors
+
+Interactors are made up of? lines, circles, text
+
+Lines, circles and text are made up of? Pixels
+
+---
+# What is on your screen?
+
+.left-column[
+![:img Example poll everywhere mobile presenter application screen, 100%](img/drawing/pollevscreen.jpeg)]
+
+.right-column[
+App is made up of? Interactors
+
+Interactors are made up of? lines, circles, text
+
+Lines, circles and text are made up of? Pixels (picture elements)
+]
+---
+# Aside: Displaying a Pixel
+
+.left-column30[
+Do you know how pixels are lit up in color or greyscale?
+- on your computer or TV screen?
+- on a projector?
+]
+--
+.right-column50[
+[Cathode Ray Tube](https://en.wikipedia.org/wiki/Cathode-ray_tube) |  [LED Display](https://en.wikipedia.org/wiki/LED_display)
+:--: | :--:
+![:img Magnified view of a delta-gun shadow mask color CRT, 90%](img/drawing/CRT_display.jpg) | ![:img Detail view of a LED display with a matrix of red green and blue diodes, 90%](img/drawing/LED_display.jpg)
+
+]
+
+???
+Get them to at least realize that the actual pixels on their
+screen are LEDs
+
+
+
+
+---
+# Drawing on the Screen
+
+What are we going to control as we build this application?
+
+--
+- Interactors
+
+--
+  - from the Toolkit
+  - they know how to draw themselves and possibly react to input
+
+--
+In Android, we call these Interactors `Views`
+
+- *Aside: Widgets, Interactors, and `Views` are all variations on the same term*
+
+--
+What if you were to build an interactor from scratch?
+
+--
+- You'd need basic drawing capabilities from the toolkit such as drawing lines, circles, and so on
+
+---
+# Toolkit Support for Basic Drawing
+
+.left-column[
+![:img Example poll everywhere mobile presenter application screen, 85%](img/drawing/DrawingPanel.png)]
+
+.right-column[
+All toolkits have some sort of `Canvas` object or abstraction
+- `Canvas` is an object level abstraction for performing drawing operations
+- Each `View` has a `Canvas` in Android
+- You can access it in the `onDraw(Canvas canvas)` method
+
+When is `onDraw()` called?
+
+]
+
+???
+Connect to DrawingPanel in 143?
+
+---
+# Toolkit Support for Basic Drawing
+
+.left-column[
+![:img Example poll everywhere mobile presenter application screen, 85%](img/drawing/DrawingPanel.png)]
+
+.right-column[
+All toolkits have some sort of `Canvas` object or abstraction
+- `Canvas` is an object level abstraction for performing drawing operations
+- Each `View` has a `Canvas` in Android
+- You can access it in the `onDraw(Canvas canvas)` method
+
+When is `onDraw()` called?
+- Handled automatically for you by toolkit
+- Triggered whenever the pixels are *dirty* (there's been a change to what needs to be viewed)
+- You can trigger this with `invalidate()` (we'll use this in the future)
+
+]
+
+???
+Lots to discuss here. Mainly focus on introducing the concept
+of a library (a bunch of views you can pick from, Canvas and its methods, etc)
+
+vs an architecture (which controls when and in what order things happen).
+We'll learn about both in this class. You need to understand both to use a toolkit.
+
+---
+# How does Canvas work?
+
+- Drawing is done by calling methods for different kinds of objects
+
+--
+
+- For example: `drawRect`, `drawOval`, `drawLine`, `drawPath` ...
+
+  [Full List in the API Documentation](https://developer.android.com/reference/android/graphics/Canvas.html)
+
+---
+# How does Canvas work?
+
+- Drawing is done by calling methods for different kinds of objects
+
+- Lots happens under the covers... let's look at an example...
+
+--
+
+"I want to draw a line on the screen"
+
+--
+
+So I would likely call `drawLine` on the `Canvas`.
+
+--
+
+So... how do I tell the computer where the start and end of the line will be?
+
+---
+# How is location decided?
+
+- (0,0) is at the top left of the screen
+- The screen is drawn pixel by pixel from top left to bottom right in "raster" lines
+
+![:img Picture of a very old CRT based TV display, 25%](img/drawing/analogtv.jpg)
+![:img Picture of raster scanning going from top left to top right; down a row; and so on, 25%](img/drawing/rasterscanning.png)
+[Source: Wikipedia](https://en.wikipedia.org/wiki/Analog_television#Displaying_an_image)
+---
+# How is a drawing object rendered on screen?
+
+- An object (like a line) would be converted into one or more **strokes**
+- A stroke has properties such as width or color
+- The stroke is converted to **pixels** (correspond to dots on your screen)
+- These pixels are put in a `Bitmap` (frame buffer) first, then updated on the screen all at once
+
+???
+top left is from old-style raster graphics, where a beam of light literally moved
+down the screen from top left to bottom right, causing chemical excitation when on
+and thus lighting the screen
+
+the last is left over from when both graphics and drawing were slower and more linear
+Still most reliable approach
+
+---
+# How is a stroke converted to pixels?
+- Strokes (can be) size independent. Pixels are not
+- Strokes are continuous. Pixels are not
+- Anti-aliasing
+
+Essentially converting from **vector** to **raster** graphics ([Bresenham's algorithm](https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm))
+
+---
+# Quick understanding test
+
+What internal data structure (abstraction) represents an entire
+picture to display on a color screen?
+
+--
+pixels in a 2D array
+
+![:img The left side of this image displays the RGB pixel values of the image of GitGrade's Hopper on the right side 3%](img/drawing/pixelcalc.png)
+
+Pixel Calculator (Tanimoto 2010)
+
+???
+
+**A frame buffer (2D array)	(picture)**
+
+The following are wrong, they represent a single pixel (but we haven't studied this yet)
+
+- A pixel (R,G,B)
+- A number from 0 to 255
+
+---
+# What is the [Paint](https://developer.android.com/reference/android/graphics/Paint.html) Object?
+
+
+.left-column[
+![:img Picture of a phone screen with a blue and green circle drawn on it at different vertical positions (50 and 150 y center point), 80%](img/drawing/circles.png)
+]
+
+.right-column[A Paint object is an abstraction that determines how drawing operations should look
+```java
+Paint drawPaint = new Paint();
+drawPaint.setColor(Color.BLUE);
+drawPaint.setAntiAlias(true);
+drawPaint.setStrokeWidth(5);
+drawPaint.setStyle(Paint.Style.STROKE);
+canvas.drawCircle(500, 500, 400, drawPaint);
+
+drawPaint.setStrokeJoin(Paint.Join.ROUND);
+drawPaint.setStrokeCap(Paint.Cap.ROUND);
+drawPaint.setColor(Color.GREEN);
+drawPaint.setStrokeWidth(15);
+canvas.drawLine(350, 300, 500,600, drawPaint);
+```]
+---
+
+# What is the [Paint](https://developer.android.com/reference/android/graphics/Paint.html) Object?
+
+- Abstraction that determines how drawing operations should look
+  - Drawing style: stroked, filled
+  - Line Characteristics: color, line width, join, cap styles
+  - Fill Characteristics (color)
+
+![:img example dotted line--unfilled,15%](img/drawing/dotted.png)
+![:img example solid filled,15%](img/drawing/filled.png)
+![:img example solid unfilled,15%](img/drawing/unfilled.png)
+---
+
+# Other Paint properties
+
+- Text Characteristics: font family, style, size, alignment settings, etc.
+
+--
+- font: shapes for chars (called *glyphs*) plus layout
+  - family or typeface
+
+![:img examples of different types of fonts,40%](img/drawing/fonts.png)
+
+---
+# Other Paint properties
+
+- Text Characteristics: font family, style, size, alignment settings,
+etc.
+- font: shapes for chars (called *glyphs*) plus layout
+  - family or typeface
+  - style: plain, *italic*, **bold**, **_both_**, ~~strikethrough~~,  *etc.*
+--
+
+  - points: 72.27 points per inch
+???
+because french inches were different (72 per inch)
+Really just a guideline these days
+It is the *width* of a capital M (no height specified)
+
+---
+# The Path Object
+
+- Canvas supports drawing primitive shapes _and_ arbitrary paths:  `void drawPath(Path p, Paint paint);`
+
+--
+
+- Declaring a `Path` can be done by combining basic primitive shapes (e.g rectangles, circles, ovals, curves like arc, cubic, etc.)
+
+--
+
+- What drawing model does creating a path in this way correspond to?
+ - Raster model
+ - Vector model
+
+---
+# The Path Object
+
+- Canvas supports drawing primitive shapes _and_ arbitrary paths:  `void drawPath(Path p, Paint paint);`
+
+- Declaring a `Path` can be done by combining basic primitive shapes (e.g rectangles, circles, ovals, curves like arc, cubic, etc.)
+
+
+- Which is more scalable?
+
+ - Raster model
+ - Vector model
+
+???
+XXXX could do in-class [drawing
+exercise](https://github.com/mriveralee/ssui-mobile-exercises-2016/tree/master/exercises/lab05/CustomDrawing)
+IF time XXXX needs updating
+
+---
+# Bounding box of an object
+
+A bounding box (or sometimes [Minimum Bounding Box](https://en.wikipedia.org/wiki/Minimum_bounding_box))
+is a term used in coordinate geometry to describe the smallest rectangular area that contains an object or set of objects.
+
+Great example to play with: https://www.mathopenref.com/coordbounds.html
+
+Drawing Demo - things to think about
+- What is the bounding box of a line that is drawn diagonally
+  - from upper left to lower right?
+  - lower right to the upper left?
+  - from the upper right to the lower left?
+  - from the lower s`
+- What is bounding box of a vertical line?
+- What is the bounding box of a horizontal line?
+
+---
+# Doodle assignment: practice with drawing
+
+Inspired by Google's Doodles, and will include animation (to be discussed)
+
+First we will create holders for things you might draw
+- Android already provides an `ImageView` and a `TextView`
+- You will create a `LineView`
+- You will produce some things we specify
+- Then you will have a chance to create any animation you want!
+
+---
+# [Example from 19sp](img/drawing/doodlevid.mp4)
+
+.left-column[
+Note that we use a `View` for **each** thing on the screen
+]
+.right-column[
+![:youtube Animation showing images of food moving in a line down the page around a U finally forming a W, Sx8oiJGjaIM]
+
+]
+
+---
+# Why so many separate `Views`?
+
+.left-column-half[
+
+Useful later when we want to do animation
+
+Also provides **separation of concerns** and good high level control
+- Can have a different paint object for each view
+- Can easily change z-order (what is on top of what)
+- Can store information used to draw that thing (whatever it is)
+- Can either make the size of the whole screen or resize around what is drawn
+
+Views can also be re-used easily
+]
+
+.right-column20[
+![:img Picture of an android device with 3 Views each one containing a line circle and square a different size with different backgrounds, 80%](img/drawing/views.png)
+]
+
+???
+This could be a good place to ask them to think about what that means and demonstrating two things with different z order.
+
+---
+# Coordinates of the Views
+
+- The coordinate system for each View has the (0, 0) point in the upper left hand corner (remember why?)
+- The width and height of the View is determined it's `ViewGroup.LayoutParams` -
+  - These will be used by the layout system for positioning.
+  - We will learn more about these next week.
+  -
+- The `View` also has a position on the screen.
+  - `View#SetX(int)` and `View.SetY(int)` set the left and top most coordinate of the `View` in its parent.
+
+---
+# Advanced Canvas: Coordinate Transformations
+
+.left-column[
+## How does the android toolkit move the various objects on this screen?
+]
+.right-column[
+![:youtube A phone screen with patterned circles spinning in different directions on it, w7DEWWtIlrs]
+]
+
+???
+Be sure to orally narrate what is happening for low-vision people in the room
+
+---
+# Linear ("affine") Transformations available
+
+Translate, Scale, Rotate, Shear (and any combination thereof)
+
+--
+
+- Translate: Move origin (and everything else) in x and y
+![:img a large moon and a large moon moved to the right a few pixels, 15%](img/drawing/translate.png)
+
+???
+used extensively in GUIS because child objects just draw themselves
+at *their* origin, so a component doesn't have to calculate how to draw
+itself based on its position
+
+--
+
+- Scale: change size (negative == flip)
+![:img a large and small moon, 15%](img/drawing/scale.png)
+
+--
+
+- Rotate and Shear
+![:img a rotated and angled moon, 25%](img/drawing/shear.png)
+
+---
+# Coordinate Transformations
+
+- Can modify any shape, including text.
+- In practice, complex transformations are done with matrices, and matrices are using `concat(Matrix)`
+- But Android helps with this by providing methods in the [Canvas](https://developer.android.com/reference/android/graphics/Canvas) object to transform a canvas such as
+```java
+translate(float dx, float dy)
+rotate(float degrees)                           // the whole canvas around the canvas origin
+rotate (float degrees, float px, float py)      // around a particular point
+scale(float, float)
+scale (float sx, float sy, float px, float py)  // around a pivot point
+skew(float sx, float sy)                        // skew by sx and sy
+save()                                          // save the current transform
+restore()                                       // restore the previous transform
+```
+
+???
+- important thing to point out here: This is a value proposition for a toolkit again
+
+– Affine transformations are based on two-dimensional matrices of the
+following form:
+
+P' = T*P where P is 1x3 and T is the transform matrix (3x3) with the
+bottom row 0 0 1
+
+Thus, x' = ax + cy + t_x and y' = bx + dy + t_y
+
+*Note* Any sequence of transform, rotate and shear can be represented
+in a single matrix of this form (just multiple the matrices together)
+
+
+
+---
+# Question: How to rotate about the center of an object
+
+<iframe src="https://embed.polleverywhere.com/multiple_choice_polls/DfxDLPdpd2zTpLlUJt9h9?controls=none&short_poll=true" width="800" height="500" frameBorder="0"></iframe>
+
+
+???
+
+[raise your hands]
+
+- A: Translate, rotate, translate
+- B: Rotate, Translate, Rotate
+- C: Scale, Rotate, Scale
+- D: Rotate
+
+
+XX define exercise
+maybe put this after android stuff?
+
+I usually draw this out on a piece of paper using the document camera to help
+
+---
+# Solution: How to rotate about the center of an object
+.left-column[
+![:img a blue square and then a translated and rotated green square, 80%](img/drawing/trans-rotate.png)]
+.right-column[
+
+```java
+int rectHeight = 300;
+int rectWidth = 300;
+int rectY = 100;
+int rectX = 100;
+float px = (rectWidth - rectX)/2 + rectX;
+float py = (rectHeight - rectY)/2 + rectY;
+
+canvas.drawRect(rectX, rectY, rectWidth, rectHeight, paint);
+
+for (int i = 15; i < 360; i += 15) {
+    int color = (i % 2 == 0) ? Color.GREEN : Color.BLUE;
+    paint.setColor(color);
+
+    canvas.drawRect(rectX, rectY, rectWidth, rectHeight, paint);
+    canvas.translate(px, py);
+    canvas.rotate(i);
+    canvas.translate(-px, -py);
+}
+```
+
+]
+
+---
+# Summary & revisiting learning goals for this week
+
+- What are the layers of the application stack
+- What are the roles of developers at each layer
+- How to add interactors to the app
+- How interactors are drawn
+- Pixel & stroke models
+- Canvas & Paint & Paths in Android
+- Maybe...Rotating around an object
diff --git a/slides/wk01/figs.pptx b/slides/wk01/figs.pptx
new file mode 100644
index 0000000000000000000000000000000000000000..640314bbc7787224d8cd6a0c4be4c8daf54b0975
Binary files /dev/null and b/slides/wk01/figs.pptx differ
diff --git a/slides/wk01/img/drawing/CRT_display.jpg b/slides/wk01/img/drawing/CRT_display.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..6e7315151756a6b0b81795cf9da1e461c26154df
Binary files /dev/null and b/slides/wk01/img/drawing/CRT_display.jpg differ
diff --git a/slides/wk01/img/drawing/DrawingPanel.png b/slides/wk01/img/drawing/DrawingPanel.png
new file mode 100644
index 0000000000000000000000000000000000000000..a80c2e8f320be3df12dcc7248e1824ef267f3ea8
Binary files /dev/null and b/slides/wk01/img/drawing/DrawingPanel.png differ
diff --git a/slides/wk01/img/drawing/LED_display.jpg b/slides/wk01/img/drawing/LED_display.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..95bd0ad4022000674e359b23a082452d1e895b7b
Binary files /dev/null and b/slides/wk01/img/drawing/LED_display.jpg differ
diff --git a/slides/wk01/img/drawing/activity_lifecycle.png b/slides/wk01/img/drawing/activity_lifecycle.png
new file mode 100644
index 0000000000000000000000000000000000000000..837eea1fc6721683c4e103348a9e704faf527835
Binary files /dev/null and b/slides/wk01/img/drawing/activity_lifecycle.png differ
diff --git a/slides/wk01/img/drawing/activity_lifecycle_full.png b/slides/wk01/img/drawing/activity_lifecycle_full.png
new file mode 100755
index 0000000000000000000000000000000000000000..879f51f6e8fafe75d267984680ef63f85b118dc5
Binary files /dev/null and b/slides/wk01/img/drawing/activity_lifecycle_full.png differ
diff --git a/slides/wk01/img/drawing/analogtv.jpg b/slides/wk01/img/drawing/analogtv.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..c74daaf942b864b1bf0fa5a0948761a35f0576ab
Binary files /dev/null and b/slides/wk01/img/drawing/analogtv.jpg differ
diff --git a/slides/wk01/img/drawing/android-animate.gif b/slides/wk01/img/drawing/android-animate.gif
new file mode 100755
index 0000000000000000000000000000000000000000..0fb1d08fd616979b31c4390966e7c2e3410b2c4f
Binary files /dev/null and b/slides/wk01/img/drawing/android-animate.gif differ
diff --git a/slides/wk01/img/drawing/animation-linear.png b/slides/wk01/img/drawing/animation-linear.png
new file mode 100755
index 0000000000000000000000000000000000000000..08bd9fc3dc2ce5d151294b1d2b695a490f2e5f00
Binary files /dev/null and b/slides/wk01/img/drawing/animation-linear.png differ
diff --git a/slides/wk01/img/drawing/boundless.gif b/slides/wk01/img/drawing/boundless.gif
new file mode 100644
index 0000000000000000000000000000000000000000..b0613367fe237b6755557dd886a4f374380ec574
Binary files /dev/null and b/slides/wk01/img/drawing/boundless.gif differ
diff --git a/slides/wk01/img/drawing/circles.png b/slides/wk01/img/drawing/circles.png
new file mode 100644
index 0000000000000000000000000000000000000000..81448d0a6c68d6aaa1ecbe4952e90d4345d08006
Binary files /dev/null and b/slides/wk01/img/drawing/circles.png differ
diff --git a/slides/wk01/img/drawing/doodlevid.mp4 b/slides/wk01/img/drawing/doodlevid.mp4
new file mode 100644
index 0000000000000000000000000000000000000000..090f7e51963466d13b647eb8fb71fb795925d70c
Binary files /dev/null and b/slides/wk01/img/drawing/doodlevid.mp4 differ
diff --git a/slides/wk01/img/drawing/dotted.png b/slides/wk01/img/drawing/dotted.png
new file mode 100644
index 0000000000000000000000000000000000000000..17a01df4330e0a8eef0d139fbe02ec41ece7910f
Binary files /dev/null and b/slides/wk01/img/drawing/dotted.png differ
diff --git a/slides/wk01/img/drawing/fastfood.mp4 b/slides/wk01/img/drawing/fastfood.mp4
new file mode 100644
index 0000000000000000000000000000000000000000..8089ac7b2d852079847bf8384d270d2bf5c62591
Binary files /dev/null and b/slides/wk01/img/drawing/fastfood.mp4 differ
diff --git a/slides/wk01/img/drawing/filled.png b/slides/wk01/img/drawing/filled.png
new file mode 100644
index 0000000000000000000000000000000000000000..eeccdb82550384e358f10b7ac93be3ec419a586a
Binary files /dev/null and b/slides/wk01/img/drawing/filled.png differ
diff --git a/slides/wk01/img/drawing/fonts.png b/slides/wk01/img/drawing/fonts.png
new file mode 100644
index 0000000000000000000000000000000000000000..102d6b0b1adc3a98b0ecc0a220901b4b605195fd
Binary files /dev/null and b/slides/wk01/img/drawing/fonts.png differ
diff --git a/slides/wk01/img/drawing/interactors.png b/slides/wk01/img/drawing/interactors.png
new file mode 100644
index 0000000000000000000000000000000000000000..339747d21e81b21df33a7a971a143991e85ffae4
Binary files /dev/null and b/slides/wk01/img/drawing/interactors.png differ
diff --git a/slides/wk01/img/drawing/interpolators.gif b/slides/wk01/img/drawing/interpolators.gif
new file mode 100644
index 0000000000000000000000000000000000000000..ad4e46ef00ad0843547fa69de0754dbaf9a7c59b
Binary files /dev/null and b/slides/wk01/img/drawing/interpolators.gif differ
diff --git a/slides/wk01/img/drawing/messaging.png b/slides/wk01/img/drawing/messaging.png
new file mode 100644
index 0000000000000000000000000000000000000000..dbcd315a04f897ddc84b88b144f447f7379ff3b8
Binary files /dev/null and b/slides/wk01/img/drawing/messaging.png differ
diff --git a/slides/wk01/img/drawing/messenger-bubble.gif b/slides/wk01/img/drawing/messenger-bubble.gif
new file mode 100755
index 0000000000000000000000000000000000000000..77defd497891e79a775a6ca3593cf33e02d2c890
Binary files /dev/null and b/slides/wk01/img/drawing/messenger-bubble.gif differ
diff --git a/slides/wk01/img/drawing/pacing.png b/slides/wk01/img/drawing/pacing.png
new file mode 100644
index 0000000000000000000000000000000000000000..3997cf6fd6aeee192b83ddd549982c9fb8c857a2
Binary files /dev/null and b/slides/wk01/img/drawing/pacing.png differ
diff --git a/slides/wk01/img/drawing/pathanimation.gif b/slides/wk01/img/drawing/pathanimation.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f2829498a59210e38138a4a30b31cc26fe948916
Binary files /dev/null and b/slides/wk01/img/drawing/pathanimation.gif differ
diff --git a/slides/wk01/img/drawing/pixelcalc.png b/slides/wk01/img/drawing/pixelcalc.png
new file mode 100644
index 0000000000000000000000000000000000000000..2a18bcc5ecfea59668643d5654782554323e6631
Binary files /dev/null and b/slides/wk01/img/drawing/pixelcalc.png differ
diff --git a/slides/wk01/img/drawing/pollevscreen.jpeg b/slides/wk01/img/drawing/pollevscreen.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..eec7d069978daffee0f466c7388aedf36c734d58
Binary files /dev/null and b/slides/wk01/img/drawing/pollevscreen.jpeg differ
diff --git a/slides/wk01/img/drawing/rasterscanning.png b/slides/wk01/img/drawing/rasterscanning.png
new file mode 100644
index 0000000000000000000000000000000000000000..95cf22eb58025670e99a1af4b1d3c4d6456e9406
Binary files /dev/null and b/slides/wk01/img/drawing/rasterscanning.png differ
diff --git a/slides/wk01/img/drawing/spinners.mov b/slides/wk01/img/drawing/spinners.mov
new file mode 100644
index 0000000000000000000000000000000000000000..90bd20b62efaa4fe887a336b371a58025539b6a8
Binary files /dev/null and b/slides/wk01/img/drawing/spinners.mov differ
diff --git a/slides/wk01/img/drawing/trans-rotate.png b/slides/wk01/img/drawing/trans-rotate.png
new file mode 100644
index 0000000000000000000000000000000000000000..bdc729191278f7a42d4470d4329b243378d1c6a6
Binary files /dev/null and b/slides/wk01/img/drawing/trans-rotate.png differ
diff --git a/slides/wk01/img/drawing/unfilled.png b/slides/wk01/img/drawing/unfilled.png
new file mode 100644
index 0000000000000000000000000000000000000000..cec58bfe8be1cfd1338377dbadd1f11197ab2af5
Binary files /dev/null and b/slides/wk01/img/drawing/unfilled.png differ
diff --git a/slides/wk01/img/drawing/valueanimator.png b/slides/wk01/img/drawing/valueanimator.png
new file mode 100755
index 0000000000000000000000000000000000000000..6cc2a13bbfca142b090c3fec00ddf410ca82eeb5
Binary files /dev/null and b/slides/wk01/img/drawing/valueanimator.png differ
diff --git a/slides/wk01/img/drawing/views.png b/slides/wk01/img/drawing/views.png
new file mode 100644
index 0000000000000000000000000000000000000000..63ed37f80d05ee622489509f2ca0fd9b9aecef78
Binary files /dev/null and b/slides/wk01/img/drawing/views.png differ
diff --git a/slides/wk01/img/toolkits/activity_lifecycle.png b/slides/wk01/img/toolkits/activity_lifecycle.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab0921a717d184442c96c1b8863018d46920a67c
Binary files /dev/null and b/slides/wk01/img/toolkits/activity_lifecycle.png differ
diff --git a/slides/wk01/img/toolkits/android-components.png b/slides/wk01/img/toolkits/android-components.png
new file mode 100644
index 0000000000000000000000000000000000000000..30d90a952ecddebdfddc1ee1cd2586bb42070762
Binary files /dev/null and b/slides/wk01/img/toolkits/android-components.png differ
diff --git a/slides/wk01/img/toolkits/android-components2.png b/slides/wk01/img/toolkits/android-components2.png
new file mode 100644
index 0000000000000000000000000000000000000000..bb2539c214d6fbaacd876a56443f5533ff5cb5bd
Binary files /dev/null and b/slides/wk01/img/toolkits/android-components2.png differ
diff --git a/slides/wk01/img/toolkits/android-editor.gif b/slides/wk01/img/toolkits/android-editor.gif
new file mode 100644
index 0000000000000000000000000000000000000000..740a8447abe8a2c87ace8be0786161fa86b0c070
Binary files /dev/null and b/slides/wk01/img/toolkits/android-editor.gif differ
diff --git a/slides/wk01/img/toolkits/android-swipe.png b/slides/wk01/img/toolkits/android-swipe.png
new file mode 100644
index 0000000000000000000000000000000000000000..3f2f55e84b63c7a9e551125f114db550ac804e52
Binary files /dev/null and b/slides/wk01/img/toolkits/android-swipe.png differ
diff --git a/slides/wk01/img/toolkits/android-type.jpg b/slides/wk01/img/toolkits/android-type.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..ce7404e45aa8b9a8b6f92cfddfd135311694b868
Binary files /dev/null and b/slides/wk01/img/toolkits/android-type.jpg differ
diff --git a/slides/wk01/img/toolkits/android-ui.png b/slides/wk01/img/toolkits/android-ui.png
new file mode 100644
index 0000000000000000000000000000000000000000..16760d5095a74f896378a3cff9e5b70231161919
Binary files /dev/null and b/slides/wk01/img/toolkits/android-ui.png differ
diff --git a/slides/wk01/img/toolkits/animation.gif b/slides/wk01/img/toolkits/animation.gif
new file mode 100644
index 0000000000000000000000000000000000000000..31558eec649308ffd33ab15872fb2c10997c6488
Binary files /dev/null and b/slides/wk01/img/toolkits/animation.gif differ
diff --git a/slides/wk01/img/toolkits/ape_fwk_hal.png b/slides/wk01/img/toolkits/ape_fwk_hal.png
new file mode 100644
index 0000000000000000000000000000000000000000..54927259aed04a9eb299408e941f69a8a615ef03
Binary files /dev/null and b/slides/wk01/img/toolkits/ape_fwk_hal.png differ
diff --git a/slides/wk01/img/toolkits/hardware.jpg b/slides/wk01/img/toolkits/hardware.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d92ec906e33b0f37b1f5cc06e2c623e148155fc5
Binary files /dev/null and b/slides/wk01/img/toolkits/hardware.jpg differ
diff --git a/slides/wk01/img/toolkits/interactors1.png b/slides/wk01/img/toolkits/interactors1.png
new file mode 100644
index 0000000000000000000000000000000000000000..73d003f6a57acf9338a629abb520bc9045e98ebb
Binary files /dev/null and b/slides/wk01/img/toolkits/interactors1.png differ
diff --git a/slides/wk01/img/toolkits/interface.png b/slides/wk01/img/toolkits/interface.png
new file mode 100644
index 0000000000000000000000000000000000000000..efc20af479615d575dd62054d447dabd3ab6f698
Binary files /dev/null and b/slides/wk01/img/toolkits/interface.png differ
diff --git a/slides/wk01/img/toolkits/many-uis.png b/slides/wk01/img/toolkits/many-uis.png
new file mode 100644
index 0000000000000000000000000000000000000000..1fd7edc75974437e56d41047b159f73339022298
Binary files /dev/null and b/slides/wk01/img/toolkits/many-uis.png differ
diff --git a/slides/wk01/img/toolkits/novellibrary.png b/slides/wk01/img/toolkits/novellibrary.png
new file mode 100644
index 0000000000000000000000000000000000000000..a6e73b04930f211e0d98219be61682337e99bcc2
Binary files /dev/null and b/slides/wk01/img/toolkits/novellibrary.png differ
diff --git a/slides/wk01/img/toolkits/phones.jpeg b/slides/wk01/img/toolkits/phones.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..167440241532cf08b589ef24ad9fb66ec70d7540
Binary files /dev/null and b/slides/wk01/img/toolkits/phones.jpeg differ
diff --git a/slides/wk01/img/toolkits/prototype.png b/slides/wk01/img/toolkits/prototype.png
new file mode 100644
index 0000000000000000000000000000000000000000..920c6b2ba08cbca1aa6406ff0987b59eda057ce2
Binary files /dev/null and b/slides/wk01/img/toolkits/prototype.png differ
diff --git a/slides/wk01/img/toolkits/sandcastle1.png b/slides/wk01/img/toolkits/sandcastle1.png
new file mode 100644
index 0000000000000000000000000000000000000000..265a540744d3b32b000231b226bd5df75de1a935
Binary files /dev/null and b/slides/wk01/img/toolkits/sandcastle1.png differ
diff --git a/slides/wk01/img/toolkits/sandcastle2.jpg b/slides/wk01/img/toolkits/sandcastle2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..19f5af8ea412f80fbd7e2fb2d1ec0a110b25a755
Binary files /dev/null and b/slides/wk01/img/toolkits/sandcastle2.jpg differ
diff --git a/slides/wk01/img/toolkits/sandcastletools.png b/slides/wk01/img/toolkits/sandcastletools.png
new file mode 100644
index 0000000000000000000000000000000000000000..befeb3939b90834e9cd3c158e418425e7410ebf2
Binary files /dev/null and b/slides/wk01/img/toolkits/sandcastletools.png differ
diff --git a/slides/wk01/img/toolkits/sketch.png b/slides/wk01/img/toolkits/sketch.png
new file mode 100644
index 0000000000000000000000000000000000000000..12952eab789096730ba6ea4040107be435804fa6
Binary files /dev/null and b/slides/wk01/img/toolkits/sketch.png differ
diff --git a/slides/wk01/img/toolkits/zoom-hall-of-fame.png b/slides/wk01/img/toolkits/zoom-hall-of-fame.png
new file mode 100644
index 0000000000000000000000000000000000000000..d11b519efcaff9347aaa4ffe0b0db21b28b2390a
Binary files /dev/null and b/slides/wk01/img/toolkits/zoom-hall-of-fame.png differ
diff --git a/slides/wk01/img/toolkits/zoom-hall-of-shame.png b/slides/wk01/img/toolkits/zoom-hall-of-shame.png
new file mode 100644
index 0000000000000000000000000000000000000000..b11f8a5d8b07fc74eddc9d0468684e13ff39c576
Binary files /dev/null and b/slides/wk01/img/toolkits/zoom-hall-of-shame.png differ
diff --git a/slides/wk01/intro.html b/slides/wk01/intro.html
index 45722dfbbe46c9d5cac56a7db0f4f7b0e412e840..7744053e9278480072292d9dea360ef4a8349892 100644
--- a/slides/wk01/intro.html
+++ b/slides/wk01/intro.html
@@ -48,93 +48,6 @@ Small Group Discussion: How is it changing us as individuals and a society?
 # Summary (somewhat tongue in cheek)
 
 
-Welcome to the class!
-
-All of HCI was already invented (sort of!)
-
-HCI has a huge influence on individuals and society
-
-HCI is really all of computer science
-
----
-layout: false
-
-<!-- (Outline Slide) -->
-
-# Today's goals
-
-- HCI: Designing the Future
-- **Learning goals**
-- Course staff
-- Syllabus
----
-.left-column[
-# This **week's** learning goals
-]
-.right-column[
-- What is HCI? Past, present and future
-- Get up to speed with Android basics
-- Learn about basic abstractions for UI implementation
-- Names for common interactors
-]
----
-.left-column[
-# Course learning goals:
-]
-.right-column[
-# Building Interfaces
-- Deep understanding of **how to build user interfaces**
-- Basic abstractions (layout, event handling, *etc.*)
-- Implementing best practices: Undo, Accessibility, Feedback, Errors,
-*etc.*
-- Exploration of advanced UI concepts: Ubicomp, Sensing, AR, *etc.*
-]
----
-
-.left-column[
-# Course learning goals:
-]
-.right-column[
-#  Iterative Design
-
-- Basic understanding of **Iterative Design**
-- Why designers are valuable
-- Iterative design process
-- How designers get data from users
-]
----
-layout: false
-
-<!-- (Outline Slide) -->
-
-# Today's goals
-
-- HCI: Designing the Future
-- Learning goals
-- **Course staff**
-- How we will teach this course
-- Learning goals
-- Course staff
-- Syllabus
-
-
----
-#  HCI in the Future
-
-Small Group Discussion: How is it changing us as individuals and a society?
-
-<iframe src="https://us.edstem.org/courses/114/sway/host/1153" width="800" height="600" frameBorder="0"></iframe>
-
-???
-- Social networking has been implicated in revolutions and elections.
-- Interfaces designs have impacted health and safety.
----
-# Return to discuss as a class
-
----
-# Summary (somewhat tongue in cheek)
-
-
 Welcome to the class!
 
 All of HCI was already invented (sort of!)
diff --git a/slides/wk01/toolkits.html b/slides/wk01/toolkits.html
new file mode 100644
index 0000000000000000000000000000000000000000..b3eebd1d97db20302d4bc4518efb1591f379ff80
--- /dev/null
+++ b/slides/wk01/toolkits.html
@@ -0,0 +1,910 @@
+---
+layout: presentation
+title: Basic Toolkit Abstractions
+description: Discussion of basic abstractions for user interfaces
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Core Toolkit Abstractions
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+name: normal
+layout: true
+class:
+---
+layout: false
+
+| Hall of Shame | Hall of Fame|
+|---|---|
+|![:img Zoom toolbar displaying over tabs, 100%](img/toolkits/zoom-hall-of-shame.png) | ![:img Zoom-hall-of-fame, 100%](img/toolkits/zoom-hall-of-fame.png)
+---
+| Hall of Shame(?) | Hall of Fame |
+|---|---|
+|![:img Picture of a small sandcastle that is falling apart, 100%](img/toolkits/sandcastle1.png) | ![:img Picture of a complex sandcastle with LEDs lighting it up, 85%](img/toolkits/sandcastle2.jpg)
+---
+![:img Simple home tools for sandcastle making such as a bucket; funnel; brush; and spackle knife, 45%](img/toolkits/sandcastletools.png)
+---
+# Announcements
+
+- We have Ed ([use us.edstem.org](https://us.edstem.org/dashboard) to log in)
+- Reminder: set up your machine before lab tomorrow!
+ - Android Basics: Follow [this](https://developer.android.com/training/basics/firstapp) tutorial to create an Android Application.
+ - Continue with the tutorial to also [run your app](https://developer.android.com/training/basics/firstapp/running-app) either on an emulator or on an Android Device.
+ - Git Setup: [macOS](https://courses.cs.washington.edu/courses/cse154/19au/resources/assets/atomgit/macosx/), [win](https://courses.cs.washington.edu/courses/cse154/19au/resources/assets/atomgit/windows/) (ignore pieces about Atom as we use Android Studio)
+Make sure you have git setup on your computer, follow above instructions
+ - If you have never used git before read through [this](http://cse340-20wi.pages.cs.washington.edu/website/docs/git.html#1) and [this](https://courses.cs.washington.edu/courses/cse331/18au/handouts/tools/versioncontrol.html) (Android Studio ≈ Intellij)
+ - Ensure that you can clone from CSE GitLab, (we recommend cloning via SSH)
+- There are now two new helpful pages
+  - An [Academic Conduct]({{site.baseurl}}/academic-conduct) page
+  with Application Content and Collaboration Policies section. (Linked to from home page)
+  - A [GitGrade]({{site.baseurl}}/docs/gitgrade) tutorial page linked to from
+  the [docs]({{site.baseurl}}/docs) page. Note: there are still more tutorials we are building up.
+
+???
+Our learning goals for the first lab are Android project structure, GitGrade and first assignment Doodle.
+Please follow the instructions below to be familiar with Android and have your Git ready before this Thursday section:
+
+---
+# Java refresher course
+
+The TAs will be hosting a Java refresher that covers most facets of Java we will be using in this
+class (and maybe some additional Java 8+ material that is nice to know). Which includes:
+
+- Inheritance
+- Generics
+- Anonymous Inner Classes
+- Lambdas (and "::" notation)
+
+If these are not topics you're comfortable with (some are not directly covered in any CS class), come join us!
+
+Time: 5:30-6:30pm Thursday
+Zoom link in Ed
+
+---
+[//]: # (Outline Slide)
+# Today's goals
+
+- **Toolkits & Toolkit Users**
+- Introduce the interactor hierarchy
+- How does an interactor draw?
+
+---
+# What does it take to run an app on a phone?
+
+![:youtube An android screen with many icons on it; then an app opens and the user can be seen drawing a line. When they finish an undo button appears, 2TJPjyMQGkM]
+
+???
+
+- Give them 60 seconds to think about it and talk with their neighbor.
+- What you want to get at is the application stack
+
+---
+# The Application Stack
+.left-column[
+<div class="mermaid">
+  graph LR
+  ap[Application Program]
+  hlt[High Level Tools]
+  t[Toolkit]
+  w[Window System]
+  o[OS]
+  h[Hardware]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+  classDef darkblue font-size:14pt,text-align:center
+
+  class ap,o,w yellow
+  class hlt,t green
+  class h darkblue
+</div>
+]
+.right-column[
+![:img Picture of a woman in front of an open laptop holding a phone with an ipad next to the laptop; a wristwatch on her arm; and a keyfob to the left of the laptop, 50%](img/toolkits/hardware.jpg)
+]
+
+???
+Get the class to brainstorm about what hardware is visible on the screen
+
+Point out that they all have stacks and the things we are learning are not android specific
+
+---
+.left-column[
+![:img Picture of the control buttons at the bottom of several different phones; with icons and order changing from phone to phone, 100%](img/toolkits/phones.jpeg)
+]
+.right-column[
+## Android Hardware
+
+![:img Picture of the Hardware Abstraction Layer for android including audio; automotive; bluetooth; camera; drm; graphics; input; media; peripherals; sensors; storage; and tv componnets, 70%](img/toolkits/ape_fwk_hal.png)]
+
+???
+Get the class to brainstorm about what hardware is available on android vs their laptop and how that might influence user interfaces
+
+---
+# The Application Stack
+.left-column[
+<div class="mermaid">
+  graph LR
+  ap[Application Program]
+  hlt[High Level Tools]
+  t[Toolkit]
+  w[Window System]
+  o[OS]
+  h[Hardware]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+  classDef darkblue font-size:14pt,text-align:center
+
+  class ap,h,w yellow
+  class hlt,t green
+  class o darkblue
+</div>
+]
+
+.right-column[
+What services does it provide?
+
+How does this impact what you might build in an application?
+]
+
+???
+Class brainstorming about what OS does
+1) manages shared resources (e.g. memory, processor power)
+2) has the power to start and pause and stop applicatinos
+
+---
+.left-column[
+# Impact of Android OS on apps
+]
+.right-column[
+![:img Android Activity Lifecycle which shows when the operating system starts; pauses and kills android processes, 45%](img/toolkits/activity_lifecycle.png)
+]
+
+???
+How does the operating system influence what
+you can build? How does this differ on an android device from a desktop?
+
+The Android Activity Lifecycle starts when an activity is launched (by the OS); which leads to
+callbacks to the application such as onCreate, onStart and onResume. Once the activity is running,
+it may be paused, stopped or destroyed. Things like priority and available memory may
+influence this process, as does the user opening the app.
+
+---
+# The Application Stack
+.left-column[
+<div class="mermaid">
+  graph LR
+  ap[Application Program]
+  hlt[High Level Tools]
+  t[Toolkit]
+  w[Window System]
+  o[OS]
+  h[Hardware]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+  classDef darkblue font-size:14pt,text-align:center
+
+  class ap,o,h yellow
+  class hlt,t green
+  class w darkblue
+</div>
+]
+.right-column[
+
+- Manages window size and visibility across many applications
+- May trigger clipping and redraw
+  - Lots of cases where this arises on a desktop (overlapping windows, minimization, etc)
+  - Toolkit handles this for you, but can lead to callbacks; redraw events
+
+Where is this on Android?
+]
+
+???
+---
+# The Application Stack
+.left-column[
+<div class="mermaid">
+  graph LR
+  ap[Application Program]
+  hlt[High Level Tools]
+  t[Toolkit]
+  w[Window System]
+  o[OS]
+  h[Hardware]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+  classDef darkblue font-size:14pt,text-align:center
+
+  class ap,w,h,o yellow
+  class hlt,t green
+  class t darkblue
+</div>
+]
+
+.right-column[
+Services a toolkit supports (in the order we will learn them)
+- Graphics
+- Animation
+- Layout
+- Accessibility
+- Event Handling
+- Interactive Components
+- Undo
+- Sensing (not covered)
+- Data (not covered)
+ - databases; apis
+]
+
+???
+What are some things you expect every interface to have that I didn't mention here?
+Example: Undo (we will learn about this)
+
+Do all user interface toolkits have all of these?
+
+---
+# What is an Interface Toolkit
+
+(Main subject of this course)
+- Difference between toolkit and IDE (Integrated Development Environment)?
+- Difference between toolkit and API (Application Programming Interface)?
+
+Structure of a Toolkit
+- Library of components
+- Architecture
+
+???
+Connect what they learned in 143 (i.e that they used the SDK for Java which had a bunch of libraries that had pre-defined code). The IDE most people used was JGrasp.
+
+---
+# Example: Doodle assignment: Makes use of the Android Toolkit
+
+Inspired by Google's Doodles, and will include drawing animation (to be discussed): <br>
+[Example from last year's class](img/drawing/doodlevid.mp4)
+
+![:youtube Animation showing images of food moving in a line down the page around a U finally forming a W, Sx8oiJGjaIM]
+
+---
+.left-column40[
+## Doodle Assignment
+
+Uses of Android Toolkit  **Library** (green)
+
+<div class="mermaid">
+  graph TD
+  Activity[Activity]
+  Activity -->|...| Doodler[Doodler]
+  Doodler --> Part1[Part1]
+  Part1 --> Part1Activity[Part1Activity]
+  Part1 --> Part2Activity[Part2Activity]
+
+  View[View]
+  View --> ImageView[ImageView]
+  View --> TextView[TextView]
+  View --> LineView[LineView]
+
+  classDef yellow font-size:12pt,text-align:center
+  classDef green font-size:12pt,text-align:center
+  classDef blue font-size:12pt,text-align:center
+
+  class Part1,Part1Activity,Part2Activity,LineView yellow
+  class Activity,View,ImageView,TextView green
+  class Doodler blue
+
+</div>
+]
+
+.right-column30[
+##  Classes we are using in Doodle
+
+- Doodler (which you don't edit) *extends* [Activity](https://developer.android.com/reference/android/app/Activity)
+- Part1 *extends* Doodler. It implements *helper methods*.
+- Part1Activity and Part2Activity both extend Part1 (and use the helper methods)
+- LineView *extends* [View](https://developer.android.com/reference/android/view/View) (so does [ImageView](https://developer.android.com/reference/android/widget/ImageView.html) and [TextView](https://developer.android.com/reference/android/widget/TextView.html)
+
+]
+
+???
+Green: Android toolkit
+Blue: Classes we provide you don't have to modify
+Yellow: Classes you implement
+
+Remind students that they did do inheritance in 142/143 like with Critters.
+
+---
+.left-column40[
+# Doodle: What you will learn
+
+- How the Android Activity Lifecycle works (*Architecture*)
+- How to use Android Toolkit `View` objects to show things on screen (*Library*)
+- How to create a custom `View` to draw lines on screen (*Library*)
+- All about Android's `Canvas` object and how to use it to draw on screen (*Library*)
+- How the Android Toolkit supports animation (*Architecture & Library*)
+]
+
+.right-column40[
+# Doodle: What you will do
+
+- Modify Android Activities (`Part1` and `Part1Activity`)
+- Implement methods to add images, text and lines
+- Create the custom view `LineView`
+- Override `onDraw` to draw on the screen in `LineView`
+- Use `ObjectAnimator` to animate Text and other things
+- Create a custom doodle in `Part2Activity`
+]
+---
+
+# The Application Stack
+.left-column[
+<div class="mermaid">
+  graph LR
+  ap[Application Program]
+  hlt[High Level Tools]
+  t[Toolkit]
+  w[Window System]
+  o[OS]
+  h[Hardware]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+  classDef darkblue font-size:14pt,text-align:center
+
+  class w,ap,o,h yellow
+  class t green
+  class hlt darkblue
+</div>
+]
+.right-column[
+![:img Screenshot of the android layout tool, 80%](img/toolkits/android-editor.gif)
+]
+---
+# Subtle influence of tools
+
+![:img Hand-drawn sketch of an interface very rough around the edges, 50%](img/toolkits/sketch.png)
+
+---
+# Subtle influence of tools
+
+![:img High Fidelity Prototype, 40%](img/toolkits/prototype.png)
+
+---
+# Subtle influence of tools
+
+Whorfian Effects
+- The way in which our tools influence how we think and thus what we do.
+
+- Origins are linguistic (e.g. the way in which language about color affects what we perceive)
+
+- Can even affect perception of human emotion!
+http://www.radiolab.org/story/91730-new-words-new-world/
+
+
+---
+# The Application Stack
+.left-column[
+<div class="mermaid">
+  graph LR
+  ap[Application Program]
+  hlt[High Level Tools]
+  t[Toolkit]
+  w[Window System]
+  o[OS]
+  h[Hardware]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+  classDef darkblue font-size:14pt,text-align:center
+
+  class w,o,h yellow
+  class t,hlt green
+  class ap darkblue
+</div>
+]
+.right-column[
+![:img Screenshot of an android ui for exploring a neighborhood showing a range of locations; activities to engage in in those locations; and things that match the selected activity in a sequence of screens, 80%](img/toolkits/android-ui.png)
+]
+
+???
+Get class to discuss all the things that a UI like this does a little bit. What do you have to think about to build an application? How might a toolkit help with this?
+---
+
+# Summary: The Application Stack
+.left-column[
+<div class="mermaid">
+  graph LR
+  ap[Application Program]
+  hlt[High Level Tools]
+  t[Toolkit]
+  w[Window System]
+  o[OS]
+  h[Hardware]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+
+  class ap,w,o,h yellow
+  class hlt,t green
+
+</div>
+]
+
+.right-column[
+- **Application Program** - An application designed for an end user to perform specific tasks.
+- **High Level Tools** - Graphical interfaces that that let you specify parts of your interface (such as layout). Subject to Worfian Effects
+- **Toolkit** - A set of libraries and tools you use to develop applications.
+- **Window System** - Manages window size and visibility across applications
+- **OS** - The operating system that is running on the device, providing system services such as acceess to displays, input devices, file I/O
+- **Hardware** - The device that is running software, such as an Android Phone
+
+High level tools and the the Toolkit are generally packaged as part of a toolkit but really should be thought of as separate things. (You can program the toolkit without the tools. )
+]
+
+---
+
+.left-column[
+## Developer roles
+
+<div class="mermaid">
+  graph LR
+  ip[Interface Programmer]
+  w[Component Developer]
+  l[Library Extender]
+  a[Architecture Extender]
+  t[Toolkit Builder]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+  classDef darkblue font-size:14pt,text-align:center
+
+  class ip,t yellow
+  class w,l,a green
+</div>
+]
+.right-column[
+## Let's say you want to build an app
+
+In this class, you will use the Android Toolkit
+
+Who are we when we build the app?
+]
+
+---
+.left-column[
+## Developer roles
+<div class="mermaid">
+  graph LR
+  ip[Interface Programmer]
+  w[Component Developer]
+  l[Library Extender]
+  a[Architecture Extender]
+  t[Toolkit Builder]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+  classDef darkblue font-size:14pt,text-align:center
+
+  class t yellow
+  class w,l,a green
+  class ip darkblue
+</div>
+]
+.right-column[
+**Interface Programmers** combine library elements according to toolkit rules & following
+constraints of architecture; common to all UI toolkits
+
+In Android
+- Construct app out of `Views`
+- Assembly happens in an `Activity` in `onCreate()` using `addView(View)`
+
+In Doodle
+- You add views when you implement `addImage`, `addText` and `addLine` in `Part1.java`
+- You will need to call `doodleView.addView([view])` (`doodleView` is defined in `Doodler`)
+]
+---
+# How does the toolkit know what to draw?
+
+![:img Picture of a very simple interface showing a ringing bell at
+left and an x at right to close the window with the words Google
+Calendar reminder Christian and Anind (Jen Mankoff) is starting at
+12:30pm. Video call between them, 70%](img/toolkits/interface.png)
+
+
+- Discuss
+???
+discuss with your neighbor based on the reading what does the
+toolkit need to know to draw this
+- what to draw; where to draw it
+- what are good abstractions for this?
+- Hierarchy normally reflects spatial containment relationships
+
+--
+
+- Deconstruct
+
+ - Let's list all the components... and arrange them in a tree
+
+???
+
+- deconstruct this interface into an interactor hierarchy
+
+---
+![:img Picture of a very simple interface showing a ringing bell at
+left and an x at right to close the window with the words Google
+Calendar reminder Christian and Anind (Jen Mankoff) is starting at
+12:30pm. Video call between them, 60%](img/toolkits/interface.png)
+
+
+<div class="mermaid">
+graph LR
+W(Window) --> L(LeftSide:Icon)
+W --> M(Middle:Label)
+W --> R(Right:Close Button)
+
+classDef start font-size:14pt,text-align:center
+classDef blue font-size:14pt,text-align:center
+
+class W start
+class M,R,L blue
+
+</div>
+
+---
+# More complex example
+
+![:img Picture of a messaging interface with two messages in it, 20%](img/drawing/messaging.png)
+
+---
+.left-column[
+## More complex example
+
+![:img Picture of a messaging interface with two messages in it, 80%](img/drawing/messaging.png)]
+
+.right-column[
+<div class="mermaid">
+graph LR
+W(Window) --> T(Controls)
+W --> M(Chats)
+W --> Q(Text Entry)
+T --> A[Button:Messages]
+T --> B[Label:288-88]
+T --> C[Button:Edit]
+M --> G[Button:Call]
+M --> H[Button:Add to Contacts]
+M --> E[Chat1]
+M --> F[Chat2...]
+E --> I[Date]
+E --> J[Chat Msg]
+E --> K[Arrow]
+
+classDef start font-size:14pt,text-align:center
+classDef blue font-size:14pt,text-align:center
+
+
+class W start
+class T,M,E,Q,A,B,C,G,H,E,F,I,J,K blue
+
+</div>
+]
+---
+# How is the tree used for drawing?
+
+Interface Programmer:
+- Build and interface == build an interactor hierarchy
+- Change an interface == change the interactor hierarchy (or its  parameters)
+
+
+---
+
+.left-column-half[
+## How does Android let you do this
+Architecture invokes the work to construct the *interactor hierarchy*
+by calling  `onCreate()`
+
+In Doodle
+- *Doodler* overrides `onCreate()` (from it's grandparent *Activity* class)
+- *Doodler* provides a helper method for this (`doodle()`) which you
+   override in `Part1Activity` and `Part2Activity`.
+]
+.right-column-half[
+```java
+
+abstract class Doodler extends AppCompatActivity {
+    // ...
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        // ...
+        doodle(...)
+    }
+
+    abstract protected void doodle(FrameLayout doodleView);
+```
+]
+
+---
+# How is the tree used for drawing?
+
+The interface programmer is not really *drawing on a canvas*, they are *adding views* to a *parent view* in `onCreate()` (or later if something changes)
+
+This is *setup* for the interface being rendered: We are constructing
+the interactor (also called component) hierarchy when we call these methods.
+
+This happens in `Doodle` inside of `Part1.java` in `addImage()` when we say `doodleView.addView(imageView);`
+
+You have to do it in `addText()` and `addLine()` too.
+
+---
+# How is the tree used for drawing?
+Toolkit Architecture:
+- Draw an interface == walk the tree and tell interactors to draw
+- Update an interface == walk the tree, only redraw things that are marked as dirty
+- Deliver input == walk the tree and deliver events (after midterm)
+
+---
+# How does an interactor draw?
+
+Interactors (Views in Android):
+- Receive draw (`onDraw()` in Android)
+- Show feedback () (Draw onto `Canvas` in Android)
+- Respond to input (Future assignment!)
+
+You will create a custom interactor, a `LineView`, which has to implement `onDraw(Canvas canvas)`
+
+You can use all the [Canvas](https://developer.android.com/reference/android/graphics/Canvas) methods (we'll talk more about these in the [Drawing](Drawing.html) lecture on Friday)
+
+???
+HTML is like this too
+
+<!-- --- -->
+<!-- .left-column-half[ -->
+<!-- ## Most GUIs still use the same 7-10 interaction techniques -->
+<!-- - Basic GUI components invented 1970s -->
+<!-- - Windows, Icons, Menus, Pointers (“WIMP”) -->
+<!-- - “Perfected” by Macintosh in 1984 -->
+<!-- - Not much change since then (even with web) -->
+<!-- ] -->
+<!-- .right-column-half[ -->
+<!-- ## Aside: Significant Stagnation -->
+
+
+<!-- ![:img Picture of a very old mac control panel showing typical interactors at the time,70%](img/toolkits/interactors1.png) -->
+<!-- ] -->
+<!-- ??? -->
+<!-- - Work well, uniform -->
+<!-- - Good for usability -->
+<!-- - GUI is victim of its own success -->
+<!-- - Opportunities lost by not customizing interaction techniques to tasks -->
+<!-- - Hard for better techniques to get traction -->
+<!-- - Only very recently with mobile devices (touch based) have we seen lots of new techniques get a major foothold -->
+
+<!-- --- -->
+<!-- .left-column[ -->
+<!-- ## In class Exercise: Interface Developer, using Android Toolkit -->
+
+<!-- Quick Tour | tutorial -->
+<!-- for [building a ui](https://developer.android.com/training/basics/firstapp/building-ui)] -->
+
+<!-- .right-column[ -->
+<!-- ![:img A picture of the setup for android study in which we can layout -->
+<!-- components,60%](img/toolkits/android-components2.png) -->
+<!-- ] -->
+
+---
+.left-column[
+## Developer Roles
+<div class="mermaid">
+  graph LR
+  ip[Interface Programmer]
+  w[Component Developer]
+  l[Library Extender]
+  a[Architecture Extender]
+  t[Toolkit Builder]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+  classDef darkblue font-size:14pt,text-align:center
+
+  class ip,t yellow
+  class w,l,a green
+  class w darkblue
+</div>
+]
+.right-column[
+**Components** are small, reusable, well defined pieces of code that allow programmers to
+design and develop our UIs in a consistent way ([source](https://blog.bitsrc.io/building-a-consistent-ui-design-system-4481fb37470f)).
+- A UI component can create both functional and visual consistency in an application or set of applications.
+- Often components support new forms of input/direct manipulation.
+- Component development is supported by many toolkits
+
+**Component Developers** create these new, re-usable components.
+
+Example: In the Doodle assignment you will be developing the `LineView` interactor, a new component
+for drawing lines on the screen at certain locations.
+
+]
+---
+# Component Developer: Developing Novel Interaction Techniques
+
+.left-column-half[
+- A method for carrying out a specific interactive task
+- Example: enter a number in a range
+ - Swiping to invoke an action
+ - Gesture based text entry
+
+![img: A picture of gesture based text entry on an android phone, 20%](img/toolkits/android-type.jpg)
+]
+
+.right-column-half[
+![img: A picture of a finger left-swiping to invoke an action on a
+list on an android phone, 10%](img/toolkits/android-swipe.png)
+
+]
+---
+.left-column[
+## Developer Roles
+<div class="mermaid">
+  graph LR
+  ip[Interface Programmer]
+  w[Component Developer]
+  l[Library Extender]
+  a[Architecture Extender]
+  t[Toolkit Builder]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+  classDef darkblue font-size:14pt,text-align:center
+
+  class ip,t yellow
+  class w,a green
+  class l darkblue
+</div>
+]
+.right-column[
+**Library Extenders** are similar to component developers, but may
+create new forms of layout, types of input, etc.
+
+- Supported by a few toolkits
+- Examples:
+  - The Java JDK can be extended by developers who create a set of components in a `.jar` file
+that is included with a software project (example [JFreeChart](http://jfree.org/jfreechart/))
+  - JavaScript has been extended by
+  [many libraries](https://en.wikipedia.org/wiki/List_of_JavaScript_libraries), such as Bootstrap or jQuery.
+]
+---
+# Library Extender: Toolkit Support for Styling
+
+.left-column-half[
+![:img A picture of the same dialogue box styled 4 different ways, 100%](img/toolkits/novellibrary.png)
+]
+.right-column-half[
+subArctic allowed visually rich, dynamically resizable, images to be
+provided using primarily conventional drawing tools (and with no
+programming or programming-like activities at all).  Scott E. Hudson
+and Kenichiro Tanaka. (UIST '00)
+]
+---
+.left-column[
+## Developer Roles
+<div class="mermaid">
+  graph LR
+  ip[Interface Programmer]
+  w[Component Developer]
+  l[Library Extender]
+  a[Architecture Extender]
+  t[Toolkit Builder]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+  classDef darkblue font-size:14pt,text-align:center
+
+  class ip,t yellow
+  class w,l,a green
+  class a darkblue
+</div>
+]
+.right-column[
+**Architecture Extenders** modifies the flow of information within a toolkit to create entirely
+new effects (e.g. adding support for command objects)
+
+Supported by very few toolkits
+]
+---
+# Architecture Extender: Animation
+
+.right-column50[
+![:img A picture of a phone interface using animation to show a menu, 80%](img/toolkits/animation.gif)
+]
+
+Integrated into existing GUI toolkit
+
+Primary abstraction: transition
+- models movement over time
+- through arbitrary space of values (e.g., color)
+- screen space is most common
+
+
+.footnote[Great post about [types of animation on mobile phones](https://yalantis.com/blog/-seven-types-of-animations-for-mobile-apps/), also
+source of the image]
+
+---
+.left-column[
+## Developer Roles
+
+<div class="mermaid">
+  graph LR
+  ip[Interface Programmer]
+  w[Component Developer]
+  l[Library Extender]
+  a[Architecture Extender]
+  t[Toolkit Builder]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+  classDef darkblue font-size:14pt,text-align:center
+
+  class ip,t yellow
+  class w,l,a green
+  class t darkblue
+</div>
+]
+.right-column[
+**Toolkit builders** create entirely new toolkits that enable radical new forms of interaction
+
+e.g. RapID https://make4all.org/portfolio/rapid/
+]
+---
+# Toolkit Builder: Physical Interfaces
+Creates entirely new toolkits that changes what we can do
+
+
+![:youtube Physical Interface made out of RFID tags,4k15uXpp7-g]
+
+---
+# Toolkit for Overloading Existing Interfaces
+Prefab supports pixel based enhancements: write interpretation logic that can be composed, reused, and shared to manage the multi-faceted nature of pixel-based interpretation; robustly annotate interface elements with metadata needed to enable runtime enhancements.
+
+![:youtube Prefab Demo,lju6IIteg9Q]
+
+---
+#  Summary: Developer Roles
+.left-column[
+<div class="mermaid">
+  graph LR
+  ip[Interface Programmer]
+  w[Component Developer]
+  l[Library Extender]
+  a[Architecture Extender]
+  t[Toolkit Builder]
+
+  classDef yellow font-size:14pt,text-align:center
+
+  class ip,w,l,a,t yellow
+</div>
+]
+.right-column[
+- **Interface Programmer** - Uses high level tools and toolkit to create a user interface.
+- **Component Developer** - Creates new, re-usable interators or interaction techniques.
+- **Library Extender** - Similar to Component Developer, creates a system of components such as new forms of layout, types of input, etc.
+- **Architecture Extender** - Modifies the flow of information within a toolkit to create entirely new effects
+- **Toolkit Builder** - Creates entirely new toolkits that enable radical new forms of interaction.
+]
+---
+#  Summary: In this class we look at General Principals
+
+Particular toolkits tend to be mired in a particular platform
+
+Along comes the next big thing  (e.g., iPhone) and you’ll need to
+learn a new one
+
+We frequently will use Android as an example of these concepts
+
+If you learn the structures/concepts (and esp. rationale behind them)
+that survives change better
diff --git a/slides/wk02/graphs/example.mmd b/slides/wk02/graphs/example.mmd
new file mode 100644
index 0000000000000000000000000000000000000000..2844fd51b384d36d23313011eef5290ab0919dab
--- /dev/null
+++ b/slides/wk02/graphs/example.mmd
@@ -0,0 +1,2 @@
+graph LR
+    Start --> Stop
\ No newline at end of file
diff --git a/slides/wk02/graphs/simple.dot b/slides/wk02/graphs/simple.dot
new file mode 100644
index 0000000000000000000000000000000000000000..454fdd5d94344e177a90e2602850802f0718a5c6
--- /dev/null
+++ b/slides/wk02/graphs/simple.dot
@@ -0,0 +1,5 @@
+digraph simplestate {
+A --> B;
+B --> A;
+}
+
diff --git a/slides/wk02/img/animation/android-animate.gif b/slides/wk02/img/animation/android-animate.gif
new file mode 100755
index 0000000000000000000000000000000000000000..0fb1d08fd616979b31c4390966e7c2e3410b2c4f
Binary files /dev/null and b/slides/wk02/img/animation/android-animate.gif differ
diff --git a/slides/wk02/img/animation/animation-linear.png b/slides/wk02/img/animation/animation-linear.png
new file mode 100755
index 0000000000000000000000000000000000000000..08bd9fc3dc2ce5d151294b1d2b695a490f2e5f00
Binary files /dev/null and b/slides/wk02/img/animation/animation-linear.png differ
diff --git a/slides/wk02/img/animation/animation-nonlinear.png b/slides/wk02/img/animation/animation-nonlinear.png
new file mode 100644
index 0000000000000000000000000000000000000000..999dddaa39b03e378e97aee307f76efa27605b39
Binary files /dev/null and b/slides/wk02/img/animation/animation-nonlinear.png differ
diff --git a/slides/wk02/img/animation/valueanimator.png b/slides/wk02/img/animation/valueanimator.png
new file mode 100755
index 0000000000000000000000000000000000000000..6cc2a13bbfca142b090c3fec00ddf410ca82eeb5
Binary files /dev/null and b/slides/wk02/img/animation/valueanimator.png differ
diff --git a/slides/wk02/img/layout/1_portrait.png b/slides/wk02/img/layout/1_portrait.png
new file mode 100644
index 0000000000000000000000000000000000000000..9bd05c02c72702aa248ba15346a46bf1e9ae0036
Binary files /dev/null and b/slides/wk02/img/layout/1_portrait.png differ
diff --git a/slides/wk02/img/layout/android-linear.png b/slides/wk02/img/layout/android-linear.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b252da67203bb2e57a21a65c2b442d1e7e14a9d
Binary files /dev/null and b/slides/wk02/img/layout/android-linear.png differ
diff --git a/slides/wk02/img/layout/colormeter.png b/slides/wk02/img/layout/colormeter.png
new file mode 100644
index 0000000000000000000000000000000000000000..0ce396fb04418a818bbabfdc8d4aa75653a62936
Binary files /dev/null and b/slides/wk02/img/layout/colormeter.png differ
diff --git a/slides/wk02/img/layout/colormetercircled.png b/slides/wk02/img/layout/colormetercircled.png
new file mode 100644
index 0000000000000000000000000000000000000000..7846c8e37ff787c175f38683920c4619ee47ff64
Binary files /dev/null and b/slides/wk02/img/layout/colormetercircled.png differ
diff --git a/slides/wk02/img/layout/design-view.png b/slides/wk02/img/layout/design-view.png
new file mode 100644
index 0000000000000000000000000000000000000000..76f63830d1dbd0e0388c6ce7f57bd2b3d7618db9
Binary files /dev/null and b/slides/wk02/img/layout/design-view.png differ
diff --git a/slides/wk02/img/layout/facebook-bad.png b/slides/wk02/img/layout/facebook-bad.png
new file mode 100644
index 0000000000000000000000000000000000000000..3803fe4e0e5e0d8ffb69f4e5b6c4253922a87359
Binary files /dev/null and b/slides/wk02/img/layout/facebook-bad.png differ
diff --git a/slides/wk02/img/layout/jackbox-bad.png b/slides/wk02/img/layout/jackbox-bad.png
new file mode 100644
index 0000000000000000000000000000000000000000..d1c9feef5ea3e5ea45202ea096aa2f63b3c7b274
Binary files /dev/null and b/slides/wk02/img/layout/jackbox-bad.png differ
diff --git a/slides/wk02/img/layout/layout-demo.png b/slides/wk02/img/layout/layout-demo.png
new file mode 100644
index 0000000000000000000000000000000000000000..78b3721df71bc0e3bd03ad5271a0b56b103e513f
Binary files /dev/null and b/slides/wk02/img/layout/layout-demo.png differ
diff --git a/slides/wk02/img/layout/layout-inspector-menu.png b/slides/wk02/img/layout/layout-inspector-menu.png
new file mode 100644
index 0000000000000000000000000000000000000000..84f498c204863802f17a63845e60d19ce7226653
Binary files /dev/null and b/slides/wk02/img/layout/layout-inspector-menu.png differ
diff --git a/slides/wk02/img/layout/part3-runtime.png b/slides/wk02/img/layout/part3-runtime.png
new file mode 100644
index 0000000000000000000000000000000000000000..e4d3a100d8ed6bfe5ead63b5feb07ee0c231337c
Binary files /dev/null and b/slides/wk02/img/layout/part3-runtime.png differ
diff --git a/slides/wk02/img/layout/pinterest-android.png b/slides/wk02/img/layout/pinterest-android.png
new file mode 100644
index 0000000000000000000000000000000000000000..b07ff8eb6c83c79e5b44007a16da7d1b47c88536
Binary files /dev/null and b/slides/wk02/img/layout/pinterest-android.png differ
diff --git a/slides/wk02/img/layout/pinterest-replica.png b/slides/wk02/img/layout/pinterest-replica.png
new file mode 100644
index 0000000000000000000000000000000000000000..ca0505920df258ef1f2bfb69e98559e25bd59878
Binary files /dev/null and b/slides/wk02/img/layout/pinterest-replica.png differ
diff --git a/slides/wk02/img/layout/watch.png b/slides/wk02/img/layout/watch.png
new file mode 100644
index 0000000000000000000000000000000000000000..a82e63211658da388620dbd69e66bac095532167
Binary files /dev/null and b/slides/wk02/img/layout/watch.png differ
diff --git a/slides/wk02/img/layout/watch2.png b/slides/wk02/img/layout/watch2.png
new file mode 100644
index 0000000000000000000000000000000000000000..bdd0e20b7981219a126087817f39a68708d532a3
Binary files /dev/null and b/slides/wk02/img/layout/watch2.png differ
diff --git a/slides/wk02/img/layout/windowsLayout.png b/slides/wk02/img/layout/windowsLayout.png
new file mode 100644
index 0000000000000000000000000000000000000000..786c745ae438c2eade82a1e2df63e1ceebc34695
Binary files /dev/null and b/slides/wk02/img/layout/windowsLayout.png differ
diff --git a/slides/wk02/img/people/777777.png b/slides/wk02/img/people/777777.png
new file mode 100644
index 0000000000000000000000000000000000000000..e16d234794a0ad23ae1da057e76a3c945901d621
Binary files /dev/null and b/slides/wk02/img/people/777777.png differ
diff --git a/slides/wk02/img/people/777777w.png b/slides/wk02/img/people/777777w.png
new file mode 100644
index 0000000000000000000000000000000000000000..bbd487ec276a647eefd22dcfed2882e7b9d8e57f
Binary files /dev/null and b/slides/wk02/img/people/777777w.png differ
diff --git a/slides/wk02/img/people/adobe.jpg b/slides/wk02/img/people/adobe.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7d830e46a1851ba4bd3aaf119ee8cf219d262975
Binary files /dev/null and b/slides/wk02/img/people/adobe.jpg differ
diff --git a/slides/wk02/img/people/amazon.png b/slides/wk02/img/people/amazon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a4aab78af76c80ed70a1bc040c7226612ec2a8a0
Binary files /dev/null and b/slides/wk02/img/people/amazon.png differ
diff --git a/slides/wk02/img/people/badviz.png b/slides/wk02/img/people/badviz.png
new file mode 100644
index 0000000000000000000000000000000000000000..f7dbf5fef601adbdc7c8627c1bd32244ed5de9c2
Binary files /dev/null and b/slides/wk02/img/people/badviz.png differ
diff --git a/slides/wk02/img/people/bluelinks.png b/slides/wk02/img/people/bluelinks.png
new file mode 100644
index 0000000000000000000000000000000000000000..78cc44cbed982de6cce60284ec1330985dd18451
Binary files /dev/null and b/slides/wk02/img/people/bluelinks.png differ
diff --git a/slides/wk02/img/people/blueonblue.png b/slides/wk02/img/people/blueonblue.png
new file mode 100644
index 0000000000000000000000000000000000000000..71c8d916afaf06f0f786e1c76b80ee45bfafb9d3
Binary files /dev/null and b/slides/wk02/img/people/blueonblue.png differ
diff --git a/slides/wk02/img/people/blues.jpg b/slides/wk02/img/people/blues.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..bb231a598f446eb6ca3230c50f5639f548a894be
Binary files /dev/null and b/slides/wk02/img/people/blues.jpg differ
diff --git a/slides/wk02/img/people/chunking.png b/slides/wk02/img/people/chunking.png
new file mode 100644
index 0000000000000000000000000000000000000000..d0b8d8b362865cdf83b73dd45616f09175c40daa
Binary files /dev/null and b/slides/wk02/img/people/chunking.png differ
diff --git a/slides/wk02/img/people/color-guidelines.png b/slides/wk02/img/people/color-guidelines.png
new file mode 100644
index 0000000000000000000000000000000000000000..d81e483ef9a8dacfe3d798eee43784b68c9b5583
Binary files /dev/null and b/slides/wk02/img/people/color-guidelines.png differ
diff --git a/slides/wk02/img/people/distinct.png b/slides/wk02/img/people/distinct.png
new file mode 100644
index 0000000000000000000000000000000000000000..ddb0ea8f7b50260b768c2a600f2cd93f9cd6970e
Binary files /dev/null and b/slides/wk02/img/people/distinct.png differ
diff --git a/slides/wk02/img/people/distinct1.png b/slides/wk02/img/people/distinct1.png
new file mode 100644
index 0000000000000000000000000000000000000000..ee1470dad6801674f88397baed960c134295f9fe
Binary files /dev/null and b/slides/wk02/img/people/distinct1.png differ
diff --git a/slides/wk02/img/people/distinct2.png b/slides/wk02/img/people/distinct2.png
new file mode 100644
index 0000000000000000000000000000000000000000..07b85fab15355dde58ae94a0109923a341fd676e
Binary files /dev/null and b/slides/wk02/img/people/distinct2.png differ
diff --git a/slides/wk02/img/people/distinct3.png b/slides/wk02/img/people/distinct3.png
new file mode 100644
index 0000000000000000000000000000000000000000..a105e0f1b55b9cfa87af8ccbf38a4b6a97d431cb
Binary files /dev/null and b/slides/wk02/img/people/distinct3.png differ
diff --git a/slides/wk02/img/people/distinct4.png b/slides/wk02/img/people/distinct4.png
new file mode 100644
index 0000000000000000000000000000000000000000..7eabd003d7af201fbe89300a7645d2755c4da1fa
Binary files /dev/null and b/slides/wk02/img/people/distinct4.png differ
diff --git a/slides/wk02/img/people/distinct5.png b/slides/wk02/img/people/distinct5.png
new file mode 100644
index 0000000000000000000000000000000000000000..e7825b09a4caac026e9b71ebd53e117ab7d51832
Binary files /dev/null and b/slides/wk02/img/people/distinct5.png differ
diff --git a/slides/wk02/img/people/distinct6.png b/slides/wk02/img/people/distinct6.png
new file mode 100644
index 0000000000000000000000000000000000000000..97b10f1439bd4d53b501975896aca04228a3893d
Binary files /dev/null and b/slides/wk02/img/people/distinct6.png differ
diff --git a/slides/wk02/img/people/distinct7.png b/slides/wk02/img/people/distinct7.png
new file mode 100644
index 0000000000000000000000000000000000000000..df1123a90d8d15a3855066417edcff5538318bec
Binary files /dev/null and b/slides/wk02/img/people/distinct7.png differ
diff --git a/slides/wk02/img/people/drawAll.gif b/slides/wk02/img/people/drawAll.gif
new file mode 100644
index 0000000000000000000000000000000000000000..5cb98a396766419682d1138f677c93a1e91f4148
Binary files /dev/null and b/slides/wk02/img/people/drawAll.gif differ
diff --git a/slides/wk02/img/people/elevator1.png b/slides/wk02/img/people/elevator1.png
new file mode 100644
index 0000000000000000000000000000000000000000..3dd5bd9705a0196e746c40f34c1ffecdfb71f280
Binary files /dev/null and b/slides/wk02/img/people/elevator1.png differ
diff --git a/slides/wk02/img/people/elevator2.png b/slides/wk02/img/people/elevator2.png
new file mode 100644
index 0000000000000000000000000000000000000000..2f502f44672d483f1b6b7bcdd4ac35bca8f1d37d
Binary files /dev/null and b/slides/wk02/img/people/elevator2.png differ
diff --git a/slides/wk02/img/people/eye.png b/slides/wk02/img/people/eye.png
new file mode 100644
index 0000000000000000000000000000000000000000..18c3959f493de660378f9c7d3d1733b35f2a9f60
Binary files /dev/null and b/slides/wk02/img/people/eye.png differ
diff --git a/slides/wk02/img/people/facebook.png b/slides/wk02/img/people/facebook.png
new file mode 100644
index 0000000000000000000000000000000000000000..92d3ad836dedbe70081798da7ce6287a9097cbc6
Binary files /dev/null and b/slides/wk02/img/people/facebook.png differ
diff --git a/slides/wk02/img/people/goodviz.png b/slides/wk02/img/people/goodviz.png
new file mode 100644
index 0000000000000000000000000000000000000000..7cf03c3b75e24e2bc53086b70dc2569aecc275f0
Binary files /dev/null and b/slides/wk02/img/people/goodviz.png differ
diff --git a/slides/wk02/img/people/hsv.png b/slides/wk02/img/people/hsv.png
new file mode 100644
index 0000000000000000000000000000000000000000..c6bede4dbe1e130f60964dd9d6bc8225a3a8556c
Binary files /dev/null and b/slides/wk02/img/people/hsv.png differ
diff --git a/slides/wk02/img/people/humanspectrum.png b/slides/wk02/img/people/humanspectrum.png
new file mode 100644
index 0000000000000000000000000000000000000000..47a8beee58beea7349195fd6a76f0c0487d19108
Binary files /dev/null and b/slides/wk02/img/people/humanspectrum.png differ
diff --git a/slides/wk02/img/people/monalisa.png b/slides/wk02/img/people/monalisa.png
new file mode 100644
index 0000000000000000000000000000000000000000..6594f080f477f7a0accc3e02f5ea77475f082886
Binary files /dev/null and b/slides/wk02/img/people/monalisa.png differ
diff --git a/slides/wk02/img/people/pixelmonalisa.png b/slides/wk02/img/people/pixelmonalisa.png
new file mode 100644
index 0000000000000000000000000000000000000000..f37b3ec30eca0745b8fdd16f1699e371fa11faec
Binary files /dev/null and b/slides/wk02/img/people/pixelmonalisa.png differ
diff --git a/slides/wk02/img/people/q1.png b/slides/wk02/img/people/q1.png
new file mode 100644
index 0000000000000000000000000000000000000000..9090ed23584f5965f01fe97ef1c3c376b3f8f0ac
Binary files /dev/null and b/slides/wk02/img/people/q1.png differ
diff --git a/slides/wk02/img/people/q3.png b/slides/wk02/img/people/q3.png
new file mode 100644
index 0000000000000000000000000000000000000000..2f6b23badf43181ad42231740acd1368a8823aad
Binary files /dev/null and b/slides/wk02/img/people/q3.png differ
diff --git a/slides/wk02/img/people/recognition.png b/slides/wk02/img/people/recognition.png
new file mode 100644
index 0000000000000000000000000000000000000000..75e626b0d15f215a6182a3dbb972de0e18513f87
Binary files /dev/null and b/slides/wk02/img/people/recognition.png differ
diff --git a/slides/wk02/img/people/redcomp.png b/slides/wk02/img/people/redcomp.png
new file mode 100644
index 0000000000000000000000000000000000000000..81dec38e9e9408f89fddf1c850100ef978395f2a
Binary files /dev/null and b/slides/wk02/img/people/redcomp.png differ
diff --git a/slides/wk02/img/people/rgb.png b/slides/wk02/img/people/rgb.png
new file mode 100644
index 0000000000000000000000000000000000000000..4d5dc962d7325f3b83f25233d6f7667a1cdbbd9c
Binary files /dev/null and b/slides/wk02/img/people/rgb.png differ
diff --git a/slides/wk02/img/people/rods_cones.png b/slides/wk02/img/people/rods_cones.png
new file mode 100644
index 0000000000000000000000000000000000000000..6c4c88eaf3d67d1545818b497d737d5ce0a87626
Binary files /dev/null and b/slides/wk02/img/people/rods_cones.png differ
diff --git a/slides/wk02/img/people/saturated.png b/slides/wk02/img/people/saturated.png
new file mode 100644
index 0000000000000000000000000000000000000000..afb6f508ce29ca418e9c27880ed232876799c702
Binary files /dev/null and b/slides/wk02/img/people/saturated.png differ
diff --git a/slides/wk02/img/people/signs.png b/slides/wk02/img/people/signs.png
new file mode 100644
index 0000000000000000000000000000000000000000..43c41773ac4b4b9a5676bd5d3175ce32b303d6b0
Binary files /dev/null and b/slides/wk02/img/people/signs.png differ
diff --git a/slides/wk02/img/people/stars.png b/slides/wk02/img/people/stars.png
new file mode 100644
index 0000000000000000000000000000000000000000..4b15a6175319606a10be47158b87682af91ae949
Binary files /dev/null and b/slides/wk02/img/people/stars.png differ
diff --git a/slides/wk02/img/people/tiger.png b/slides/wk02/img/people/tiger.png
new file mode 100644
index 0000000000000000000000000000000000000000..0d881bc771abf977c2e1982eba348b1771a47bc6
Binary files /dev/null and b/slides/wk02/img/people/tiger.png differ
diff --git a/slides/wk02/img/people/tufte.png b/slides/wk02/img/people/tufte.png
new file mode 100644
index 0000000000000000000000000000000000000000..dc6f6a97a2a71c926e3a2a2dfcd4be3281fc2a81
Binary files /dev/null and b/slides/wk02/img/people/tufte.png differ
diff --git a/slides/wk02/img/people/value-sat.png b/slides/wk02/img/people/value-sat.png
new file mode 100644
index 0000000000000000000000000000000000000000..b5ffb6814dde40eb19feca12d1c5d404219c0831
Binary files /dev/null and b/slides/wk02/img/people/value-sat.png differ
diff --git a/slides/wk02/img/people/visualgrouping.png b/slides/wk02/img/people/visualgrouping.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce969612793e2c9977149f83e24a61692ff1e36b
Binary files /dev/null and b/slides/wk02/img/people/visualgrouping.png differ
diff --git a/slides/wk02/img/people/web1.png b/slides/wk02/img/people/web1.png
new file mode 100644
index 0000000000000000000000000000000000000000..61ca27232965dbb3424d46dba693138c05fa85a7
Binary files /dev/null and b/slides/wk02/img/people/web1.png differ
diff --git a/slides/wk02/img/people/web2.png b/slides/wk02/img/people/web2.png
new file mode 100644
index 0000000000000000000000000000000000000000..f0f96e2b9bda73c4f40f7a970100f0d9095dd817
Binary files /dev/null and b/slides/wk02/img/people/web2.png differ
diff --git a/slides/wk02/img/people/web3.png b/slides/wk02/img/people/web3.png
new file mode 100644
index 0000000000000000000000000000000000000000..88a1df7b1ee3b4095219efce172c12f7feebbf9b
Binary files /dev/null and b/slides/wk02/img/people/web3.png differ
diff --git a/slides/wk02/img/people/windowsLayout.png b/slides/wk02/img/people/windowsLayout.png
new file mode 100644
index 0000000000000000000000000000000000000000..786c745ae438c2eade82a1e2df63e1ceebc34695
Binary files /dev/null and b/slides/wk02/img/people/windowsLayout.png differ
diff --git a/slides/wk02/img/people/windowsLayoutGreyscale.png b/slides/wk02/img/people/windowsLayoutGreyscale.png
new file mode 100644
index 0000000000000000000000000000000000000000..5b253f3fe0b9b3243b844f0674614aa93ccc350a
Binary files /dev/null and b/slides/wk02/img/people/windowsLayoutGreyscale.png differ
diff --git a/slides/wk02/img/people/yellow.png b/slides/wk02/img/people/yellow.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa27be165b215ba5c1737359b12610ef7f37f29e
Binary files /dev/null and b/slides/wk02/img/people/yellow.png differ
diff --git a/slides/wk02/img/toolkit-drawing/accelerate.gif b/slides/wk02/img/toolkit-drawing/accelerate.gif
new file mode 100644
index 0000000000000000000000000000000000000000..519648efffb6d5c51fe0b4f1a392de59116a4ce7
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/accelerate.gif differ
diff --git a/slides/wk02/img/toolkit-drawing/animation-linear.png b/slides/wk02/img/toolkit-drawing/animation-linear.png
new file mode 100644
index 0000000000000000000000000000000000000000..08bd9fc3dc2ce5d151294b1d2b695a490f2e5f00
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/animation-linear.png differ
diff --git a/slides/wk02/img/toolkit-drawing/bounce.gif b/slides/wk02/img/toolkit-drawing/bounce.gif
new file mode 100644
index 0000000000000000000000000000000000000000..c313049ed5d7841a755f38f3d48aafd6b3715021
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/bounce.gif differ
diff --git a/slides/wk02/img/toolkit-drawing/bounding-animation.png b/slides/wk02/img/toolkit-drawing/bounding-animation.png
new file mode 100644
index 0000000000000000000000000000000000000000..411566257aaa2a6e8fa0df2697b0e44726f7bc9b
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/bounding-animation.png differ
diff --git a/slides/wk02/img/toolkit-drawing/boundless.gif b/slides/wk02/img/toolkit-drawing/boundless.gif
new file mode 100644
index 0000000000000000000000000000000000000000..b0613367fe237b6755557dd886a4f374380ec574
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/boundless.gif differ
diff --git a/slides/wk02/img/toolkit-drawing/doodle-layout.png b/slides/wk02/img/toolkit-drawing/doodle-layout.png
new file mode 100644
index 0000000000000000000000000000000000000000..80b9fd17ebb77684d1000953988f9d9258137bb5
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/doodle-layout.png differ
diff --git a/slides/wk02/img/toolkit-drawing/doodle-layout2.png b/slides/wk02/img/toolkit-drawing/doodle-layout2.png
new file mode 100644
index 0000000000000000000000000000000000000000..a3d68d2f3fc0e04fe7bd44fabbcf25079fce798c
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/doodle-layout2.png differ
diff --git a/slides/wk02/img/toolkit-drawing/doodle-screenshot.png b/slides/wk02/img/toolkit-drawing/doodle-screenshot.png
new file mode 100644
index 0000000000000000000000000000000000000000..e2ead8c9139d191ba5182a6a95e12bd1ae0cd51e
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/doodle-screenshot.png differ
diff --git a/slides/wk02/img/toolkit-drawing/interactor-hierarchy.png b/slides/wk02/img/toolkit-drawing/interactor-hierarchy.png
new file mode 100644
index 0000000000000000000000000000000000000000..bb41dc3d5b987687e7df6970f7df476cea7c6bbd
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/interactor-hierarchy.png differ
diff --git a/slides/wk02/img/toolkit-drawing/interpolators.gif b/slides/wk02/img/toolkit-drawing/interpolators.gif
new file mode 100644
index 0000000000000000000000000000000000000000..ad4e46ef00ad0843547fa69de0754dbaf9a7c59b
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/interpolators.gif differ
diff --git a/slides/wk02/img/toolkit-drawing/linear.gif b/slides/wk02/img/toolkit-drawing/linear.gif
new file mode 100644
index 0000000000000000000000000000000000000000..862a9241ff308d3e216ebf75f82e733db6637fe6
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/linear.gif differ
diff --git a/slides/wk02/img/toolkit-drawing/linearrotate.gif b/slides/wk02/img/toolkit-drawing/linearrotate.gif
new file mode 100644
index 0000000000000000000000000000000000000000..8fc4be4fac5d10a2d5c6fc593e13284ce0339fb3
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/linearrotate.gif differ
diff --git a/slides/wk02/img/toolkit-drawing/overshoot.gif b/slides/wk02/img/toolkit-drawing/overshoot.gif
new file mode 100644
index 0000000000000000000000000000000000000000..13bda4720e4de0f0584a7eee39c1a7cb65e22c3d
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/overshoot.gif differ
diff --git a/slides/wk02/img/toolkit-drawing/pathanimation.gif b/slides/wk02/img/toolkit-drawing/pathanimation.gif
new file mode 100644
index 0000000000000000000000000000000000000000..daf37d692c757cca41c53c041f6117921adb074a
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/pathanimation.gif differ
diff --git a/slides/wk02/img/toolkit-drawing/rotatedrects-center.png b/slides/wk02/img/toolkit-drawing/rotatedrects-center.png
new file mode 100644
index 0000000000000000000000000000000000000000..c84316897dace66263a21265cf31a6d4febaa1d4
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/rotatedrects-center.png differ
diff --git a/slides/wk02/img/toolkit-drawing/rotatedrects-original-origin.png b/slides/wk02/img/toolkit-drawing/rotatedrects-original-origin.png
new file mode 100644
index 0000000000000000000000000000000000000000..f8534eb40c19fb39bd2e9b8a4fa1763d8fd56e34
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/rotatedrects-original-origin.png differ
diff --git a/slides/wk02/img/toolkit-drawing/scale.png b/slides/wk02/img/toolkit-drawing/scale.png
new file mode 100644
index 0000000000000000000000000000000000000000..8dbb996d67c33c9469850bac11933aeb5fdb061f
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/scale.png differ
diff --git a/slides/wk02/img/toolkit-drawing/screenshot_no_animation.jpeg b/slides/wk02/img/toolkit-drawing/screenshot_no_animation.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..f06bf323fa86e6e9285eebbaae7ce2a4805b890e
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/screenshot_no_animation.jpeg differ
diff --git a/slides/wk02/img/toolkit-drawing/shear.png b/slides/wk02/img/toolkit-drawing/shear.png
new file mode 100644
index 0000000000000000000000000000000000000000..75ba28462f9ec3df6717dbb306e91391e53cc3f2
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/shear.png differ
diff --git a/slides/wk02/img/toolkit-drawing/translate.png b/slides/wk02/img/toolkit-drawing/translate.png
new file mode 100644
index 0000000000000000000000000000000000000000..37fa3326c7b96cefe9e0d17c89c4fb45bf122030
Binary files /dev/null and b/slides/wk02/img/toolkit-drawing/translate.png differ
diff --git a/slides/wk02/interface-drawing.html b/slides/wk02/interface-drawing.html
new file mode 100644
index 0000000000000000000000000000000000000000..dbf8ef56f2efa3ecb8df8fc7bac5a1c15b02b29c
--- /dev/null
+++ b/slides/wk02/interface-drawing.html
@@ -0,0 +1,871 @@
+---
+layout: presentation
+title: Drawing Interfaces
+description: Discussion of how toolkits draw interfaces
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Introduction to Drawing Interfaces
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout: false
+
+
+[//]: # (Outline Slide)
+# Today's goals
+
+- Reviewing Transformations
+- Breakout room test 2
+- Reviewing Rotation
+- Role of Interactor Hierarchy in drawing the screen
+- How to use Animation to move Interactors
+- Summary of what we've learned so far
+
+---
+
+# Administrivia
+
+Important [Ed Post about two changes to the spec](https://us.edstem.org/courses/381/discussion/24921)
+1. You do not need to handle lines that have a "positive slope"
+2. We are asking that you turn in a video of your running custom doodle at the same time as your code.  (demo)
+
+---
+# Linear ("affine") Transformations
+
+Translate, Scale, Rotate, Shear (and any combination thereof)
+
+--
+
+- Translate: Move origin (and everything else) in x and y
+![:img a large moon and a large moon moved to the right a few pixels, 15%](img/toolkit-drawing/translate.png)
+
+???
+used extensively in GUIS because child objects just draw themselves
+at *their* origin, so a component doesn't have to calculate how to draw
+itself based on its position
+
+--
+
+- Scale: change size (negative == flip)
+![:img a large and small moon, 15%](img/toolkit-drawing/scale.png)
+
+--
+
+- Rotate and Shear
+![:img a rotated and angled moon, 25%](img/toolkit-drawing/shear.png)
+
+---
+# Coordinate Transformations
+
+- Can modify any shape, including text.
+- In practice, complex transformations are done with matrices, and matrices are using `concat(Matrix)`
+- But Android helps with this by providing methods in the
+[Canvas](https://developer.android.com/reference/android/graphics/Canvas) object to transform a canvas such as
+
+```java
+translate(float dx, float dy)
+rotate(float degrees)                           // the whole canvas around the canvas origin
+rotate (float degrees, float px, float py)      // around a particular point
+scale(float, float)
+scale (float sx, float sy, float px, float py)  // around a pivot point
+skew(float sx, float sy)                        // skew by sx and sy
+save()                                          // save the current transform
+restore()                                       // restore the previous transform
+```
+
+???
+- important thing to point out here: This is a value proposition for a toolkit again
+
+– Affine transformations are based on two-dimensional matrices of the
+following form:
+
+P' = T*P where P is 1x3 and T is the transform matrix (3x3) with the
+bottom row 0 0 1
+
+Thus, x' = ax + cy + t_x and y' = bx + dy + t_y
+
+*Note* Any sequence of transform, rotate and shear can be represented
+in a single matrix of this form (just multiple the matrices together)
+
+---
+# Breakout question: How can you rotate around the center of an object:
+
+<iframe src="https://embed.polleverywhere.com/multiple_choice_polls/DfxDLPdpd2zTpLlUJt9h9?controls=none&short_poll=true" width="800" height="500" frameBorder="0"></iframe>
+
+
+???
+
+[raise your hands]
+
+- A: Translate, rotate, translate
+- B: Rotate, Translate, Rotate
+- C: Scale, Rotate, Scale
+- D: Rotate
+
+
+XX define exercise
+maybe put this after android stuff?
+
+I usually draw this out on a piece of paper using the document camera to help
+
+---
+# Breakout rooms test 2
+
+- You've been randomly assigned you to breakout rooms with one TA each.
+- In the future, we will experiment with a system where you can choose your breakout partners
+- Goal: Meet other students, test out the technology
+  - Please turn your cameras on in the breakouts
+  - Introduce yourself, and tell your group what color your favorite shirt is.
+  - Discuss the poll everywhere question and vote
+
+We'll do this for 5 minutes, then I will close the breakouts
+
+---
+
+# Explanation
+
+.left-column[
+![:img Three rectangle with a second rectangle displayed rotating around the origin of the rectangle, 80%](img/toolkit-drawing/rotatedrects-original-origin.png)
+]
+
+.right-column[
+New view created called `RotatedRectangleView` that has `mEndPoint` and `mBrush` defined in a
+similar way to your `LineView`. It also is given the number of degrees (stored in the variable mDegrees)
+by which to rotate the rectangle.
+
+```java
+public void onDraw(Canvas canvas) {
+
+  canvas.drawRect(0, 0, mEndPoint.x , mEndPoint.y, mBrush);
+
+  int saveColor = mBrush.getColor();
+  mBrush.setColor(Color.GREEN);
+  canvas.rotate(mDegrees);
+  canvas.drawRect(0, 0, mEndPoint.x, mEndPoint.y, mBrush);
+}
+```
+]
+
+---
+# Moving the canvas
+
+.left-column[
+![:img Three rectangle with a second rectangle displayed rotating around the origin of the rectangle, 80%](img/toolkit-drawing/rotatedrects-center.png)
+]
+
+.right-column[
+Move origin of the `canvas` to the center of the object, THEN rotate it, then
+move the origin back to it's original location (in this new rotated orientation)
+
+```java
+public void onDraw(Canvas canvas) {
+
+  canvas.drawRect(0, 0, mEndPoint.x , mEndPoint.y, mBrush);
+
+  float px = mEndPoint.x / 2;
+  float py = mEndPoint.y / 2;
+  int saveColor = mBrush.getColor();
+  mBrush.setColor(Color.GREEN);
+  canvas.translate(px, py);
+  canvas.rotate(mDegrees);
+  canvas.translate(-px, -py);
+  canvas.drawRect(0, 0, mEndPoint.x, mEndPoint.y, mBrush);
+}
+```
+]
+
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Toolkits
+---
+layout: false
+
+## Review: Developer roles
+
+.left-column[
+
+<div class="mermaid">
+  graph LR
+  ip[Interface Programmer]
+  w[Component Developer]
+  l[Library Extender]
+  a[Architecture Extender]
+  t[Toolkit Builder]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+
+  class t,l,a,w yellow
+  class ip green
+</div>
+]
+
+.right-column[
+Recall the role Interface Programmer a developer can play in app development.
+]
+
+---
+
+# Draw the interactor hierarchy
+
+Think about why we use a `View` for **each** thing on the screen...
+
+ ![:img Picture of images arranged in a heart shape with a vertical line above them; the words UW below them and a horizontal line below that, 15%](img/toolkit-drawing/screenshot_no_animation.jpeg) &nbsp; &nbsp;  ![:img Interactor hierarcy of the image to the left , 20%](img/toolkit-drawing/interactor-hierarchy.png)
+
+
+---
+
+# Simpler Example as an Interface Programmer
+
+.left-column[
+![:img Picture of a very simple doodle with the word 'placeholder' at the top and a line that goes from top left to about halfway down the screen, 100%](img/toolkit-drawing/doodle-screenshot.png)
+]
+.right-column[
+
+```java
+ LineView line = new LineView(this, startX, startY, endX, endY, width, color);
+ canvas.addView(line);
+ TextView text = new TextView(this);
+ text.setX(x);
+ text.setY(y);
+ text.setText("placeholder");
+ canvas.addView(text);
+```
+]
+
+---
+
+## Review: Developer roles
+
+.left-column[
+
+<div class="mermaid">
+  graph LR
+  ip[Interface Programmer]
+  w[Component Developer]
+  l[Library Extender]
+  a[Architecture Extender]
+  t[Toolkit Builder]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+
+  class t green
+  class ip,l,a,w yellow
+
+</div>
+]
+
+.right-column[
+Today we're going to discuss the role Toolkit builder plays in app development
+]
+
+
+---
+# What is the toolkit architecture?
+
+???
+Applies to the flow of information within the toolkit
+
+Example: How the interface is drawn
+
+What could you add? Support for animation, machine learning, etc
+
+Supported by very few toolkits
+
+---
+# What is the toolkit architecture?
+
+Applies to the flow of information within the toolkit
+
+Examples:
+- How the interface is drawn
+- How the interface is layed out
+- How the interface responds to the user
+
+What could you add? Support for animation, machine learning, etc
+
+Adding new features at the toolkit level is supported by very few toolkits
+
+---
+
+# How is a View drawn on the screen?
+
+**Toolkit Architecture Builder**
+
+- Depth-first tree traversal of the interactor hierarchy
+- Each View draws itself in its location
+- Siblings drawn in order they appear
+
+Naive Pseudocode:
+
+```java
+protected void drawAll() {
+    onDraw();                     // Draw yourself. (lower in the Z-order)
+    foreach child c {             // for all of the children in this node
+        if (child.isVisible()) {  // if the child is visible
+          child.drawAll();        // tell the child to draw itself
+        }
+    }
+}
+```
+
+???
+What is missing here?
+How can children misbehave?
+What are they expecting that we don't do?
+Draw out what will happen on paper
+
+---
+# How is a View drawn on the screen?
+
+Naive Pseudocode:
+
+```java
+protected void drawAll() {
+   onDraw();
+   foreach child c {
+     if (child.isVisible()) {
+       child.drawAll();
+     }
+   }
+}
+```
+
+- How could children misbehave?
+- Work arounds could we do?
+
+???
+Imagine if all the children were the same dimensions.
+
+---
+# Work arounds?
+
+Make the **Interface Programmer** fix this
+
+Could make every view the size of the whole screen; Then just draw items in those views
+in the correct position
+
+Could tell every view where it is so it draws properly
+
+
+---
+# For this, view needs a position, width and height
+
+.left-column-half[
+![:img Picture of the interactor hierarchy for the same app, 70%](img/toolkit-drawing/doodle-layout.png)
+]
+
+.right-column-half[
+What could go wrong with this approach?
+
+]
+???
+- What if we want to place a different view, automatically, to the right of the text?
+- How do we guarrantee that a view doesn't draw over it's neighbor?
+
+---
+# For this, view needs a position, width and height
+
+.left-column-half[
+![:img Picture of the interactor hierarchy for the same app, 70%](img/toolkit-drawing/doodle-layout.png)
+]
+
+.right-column-half[
+What could go wrong with this approach?
+- What if we want to place a different view, automatically, to the right of the text?
+- How do we guarrantee that a view doesn't draw over it's neighbor?
+
+]
+---
+# Specifying View position, width and height?
+
+.left-column-half[
+<br>
+![:img Picture of the interactor hierarchy for the same app, 70%](img/toolkit-drawing/doodle-layout2.png)
+]
+
+.right-column-half[
+**Interface Programmer** does this
+
+```java
+View view = new View();
+view.setX();
+view.setY();
+ViewGroup.LayoutParams params = view.getLayoutParams();
+param.width = width;
+param.height = height;
+view.setLayoutParams(param);
+```
+]
+???
+We'll go into much more depth on this in your next assignment
+
+---
+# How does a toolkit use this?
+**Toolkit Architecture Builder**
+
+**Uses coordinate transformations to make each child the center of its universe!**
+ - Parent (usually) specifies position of child when adding to the interactor hierarchy
+ - Child counts on parent to set things up so child's internal coordinate system starts at (0,0)
+
+--
+We just saw this with rotating the canvas!
+
+---
+# How is a View drawn on the screen
+**Toolkit Architecture Builder**
+
+```java
+protected void drawAll() {
+    onDraw();
+    foreach child c {
+        if (child.isVisible()) {
+
+
+
+
+			 child.drawAll();
+
+		}
+  }
+}
+```
+Is this part of the _Toolkit Architecture_ or _Toolkit Library_?
+
+---
+# How is a View drawn on the screen
+**Toolkit Architecture Builder**
+
+```java
+protected void drawAll() {
+    onDraw();
+    foreach child c {
+        if (child.isVisible()) {
+*            Rectangle r = child.getLayoutParams(); // Find child coordinates
+*            canvas.save();                         // Capture the current state of canvas
+*            canvas.translate(r.x, r.y);            // Move origin to child's top-left corner
+*            canvas.clip(0,0,r.width,r.height);     // Clip to child
+             child.drawAll();                       // Draw child (and all it's kids)
+*            canvas.restore();                      // Restore
+		}
+  }
+}
+```
+Is this part of the _Toolkit Architecture_ or _Toolkit Library_?
+???
+Draw out on paper again
+Note that this is  has absolute layout!
+
+---
+
+# Why is a bounding box important here?
+
+![:img mouse moving along a path with linear interpolation, 25%](img/toolkit-drawing/linear.gif)
+&nbsp;
+![:img Bounding box around the objects being animated used to control their position, 40%](img/toolkit-drawing/bounding-animation.png)
+
+
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Animation
+---
+layout: false
+
+.left-column[
+![:img Android Animation Example with bouncing and spinning circles that eventually transition to spell out android, 100%](img/animation/android-animate.gif)
+]
+
+.right-column[
+# Animation becoming core pillar of UX design
+
+Greater awareness of role for communicating UI behavior
+Guide, provide context, delight, engage
+
+.quote[‘Animation is increasingly becoming an important part of the UI
+design experience. Google’s material design guidelines are a good
+illustration of this. Expect to see even more tools and optimizations
+made to improve the production workflow and performance in browsers
+and on devices.’ ([Weareathlon](https://www.weareathlon.com/ideas/ten-ux-design-trends-for-2015))]
+]
+
+
+---
+# Old implementation approach
+
+Frame-based
+- Redraw scene at regular intervals
+- Developer defines redraw function
+
+What toolkit principals does this violate?
+
+???
+it's bad because it doesn't provide any useful abstractions
+
+Fails to provide separation of concerns
+--
+- Doesn't provide supportive abstractions
+
+--
+- Fails to provide separation of concerns
+
+---
+# Main implementation approach
+Transition-based (Hudson & Stasko '93)
+- Specify property values of animation transition speed and process
+ - Uses 'pacing' functions to stylize animation, e.g. slow-in
+slow-out (see [easings.net](http://easings.net))
+
+- Typically computed via __interpolation__
+```java
+step(fraction){x_now = x_start + fraction*(x_end - x_start);}
+```
+- Timing and redraw managed by toolkit
+
+
+---
+# Toolkit Architecture for Animation
+
+.left-column[
+<br>
+<br>
+<br>
+<br>
+<br>
+![Value Animator Process](img/animation/valueanimator.png)
+]
+.right-column[
+
+Steamlined process for animation of each frame
+- An update function is called
+- `invalidate()` is called
+- View is redrawn
+]
+
+---
+# How an animation is set up
+
+Define an animation that changes on object's property (a field on a object) over a length of time.
+
+![:img boxes showing position and time changing over a 40 ms duration, 80%](img/toolkit-drawing/animation-linear.png)
+
+.footnote[[image source: Android animation documentation](https://developer.android.com/guide/topics/graphics/prop-animation)]
+
+---
+# How an animation is set up
+
+Need the start and end value of the properties to be
+modified. Typically use a
+[Path](https://developer.android.com/reference/android/graphics/Path)
+for this.
+
+Need a *duration* (total time in ms for the animation)
+
+Need the *pacing function* for animation using an [Interpolator](https://developer.android.com/reference/android/view/animation/Interpolator)
+- Default is [AccelerateDecelerateInterpolator](https://developer.android.com/reference/android/view/animation/AccelerateDecelerateInterpolator)
+- Other subclasses include AccelerateInterpolator, AnticipateInterpolator, AnticipateOvershootInterpolator,
+BounceInterpolator, CycleInterpolator, DecelerateInterpolator, LinearInterpolator,
+OvershootInterpolator, PathInterpolator
+- Or make your own!
+
+---
+
+# [ObjectAnimator](https://developer.android.com/reference/android/animation/ObjectAnimator)
+
+Directly animate a properties on an object
+
+**However**: the property that you are animating must have a setter
+function (in camel case) in the form of `set<propertyName>()` for this
+to work
+
+Can use a string (like `"alpha"`) or a property (like `View.X` in [View](https://developer.android.com/reference/android/view/View))
+
+---
+# [ObjectAnimator](https://developer.android.com/reference/android/animation/ObjectAnimator)
+
+.left-column[
+<br>
+<br>
+![:img Boundless animation, 90%](img/toolkit-drawing/boundless.gif)
+]
+
+.right-column[
+Example for color
+```java
+// takes a target view, a property name, and values
+ObjectAnimator anim = ObjectAnimator.ofFloat(boundlessView, "alpha", 0f, 1f);
+anim.setDuration(1000);
+anim.start();
+```
+]
+---
+# [ObjectAnimator](https://developer.android.com/reference/android/animation/ObjectAnimator)
+
+.left-column[
+![:img Path animation, 90%](img/toolkit-drawing/linear.gif)
+]
+
+.right-column[
+Example for position (using a
+[Path](https://developer.android.com/reference/android/graphics/Path))
+```java
+ImageView mouse = addImage(doodleView, "mouse", 500f, 50f, size);
+Path path = new Path();
+path.moveTo(400f, 50f);
+path.arcTo(200f, 50f, 600f, 450, 270, -180, true);
+path.arcTo(200f, 450f, 600f, 850, 270f, 180f, true);
+
+ObjectAnimator anim = ObjectAnimator.ofFloat(mouse, View.X, View.Y, path);
+anim.setDuration(5000);
+anim.start();
+
+
+```
+]
+
+---
+# [ObjectAnimator](https://developer.android.com/reference/android/animation/ObjectAnimator)
+
+.left-column[
+![:img Path animation, 90%](img/toolkit-drawing/linearrotate.gif)
+]
+
+.right-column[
+- The static functions (like ofFloat) in ObjectAnimator are "factories" - the method creates the
+ObjectAnimator object for you!
+- You can have multiple ObjectAnimators working on a single view at the same time!
+
+```java
+ImageView mouse = addImage(doodleView, "mouse", 500f, 50f, size);
+Path path = new Path();
+// code to set up the path....
+ObjectAnimator anim = ObjectAnimator.ofFloat(mouse, View.X, View.Y, path);
+anim.setDuration(5000);
+anim.start();
+
+ObjectAnimator anim = ObjectAnimator.ofFloat(mouse,"rotation", 720);
+anim.setDuration(5000);
+anim.start();
+```
+
+]
+---
+
+# Other useful properties for animation
+
+- `translationX` /`translationY` - view location as a delta from its top/left coordinates relative to the parent
+- `rotation` / `rotationX`/`rotationY` - control 2D rotation and 3D rotation around a pivot point
+- `scaleX` / `scaleY` - 2D scaliong of a `View` around a pivot point
+- `pivotX` / `pivotY` - changes location of thej pivot point (default is object's center)
+- `x` / `y` - utility property to describe the final location of a `View` in its container as a sum of (left, top) + `translationX`, `translationY`)
+- `alpha`
+
+.footnote[All found in the [View](https://developer.android.com/reference/android/view/View) class]
+---
+
+# For more more flexibility...
+You can specify `Keyframe` objects to control the animation
+
+```java
+  // Key for start at 0
+  Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
+  // Key for half way finished animation
+  Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
+  // Key for end state
+  Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
+  // ValueName-to-keyframes
+  PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation",
+                                                                      kf0, kf1, kf2);
+  // Create the animation
+  ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target,
+                                                                      pvhRotation)
+  rotationAnim.setDuration(5000ms);
+```
+---
+
+# Taking Animation to the next level
+
+.quote[ Despite the differences between user interfaces and cartoons
+-- cartoons are frivolous, passive entertainment and user interfaces
+are serious, interactive tools -- cartoon animation has much to lend
+user interfaces to realize both affective and cognitive benefits]
+.small[Principals of animation borrowed from Johnston & Thomas ‘81,
+Lasseter ‘87]
+
+---
+# Chang & Ungar, UIST '93
+
+What strategies do you see here?
+
+![:youtube Opening cartoon from who framed roger rabbit showing him trying to keep a baby safe,oQe0OWZvwWo]
+
+???
+- Squash-and-Stretch
+- Staging, Overlapping Action
+- Anticipation
+- Follow-Through
+- Slow In Slow Out
+
+
+---
+## Example pacing functions -- derived from Disney style animation!
+.left-column[
+![:img Picture of for types of interpolation functions provided with
+android, 100%](img/toolkit-drawing/interpolators.gif)
+]
+.right-column[
+Slow in slow out (Accelerate/decelerate)
+<br>
+<br>
+
+Slow in (Accelerate)
+<br>
+<br>
+
+Anticipate (back up slightly, then accelerate)
+<br>
+<br>
+
+Anticipate Overshoot (same, then go too far and slow down)
+]
+
+---
+# Why is pacing so important?
+
+Need to mimic real world
+- Observing motion tells us about size, weight, rigidity
+- No abrupt changes in velocity!
+
+Gives a feeling of reality and liveness
+- “animation” = “bring to life”
+- make inanimate object animate
+
+With this can come appeal and desirability
+
+---
+# Example pacing functions
+
+Watch this and note the pacing you see!
+
+![:youtube Video showing a mother and child lamp playing with a ball
+illustrating a range of techniques,6G3O60o5U7w]
+
+???
+Normally I show this twice and ask them what they see:
+- No teleportation!
+- Squash and Stretch (preserve volume; can approximate inertia (ball))
+- Follow through (i.e. cord lags behind lamp)
+- Anticipation (small amount of counter movement (lampshade motion))
+- Exaggeration (cord up and down)
+
+- (not shown) Motion blur (doesn't need to be realistic
+
+
+---
+# How implement pacing in animation?
+
+How would `t` and `x` change for slow in slow out?
+
+--
+![:img boxes showing position and time changing over a 40 ms duration, 80%](img/animation/animation-nonlinear.png)
+
+.footnote[[image source: Android animation documentation](https://developer.android.com/guide/topics/graphics/prop-animation)]
+
+---
+# We implement these with `Interpolators` in Android
+.left-column-half[
+![:img mouse moving along a path with linear interpolation,22%](img/toolkit-drawing/linear.gif)
+![:img mouse moving along a path with linear interpolation,22%](img/toolkit-drawing/accelerate.gif)
+![:img mouse moving along a path with overshoot interpolation,22%](img/toolkit-drawing/overshoot.gif)
+![:img mouse moving along a path with bounce interpolation,22%](img/toolkit-drawing/bounce.gif)
+]
+.right-column-half[
+The durations are the same for each of these animations
+- Left side is _Linear_
+- Second one is _Accelerate_
+- Third one is ??
+- Right side is ??
+
+
+]
+
+???
+overshoot
+bounce
+
+---
+# Using an Interpolator
+```java
+ObjectAnimator anim = ObjectAnimator.ofFloat(mouse,
+                                             View.X, View.Y, path);  // Create the ObjectAnimator
+OvershootInterpolator interpolator = new OvershootInterpolator();    // Create an Interpolator
+anim.setInterpolator(interpolator);                                  // Tell the animator to use the interpolator
+anim.setDuration(3000);                                              // set the duration
+anim.start();                                                        // Tell the animation to start
+```
+
+---
+# Using Animation Well - Accessbility
+
+.quote['The impact of animation on people with vestibular disorders can be quite severe.
+Triggered reactions include nausea, migraine headaches, and potentially
+needing bed rest to recover.' [W3C Accessibility Guidelines](https://www.w3.org/WAI/WCAG21/Understanding/animation-from-interactions.html)]
+
+Best option: provide control, be minimalistic
+???
+
+---
+# Summary: Animation Design Tips
+
+1. Used sparingly and understandingly, animation can enhance the interface … otherwise can distract!
+2. Need to mimic real world
+3. Observing motion tells us about size, weight, rigidity
+4. No abrupt changes in velocity!
+5. Think about accessibility.
+
+---
+# What to do for Doodle Part2Activity?
+
+Your chance to  make something creative.
+
+Peers will reviewed your custom doodle to ensure it uses some combination of lines, text, images, and animation.
+
+Peers will also "evaluate" (give you feedback on how much they liked it).
+
+
+---
+# Summary & revisiting learning goals for this week and last
+
+.left-column-half[
+- What is HCI?
+- What is a toolkit? How do an architecture and library differ?
+- How do we draw on the screen?
+  - What is a pixel?
+  - What is a raster vs a vector model?
+  - What abstractions help with drawing?
+  - How do we use affine transformations?
+- What is the interactor hierarchy?
+  - How is it used for drawing?
+  - What role do affine transformations play in this?
+- What are the key abstractions for animation?
+  ]
+.right-column-half[
+- Android basics
+- What is a `View`?
+- `onCreate()` and `onDraw()`
+- How does `Canvas` work?
+- How do we construct the interactor hierarchy?
+- Implementing Animation
+]
diff --git a/slides/wk02/layout.html b/slides/wk02/layout.html
new file mode 100644
index 0000000000000000000000000000000000000000..650ec178ce507ce3f152c01f378f68028f5ffddc
--- /dev/null
+++ b/slides/wk02/layout.html
@@ -0,0 +1,634 @@
+---
+layout: presentation
+title: Layout
+description: Description of Layout Algorithms and Approaches
+class: middle, center, inverse
+---
+layout: false
+
+
+# Visual Design Tips Employed or Avoided?
+
+.left-column-half[
+<br>
+<br>
+![:img Facebook group page with 4 cards each with a picture and light grey on white fonts,80%](img/layout/facebook-bad.png)
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+<br>
+]
+
+.right-column-half[
+- #1: Don't rely on blue for small objects
+- #2: Don't rely on blue for older users
+- #3: Make sure that contrast is high enough
+- #4:  Minimize saturated colors
+- #5: Use redundant cues
+- #6: Make things distinct
+- #7: Use small multiples
+- #8: Manage expectations if you can't change response time
+- #9: Replace subtle changes with obvious ones
+- #10: Use well-tested visual grouping strategies
+- #11: Minimize the number of options
+- #12: Rely on recognition rather than recall
+]
+
+.footnote[Shile W, 20sp from a Facebook group page]
+
+---
+# Visual Design Tips Employed or Avoided?
+
+
+.left-column-half[
+<br>
+![:img Jackbox games front screen with many visual design tips not followed including using blue,80%](img/layout/jackbox-bad.png)
+<br>
+<br>
+]
+
+.right-column-half[
+- #1: Don't rely on blue for small objects
+- #2: Don't rely on blue for older users
+- #3: Make sure that contrast is high enough
+- #4:  Minimize saturated colors
+- #5: Use redundant cues
+- #6: Make things distinct
+- #7: Use small multiples
+- #8: Manage expectations if you can't change response time
+- #9: Replace subtle changes with obvious ones
+- #10: Use well-tested visual grouping strategies
+- #11: Minimize the number of options
+- #12: Rely on recognition rather than recall
+]
+
+.footnote[Lauren Bricker after visiting Jackbox games in 20sp]
+
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Introduction to Layout
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+
+---
+name: normal
+layout: true
+class:
+---
+
+[//]: # (Outline Slide)
+# Today's goals
+- Announcements
+  - Reminder: Peer review emails will go out Saturday night/Sunday morning
+  - Layout will be released later today
+- Review of tree construction
+- Using tree for layout
+- Container components
+
+---
+# Hall of Shame (from [CSE 154](https://courses.cs.washington.edu/courses/cse154/19au/lectures/lec05-css-iii-more-layout/index.html#/))
+
+![:img Terrible website from gatesnfences.com, 50%](https://courses.cs.washington.edu/courses/cse154/19au/lectures/lec05-css-iii-more-layout/images/gatesnfences.png)
+
+Thoughts?
+
+.footnote[[gatesnfences.com](http://www.gatesnfences.com/)]
+
+---
+
+![:img Windows tablet screen with a grid of interactive squares...
+icons along the side for invoking menus... and a colorful background
+picture,70%](img/layout/windowsLayout.png)
+
+
+???
+Key Issues
+- where do components get placed?
+- how much space should they occupy?
+
+---
+# Review of tree construction
+
+Circle all of the interactors in this interface.
+
+.left-column[![:img Color Meter Mac App -- shows the RGB values for whatever pixel the cursor is over, 150%](img/layout/colormeter.png)]
+
+
+---
+# Review of tree construction
+
+Circle all of the interactors in this interface.
+
+.left-column[![:img Color Meter Mac App -- shows the RGB values for whatever pixel the cursor is over, 150%](img/layout/colormetercircled.png)]
+
+---
+# What is the interactor hierarchy?
+
+<br>
+
+.left-column30[
+![:img Color Meter Mac App -- shows the RGB values for whatever pixel the cursor is over, 100%](img/layout/colormeter.png)]
+
+
+---
+# What is the interactor hierarchy?
+
+Naive version...
+
+.left-column30[
+![:img Color Meter Mac App -- shows the RGB values for whatever pixel the cursor is over, 100%](img/layout/colormeter.png)]
+
+.right-column-half[
+<div class="mermaid">
+graph TD
+W(Window) --> M[Icon:Mag Window]
+W --> A[Slider:Aperture Size x y w h]
+W --> C[Menu:Choice x y w h]
+W --> I[Icon:Color x y w h]
+W --> T[Text:RGB x y w h]
+W --> La[Text:Label x y w h]
+
+classDef blue font-size:14pt,text-align:center
+classDef green font-size:14pt,text-align:center
+
+class W green
+class M,A,C,I,T,La blue
+</div>
+]
+
+???
+Start talking here about meta data that maters, they know about x, y, w and h from doodle
+
+Ask them to think about what else you might want to know to position something?
+
+---
+# Why do we need layout?
+.left-column[
+
+<br>
+
+![:img Color Meter Mac App -- shows the RGB values for whatever pixel the cursor is over, 100%](img/layout/colormeter.png)
+]
+.right-column[
+How can you center something?
+
+How can you lock it to an edge?
+
+How can you design layout that reacts (responds) well to turning your phone?
+
+Examples for web (from [CSE 154](https://courses.cs.washington.edu/courses/cse154/19au/lectures/lec05-css-iii-more-layout/index.html#/6))
+- c0FFEE shop with [no layout](https://courses.cs.washington.edu/courses/cse154/19au/lectures/lec05-css-iii-more-layout/code/coffee-shop-solution/coffee-shop.html)
+- c0FFEE shop with [layout](https://courses.cs.washington.edu/courses/cse154/19au/lectures/lec05-css-iii-more-layout/code/coffee-shop-starter/coffee-shop.html)
+]
+
+---
+# User Interfaces on Android
+.left-column-half[
+- Views
+  - Base class for __all__ UI elements
+  - Interactors (e.g buttons, labels, image views, etc)
+- ViewGroups
+  - Encapsulates one or more views (e.g. Android Components, **Layouts**)
+  - Can define specific **layout** properties
+
+  We will use the word *Components* to include both layout components and interactors (Views) since you
+  don't generally "interact" with layouts
+]
+
+.right-column-half[
+<div class="mermaid">
+graph TD
+W(ViewGroup) --> V[ViewGroup]
+W --> V1[View]
+W --> V2[View]
+V --> V3[View]
+V --> V4[View]
+V --> V5[View]
+
+classDef blue font-size:14pt,text-align:center
+classDef darkblue font-size:14pt,text-align:center
+
+class W,V darkblue
+class V1,V2,V3,V4,V5 blue
+</div>
+
+]
+
+---
+# Practice: Let's try to recreate this layout using containers and spacers
+
+.left-column[![:img Color Meter Mac App -- shows the RGB values for whatever pixel the cursor is over, 150%](img/layout/colormeter.png)]
+
+--
+.right-column-half[
+<div class="mermaid">
+graph TD
+W(Window) --> L(LeftSide:DisplayVert)
+W --> R(RightSide:DisplayVert)
+L --> Z[Space:Fixed]
+L --> Y[Space:Stretchy]
+R --> D(RGB DisplayHor)
+D --> V[Space:Fixed]
+D --> U[Space:Flexible]
+
+
+classDef bluegreen font-size:14pt,text-align:center
+classDef blue font-size:14pt,text-align:center
+classDef green font-size:14pt,text-align:center
+classDef yellow font-size:14pt,text-align:center
+
+class W bluegreen
+class L,R,D green
+class Z,Y,V,U yellow
+class M,A,C,I,T,Q blue
+</div>
+]
+
+---
+# Practice: Let's try to recreate this layout using containers and spacers
+
+.left-column[![:img Color Meter Mac App -- shows the RGB values for whatever pixel the cursor is over, 150%](img/layout/colormeter.png)]
+
+.right-column-half[
+<div class="mermaid">
+graph TD
+W(Window) --> L(LeftSide:DisplayVert)
+W --> R(RightSide:DisplayVert)
+L --> Z[Space:Fixed]
+L --> M[Icon:Mag Window]
+L --> A[Slider:Aperture Size]
+L --> Y[Space:Stretchy]
+R --> C[Menu:Choice]
+R --> D(RGB DisplayHor)
+D --> V[Space:Fixed]
+D --> I[Icon:Color]
+D --> T[Text:RGB]
+D --> U[Space:Flexible]
+R --> Q[Text:Label]
+
+classDef bluegreen font-size:14pt,text-align:center
+classDef blue font-size:14pt,text-align:center
+classDef green font-size:14pt,text-align:center
+classDef yellow font-size:14pt,text-align:center
+
+class W bluegreen
+class L,R,D green
+class Z,Y,V,U yellow
+class M,A,C,I,T,Q blue
+</div>
+]
+
+---
+# Vertical Container Components
+
+.left-column[
+
+![:img Color Meter Mac App -- shows the RGB values for whatever pixel the cursor is over, 150%](img/layout/colormeter.png)
+
+Linear (1D) layout of components
+- Always layout in the same direction
+- Places its direct descendants, in order, in that direction
+
+]
+
+.right-column[
+<div class="mermaid">
+graph TD
+W(Window) --> L(LeftSide:DisplayVert)
+W --> R(RightSide:DisplayVert)
+L --> Z[Space:Fixed]
+L --> M[Icon:Mag Window]
+L --> A[Slider:Aperture Size]
+L --> Y[Space:Stretchy]
+R --> C[Menu:Choice]
+R --> D(RGB DisplayHor)
+D --> V[Space:Fixed]
+D --> I[Icon:Color]
+D --> T[Text:RGB]
+D --> U[Space:Flexible]
+R --> Q[Text:Label]
+
+classDef bluegreen font-size:14pt,text-align:center
+classDef darkblue font-size:14pt,text-align:center
+classDef blue font-size:14pt,text-align:center
+classDef green font-size:14pt,text-align:center
+classDef yellow font-size:14pt,text-align:center
+
+class L,R darkblue
+class W bluegreen
+class D green
+class Z,Y,V,U yellow
+class M,A,C,I,T,Q blue
+</div>
+
+]
+
+---
+# Horizontal Container Components
+
+.left-column[
+![:img Color Meter Mac App -- shows the RGB values for whatever pixel the cursor is over, 150%](img/layout/colormeter.png)
+
+Same: Linear (1D) layout of components
+- Always layout in the same direction
+- Places its kids, in order, in that direction
+]
+
+.right-column[
+<div class="mermaid">
+graph TD
+W(Window) --> L(LeftSide:DisplayVert)
+W --> R(RightSide:DisplayVert)
+L --> Z[Space:Fixed]
+L --> M[Icon:Mag Window]
+L --> A[Slider:Aperture Size]
+L --> Y[Space:Stretchy]
+R --> C[Menu:Choice]
+R --> D(RGB DisplayHor)
+D --> V[Space:Fixed]
+D --> I[Icon:Color]
+D --> T[Text:RGB]
+D --> U[Space:Flexible]
+R --> Q[Text:Label]
+
+classDef bluegreen font-size:14pt,text-align:center
+classDef darkblue font-size:14pt,text-align:center
+classDef blue font-size:14pt,text-align:center
+classDef green font-size:14pt,text-align:center
+classDef yellow font-size:14pt,text-align:center
+
+class D darkblue
+class W bluegreen
+class L,R,D green
+class Z,Y,V,U yellow
+class M,A,C,I,T,Q blue
+</div>
+
+
+]
+
+---
+# Spacers
+
+.left-column[
+![:img Color Meter Mac App -- shows the RGB values for whatever pixel the cursor is over, 150%](img/layout/colormeter.png)
+
+- Work extra well with layout containers
+- We can add *Fixed Space* (struts)
+  - Think of it like a strut in a building
+  - They hold things a fixed distance apart
+- We can also add *Stretchy Space* (springs)
+  - they push things apart as much as possible
+]
+
+.right-column[
+<div class="mermaid">
+graph TD
+W(Window) --> L(LeftSide:DisplayVert)
+W --> R(RightSide:DisplayVert)
+L --> Z[Space:Fixed]
+L --> M[Icon:Mag Window]
+L --> A[Slider:Aperture Size]
+L --> Y[Space:Stretchy]
+L --> C[Menu:Choice]
+R --> D(RGB DisplayHor)
+D --> V[Space:Fixed]
+D --> I[Icon:Color]
+D --> T[Text:RGB]
+D --> U[Space:Flexible]
+R --> Q[Text:Label]
+
+classDef bluegreen font-size:14pt,text-align:center
+classDef darkblue font-size:14pt,text-align:center
+classDef blue font-size:14pt,text-align:center
+classDef green font-size:14pt,text-align:center
+classDef yellow font-size:14pt,text-align:center
+
+class Y,Z,V,U darkblue
+class W bluegreen
+class L,R,D green
+class Z,Y,V,U yellow
+class M,A,C,I,T,Q blue
+</div>
+
+]
+
+
+---
+
+.left-column-half[
+# Example (Layout Assignment)
+
+![:img Picture of Pintrest, 50%](img/layout/pinterest-android.png)
+]
+
+.right-column30[
+![:img Picture of layout part 3, 60%](img/layout/pinterest-replica.png)
+]
+
+???
+This is the kind of stuff we can do thanks to viewgroups
+
+---
+# Example (Layout Assignment, part 3)
+
+.left-column-half[
+I've highlighted things that are visible (as opposed to just doing layout work)
+<div class="mermaid">
+graph TD
+C[ViewGroup:ConstraintLayout]
+C --> Column1[ViewGroup:Column1]
+C --> Column2[ViewGroup:Column2]
+Column1 --> V1[View:Fox]
+Column1 --> V2[View:Squirrel]
+Column1 --> V3[...]
+Column2 --> V4[View:Duckling]
+Column2 --> V5[...]
+
+classDef darkblue font-size:14pt,text-align:center
+classDef blue font-size:14pt,text-align:center
+
+class C,Column1,Column2 blue
+class V1,V2,V3,V4,V5 darkblue
+</div>
+
+]
+.right-column30[
+![:img Picture of layout part 3,60%](img/layout/pinterest-replica.png)
+]
+
+???
+This is the kind of stuff we can do thanks to viewgroups
+
+---
+# Android's runtime view of the same
+
+.left-column[
+![:img Picture of the android studio tools menu with Layout Inspector highlighted, 100%](img/layout/layout-inspector-menu.png)
+
+VERY IMPORANT debugging tool
+]
+.right-column-half[
+![:img Picture of Part3 of the assignment running with the related interactor hierarchy at right, 50%](img/layout/part3-runtime.png)
+]
+
+---
+# Layout Assignment
+
+.left-column[
+![:img Part1: picture of animals a button and a big textbox in a phone held vertically, 65%](img/layout/1_portrait.png)
+
+You can scroll this and the images are all equidistant.
+]
+.right-column[
+- Part 1 is about basic reactive layout using XML and constraints for a fixed number of images
+- Part 2 replicates this in code for a fixed number of images
+- Part 3 you create a *Layout Container* that can do a fancier layout, for an arbitrary number of images **Pintrest** style!
+- Part 4 you try to recreate a layout of your choice!
+
+]
+
+---
+# Brief Diversion: What is XML?
+- XML stands for eXtensible Markup Language
+- A superset of HTML
+  - Tag names are surrounded by '<' and '>''s (Alligators or "wakkas")
+  - Tags are generally in pairs such as `<html>` `</html>` or can be self closing `<ImageView />`
+  - Tags can have attributes such as
+
+     `<tagname attribute="value" attribute="value"> content </tagname>`
+
+---
+# Layout in Android
+.left-column-half[
+
+![:img A simple layout on an android watch with a textview and two buttons (save and discard),100%](img/layout/layout-demo.png)
+]
+
+.right-column-half[
+This is Android's GUI layout editor
+
+Where's the interactor hierarchy here?
+]
+
+???
+point out the "space"
+
+---
+# Layout in Android
+.left-column-half[
+
+![:img A simple layout on an android watch with a textview and two buttons (save and discard),100%](img/layout/layout-demo.png)
+]
+
+.right-column-half[
+This is Android's GUI layout editor
+
+Where's the interactor hierarchy here?
+- It's the component tree!
+- The XML is a visual way of specifying the hierarchy that exists once the XML is loaded into the application
+
+What are the leaf nodes?
+Do you see anything unusual?
+]
+
+???
+point out the "space"
+
+
+---
+# What is a spacer?
+.left-column-half[
+
+![:img A simple layout on an android watch with a textview and two buttons (save and discard),100%](img/layout/layout-demo.png)
+
+]
+
+.right-column-half[
+
+What is a Space?
+- Works extra well with layout containers
+- We can add *struts*
+  - Think of it like a strut in a building
+  - They hold things a fixed distance apart
+- We can also add *springs*
+  - they push things apart as much as possible
+
+```xml
+<Space
+  android:layout_width="0dp"
+  android:layout_height="wrap_content"
+  android:layout_weight="1" />
+```
+]
+
+???
+see next slide!
+
+---
+# Layout in Android
+.left-column-half[
+
+![:img A simple layout on an android watch with a textview and two buttons (save and discard),100%](img/layout/layout-demo.png)
+]
+.right-column-half[
+In this case, they are in a `LinearLayout`
+- It always has a direction (horizontal or vertical)
+- And it places its kids, in order, in that direction, within its bounds
+
+Where is the linear layout on the screen?
+]
+
+---
+# Layout in Android
+.left-column-half[
+
+![:img A simple layout on an android watch with a textview and two buttons (save and discard),100%](img/layout/layout-demo.png)
+]
+.right-column-half[
+In this case, they are in a `LinearLayout`
+- It always has a direction (horizontal or vertical)
+- And it places its kids, in order, in that direction, within its bounds
+
+Where is the linear layout on the screen?
+
+It's the box around 'Save and Discard'
+- We call this a *Layout Container*
+- Note: this is not visible in the actual GUI, it's a hidden interactor tree element
+]
+---
+# Layout in Android
+.left-column-half[
+
+![:img A simple layout on an android watch with a textview and two buttons (save and discard),100%](img/layout/layout-demo.png)
+]
+.right-column-half[
+A Layout Container can
+ - automate a lot of the layout tasks
+ - make it much simpler to ensure reliable results
+ - use these whenever they do the job
+ - you will implement one for your assignment
+]
+
+
+---
+# Layout in Android
+Many layout and other attributes for components. You should explore!
+
+![:img Picture of the whole android layout interface showing the possible components that can be added; the component tree (interactor hierarchy; and the attributes for the Save Button; which is selected, 90%](img/layout/design-view.png)
+
+???
+Talk about how there's many layout and other attributes for components that they should explore!
+
+---
+# End of Deck
+
+The slides that were here have move to [Layout Part II](../wk03/layout-ii.html)
diff --git a/slides/wk02/people-vision.html b/slides/wk02/people-vision.html
new file mode 100644
index 0000000000000000000000000000000000000000..e1067dd972909f54a7970e66c8fe2135b5c33f77
--- /dev/null
+++ b/slides/wk02/people-vision.html
@@ -0,0 +1,1045 @@
+---
+layout: presentation
+title: Properties of People-- Visual Capacity
+description: Discussion of what we know about people that influences interface design in the vision realm
+class: middle, center, inverse
+
+---
+
+# Open poll
+
+<iframe src="https://embed.polleverywhere.com/free_text_polls/sK4PfNJjme9aKeezruC36?controls=none&short_poll=true" width="800" height="600" frameBorder="0"></iframe>
+
+???
+
+
+---
+# Critique this ad:
+
+![:img Adobe advertisement in vibrant colors showing a red cloud icon
+on a blueish background along with bold and very thin white text on
+the blueish background and more white text on a
+blue button and a play arrow in light blue on a light grey
+background,100%](img/people/adobe.jp
+
+--
+
+Adobe, what were you thinking?
+- Selling Software
+- showing off what they can do
+- Make sure it's said that it is hard to read - thin white line/poor contrest.
+
+???
+---
+# Review
+
+.left-column60[
+In the `drawAll()` method for the toolkit:
+
+Which of the following must a parent component do to its own Canvas obect before
+telling a child component to draw itself?
+
+- [a] canvas.translate(child.x, child.y)
+- [b] canvas.clip(parent.x, parent.y, parent.w, parent.h)
+- [c] canvas.translate(-child.x, -child.y)
+- [d] canvas.clip(0, 0, child.w, child.h)
+]
+
+--
+.right-column30[
+![:img Animation of the drawAll method with translation and clipping,95%](img/people/drawAll.gif)
+]
+--
+
+What does it need to do after the child draws itself?
+
+.footnote[See [How a view is drawn on the screen](https://courses.cs.washington.edu/courses/cse340/20sp/slides/wk02/interface-drawing.html#29)]
+
+???
+Answer: Translate (a), then clip (d)
+Answer 2: (c)
+
+
+
+
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Properties of People
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+name: normal
+layout: true
+class:
+---
+
+[//]: # (Outline Slide)
+
+# Today's goals
+
+- Discuss visual properties of people
+- Discuss memory
+
+## Future Goals
+- Discuss motor control
+
+---
+# Administrivia
+
+- Reminder: [Doodle](https://courses.cs.washington.edu/courses/cse340/20sp/assignments/) code is due Thursday night.
+  - IMPORTANT: git add/commit/push - then [TURN IN](https://gitgrade.cs.washington.edu/student/assignment/116/turnin)
+  - Lab will go over this
+- Doodle peer reviews will be out late Saturday or early Sunday. Get these done quickly. They do not take long
+- Layout will be out on Friday
+- Religious accomodations section added to [syllabus](https://courses.cs.washington.edu/courses/cse340/20sp/#Religious-Accommodations)
+(Chag sameach Pesach to those who celebrate)
+
+---
+# Visual Properties of People
+
+People's visual abilities have a big impact on everything from how we
+model color to what makes for good design
+
+People have a variety of visual capabilities, which you should know
+- 4.5% of the world population (mostly men) is color blind<sup>1</sup>
+- 17% of the world population live with some vision impairment<sup>2</sup>
+
+Good design is generally more accessible design
+
+*Bad psychology is good enough to support good design (I hope! :)*
+
+.footnote[
+<sup>1</sup>[colourblindawareness.org](www.colourblindawareness.org/colour-blindness/)<br>
+<sup>2</sup>[WHO](https://www.who.int/news-room/fact-sheets/detail/blindness-and-visual-impairment)<br>
+]
+???
+talk about my own disability
+
+---
+layout: false
+# What does this image show? (raise hands if you know)
+
+.body[
+![:img Picture of unknown object. Color range is -3500 (blue) to 1000 (red) but
+only yellow and a little blue shows, 40%](img/people/badviz.png)
+]
+.footnote[
+Example from
+http://10qviz.org/home/categories/rainbow-color-map/
+]
+
+---
+# What does this image show? (raise hands if you know)
+
+.body[
+![:img Picture of unknown object. Color range is -3500 (blue) to 1000 (red) but
+only yellow and a little blue shows, 40%](img/people/badviz.png)
+![:img Picture of US Coastline (florida). Color range is -3500 (blue)
+to 1000 (white) and range maps well onto values so detail can be made out, 40%](img/people/goodviz.png)
+]
+.footnote[
+Example from
+http://www.research.ibm.com/people/l/lloydt/color/color.HTM
+]
+
+
+???
+So why is the color choice poor?
+- No mapping of color (note on right how blues are used for water, and greens for land)
+- Color is better if you adjust by saturation (purity) or value (brightness) rather than hue (rough color, ie red, green, blue, orange) for mapping. People can more easily see and compare differences in saturation and value over hue. Also, changes in hue don’t naturally map to a scale, whereas saturation and value do.
+
+---
+# Visible Spectrum (Human Limits matter!)
+![:img Color spectrum UV to IR (purple to red), 50%](img/people/humanspectrum.png)
+
+.footnote[
+http://insight.med.utah.edu/Webvision/index.html]
+---
+.left-column-half[
+## Why RGB
+
+- Match eye's model
+  - Receptor cells for red, green, blue (cones)
+- Receptor cells for grayscale (rods)
+]
+.right-column-half[
+![:img Picture of Rod & Cone cells, 85%](img/people/rods_cones.png)
+]
+---
+# Retina covered with light-sensitive receptors
+
+.right-column[
+Rods
+- Primarily for night vision & perceiving movement
+- Sense intensity or shades of gray
+- Can’t discriminate between colors
+- Mostly at edge of retina
+- ~75M – 150M rods
+]
+.left-column[
+![:img Diagram of eye, 120%](img/people/eye.png)
+]
+
+---
+# Retina covered with light-sensitive receptors
+
+.right-column[
+Rods
+- ~75M – 150M rods
+
+Cones
+- Used to sense color
+- Mostly in center of retina
+- ~4.5M – 7M cones
+
+Many more rods than cones
+]
+.left-column[
+![:img Diagram of eye, 120%](img/people/eye.png)
+]
+---
+# RGB Matches how human vision works
+
+.right-column[
+In Java, CSS, and other GUI programming, color is 24 bit (+ 8 bits for
+alpha transparency)
+
+So 8 bits for each of red, green, blue
+
+- Why not more bits?
+- Why not 64 bit color?
+
+Discuss!
+]
+.left-column[
+![:img RGB color scheme, 100%](img/people/rgb.png)
+]
+
+???
+Humans can’t really see much more colors
+
+---
+# RGB Matches how human vision works
+
+.right-column[
+However, RGB isn't all that intuitive (technology centric)
+- Especially artists and visual designers
+- Hard to pick colors in 3d on a 2d screen
+- Or actually perceive them at a cognitive level
+]
+.left-column[
+![:img RGB color scheme, 100%](img/people/rgb.png)
+]
+???
+
+---
+# RGB Matches how human vision works
+
+.right-column[
+However, RGB isn't all that intuitive (technology centric)
+- Especially artists and visual designers
+- Hard to pick colors in 3d on a 2d screen
+- Or actually perceive them at a cognitive level
+
+HSV is much better for *people*
+- Hue: Dominant wavelength of light
+- Saturation: Purity (how much white/black mixed in)
+- Value: Luminance or amount of light in color = max(R,G,B)
+]
+.left-column[
+## RGB
+![:img RGB color scheme, 50%](img/people/rgb.png)
+## HSV
+![:img HSV color scheme, 50%](img/people/hsv.png)
+
+]
+
+???
+HSV cylindrical – hue around the outside (angle) on the web value between
+0 and 360 (red is 0, green is 120, blue is 240) and it’s in rainbow
+order), saturation from center to edge, value is top to bottom
+
+---
+# Understanding HSV
+
+.left-column[
+![:img HSV color scheme, 100%](img/people/hsv.png)
+]
+
+.right-column[
+- Hue - or color value, is around the circle at the top of the cone.
+- Saturation - the colors get more saturated the further out from the center of the cone
+- Value - the color gets "brighter" the closer you are to the top of the cone and darker the further you go down.
+
+
+]
+---
+# Compare the following colors using HSV
+.right-column[
+Which is correct?
+
+- A: Top color has different *hue* than bottom color
+- B: Top color has higher *saturation* than bottom color
+- C: Top color has higher *value* than bottom color
+]
+.left-column[
+![:img Darker and lighter red boxes, 100%](img/people/redcomp.png)
+]
+???
+B: Saturation
+
+---
+# Value vs saturation
+
+![Red with varying saturation (to white) and value (to black)](img/people/value-sat.png)
+---
+# Question
+
+You have been asked to create a digital-paper compatible interface. As a result; you need to pick colors that will be easily distinguishable in black and white. Which of 'H' 'S' and 'V' should you vary to support black and white display?
+
+???
+last year's answers
+
+![:img You have been asked to create a digital-paper compatible interface. As a result; you need to pick colors that will be easily distinguishable in black and white. Which of 'H' 'S' and 'V' should you vary to support black and white display?, 75%](img/people/q3.png)
+
+---
+# Perception of Color is Culturally Defined!
+
+.footnote[
+<sup>1</sup>[New Scientist: Russian speakers get the blues](https://www.newscientist.com/article/dn11759-russian-speakers-get-the-blues/)
+]
+
+.right-column[
+
+Not only are we limited to RGB, but we disagree about how to interpret
+it<sup>1</sup>
+]
+.left-column[
+![:img Picture of blues that not everyone can distinguish,90%](img/people/blues.jpg)
+]
+???
+
+The language you speak can affect how you see the world, a new study of colour perception indicates. Native speakers of Russian – which lacks a single word for “blue” – discriminated between light and dark blues differently from their English-speaking counterparts, researchers found.
+
+---
+# And Relative
+
+![:youtube Vergeer and Van Lier illusion,Db4PwJ2LDVk]
+---
+# Design Tip #1: Don't rely on Blue for Small Objects
+
+.left-column-half[
+![:img Example webpage from
+https://www.crazyegg.com/blog/why-hyperlinks-are-blue/ describing why
+hyperlinks are blue historically and which has blue hyperlinks, 80%](img/people/bluelinks.png)
+
+]
+.right-column-half[
+- Photopigments not distributed evenly
+ - Mainly reds (64%) & few blues (2-4%)
+ - Less sensitive to short wavelengths (blue)
+]
+
+---
+# Design Tip #1: Don't rely on Blue for Small Objects
+
+.left-column-half[
+![:img Example webpage from
+https://www.crazyegg.com/blog/why-hyperlinks-are-blue/ describing why
+hyperlinks are blue historically and which has blue hyperlinks, 80%](img/people/bluelinks.png)
+
+]
+.right-column-half[
+- Photopigments not distributed evenly
+ - Mainly reds (64%) & few blues (2-4%)
+ - Less sensitive to short wavelengths (blue)
+- Few blue cones in fovea
+ - Harder to see small blue objects you fixate on
+ - Blue text also slightly harder to read
+
+
+- So: blue hyperlinks as default is worst choice
+- Note: strong contrast >> avoiding blue
+]
+
+---
+# Design Tip #2: Don’t Rely on Blue for Older Users
+
+- As we age, our lens yellows and absorbs <Br> shorter wavelengths
+- Sensitivity to blue is even more reduced
+
+![:img Example article from IEEE pervasive with inaccessible blue on blue text, 40%](img/people/blueonblue.png)
+
+---
+# Design Tip #3: Make sure that contrast is high enough
+
+.left-column-half[
+**Accessibility Issue!**
+
+WCAG requires *at least 4.5:1* contrast, so you cannot round a
+contrast ratio up to 4.5:1. For example, #777777 <br>(![:img grey with
+black text,10%](img/people/777777.png) ![:img grey with
+white text,10%](img/people/777777w.png)) is a commonly-used
+shade of gray with a 4.48:1 contrast ratio. It does not meet the WCAG
+contrast threshold.<sup>1</sup>
+]
+.right-column-half[
+![:img Windows tablet screen with a grid of interactive squares...
+icons along the side for invoking menus... and a colorful background
+picture,100%](img/people/windowsLayout.png)]
+
+.footnote[
+[WCAG guidelines on contrast](https://webaim.org/articles/contrast/)
+]
+???
+Test in greyscale
+
+---
+# Design Tip #3: Make sure that contrast is high enough
+
+.left-column-half[
+**Accessibility Issue!**
+
+WCAG requires "at least 4.5:1" contrast, so you cannot round a
+contrast ratio up to 4.5:1. For example, #777777 <br>(![:img grey with
+black text,10%](img/people/777777.png) ![:img grey with
+white text,10%](img/people/777777w.png)) is a commonly-used
+shade of gray with a 4.48:1 contrast ratio. It does not meet the WCAG
+contrast threshold.
+]
+
+.right-column-half[
+![:img Windows tablet screen with a grid of interactive squares...
+icons along the side for invoking menus... and a colorful background
+picture,100%](img/people/windowsLayoutGreyscale.png)
+]
+
+
+???
+Test in greyscale
+
+Focus on value over hue or saturation
+
+This will help ensure visibility
+
+Can use a b/w photocopier to help if you already have a GUI
+
+Keep luminance / intensity / value the same from grayscale when moving to color
+
+---
+# Designing Tip #4: Minimize saturated Colors
+
+.medium.right-column70[
+- Different wavelengths of light focus at different distances behind
+eye’s lens
+
+- If your GUI has lots of reds and blues, will force lots of
+refocusing and cause fatigue
+
+- Design Implication
+ - Pure (saturated) colors require more focusing than less pure
+(desaturated, pastel)
+ - Avoid saturated colors in UIs unless really need something to stand
+out (stop sign)
+ - Don't follow this advice! [Vibrant Colors in Web Design](https://uxplanet.org/vibrant-colors-in-web-design-20-visually-impactful-websites-to-inspire-you-bc7988da1e95)
+]
+.left-column[
+![:img Picture of President Trump and Hilary Clinton in bright blue
+and red with yellow writing over the top,150%](img/people/saturated.png)
+
+[mediaelection.com](http://mediaelection.com/)
+]
+---
+# Where to Find More Color Advice?
+
+.medium.right-column70[
+- Martin Krzywinski<sup>1</sup> on <br>[Brewer Palettes](http://mkweb.bcgsc.ca/brewer/)
+- [Color Brewer](http://colorbrewer2.org/), [Color Scheme
+Desginer](http://colorschemedesigner.com), [Color Schemer](http://colorschemer.com)
+]
+.left-column[![:img Picture of color palette that is vibrant and less saturated, 150%](img/people/color-guidelines.png)]
+.footnote[
+<sup>1</sup>Famous information graphics artist, [bio](http://mkweb.bcgsc.ca/bio/martin-krzywinski-bio.pdf)]
+---
+# Color Blindness: Ishihara Test
+![:youtube Ishihara Colorblindness test showing colored dots inside
+colored dots showing numbers,WzAW41DugXQ]
+
+If you can’t see numbers, don’t worry
+- Projectors, LCD screens, CRT, and print all have different dynamic ranges, hard to get them to match
+???
+
+Trouble discriminating colors
+
+About 9% of males, 0.5% of females
+
+Two main types
+- Different photopigment response is common
+ - Reduces capability to discern small color diffs
+- Red-green deficiency is best known
+ - Lack of either green or red photopigment can’t discriminate colors dependent on R & G
+ - More rare are blue-yellow and total color blindness
+
+Some women have a fourth type of cone
+- Estimates are 12% women
+- Some can see more colors than ordinary humans
+
+
+---
+# Design Tip #5: Use Redundant Cues
+
+.left-column-half[
+![:img Picture of hexagonal red stopsign and triangular red yield
+sign, 70%](img/people/signs.png)
+]
+
+
+.right-column-half[
+Don't rely solely on Hue: Use mixtures of colors (red / green issues)
+
+Also have contrast in intensity
+
+Consider having other redundant cues too
+ - What redundant cues used for traffic signs?
+]
+
+???
+Traffic signs have multiple cues: color, word, shape
+
+another case for using greyscale to test
+
+---
+# Gestalt Psychology
+
+A lot of this draws from Gestalt Psychology.
+
+_Gestalt_ means "an organized whole that is perceived as more than the sum of its parts."
+
+Read about other [gestalt psychology](https://www.interaction-design.org/literature/article/the-law-of-similarity-gestalt-principles-1) principles
+- similarity
+- continuation
+- closure
+- proximity
+- figure/ground
+- symmetry and order
+
+---
+# People are easy to trick
+
+.left-column50[
+![:img Spheres where the foreground colorr hue 230° & 90° appear similar but the background spheres all base color RGB 255 157 194 appear distinctly pink and orange, 85%](https://pbs.twimg.com/media/EZ_3kqmWkAAU2R9?format=jpg&name=large)
+]
+
+.right-column40[
+From [@NovikProf](https://twitter.com/NovickProf/status/1270005909704638470/photo/1)
+
+Surprising 4: The foreground colors (hue 230° & 90°) appear similar but the background spheres
+(all base color RGB 255 157 194) appear distinctly pink and orange.
+Original .png file is at [http://bit.ly/2O74l2I](http://bit.ly/2O74l2I).
+]
+
+
+---
+# People are easy to trick
+
+How do we actually create color? We don't have LEDs of every color
+--
+
+- Three LCD cells per pixel
+
+- Keep them small!
+
+---
+# Why Pixels are enough
+
+.right-column-half[
+Limits of human perceptual system
+
+Eye reconstructs
+]
+.left-column-half[
+![:img Picture of mona lisa,45%](img/people/monalisa.png) ![:img pixelated
+zoomed in picture of mona lisa, 45%](img/people/pixelmonalisa.png)
+]
+---
+# People are easy to trick
+
+How do we actually create color? We don't have LEDs of every color
+
+- Three LCD cells per pixel
+
+- Keep them small!
+
+How might we do grayscale?
+
+???
+make connection to video
+---
+# How fast can people see things?
+
+.left-column[
+![:img Picture of a sabertooth tiger,100%](img/people/tiger.png)
+]
+
+.right-column[
+*&lt; ~20ms (1/50 sec) discrete images/flashes merge into continuous perception*
+
+Image you are looking at flickers 60 times per second
+
+Differences in peripheral vision
+ -  Sabertooth tigers
+]
+---
+# How fast can people see things?
+.left-column[
+![:img Picture of a sabertooth tiger,100%](img/people/tiger.png)
+]
+.right-column[
+*&lt; ~20ms (1/50 sec) discrete images/flashes merge into continuous perception*
+
+Pretty much never have to be faster than this for user response!
+- Get >120 million instructions per core (@3Ghz)
+- High end GPU theoretically as high as 26 *billion* instr.
+- First GUIs had ~20 *thousand*
+]
+---
+# Can use this to create greyscale
+
+How might we do grayscale?
+
+--
+
+- Black 25% of the time,
+- 40-60 frames per second (FPS)?
+???
+40-60 FPS
+
+---
+# Can use this for animation
+- minimum of 10 FPS
+- 24-40 smoother
+---
+# How fast can people see things?
+
+&lt; ~20ms (1/50 sec) discrete images/flashes merge into continuous perception
+
+*&lt; ~100-200ms seems like “instant response”*
+- Hard to tell response times below this apart
+- Upper range of eye saccades
+
+---
+# Let's try an experiment
+
+---
+# Also useful for Pre-attentive processing
+
+.left-column[
+![:img Picture of red squares,170%](img/people/distinct1.png)
+]
+
+.right-column-half[
+On the next couple of slides you're going to see a picture.
+
+- Turn on your mics if you'd like to partipate.
+- If all of the shapes are the same, you'll call out "same", call out "different" if they are different.
+- One of the TAs will time us.
+
+Need a ~~victim~~ volunteer with a stopwatch
+
+]
+
+???
+Grouping looks at how to make things look related
+
+What if we want to make things look different and stand out?
+
+Let's try it: Say out loud:
+
+Same 		if every object is the same
+
+Different 	if at least one object is different
+---
+# Pre-attentive processing
+
+![:img Picture of red squares and one red circle,35%](img/people/distinct2.png)
+
+???
+this is about shape
+
+---
+# Pre-attentive processing
+
+![:img Picture of blue circles and one red
+circle,35%](img/people/distinct3.png)
+
+???
+this is about color
+---
+# Pre-attentive processing
+
+![:img Picture of blue circles with no standout,35%](img/people/distinct4.png)
+
+???
+gotcha!
+
+---
+# Pre-attentive processing
+
+![:img Picture of blue circles and one larger blue
+circle,35%](img/people/distinct5.png)
+
+???
+this is about size
+---
+# Pre-attentive processing
+
+![:img Picture of blue circles and red squares and one red circle. ,35%](img/people/distinct6.png)
+
+???
+This one doesn't work well
+---
+# Design Tip #6 Make things Distinct
+
+![:img Picture of blue circles and red squares and one red circle. ,45%](img/people/distinct7.png)
+
+What other variables might be important to making things distinct?
+???
+From Kevin Mullet and Darrell Sano, Designing Visual Interfaces
+
+- Value
+- Orientation
+- Texture
+- Position (2d/3d)
+---
+# Design Tip #7: Use [Small Multiples](https://en.wikipedia.org/wiki/Small_multiple)
+
+.left-column-half[
+
+![:img 5 star rating for a review with the stars being multiples, 30%](img/people/stars.png)
+
+]
+
+![:img Picture of Tufte book cover with examples of small multiples
+including micro-macro readings (clothes of different colors hanging on
+a line) and layering and separation ( people waving signals). ,50%](img/people/tufte.png)
+
+.footnote["Information consists of differences that make a difference" -- Edward --
+-- Tufte, Envisioning Information]
+
+
+---
+# How fast can people see things?
+
+.left-column-half[
+&lt; ~20ms (1/50 sec) discrete images/flashes merge into continuous perception
+
+&lt; ~100-200ms seems like “instant response”
+
+.bold.blue[&lt; 1-2 seconds typically “good response time”]
+- Similar times in conversational turn taking protocols
+- Longer delays ~5 sec have to say something to keep conversation
+       alive
+- Note: numbers fuzzier as we go out
+]
+---
+# How fast can people see things?
+.left-column-half[
+&lt; ~20ms (1/50 sec) discrete images/flashes merge into continuous perception
+
+&lt; ~100-200ms seems like “instant response”
+
+&lt; 1-2 seconds typically “good response time”
+
+.bold.blue[More than  10-15 sec is typically “bad response time”]
+
+- Short Term Memory (STM) g#1 decay effects
+- Web has trained us to accept slower response times
+- However a difference of 250 ms can switch people to a competitor
+]
+---
+# How fast can people see things?
+.left-column-half[
+&lt; ~20ms (1/50 sec) discrete images/flashes merge into continuous perception
+
+&lt; ~100-200ms seems like “instant response”
+
+&lt; 1-2 seconds typically “good response time”
+
+.bold.blue[More than  10-15 sec is typically “bad response time”]
+]
+.right-column-half[
+.quote["Two hundred fifty msec, either slower or faster, is close to
+the magic number now for competitive advantage on the Web"]
+]
+.footnote[Harry Shum, a computer scientist and speed specialist at Microsoft]
+
+---
+# Design Tip #8: Manage Expectations
+
+Long response times are more manageable if you
+
+- Tell people what to expect, be predictable (follow through)
+
+- Also good to support interrupts
+
+---
+
+# How fast can people see things?
+.left-column-half[
+&lt; ~20ms (1/50 sec) discrete images/flashes merge into continuous perception
+
+&lt; ~100-200ms seems like “instant response”
+
+&lt; 1-2 seconds typically “good response time”
+
+.bold.blue[More than  10-15 sec is typically “bad response time”]
+]
+
+.right-column-half[
+Can also manipulate perception: [Chris Harrison's
+work](http://chrisharrison.net/index.php/Research/ProgressBars2)
+
+
+![:youtube Harrison progress bar manipulation shows how animation of
+progress bars changes perception of response time,CDnN3wLY3OE]
+]
+
+---
+# How fast can people see things?
+
+.left-column-half[
+&lt; ~20ms (1/50 sec) discrete images/flashes merge into continuous perception
+
+&lt; ~100-200ms seems like “instant response”
+
+&lt; 1-2 seconds typically “good response time”
+
+More than  10-15 sec is typically “bad response time”
+
+.bold.blue[No response: Change Blindness]
+]
+.right-column-half[
+![:youtube Video of someone asking for directions while another person
+walks by with a door,FWSxSQsspiQ]
+]
+
+???
+
+- Subtle changes over time
+- Distractors
+- Discontinuities (Ex. in movies)
+
+---
+# How fast can people see things?
+
+.left-column-half[
+&lt; ~20ms (1/50 sec) discrete images/flashes merge into continuous perception
+
+&lt; ~100-200ms seems like “instant response”
+
+&lt; 1-2 seconds typically “good response time”
+
+More than  10-15 sec is typically “bad response time”
+
+.bold.blue[No response: Change Blindness]
+]
+.right-column-half[
+![:youtube Video of basketball players, 0grANlx7y2E]
+]
+---
+# Design Tip #9: Replace subtle changes with obvious ones
+
+![:img Picture of a web page form,40%](img/people/web1.png)
+---
+# Design Tip #9: Replace subtle changes with obvious ones
+
+![:img Picture of a web page form,40%](img/people/web2.png)
+---
+# Design Tip #9: Replace subtle changes with obvious ones
+
+![:img Picture of a web page form,40%](img/people/web3.png)
+---
+
+# What's wrong with these buttons?
+
+![:img Picture of an elevator button panel with the labels and buttons
+not visually associated leading to ambiguity,40%](img/people/elevator1.png)
+
+???
+No clear association between buttons and labels
+---
+# Better grouping strategy
+
+![:img Picture of an elevator button panel with the labels and buttons
+ visually associated removing ambiguity,40%](img/people/elevator2.png)
+
+???
+Clear association between buttons and labels
+
+---
+# Good or bad?
+
+Review Star Labels | Icon Labels
+----|----
+![:img Similar issue but with star ratings for multiple categories of issues such as durability and fun ambiguously associated on Amazon,80%](img/people/amazon.png) | ![:img Similar issue but with labels for icons on Facebook,60%](img/people/facebook.png)
+
+???
+No clear association between icons and labels
+
+---
+# Design Tip #10: Use well-tested visual grouping strategies
+
+.right-column[![:img Visual grouping strategies including proximity similarity and
+connections between related things are shown in the image. For example
+putting things close together that are grouped and further otherwise
+is proximity. Using color or shape could be for similarity. Lines can support connections. ,40%](img/people/visualgrouping.png)
+]
+---
+# But not too many groups!
+
+[Hick's law](https://en.wikipedia.org/wiki/Hick%27s_law): Reaction
+ time (RT) is logarithmically related to the number of options
+ .jax[$$RT = T * log_2(n+1)$$]
+
+ - in other words people use *binary search*
+ - Assumes there is a logic to the ordering (worse when random)
+
+ - General case: Information foraging theory (Pirolli & Card)
+
+---
+# Design Tip #11: Minimize the number of options
+
+With every additional choice the time it will take
+ more time for  selection
+
+
+---
+# How much can a person remember?
+
+Short term (working memory)
+- Famous 7 +/- 2 “chunks” (Somewhat outdated model)
+ - 2461827176
+ - YBEAMBIMGC
+
+---
+# How much can a person remember?
+
+Short term (working memory)
+- Famous 7 +/- 2 “chunks” (Somewhat outdated model)
+ - 2461827176 vs (412) 268-1776
+ - YBEAMBIMGC vs EBAY IBM GMC
+
+---
+# Chunking in practice
+
+![:img 4 different example ribbons from microsoft demonstrating
+chunking of related functions, 70%](img/people/chunking.png)
+---
+
+# How much can a person remember?
+
+Short term (working memory)
+- Famous 7 +/- 2 “chunks” (Somewhat outdated model)
+- Basically: “very limited” and “decays quickly”
+- Has become “worse” with constant multitasking
+
+--
+Long term
+- Essentially unbounded
+- But requires effort & may not always work on cue
+- Can’t explicitly forget! Even though you try!
+---
+# How much can a person remember?
+
+Short term
+- 7 +/- 2 "chunks" (or less); decays quickly
+
+Long term
+- Essentially unbounded, but slower
+
+Novice / expert differences
+-  Experts have learned items in long term memory to draw on, novices don’t
+
+---
+# Design Tip #12: Rely on Recognition rather than Recall
+.right-column[
+Cannot count on memory to be there, or be fast!
+
+- Generally better to rely on recognition (seeing it in front of you)
+than just recall (having to pull it out of long term memory)
+
+-  But note that having the ability to operate from recognition does
+not preclude recall
+]
+.left-column[
+![:img Example of printer dialog with image of printed page at top
+right illustrating impact of settings and thus supporting recognition,
+110%](img/people/recognition.png)
+]
+---
+# Recap of Design Tips for Vision
+
+- #1: Don't rely on blue for small objects
+- #2: Don't rely on blue for older users
+- #3: Make sure that contrast is high enough
+- #4:  Minimize saturated colors
+- #5: Use redundant cues
+- #6: Make things distinct
+- #7: Use small multiples
+- #8: Manage expectations if you can't change response time
+- #9: Replace subtle changes with obvious ones
+- #10: Use well-tested visual grouping strategies
+- #11: Minimize the number of options
+- #12: Rely on recognition rather than recall
+
+---
+# Summary
+
+Human Physiology drives design
+- Number of colors
+- Pixel size (retina displays)
+
+Good design is accessible design
+
+- There is tons to know about good use of color and other visual
+design elements. For not, the simplest thing to do is to look for existing color palettes, and just those. That should account for the vast majority of your needs for colors. There is also red-green color blindness too. Simplest thing to do is to turn your screens into greyscale, and see if you can see differences.
+
+---
+# End of deck (unused slides past here)
+---
+# Demonstrate your Understanding of HSV
+
+You have been asked to create a digital-paper compatible interface. As
+a result, you need to pick colors that will be easily distinguishable
+in black and white. Which of 'H' 'S' and 'V' should you vary to
+support black and white display?
+
+Which is correct?
+- A: Hue
+- B: Saturation
+- C: Value
+
+???
+C Value
+
+---
+
+# Aside: Color Gamuts<sup>1</sup>
+
+![:youtube Explanation of color gamuts,8y9yENEdtG4]
+
+.footnote[
+<sup>1</sup>
+See the [Wikipedia page on color
+gamuts](http://en.wikipedia.org/wiki/Gamut) for more information]
+
+???
+- no time to play video
+- Outside is wavelengths (hues)
+- Triangle shows primary colors for this gamut
+---
diff --git a/slides/wk03/examlet.html b/slides/wk03/examlet.html
new file mode 100644
index 0000000000000000000000000000000000000000..5e865cfd2d80d936f639bd9839237df380066821
--- /dev/null
+++ b/slides/wk03/examlet.html
@@ -0,0 +1,20 @@
+---
+layout: presentation
+title: AMA/Examlet
+description: Review, then assessment.
+---
+
+# On Tap for today
+
+Part 1: Review on anything up to 4/9 (25 minutes)
+
+Part 2: Our Examlet. (25 minutes)
+  - The examlet will open at 10:55 - 25 minutes into class.
+  - The expectation is that everyone that is in our timezone (PDT) or close to PDT would take this before the end of class.  I have
+  spoken to the students I know are not in this time zone separately
+  - You should start right away as you would in a traditional classroom and not wait around.
+  - We will be checking to see that everyone has taken it by 11:45am
+  - You will not need to stay on Zoom to take the assessment. However we will stay in the classroom session in case you have questions about the format etc.
+  - This should be about 20 minutes, but you will have a buffer to 25 minutes to ensure that everyone can submit on time.
+  - If you have problems with any of the technology you MUST get in touch with the course staff immediately.
+  - You may use your notes, the website, take a look at your code, etc, but *you may not collaborate with others on the exam*.
diff --git a/slides/wk03/img/layout-algorithm/android-linear.png b/slides/wk03/img/layout-algorithm/android-linear.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b252da67203bb2e57a21a65c2b442d1e7e14a9d
Binary files /dev/null and b/slides/wk03/img/layout-algorithm/android-linear.png differ
diff --git a/slides/wk03/img/layout-algorithm/bad-layout.jpg b/slides/wk03/img/layout-algorithm/bad-layout.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..55cf47438eb8cae311aa26180659dbc9d7975f50
Binary files /dev/null and b/slides/wk03/img/layout-algorithm/bad-layout.jpg differ
diff --git a/slides/wk03/img/layout-algorithm/badLayout.png b/slides/wk03/img/layout-algorithm/badLayout.png
new file mode 100644
index 0000000000000000000000000000000000000000..1272a6dab0bd83e82e70988038b0ca788e522d15
Binary files /dev/null and b/slides/wk03/img/layout-algorithm/badLayout.png differ
diff --git a/slides/wk03/img/layout-algorithm/constraints.png b/slides/wk03/img/layout-algorithm/constraints.png
new file mode 100644
index 0000000000000000000000000000000000000000..78898ddb4fc866d46c7981a84778ddd14ebdd44b
Binary files /dev/null and b/slides/wk03/img/layout-algorithm/constraints.png differ
diff --git a/slides/wk03/img/layout-algorithm/goodLayout.png b/slides/wk03/img/layout-algorithm/goodLayout.png
new file mode 100644
index 0000000000000000000000000000000000000000..ad8b0eee3f09ef6e9fa90147d74456ad290929de
Binary files /dev/null and b/slides/wk03/img/layout-algorithm/goodLayout.png differ
diff --git a/slides/wk03/img/layout-algorithm/pinterest-android.jpg b/slides/wk03/img/layout-algorithm/pinterest-android.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3c36582648b9294fa1bfbbaf56f7f0f9fcc8d670
Binary files /dev/null and b/slides/wk03/img/layout-algorithm/pinterest-android.jpg differ
diff --git a/slides/wk03/img/layout-algorithm/quiz1.png b/slides/wk03/img/layout-algorithm/quiz1.png
new file mode 100644
index 0000000000000000000000000000000000000000..80e63bddd1e58cee348d0f8bff3c241b688745ec
Binary files /dev/null and b/slides/wk03/img/layout-algorithm/quiz1.png differ
diff --git a/slides/wk03/img/layout-algorithm/quiz2.png b/slides/wk03/img/layout-algorithm/quiz2.png
new file mode 100644
index 0000000000000000000000000000000000000000..024ddbdd8c6f8a519caa3ab8ac5908c24fd27166
Binary files /dev/null and b/slides/wk03/img/layout-algorithm/quiz2.png differ
diff --git a/slides/wk03/img/layout-algorithm/trylayout.png b/slides/wk03/img/layout-algorithm/trylayout.png
new file mode 100644
index 0000000000000000000000000000000000000000..d001b208ec53f2c7ece0a3aaf50adffe8a453125
Binary files /dev/null and b/slides/wk03/img/layout-algorithm/trylayout.png differ
diff --git a/slides/wk03/img/layout-algorithm/watch3.png b/slides/wk03/img/layout-algorithm/watch3.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce7134c4b0c57883931335e40fef086a366e7294
Binary files /dev/null and b/slides/wk03/img/layout-algorithm/watch3.png differ
diff --git a/slides/wk03/img/layout-algorithm/worseLayout.png b/slides/wk03/img/layout-algorithm/worseLayout.png
new file mode 100644
index 0000000000000000000000000000000000000000..b94189d6c98f546d08d4aced03c7dfaf972e34a1
Binary files /dev/null and b/slides/wk03/img/layout-algorithm/worseLayout.png differ
diff --git a/slides/wk03/img/layout-ii/constraint-editor.png b/slides/wk03/img/layout-ii/constraint-editor.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb898264dbb375ea8f1fe36aa38180cf76f5ceee
Binary files /dev/null and b/slides/wk03/img/layout-ii/constraint-editor.png differ
diff --git a/slides/wk03/img/layout-ii/constraints.png b/slides/wk03/img/layout-ii/constraints.png
new file mode 100644
index 0000000000000000000000000000000000000000..78898ddb4fc866d46c7981a84778ddd14ebdd44b
Binary files /dev/null and b/slides/wk03/img/layout-ii/constraints.png differ
diff --git a/slides/wk03/img/layout-ii/design-view.png b/slides/wk03/img/layout-ii/design-view.png
new file mode 100644
index 0000000000000000000000000000000000000000..76f63830d1dbd0e0388c6ce7f57bd2b3d7618db9
Binary files /dev/null and b/slides/wk03/img/layout-ii/design-view.png differ
diff --git a/slides/wk03/img/layout-ii/explore-devices.png b/slides/wk03/img/layout-ii/explore-devices.png
new file mode 100644
index 0000000000000000000000000000000000000000..f226288d9e058fef8b2b28d1f9836d908661407a
Binary files /dev/null and b/slides/wk03/img/layout-ii/explore-devices.png differ
diff --git a/slides/wk03/img/layout-ii/fixed.png b/slides/wk03/img/layout-ii/fixed.png
new file mode 100644
index 0000000000000000000000000000000000000000..412bad473f486a9178681db203cbae918e767c56
Binary files /dev/null and b/slides/wk03/img/layout-ii/fixed.png differ
diff --git a/slides/wk03/img/layout-ii/layoutparams.png b/slides/wk03/img/layout-ii/layoutparams.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e80c2fef10e2de5d5b0691481112a8dc323744f
Binary files /dev/null and b/slides/wk03/img/layout-ii/layoutparams.png differ
diff --git a/slides/wk03/img/layout-ii/layouttoolbar.png b/slides/wk03/img/layout-ii/layouttoolbar.png
new file mode 100644
index 0000000000000000000000000000000000000000..be73a95c45ee9ec84379257721b63951c60e7f2f
Binary files /dev/null and b/slides/wk03/img/layout-ii/layouttoolbar.png differ
diff --git a/slides/wk03/img/layout-ii/linearlayout.png b/slides/wk03/img/layout-ii/linearlayout.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab3d68b83b6c5a7cb915ab87c6c75cfb4b952864
Binary files /dev/null and b/slides/wk03/img/layout-ii/linearlayout.png differ
diff --git a/slides/wk03/img/layout-ii/match.png b/slides/wk03/img/layout-ii/match.png
new file mode 100644
index 0000000000000000000000000000000000000000..96fdca857d70a2ecd6c7f3e4e2b1e2493865cd10
Binary files /dev/null and b/slides/wk03/img/layout-ii/match.png differ
diff --git a/slides/wk03/img/layout-ii/modern-yahoo.png b/slides/wk03/img/layout-ii/modern-yahoo.png
new file mode 100644
index 0000000000000000000000000000000000000000..0760609a794ec4c1a2797bdbfd5d5190fc9723da
Binary files /dev/null and b/slides/wk03/img/layout-ii/modern-yahoo.png differ
diff --git a/slides/wk03/img/layout-ii/part1-diagram.png b/slides/wk03/img/layout-ii/part1-diagram.png
new file mode 100644
index 0000000000000000000000000000000000000000..d35a62e29abba453847a525fc4eba2956e1d34d2
Binary files /dev/null and b/slides/wk03/img/layout-ii/part1-diagram.png differ
diff --git a/slides/wk03/img/layout-ii/spottheheron-prototype.png b/slides/wk03/img/layout-ii/spottheheron-prototype.png
new file mode 100644
index 0000000000000000000000000000000000000000..240a67f5cbb7a18f176a778be692c4e09d26ec7f
Binary files /dev/null and b/slides/wk03/img/layout-ii/spottheheron-prototype.png differ
diff --git a/slides/wk03/img/layout-ii/spottheheron-wireframe.png b/slides/wk03/img/layout-ii/spottheheron-wireframe.png
new file mode 100644
index 0000000000000000000000000000000000000000..f54d313eb11c98a26d1dc0d1b855b902bbe1b875
Binary files /dev/null and b/slides/wk03/img/layout-ii/spottheheron-wireframe.png differ
diff --git a/slides/wk03/img/layout-ii/text-view.png b/slides/wk03/img/layout-ii/text-view.png
new file mode 100644
index 0000000000000000000000000000000000000000..1d49a12ee182cd49abf523f77607b1f62b181c73
Binary files /dev/null and b/slides/wk03/img/layout-ii/text-view.png differ
diff --git a/slides/wk03/img/layout-ii/watch.png b/slides/wk03/img/layout-ii/watch.png
new file mode 100644
index 0000000000000000000000000000000000000000..44b8d98d37b56d24272f42df63a5ae6cb3d40700
Binary files /dev/null and b/slides/wk03/img/layout-ii/watch.png differ
diff --git a/slides/wk03/img/layout-ii/watch3.png b/slides/wk03/img/layout-ii/watch3.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce7134c4b0c57883931335e40fef086a366e7294
Binary files /dev/null and b/slides/wk03/img/layout-ii/watch3.png differ
diff --git a/slides/wk03/img/layout-ii/wrap.png b/slides/wk03/img/layout-ii/wrap.png
new file mode 100644
index 0000000000000000000000000000000000000000..6cc11d6b590c7545445ea02762584ac07f51d6af
Binary files /dev/null and b/slides/wk03/img/layout-ii/wrap.png differ
diff --git a/slides/wk03/img/layout-ii/xml-files.png b/slides/wk03/img/layout-ii/xml-files.png
new file mode 100644
index 0000000000000000000000000000000000000000..97e22458b2bb3db69d909a66b8df2e0b0e32a16a
Binary files /dev/null and b/slides/wk03/img/layout-ii/xml-files.png differ
diff --git a/slides/wk03/layout-algorithm.html b/slides/wk03/layout-algorithm.html
new file mode 100644
index 0000000000000000000000000000000000000000..1861944f3761e789c63e121e82e238474720e642
--- /dev/null
+++ b/slides/wk03/layout-algorithm.html
@@ -0,0 +1,800 @@
+---
+layout: presentation
+title: Layout Algorithms
+description: Introduction the implementation of layout
+class: middle, center, inverse
+---
+
+# Hall of Fame or Hall of Shame?
+
+.left-column-half[
+Think about those Visual Design Tips!
+
+![:img Picture of two layouts with very small areas for interaction or images that are too small to see, 60%](img/layout-algorithm/bad-layout.jpg)
+]
+
+.right-column-half[
+
+- #1: Don't rely on blue for small objects
+- #2: Don't rely on blue for older users
+- #3: Make sure that contrast is high enough
+- #4:  Minimize saturated colors
+- #5: Use redundant cues
+- #6: Make things distinct
+- #7: Use small multiples
+- #8: Manage expectations if you can't change response time
+- #9: Replace subtle changes with obvious ones
+- #10: Use well-tested visual grouping strategies
+- #11: Minimize the number of options
+- #12: Rely on recognition rather than recall
+]
+
+---
+
+# What went wrong?
+.left-column50[![:img File browser with toolbar, 90%](img/layout-algorithm/goodLayout.png)]
+.right-column50[![:img File browser with only half of same toolbar, 80%](img/layout-algorithm/badLayout.png)]
+
+???
+- Changing available space e.g., window resized by user
+- Changing sizes, fonts, etc.
+- Adding and removing components
+- Layout mechanism has to deal with all cases
+---
+# What went wrong?
+![:img File browser with only half of same toolbar, 80%](img/layout-algorithm/worseLayout.png)
+
+???
+- No scroll bar for text boxes that are too narrow
+- No way to redistribute space between directory & file list
+- Important controls (e.g., Open) get hidden
+- Min size is much too small
+- No way to send the dialog away (buttons gone)
+
+
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+
+# Layout Algorithms
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+
+---
+name: normal
+layout: true
+class:
+
+---
+layout: false
+
+[//]: # (Outline Slide)
+# Goals for today
+- __Review__
+- How layout is implemented in the toolkit
+
+---
+# Review: XML Inflation
+
+
+Inflation in `MainActivity#onCreate(Bundle)`:
+```java
+// contents is the ScrollView
+contents.addView(getLayoutInflater().inflate(R.layout.part1solution, null), PARAMS);
+```
+
+To break this down, recall that `MainActivity` inherits (indirectly) from  `Context`
+```java
+LayoutInflater inflater = getLayoutInflater();         // ask the Context for the inflater
+View newView = inflater.inflate(R.layout.part1, null); // newView is at the root of the inflated tree
+contents.addView(newView, PARAMS);                     // attach the newView to the parent
+```
+
+In a View (in say `Part3View.java`) get the inflater this way:
+```java
+LayoutInflater inflater = LayoutInflater.from(context); // Use a static method to get the inflater
+// The rest is the similar
+```
+???
+Remind that you can inflate once but use many times
+
+---
+# Review: Adding Programatically
+
+Adding a view programatically in `MainActivity` broken down in steps
+1. The LayoutParams are created
+2. The new view is created
+3. Use [ViewGroup#addView(View, ViewGroup.LayoutParams)](https://developer.android.com/reference/android/view/ViewGroup#addView%28android.view.View,%20android.view.ViewGroup.LayoutParams%29)
+method on the parent to add it to the Interactor Hierarchy (with the params)
+
+```java
+public static final RelativeLayout.LayoutParams PARAMS = new RelativeLayout.LayoutParams(
+            RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
+....
+Part2View p2v = new Part2View(this, getImageStrings(), vMargin);
+contents.addView(p2v, PARAMS);
+```
+---
+# Review: Adding Programatically
+
+A slightly different way:
+1. Create the new view
+2. Add it to the parent using [ViewGroup#addView(View)](https://developer.android.com/reference/android/view/ViewGroup#addView%28android.view.View%29)
+3. Set up the LayoutParams
+4. Add the LayoutParams to the view
+
+```java
+public static final RelativeLayout.LayoutParams PARAMS = new RelativeLayout.LayoutParams(
+            RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
+...
+Part2View p2v = new new Part2View(this, getImageStrings(), vMargin);
+contents.addView(p2v);
+// Add more setup for the params if needed.
+contents.setLayoutParams(PARAMS);
+```
+
+---
+# Solutions to [LayoutLab](https://github.com/harshitha-akkaraju/layoutlab)
+
+Don't peek until you've tried it :)
+
+- [Inflation](https://github.com/harshitha-akkaraju/layoutlab/blob/complete/app/src/main/res/layout/activity_main.xml)
+- [Programatically](https://github.com/harshitha-akkaraju/layoutlab/blob/complete/app/src/main/java/com/harshiakkaraju/layoutlab/ProgrammaticConstraints.java)
+
+---
+# Aside: changing properties dynamically
+
+What if you canted to change background color of all of the buttons to red?
+
+
+```java
+for (int i = 0; i &lt; layout.getChildCount(); i++) {
+  view = layout.getChildAt(i);
+  view.setBackgroundColor(Color.RED);
+}
+```
+
+---
+# Reminder: Layout Types in Android
+
+- [FrameLayout](https://developer.android.com/reference/android/component/FrameLayout.html) - good for position views on
+top of each other, or encapsulating a bunch of views. Used in [Doodle](/assignments/doodle).
+
+- [__LinearLayout__](https://developer.android.com/reference/android/component/LinearLayout.html) - places views one after
+the other in order according to the orientation (Horizontal or Vertical). Used in [Layout](/assignments/layout).
+
+- [__RelativeLayout__](https://developer.android.com/reference/android/widget/RelativeLayout) - Positions of the children
+are desribed in relation to one another
+
+- [__TableLayout__](https://developer.android.com/reference/android/component/TableLayout.html) - Rows and columns style
+way of declaring a layout
+
+- [GridLayout](https://developer.android.com/reference/android/component/GridLayout.html) - Uses
+an [*adapter*](https://developer.android.com/reference/android/interactor/Adapter.html) that provides items to display in
+a grid
+
+- [ConstraintLayout](https://developer.android.com/reference/android/component/ConstraintLayout.html) Let's you use constraints to specify how things should lay out. Used in [Layout](/assignments/layout).
+
+
+- More on https://developer.android.com/guide/topics/ui/declaring-layout.html
+
+???
+
+Talk about different Toolkits may have different layouts.
+
+---
+
+# Layouts in Play
+
+.left-column-half[
+Which layouts are used in these apps?
+]
+.right-column-half[
+![:img Pinterest layout, 36%](img/layout-algorithm/pinterest-android.jpg)
+![:img Pinterest layout, 35%](img/layout-algorithm/android-linear.png)
+]
+
+--
+.left-column-half[
+Probably:
+- **LinearLayout**
+- **ConstraintLayout**
+
+Thinking about what layouts are in an app is part of your Part 4 of the Layout assignment.
+]
+
+---
+# General & Powerful Approach: Constraints
+
+General mechanism for establishing and maintaining relationships between things
+- Layout is one use
+- Several other uses in UI
+ - Connection of application to UI, e.g. deriving appearance from data
+ - Multiple views of same data
+ - Automated semantic feedback
+ - Automatic arrangement of lines (powerpoint snapping!)
+
+---
+layout: false
+
+## ConstraintLayout in Android
+
+.left-column[
+![:img A simple layout on an android watch with a textview and two
+buttons (save and discard) and the constraints highlighted,100%](img/layout-algorithm/watch3.png)
+]
+.right-column[
+- [ConstraintLayout](https://developer.android.com/reference/android/support/constraint/ConstraintLayout)
+  - Allows you to position widgets in a flexible way
+  - Useful for building **responsive** interfaces in Android.
+
+- You will be using ConstraintLayout for the Layout exercise
+
+- Review Monday's slides for more details
+]
+
+---
+layout: false
+
+[//]: # (Outline Slide)
+# Goals for today
+- Review
+- **How layout is implemented in the toolkit**
+
+---
+# Time to talk about position again
+
+.left-column-half[
+.quote[You have been asked to create a new `CircleView` object that can draw a circle in our
+`drawingView` object in Doodle. The user wants to add a circle so that the center point is at
+(100,100) on the drawingView and has a radius of (10). In `CircleView#onDraw(Canvas)` you will
+need to call `canvas.drawCircle(cx, cy, radius, paint)` (note that drawCircle takes the (x, y)
+location of the center of the circle as input). What values should you use for `cx` and `cy`
+in this your onDraw code?]
+]
+
+.right-column-half[
+![:img Quiz results showing that many people correctly selected 10 10 although some incorrectly selelected 100 100, 100%](img/layout-algorithm/quiz1.png)
+]
+
+---
+# Time to talk about position again
+.left-column-half[
+.quote[Consider the same CircleView object that contains a circle of radius 10 that we want to
+display in the drawingView so the center appears at `100, 100` in the parent view's coordinate system.
+How should we set up the bounding box for the `CircleView` so that its canvas will be correctly
+clipped? What are `x`, `y`, `width` and `height` for the bounding box (in parent coordinates?)]
+]
+.right-column-half[
+![:img Quiz results showing that many people correctly selected 90 90 20 20, 100%](img/layout-algorithm/quiz2.png)
+
+]
+
+---
+# Time to talk about position again
+
+.left-column-half[
+
+.quote[You have been asked to create a new `SquareView` object that can draw a square. The user
+  wants to add a square with its top left corner at (150,50) and a width of (20). In `SquareView.onDraw()`
+  you will need to call `canvas.drawRect(left, top, right, bottom, paint)` What values should
+  you use for `left` and `top`?
+]
+]
+???
+(0,0)
+--
+.right-column-half[
+`(0,0)`
+]
+---
+# Time to talk about position again
+.left-column-half[
+.quote[Consider the same square (at `150,50` with a width of `20` in its parent). How should we set
+up the bounding box for the `SquareView` so that its `Canvas` will be correctly clipped?
+What are `x`, `y`, `width` and `height` for the bounding box (in parent coordinates?)
+]
+]
+???
+(150,50,20,20)
+--
+.right-column-half[
+`(150,50,20,20)`
+]
+---
+# So: what have we learned?
+
+
+--
+When an interactor draws itself, its drawing area always starts at (0,0)
+
+The *View* that interactor is in (it's *parent*) determines the location of its bounding box. This is what correctly positions it!
+
+---
+# How does layout come into this?
+
+In Doodle you hard-coded the position of everything (or used animation to set it)
+
+But in most interfaces, we use *layout containers* to accomplish this.
+- Layout containers make decisions like "stack these views vertically" or "make them fit into this size area" and set their position and bounding box on this basis
+- The *toolkit architecture* then helps to enforce this
+
+---
+# How is position calculated by the toolkit architecture?
+.left-column-half[
+<br>
+<br>
+
+<div class="mermaid">
+graph TD
+W(ViewGroup) --> V[ViewGroup]
+W --> V1[View]
+W --> V2[View]
+V --> V3[View]
+V --> V4[View]
+V --> V5[View]
+
+classDef blue font-size:14pt,text-align:center
+classDef darkblue font-size:14pt,text-align:center
+
+class W,V darkblue
+class V1,V2,V3,V4,V5 blue
+</div>
+]
+.right-column-half[
+- The Component (Interactors + ViewGroups) Hierarchy in just about everything
+  - Draw and redraw
+  - Layout
+- Toolkit architecture invokes layout
+- Containers do the work
+  - Manage size and position of children
+  - Enforce component abstraction: Simple loop through child components --> Recursive tree traversal
+    - Translate child to correct location
+    - Clip child after drawing is complete
+  - Know how to handle resizing (reactive)
+
+]
+???
+- Parent knows how to setup for drawing of children, invoke their
+drawing code, and add additional output (before and/or after) based on
+what the parent is and its internal state
+
+- Whorfian effects (things not in the library are hard)
+
+- Nesting not well defined
+
+
+---
+# How do Container Components actually do layout?
+.left-column-half[
+<br>
+<br>
+
+<div class="mermaid">
+graph TD
+W(ViewGroup) --> V[ViewGroup]
+W --> V1[View]
+W --> V2[View]
+V --> V3[View]
+V --> V4[View]
+V --> V5[View]
+
+classDef blue font-size:14pt,text-align:center
+classDef darkblue font-size:14pt,text-align:center
+
+class W,V darkblue
+class V1,V2,V3,V4,V5 blue
+</div>
+]
+.right-column-half[
+Key Issues:
+- Where do components get placed?
+- How much space should they occupy?
+- How should components to react to changes?
+  - number of components
+  - size of window
+- Who should get to decide children's sizes? parents or children?
+  - Should it be a top down vs bottom up approach
+  - Depth first tree traversal
+]
+---
+# Simplest possible layout implementation (similar to what is in Frame layout)
+
+Depth first tree traversal
+
+No consideration of child size or position in doing layout
+
+Simplified from
+FrameLayout
+[source
+code](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/FrameLayout.java),
+[View](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/View.java)
+and [ViewGroup](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewGroup.java)
+
+```java
+protected void onLayout(boolean changed, int l, int t, int r, int b) {
+    foreach child c {
+        if (child.isVisible()) {
+             Rectangle r = child.getLayoutParams();
+             childLeft = padding + r.x;
+             childTop = padding + r.y;
+             child.layout(childLeft, childTop, r.w, r.h);
+        }
+    }
+}
+```
+???
+we're ignoring the implementation of gravity here
+
+remind them what protected means?
+
+---
+# Generalized implementation of layout
+Details of most else, and two-pass process, handled in [View](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/View.java)
+and [ViewGroup](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewGroup.java)
+
+```java
+// Second: do the actual updating
+public void layout(Rectangle newBounds) {
+   onMeasure() // measure myself; this is recursive
+   onLayout()  // again; recursive. Makes use of calculated measurements
+}
+```
+
+---
+.left-column[
+# Measuring
+]
+.right-column[
+`onMeasure()` is a callback* invoked by `View.measure()`
+]
+.footnote[We'll be talking more about callbacks when we talk about events]
+
+--
+.right-column[
+Object is given guidance about the size is given from parent view in the form of `MeasureSpec` parameters
+]
+--
+.right-column[
+`onMeasure` ensures every view has a width and height value set prior to a layout pass
+]
+--
+
+.right-column[
+Note: You must manually take padding into account (subtract padding
+from the width/height dimensions)
+]
+
+---
+.left-column[
+# Best toolkits let child specify
+]
+.right-column[
+Size (based on nature of component (think TextBox vs Button vs LinearLayout)
+- preferred size
+- minimum size
+- maximum size
+
+Parent gets to ignore all of that, but usually tries not to. Someone has to be in charge; it's the parents (my kids hate that! :)
+- Usually tries to give each child as much as possible & divide up the remainder proportionally
+- However, child component has to deal if not enough (i.e. truncate text)
+]
+
+---
+# Reference Implementation of onMeasure
+
+```java
+// First: Measure everything
+protected void onMeasure(int widthspec, int heightspec) {
+  // loop through children in order they were added
+  foreach child {
+    // get child's preferred layout size
+	onMeasure()
+	// story relevant information & do calculations about
+	// the container size
+  }
+  // based on all that, update our dimensions
+  setMeasuredDimension()
+}
+```
+
+Why does a container need to know about its kids' sizes to measure itself?
+
+???
+
+Example: it might need to be big enough to fit them all (LinearLayout)
+
+---
+# Aside `ImageView` height:
+
+- What is it's height before layout is done? Unknown!
+- But you need it in Part3 to decide where to put it
+ - You haven't added it to the interactor hierarchy yet
+ - How do you get height?
+
+--
+
+Call `image.measure()` (you'll have to think about what the right parameters are)
+
+Then call `image.getMeasuredHeight()` (why not `image.getHeight()`?)
+
+--
+
+Because it's 0! Since this image isn't laid out.
+
+---
+# Frame layout -- actual implementation (slightly simplified)
+
+```java
+protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec {
+   // recursively calculate size of children
+   foreach child  {
+     // ... calculate max child width and max child height
+     maxWidth = Math.max(maxWidth, child.getMeasuredWidth() // +  margins);
+     maxHeight = ...
+   }
+   // ... add in padding
+   setMeasuredDimension(... based on what was found)
+   // now recursively set dimensions for all children
+
+   foreach child {
+       final View child = getChildAt(i);
+       child.measure(childWidthMeasureSpec, childHeightMeasureSpec); // recursion through callback
+   }
+}
+```
+???
+How would we do this for linearLayout?
+
+---
+# Generalized implementation of layout
+Details of most else, and two-pass process, handled in [View](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/View.java)
+and [ViewGroup](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewGroup.java)
+
+```java
+// Second: do the actual updating
+public void layout(Rectangle newBounds) {
+   onMeasure() // measure myself; this is recursive
+   onLayout()  // again; recursive. Makes use of calculated measurements
+}
+```
+
+---
+.left-column[
+# Layout
+]
+.right-column[
+`onLayout()` is a callback triggered when a view's position is changed
+]
+--
+.right-column[
+Gives the new position __relative__ to the parent
+]
+--
+.right-column[
+Causes a layout call on all children (!)
+]
+
+---
+# Reference implementation of onLayout
+
+```java
+// a layout class should override onLayout.
+protected void onLayout(boolean changed, int l, int t, int r, int b) {
+   // recursively calls layout on each child
+   foreach child {
+       LayoutParams lp = child.getLayoutParams();
+	   // calculate the width and height of the kids
+       int width = calculated width
+       int height = calculated height
+	   // calculate the position of kids
+       int childLeft = calculated position
+	   int childTop = calculated position
+       child.layout(childLeft, childTop, childLeft + width, childTop + height);
+   }
+}
+```
+???
+
+What might we use for left/top/width/height
+- in FrameLayout?
+- in LinearLayout?
+
+---
+# How would LinearLayout calculate these?
+This is just setting the bounding box!
+What is child *n*'s position? Width? Height?
+- need to know we are vertical
+- can decide to set our width entirely based on kids
+- we get to decide position
+
+---
+# Generalized implementation of onLayout
+
+When is this called?
+
+???
+- Whenever the interface is *damaged* (call `invalidate(true)` to force this)
+- Before the recursive `drawAll()` function we talked about last week. **Why?**
+
+
+--
+- Whenever the interface is *damaged* (call `invalidate(true)` to force this)
+- Before the recursive `drawAll()` function we talked about last week. **Why?**
+
+
+???
+Because `drawAll()` needs to know where interactors are to properly *translate* and *clip* before calling `onDraw()` on each of them
+
+--
+
+ - Because `drawAll()` needs to know where interactors are to properly *translate* and *clip* before calling `onDraw()` on each of them
+
+---
+# How does this relate to drawing?
+.left-column-half[
+<br>
+<br>
+
+<div class="mermaid">
+graph TD
+W(ViewGroup) --> V[ViewGroup]
+W --> V1[View]
+W --> V2[View]
+V --> V3[View]
+V --> V4[View]
+V --> V5[View]
+
+classDef blue font-size:14pt,text-align:center
+classDef darkblue font-size:14pt,text-align:center
+
+
+class W,V darkblue
+class V1,V2,V3,V4,V5 blue
+</div>
+]
+.right-column-half[
+*After* measuring & layout:
+
+__Tree traversal__ may be done on the layout hierarchy. Order depends on the specific layout algorithm (constraints don't require any!)
+]
+
+--
+.right-column-half[
+Each view is responsible for drawing itself
+]
+--
+.right-column-half[
+Siblings are drawn in the order that they appear
+]
+---
+.left-column[
+# When to (re)Draw?
+]
+.right-column[
+Drawing is costly- (e.g. frame rates dropping for scrolling interactions)
+]
+--
+.right-column[
+Often the screen is static
+]
+--
+.right-column[
+We should *draw when we need to*
+]
+
+--
+.right-column[
+Re-drawing "damaged" areas: call `invalidate()`
+]
+---
+.left-column[
+# Summary of the Drawing Process
+]
+.right-column[
+1) Android calls measure on root node (view)
+```java
+// View specifies size of self
+protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec);
+```
+]
+---
+.left-column[
+# Summary of the Drawing Process
+]
+.right-column[
+1) Android calls measure on root node (view)
+```java
+// View specifies size of self
+protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec);
+```
+2) Android calls layout on view
+```java
+// View specifies size and position of children
+protected void onLayout(boolean changed, int left, int top, int right, int bottom);
+```
+]
+---
+.left-column[
+# Summary of the Drawing Process
+]
+.right-column[
+1) Android calls measure on root node (view)
+```java
+// View specifies size of self
+protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec);
+```
+2) Android calls layout on view
+```java
+// View specifies size and position of children
+protected void onLayout(boolean changed, int left, int top, int right, int bottom);
+```
+3) Android calls draw on view
+```java
+// Add the drawing happens
+protected void onDraw(Canvas canvas);
+```
+]
+---
+# What of this do *you* need to do
+
+- If you are creating an interface, none of it
+ - Just use the layouts
+- If you are creating a new type of layout class
+ - It depends
+ - If you can manage layout entirely by specifying
+   an interactor hierarchy with layout params that do what you want, you are golden (our assignment)
+- If you want to do something entirely new (lay out images in a spiral for example) you have to override `onLayout()` or `onMeasure()` or both (not assigned)
+---
+# End of deck
+
+---
+#Conceptual form of UI constraints
+
+``` java
+// this is 5 pixels to the right of that
+this.x = that.x + that.w + 5
+// this is centered
+this.x = that.x + that.w/2 - this.w/2
+// this is 10 larger than children
+this.w = 10 + max_child().x + max_child().w
+```
+
+---
+# Frame layout -- actual implementation (slightly simplified)
+
+Simplified from
+FrameLayout
+[source
+code](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/FrameLayout.java),
+[View](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/View.java)
+and [ViewGroup](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewGroup.java)
+```java
+// this is implemented in view
+public void layout(int l, int t, int r, int b) {
+  // first make sure everything has a size (recursively)
+  onMeasure()
+  // then do layout
+  onLayout(changed, left, top, right, bottom)
+}
+
+// a layout class should override onLayout. In FrameLayout
+protected void onLayout(boolean changed, int l, int t, int r, int b) {
+   // recursively calls layout on each child
+   foreach child {
+       LayoutParams lp = child.getLayoutParams();
+       int width = child.getMeasuredWidth();
+       int height = child.getMeasuredHeight();
+       int childLeft = parentLeft + lp.leftPadding; // add padding
+       int childTop = parentTop + lp.topPadding; // add padding
+       child.layout(childLeft, childTop, childLeft + width, childTop + height);   // recursion through callback
+   }
+}
+```
+???
+Traverses the hierarchy many times over as implemented
+Can try to be more efficient or give more control... tradeoffs
diff --git a/slides/wk03/layout-ii.html b/slides/wk03/layout-ii.html
new file mode 100644
index 0000000000000000000000000000000000000000..1945cd1068cf3855f404cb2951a27b4e1fe1db15
--- /dev/null
+++ b/slides/wk03/layout-ii.html
@@ -0,0 +1,641 @@
+---
+layout: presentation
+title: Layout II - More on Android Layout
+description: Layout II - the details
+class: middle, center, inverse
+---
+
+<iframe src="https://embed.polleverywhere.com/multiple_choice_polls/cnO00FYxqbWSpDfHzx2PM?controls=none&short_poll=true" width="800" height="600" frameBorder="0"></iframe>
+
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+
+# Layout II - More on Android Layout
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+
+---
+name: normal
+layout: true
+class:
+
+---
+
+[//]: # (Outline Slide)
+# Today's goals
+- Announcements
+  - Peer reviews technically due Tuesday, please do them early
+  - Reflection due Wednesday (no late days)
+  - Layout 1-2 due Friday (no late days)
+- Specifying Layout in XML
+- Inflation
+- Laying out views programatically
+- Wednesday we will talk about the theory behind layout.
+
+
+---
+# Why do we need layout?
+.left-column60[
+![:img Yahoo in 1996 with no layout other than centering, 40%](http://blogoscoped.com/files/yahoo-1996-large.png)&nbsp;&nbsp;![:img screen capture of modern yahoo  with blocks laying out different news articles, 50%](img/layout-ii/modern-yahoo.png)
+]
+
+.right-column30[
+- Visual appeal
+- Organization (think about Properties of People Design tip #10: Use well-tested visual grouping strategies)
+]
+
+---
+# Reminder: User Interfaces on Android
+.left-column-half[
+- Views
+  - Base class for __all__ UI elements
+  - Interactors (e.g buttons, labels, image views, etc)
+- ViewGroups
+  - Encapsulates one or more views (e.g. Android Components, **Layouts**)
+  - Can define specific **layout** properties
+
+ We will use the word *Components* to include both layout components and interactors (Views) since you
+ don't generally "interact" with layouts
+]
+.right-column-half[
+<div class="mermaid">
+graph TD
+W(ViewGroup) --> V[ViewGroup]
+W --> V1[View]
+W --> V2[View]
+V --> V3[View]
+V --> V4[View]
+V --> V5[View]
+
+classDef blue font-size:14pt,text-align:center
+classDef darkblue font-size:14pt,text-align:center
+
+class W,V darkblue
+class V1,V2,V3,V4,V5 blue
+</div>
+
+]
+
+---
+# Layout in Android
+Where we left off: "Many layout and other attributes for components. You should explore!"
+
+![:img Picture of the whole android layout interface showing the possible components that can be added; the component tree (interactor hierarchy; and the attributes for the Save Button; which is selected, 90%](img/layout-ii/design-view.png)
+
+???
+Talk about how there's many layout and other attributes for components that they should explore!
+
+---
+# Layout Types in Android
+
+- [FrameLayout](https://developer.android.com/reference/android/component/FrameLayout.html) - good for position views on
+top of each other, or encapsulating a bunch of views. Used in [Doodle](/assignments/doodle).
+
+- [__LinearLayout__](https://developer.android.com/reference/android/component/LinearLayout.html) - places views one after
+the other in order according to the orientation (Horizontal or Vertical). Used in [Layout](/assignments/layout).
+
+- [__RelativeLayout__](https://developer.android.com/reference/android/widget/RelativeLayout) - Positions of the children
+are desribed in relation to one another
+
+- [__TableLayout__](https://developer.android.com/reference/android/component/TableLayout.html) - Rows and columns style
+way of declaring a layout
+
+- [GridLayout](https://developer.android.com/reference/android/component/GridLayout.html) - Uses
+an [*adapter*](https://developer.android.com/reference/android/interactor/Adapter.html) that provides items to display in
+a grid
+
+- [ConstraintLayout](https://developer.android.com/reference/android/component/ConstraintLayout.html) Let's you use constraints to specify how things should lay out. Used in [Layout](/assignments/layout).
+
+
+- More on https://developer.android.com/guide/topics/ui/declaring-layout.html
+
+???
+
+We'll talk more about Constraint layouts later
+
+
+---
+.left-column[
+## Example: Linear Layout of Email
+
+[Linear Layout Tutorial](https://developer.android.com/guide/topics/ui/layout/linear)
+
+![:img Linear layout of an email message with to line subject line and message arranged vertically, 100%](img/layout-ii/linearlayout.png)
+
+]
+
+.right-column[
+
+```xml
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingLeft="16dp"
+    android:paddingRight="16dp"
+    android:orientation="vertical" &gt;
+  &lt;EditText
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:hint="@string/to" /&gt;
+  &lt;EditText
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:hint="@string/subject" /&gt;
+  &lt;EditText
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:gravity="top"
+        android:hint="@string/message" /&gt;
+  &lt;Button
+        android:layout_width="100dp"
+        android:layout_height="wrap_content"
+        android:layout_gravity="right"
+        android:text="@string/send" /&gt;
+&lt;/LinearLayout&gt;
+```
+
+]
+
+
+???
+Can implement all of the things we discussed earlier using constraints
+
+note that they can be hard to debug?
+
+Discussion of specific inheritance hierarchy for constraints
+
+- Only have to write once when we use classes properly
+- can mix and match things
+
+
+
+---
+# Layout in Android
+- The Layout XML View completely specifies what was in the GUI (and vice versa)
+- Get to it by clicking 'Text' (next to 'Design')
+
+.left-column-half[
+![:img Picture of the  android layout interface showing the xml which completely specifies what was in the other image,45%](img/layout-ii/text-view.png)&nbsp;
+![:img A simple layout on an android watch with a textview and two buttons (save and discard),50%](img/layout-ii/watch.png)
+]
+
+.right-column-half[
+
+```xml
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;-...-&gt;
+&lt;TextView
+&lt;-...-&gt;
+&lt;LinearLayout
+   &lt;-...-&gt;
+   &lt;Button
+      android:id="@+id/button"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:text="@string/Save" /&gt;
+      &lt;-...-&gt;
+&lt;/LinearLayout&gt;
+```
+
+]
+
+???
+What examples do we have here?
+- Layout container (linearlayout)
+- Spacer
+- springiness
+- struts
+- constraints
+
+---
+# More about XML and Android
+.left-column[
+![:img Picture of the android ide file system with an xml file inside of res highlighted, 70%](img/layout-ii/xml-files.png)
+]
+.right-column[
+
+Android has XML, where all sorts of static properties can be specified
+
+Every Android app has a `layout` directory and a `values` directory and several others. We'll use these in this assignment
+
+In XML you can set variables that we can access later in XML or code
+- In XML access a value (such as  `vMargin` from our assignment) using `@(file name)/(value name)`
+, where the file name is a file somewhere in `res` and the value name is an xml value found in that file.  i.e., for `vMargin`, you can use  `"@dimen/vMargin"`
+- In code, you refer to that value by `R.(file name).(value name)`
+
+]
+
+---
+# The importance of ID
+
+.left-column-half[
+In `MainActivity.java` for Layout
+```java
+// Set window contents based on selected item.
+*switch (item.getItemId()) {
+*  case R.id.action_part_1:
+*    setCurrentTabId(R.id.action_part_1);
+     contents.addView(getLayoutInflater().inflate(R.layout.part1, null), PARAMS); // params here is a set of layout paramaters for this view
+     return true;
+*  case R.id.action_part_2:
+*    setCurrentTabId(R.id.action_part_2);
+     contents.addView(new Part2View(this, getImageStrings()), PARAMS);
+     return true;
+     //...
+}
+```
+]
+.right-column-half[
+- Set the IDs in your layout XML when you create things!
+- Use good ID names (like variables in programming)
+- Access it programmatically using `[Component].getId()` and `[Component].setID()`.
+- Access all Ids using `R.id.[ID]`
+- We use this to implement the tab navbar in Layout
+
+![:img Picture of the android layout toolbar, 50%](img/layout-ii/layouttoolbar.png)
+
+]
+---
+# Lots to unpack here
+
+`PARAMS` is a class constant added to `MainActivity` to hold the parameters for the layout:
+```java
+*public static final RelativeLayout.LayoutParams PARAMS =
+*            new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
+*                                            RelativeLayout.LayoutParams.MATCH_PARENT);
+...
+switch (item.getItemId()) { // Set window contents based on selected item.
+  case R.id.action_part_1:
+    setCurrentTabId(R.id.action_part_1);
+*   contents.addView(getLayoutInflater().inflate(R.layout.part1, null), PARAMS);
+    return true;
+  case R.id.action_part_2:
+    setCurrentTabId(R.id.action_part_2);
+*   contents.addView(new Part2View(this, getImageStrings()), PARAMS);
+    return true;
+    //...
+}
+```
+---
+# PARAMS
+
+```java
+public static final RelativeLayout.LayoutParams PARAMS =
+            new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
+                                            RelativeLayout.LayoutParams.MATCH_PARENT);
+```
+.left-column40[
+- There are a lot of options for layout parameters, study the documentation! [Here](https://developer.android.com/reference/android/widget/RelativeLayout.LayoutParams) is the documentation for the `RelativeLayout` `LayoutParams`
+- Width and height are often set as either `MATCH_PARENT` or `WRAP_CONTENT` (could be used to wrap the bounding box wrap around the text in your `TextView` in Doodle)
+]
+.right-column-half[
+![:img Four different permuations of the MATCH_PARENT or WRAP_CONTENT layout parameters, 100%](img/layout-ii/layoutparams.png)
+
+]
+---
+# Two ways to create Interactors
+
+- Specify elements in WYSIWYG* editor, which will automatically create and initialize the objects via XML.
+  - You could also hand type the XML the editor would produce.
+  - Done in `Doodler#onCreate(Bundle)` - the line `setContentView(R.layout.activity_main);`
+  - Will be done in Part 1, Part 3, and Part 4 for Layout
+
+```java
+*   contents.addView(getLayoutInflater().inflate(R.layout.part1, null), PARAMS);
+```
+
+- Instantiate UI classes at runtime.
+  - We did this creating new views in Doodle at runtime!
+  - Will do this in Part 2, Part 3, and Part 4 for Layout
+
+```java
+*   contents.addView(new Part2View(this, getImageStrings()), PARAMS);
+```
+.footnote[\*WYSIWYG = What You See Is What You Get]
+---
+# Where are these views getting added?
+
+Looking at  `MainActivity#onCreate(Bundle)` we see `setContentView(R.layout.activity_main);`
+
+This statement loads `activity_main.xml`.
+
+Looking deeper we see that contains a `RelativeLayout`
+which contains a `ScrollView` and the `BottomNavigationView`.
+
+```
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ... >
+    <ScrollView
+       android:id="@+id/tab_contents" >
+     </ScrollView>
+
+    <android.support.design.widget.BottomNavigationView
+      android:id="@+id/bottom_nav"
+      ...  />
+
+</RelativeLayout>
+```
+
+---
+
+# Using that id
+
+So we find the `contents` (a `ScrollView`) by that unique id
+
+`ScrollView contents = findViewById(R.id.tab_contents);`
+
+---
+# Runtime Instantiation *FROM XML*
+
+In part 1 we instantiate (create) `part1.xml` into the hierarchy of view which will be the children of
+the `ScrollView contents` using **Inflation**.
+
+We use a [LayoutInflater](https://developer.android.com/reference/android/view/LayoutInflater)
+pass it in the id of the xml we're interested in (`R.layout.part1`). Once inflated, we add
+it to the ScrollView.
+
+```java
+*   contents.addView(getLayoutInflater().inflate(R.layout.part1, null), PARAMS);
+```
+
+To do Inflation in your code you need to `import [package].R;`
+
+---
+# Programatic creation of the hierarchy
+
+In part 2, we recreate his hierarchy programatically by instantiating an `Part2View` object and adding
+that to the view.
+
+```java
+*   contents.addView(new Part2View(this, getImageStrings()), PARAMS);
+```
+
+Just like with Part 1, we need to create a `ConstraintLayout` then add that to the ScrollView.
+
+We did that for you... Your job is to add `ImageView` objects to the `ConstraintLayout`.
+
+Hint: create and use `ConstraintLayout.LayoutParams` for specifying the constraints on the `ImageView`
+objects you create. You'll probably want to look at the [documentation](https://developer.android.com/reference/android/support/constraint/ConstraintLayout.LayoutParams)
+
+---
+# Constraint Layout in Android
+.left-column-half[
+
+![:img A simple layout on an android watch with a textview and two
+buttons (save and discard) and the constraints highlighted,90%](img/layout-ii/constraint-editor.png)
+]
+.right-column-half[
+This assignment also uses **Constraints** (the `ConstraintLayout`)
+
+You can see little lines connecting the `textView` to its container and it's sibling (the `linearLayout`).
+- This specifies how it's attached (can change type by clicking on right)
+- If you were to change the interface (e.g. a different sized screen), it would stay attached and keep filling the space
+- All ends up in XML you can explore too
+]
+
+---
+# Constraint Layout in Android
+.left-column-half[
+
+![:img A simple layout on an android phone instead of a watch with a textview and two buttons (save and discard),100%](img/layout-ii/explore-devices.png)
+]
+.right-column-half[
+You  can test this:  modify the aspect ratio of your display, and flip it to horizontal to test things
+]
+
+???
+Demonstration: consider demoing this interface live
+PRINT THIS LIST
+- Show dragging things to create layout
+- Show different size and orientation phones
+- Show editing attributes
+- Show clicking on constraints in box to change type
+- Show simple interface hierarchy
+- Show simplifying xml
+- Show changing button names/ids
+
+---
+# What are  Constraints?
+.left-column[
+![:img A simple layout on an android watch with a textview and two
+buttons (save and discard) and the constraints highlighted,110%](img/layout-ii/watch3.png)]
+.right-column[
+
+- Very general
+- Can reproduce most other things
+- Can operate on multiple axes
+- Can enhance other layout options
+
+]
+
+---
+
+# What are  Constraints?
+.left-column[
+![:img A simple layout on an android watch with a textview and two
+buttons (save and discard) and the constraints highlighted,110%](img/layout-ii/watch3.png)]
+
+.right-column[
+
+- What do you think this does? `app:layout_constraintBottom_toTopOf="@+id/linearLayout"`
+- And this? `app:layout_constraintEnd_toEndOf="parent"`
+- We  also use `Start_tStartOf` and 'Top_toTopOf` to create this
+
+```xml
+&lt;TextView
+  android:id="@+id/textView"
+  android:layout_width="0dp"
+  android:layout_height="0dp"
+  android:text="@string/sample_text"
+  app:layout_constraintBottom_toTopOf="@+id/linearLayout"
+  app:layout_constraintEnd_toEndOf="parent"
+  app:layout_constraintStart_toStartOf="parent"
+  app:layout_constraintTop_toTopOf="parent"
+  android:layout_marginStart="8dp"
+  android:layout_marginTop="8dp"
+  android:layout_marginEnd="8dp"
+  android:layout_marginBottom="8dp"/&gt;
+
+```
+]
+---
+.left-column[
+## Constraints in Android
+
+![:img picture of attributes window showing controls for
+constraint-based layout including five types of elements, 100%](img/layout-ii/constraints.png)]
+
+.right-column[
+[Docs](https://developer.android.com/training/constraint-layout/): limited set of constraints
+- 1 Size ratio
+- 2 Delete constraint (not a constraint, just removes them)
+- 3 Height/width mode (3 main types):
+ - Wrap constraint ![:img wrap symbol >>>, 5%](img/layout-ii/wrap.png)
+ - Fixed size ![:img fixed symbol I--I, 5%](img/layout-ii/fixed.png)
+ - Match Constraint ![:img match symbol IvvvI, 5%](img/layout-ii/match.png)
+- 4 Margins
+- 5 Constraint bias (essentially weights on competing constraints)
+
+Range of attachment options (e.g. button sides, corners)
+
+Worth getting to know additional abstractions (groups; guidelines;
+barriers; chains)
+]
+???
+
+-bias lets us create something that is 2-3 of the way over rather than
+centered
+
+go back to android to demo again
+---
+# Powerful option
+
+Can do everything we can do with springs, struts, and linear layouts
+
+Declare relationships (.red[what] should be true)
+
+System automatically maintains relationships under change (.red[how])
+---
+# Powerful option
+
+Can do everything we can do with springs, struts, and linear layouts
+
+Declare relationships (what should be true)
+
+- This should be centered in that
+
+- This should be 12 pixels to the right of that
+
+- Parent should be 5 pixels larger than child
+
+System automatically maintains relationships under change (how)
+---
+# Powerful option
+Can do everything we can do with springs, struts, and linear layouts
+
+Declare relationships (what should be true)
+
+System automatically maintains relationships under change (how)
+
+Too good to be true?
+- Unsolvable for arbitrary things
+- Works really well for a limited set
+???
+a good set for ui programming
+xx need to make sure I know why it is hard for arbitrary things
+
+---
+# Note that these are one-way constraints
+
+You can change the right side, and it will update the left side (not
+the reverse)
+
+Can be very inefficient  .jax[$$O(2^n)$$]
+
+But highly efficient incremental update algorithms exist
+???
+
+Only have to update things that might change
+
+Hudson's work on this was seminal
+
+can have a Directed Acyclic Graph (DAG) but not a cycle (thus, a tree)
+hard to guard against cycles
+
+---
+# Layout Assignment
+.left-column[
+![:img Part1: diagram of images evenly spaced stacked vertically, 100%](img/layout-ii/part1-diagram.png)
+]
+
+.right-column[
+Part 1 is about basic reactive layout using XML and constraints
+- We will use constraints for the left/right/top/bottom of each image
+- `scaleType`, `width` and `height` will be provided for you
+
+There are also things we specify without constraints: margins, for example.
+- Android best practice is to use a variable for this
+- How do we do that in XML?
+
+Note: the image on the left is what we are calling a __Layout Wireframe__
+]
+
+---
+# Layout Assignment
+.left-column[
+![:img Part1: diagram of images evenly spaced stacked vertically, 100%](img/layout-ii/part1-diagram.png)
+]
+
+.right-column[
+Part 1 is about basic reactive layout using XML and constraints
+
+Part 2 asks you to reproduce this in code
+- Not all that different from creating views in Doodle
+- What are the key steps here?
+]
+???
+instantiate
+add to the hierarchy
+
+Just now we will also add layout containers
+---
+# Layout Assignment
+.left-column[
+![:img Part1: diagram of images evenly spaced stacked vertically, 100%](img/layout-ii/part1-diagram.png)
+]
+
+.right-column[
+Part 1 is about basic reactive layout using XML and constraints
+
+Part 2 asks you to reproduce this in code
+- Not all that different from creating views in Doodle
+- What are the key steps here?
+  - instantiate (create an interactor)
+  - add to the hierarchy
+  - just now we will also add layout containers
+]
+
+---
+# Layout Assignment
+.left-column[
+![:img Part4: Spot the heron low fidelity prototype, 40%](img/layout-ii/spottheheron-prototype.png) ![:img Part4: Spot the heron layout wireframe, 50%](img/layout-ii/spottheheron-wireframe.png)
+
+]
+
+.right-column[
+Part 3 is about using both XML and programatic means to create a Pinterest style Layout
+
+Part 4 is about designing and creating your own mock up of another app layout
+- Make sure you do the design first
+- Create your Layout Wireframe (see left)
+- Create your interactor hierarchy
+]
+
+---
+# Constraints: A General and Powerful Approach
+
+General mechanism for establishing and maintaining relationships between things
+- Layout is one use
+- Several other uses in UI
+ - Connection of application to UI, e.g. deriving appearance from data
+ - Multiple views of same data
+ - Automated semantic feedback
+ - Automatic arrangement of lines (Snapping in drawing programs)
+
+
+---
+
+# Practice with the [Layout Lab](https://github.com/harshitha-akkaraju/layoutlab)
+
+- Clone [https://github.com/harshitha-akkaraju/layoutlab.git](https://github.com/harshitha-akkaraju/layoutlab.git)
+- Open it up in Android studio
+- Switch between the challenges based in the `AndroidManifest.xml`
+
+| Create this layout using XML | Create this layout programatically |
+| :-- | :-- |
+| ![:img Challenge for buttons in XML, 30%](https://github.com/harshitha-akkaraju/layoutlab/raw/master/img/xml-layout.png) | ![:img Challenge with buttons to be added programatically, 30%](https://github.com/harshitha-akkaraju/layoutlab/raw/master/img/programmatic-layout.png)|
diff --git a/slides/wk04/340AccessibiltyScanner.pdf b/slides/wk04/340AccessibiltyScanner.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..12d1e850100a27121cf1ec26b917e66545bc79fb
Binary files /dev/null and b/slides/wk04/340AccessibiltyScanner.pdf differ
diff --git a/slides/wk04/340AccessibiltyScanner.pptx b/slides/wk04/340AccessibiltyScanner.pptx
new file mode 100644
index 0000000000000000000000000000000000000000..349f162034811496921188fb0e680c38c7f1b6fe
Binary files /dev/null and b/slides/wk04/340AccessibiltyScanner.pptx differ
diff --git a/slides/wk04/accessibility-and-inclusive-design.pdf b/slides/wk04/accessibility-and-inclusive-design.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..743b2c59227b9aaf00d299c8970bf1d362c302a5
Binary files /dev/null and b/slides/wk04/accessibility-and-inclusive-design.pdf differ
diff --git a/slides/wk04/accessibility.html b/slides/wk04/accessibility.html
new file mode 100644
index 0000000000000000000000000000000000000000..df690dde43c9586011fd0997f35b3573d4883921
--- /dev/null
+++ b/slides/wk04/accessibility.html
@@ -0,0 +1,113 @@
+---
+layout: presentation
+title: Accessibility --Week 4, Monday--
+description: Accessibility
+class: middle, center, inverse
+---
+[//]: # (Outline Slide)
+.left-column[
+# Today's goals
+]
+.right-column[
+
+Reminders
+  - Layout Part 3-5 due tomorrow at 10pm
+    - Remember you needed to accept [as2-layout-part-3-4](https://gitgrade.cs.washington.edu/student/assignment/120) first!
+    - Remember git add/commit/push __then go to [GitGrade to turn in](https://gitgrade.cs.washington.edu/student/assignment/120/turnin)__
+  - Accessiblity is now open!
+    - Remember to [accept]() the assignment through GitGrade
+
+Accessibility in practice!
+
+Intro to the Accessibility assignment
+]
+---
+
+# Screen Reader Accessibility on Android
+
+Venkatesh Potluri & Anne Ross
+
+CSE 340, {{site.quarter}}
+
+---
+name: normal
+layout: true
+class:
+
+---
+# Venkatesh Research Interests
+
+Accessible programming tools for blind software developers
+- A Multi Modal Approach for Blind and Visually Impaired Developers to Edit Webpage Designs
+- CodeTalk (aka.ms/codetalk)
+
+Improving screen reader interactions
+- investigating nonvisual interaction techniques on laptop touchpads
+- QBit: an exploratory tangible user interface to support nonlinear nonvisual window switching
+
+---
+# A Multimodal Approach for Blind and Visually Impaired Developers to Edit Webpage Designs
+
+<iframe width="560" height="315" src="https://www.youtube.com/embed/NbkiVG9Mi9s" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
+
+---
+# Today’s focus
+
+.left-column-half[
+Screen readers.
+
+What are screen readers?
+
+Different types of screen readers.
+- JAWS for Windows
+- NonVisual Desktop Access
+- VoiceOver
+- TalkBack
+- ChromeVox
+
+]
+.right-column-half[
+![:img JAWS logo. A blue shark; with talking rings over blue text that reads JAWS.,30%](img/accessibility/JAWS_logo.png) ![:img NVAccess logo. geometric shapes intermix in orange blues and purple. text reads; NVAccess empowering lives through non-visual access to technology,50%](img/accessibility/NVDA_logo.png)
+
+*Where can you find one?*
+Different devices used to interact with screen readers.
+]
+
+---
+# Building for screen readers
+
+Screen readers get underlying information about controls from operating systems.
+- this information is provided by a developer.
+- Accessibility APIs provide the information to a screen reader.
+- Screen readers provide this information visually, through audio or in Braille to users.
+
+.left-column-half[
+![:img Diagram showing the client (screen reader) making a call to the accessibility API; which passes along the request to the provider (browser); which checks the content in the web document; which sends the information back up the chain, 100%](img/accessibility/ScreenReaderIllustration.png)
+]
+.right-column-half[
+Illustrative example of how screen readers get information. Source: semantics to screen readers -- a list apart.
+
+*Do all developers provide this information?*
+]
+
+---
+# App Health Indicators reported by Google's Accessibility Scanner
+
+| Error                | Description                                                                                                                   |
+|----------------------|-------------------------------------------------------------------------------------------------------------------------------|
+| Clickable Items      | Overlapping clickable items                                                                                                   |
+| Editable Image Label | TextView has a content description. This might interfere with a screen reader’s ability to read the content of the text field |
+| Image Contrast       | Low contrast in image or icon                                                                                                 |
+| Item Descriptions    | Items with identical speakable text                                                                                           |
+| Item Label           | Missing element label                                                                                                         |
+| Item Type Label      | Item label ends with type, e.g., “Play Button.” TalkBack automatically announces item type, so information is redundant       |
+| Link                 | URL in link may be invalid                                                                                                    |
+| Text Contrast        | Low text contrast between foreground and background                                                                           |
+| Touch Target         | Item is too small|
+
+
+---
+# Demo
+
+---
+# Accessbility assignment
diff --git a/slides/wk04/events.html b/slides/wk04/events.html
new file mode 100644
index 0000000000000000000000000000000000000000..5be04a5d53d9461f12bfe56bd78875547a4e476b
--- /dev/null
+++ b/slides/wk04/events.html
@@ -0,0 +1,721 @@
+---
+layout: presentation
+title: Event Handling I -- Callbacks, Model View Controller, and Events
+description: Describes input devices, abstractions around events, Listeners, Event Delivery
+class: center, middle, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Write down three things that you reacted to this week
+
+What are some examples?
+
+--
+
+This is event-driven interaction
+
+--
+
+We will be studying the theory and practice of event driven interactions in Android
+
+
+
+---
+# Event Handling I - Callbacks, Model View Controller, and Events
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+
+
+---
+layout: false
+
+# Administrivia
+- Layout part 3-5
+   - Due date TONIGHT at 10pm
+   - Reflection is due with code.
+   - Lock date (aka when GitGrade and Gradescope will lock) TOMORROW at 10pm
+- Assesssments
+   - [Post Layout Quiz](https://canvas.uw.edu/courses/1370612/quizzes/1236290) it out due Sunday.
+   - Will likely change the format for the Layout Examlet.
+- Accessiblity is out
+- Mid quarter evals are out
+
+
+---
+[//]: # (Outline Slide)
+# Today's goals
+
+- What is a callback?
+- What is an event?
+- What is a Model View Controller?
+- How is this all related? 
+---
+
+# Java 102: `Comparator&lt;E&gt;`
+
+Recall that if you have an array of items that have a "natural sorting order"
+such as:
+
+```java
+String[] names = {"Emma", "Ncuti", "Tina", "Idris", "Awkwafina"};
+```
+
+We can sort those things using `Arrays.sort`
+
+```java
+Arrays.sort(names);
+System.out.println(Arrays.toString(names));
+```
+
+Which will output:
+
+```
+[Awkwafina, Emma, Idris, Ncuti, Tina]
+```
+
+---
+
+# Java 102: `Comparator&lt;E&gt;`
+
+What if you want to create a new class: [Person](person.zip)
+
+```java
+public class Person {
+
+   private String mFirstName;
+   private String mLastName;
+   private int mAge;
+
+   public Person(String firstName, String lastName, int age) {
+      mFirstName = firstName;
+      mLastName = lastName;
+      mAge = age;
+   }
+
+   public String toString() { return mFirstName + " " + mLastName + " - age " + mAge; }
+```
+
+
+---
+
+# Java 102: `Comparator&lt;E&gt;`
+
+If we had an array of these `Person` objects
+
+```
+Person[] people = {new Person("Emma", "Watson", 30), new Person("Ncuti", "Gatwa", 27), ... }
+```
+
+How would we sort that array using `Arrays.sort`?
+
+--
+
+```java
+public class Person implements Comparable<Person> {
+
+  ...
+  public int compareTo(Person other) {
+    // what would go in here?!?!?!?!?
+  }
+}
+```
+
+Should we choose based on the first name? Last name? age?
+
+---
+
+# Java 102: `Comparator&lt;E&gt;`
+
+There's another way to set up sorting: by creating an object that extends from
+[`Comparator&lt;E&gt;`](https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/util/Comparator.html)
+
+A subclass of `Comparator&lt;E&gt;` must implement one method:
+
+```java
+public int compare​(E object1, E object2)	 // Compares its two arguments for order.
+```
+`compare` compare returns
+
+* -1 if object1 is "less than" object2
+* 0 if object1 and object2 are equivalent
+* 1 if object1 is "greater than" object 2
+
+---
+# Java 102: `Comparator&lt;E&gt;`
+
+Example:
+
+```
+// this class is defined in PersonLastNameComparator.java
+public class PersonLastNameComparator implements Comparator<Person> {
+
+   @Override
+   public int compare(Person p1, Person p2) {
+     return p1.getLastName().compareTo(p2.getLastName());
+   }
+}
+```
+
+Then we could do the folowing to sort the array by the last name.
+
+
+```java
+Arrays.sort(people, new PersonLastNameComparator());
+```
+
+---
+# Callbacks
+
+The model used for implementing Comparators is consider a **Callback**
+
+From [Wikipedia](https://en.wikipedia.org/wiki/Callback_(computer_programming)):
+
+> A callback ... is any executable code that is passed as an argument to other code;
+> that other code is expected to call back (execute) the argument at a given time.
+
+---
+# Classes, Inner classes, and Anonymous classes.
+
+There are three ways to implement callbacks in Java
+
+1. Creating a class in a separate file (like `PersonLastNameComparator`)
+2. Creating an inner class (like `Person.FirstNameComparator`)
+3. Creating an anonymous class (like the following)
+
+```java
+Arrays.sort(people, new Comparator<Person>() {
+   @Override
+   public int compare(Person p1, Person p2) {
+
+      return p1.getAge() - p2.getAge();
+   }
+});
+```
+---
+# Classes, Inner classes, and Anonymous classes.
+
+There are <del>three</del> four ways to implement callbacks in Java
+
+1. Creating a class in a separate file (like `PersonLastNameComparator`)
+2. Creating an inner class (like `Person.FirstNameComparator`)
+3. Creating an anonymous class (like the following)
+4. Using a lambda
+
+```java
+Arrays.sort(people, (Person p1, Person p2)->{return p1.getAge() - p2.getAge();});
+```
+
+---
+# Callback Exercise
+
+Note: this is a breakout room exercise
+
+- Please participate!
+- TAs will help moderate the activity.
+
+---
+
+# Callback Exercise
+
+1. Imagine we're designing a Zoo. Each group is going to design a different zoo enclosure
+2. In your rooms
+  - Agree on and write down the name of your enclosure (what animal you contain)
+  - Determine the type of animal in this enclosure.
+  - Decide what sound will emanate from this enclosure when you get a “makeNoise for some number of seconds” request
+  - Decide who will turn their mic on in the main room to make the sound.
+  - Decide who will type the name of your enclosure in the chat upon your return
+3. When you come back into the main room
+  - One person type the name of your enclosure in the chat.
+4. Wait until the instructor calls your enclosure name, then make the sound for the requested number of seconds.
+
+---
+# Callback Exercise
+
+As code, I've asked each enclosure to implement the following interface to define the behavior. (Note:
+Listeners are a type of event handling callback in Java/Android)
+
+  ```java
+  public interface EnclosureListener {
+      public void makeNoise(int numSeconds);
+  }
+  ```
+
+For example:
+
+  ```java
+  public class LionCage implements EnclosureListener {
+    ...
+
+    public void makeNoise(int numSeconds) {
+      // make the animal noise for the given number of seconds
+    }
+  }
+  ```
+
+---
+# Callback Exercise
+
+Further, by telling me the name of your enclosure you're registering your listener WITH me, the "zookeeper"
+
+  ```java
+  public class LionCage implements EnclosureListener {
+    ...
+
+    public void makeNoise(int numSeconds) {
+      // make the animal noise for the given number of seconds
+    }
+
+    public void onCreate(Bundle savedInstanceState) {
+      ...
+      zookeeper.addEnclosureListener(this);
+    }
+  }
+  ```
+---
+# Callback Exercise
+
+  ```java
+  public class Zookeeper {
+    // The zookeeper keeps a list of all EnclosureListeners that were registered,
+    private List<EnclosureListeners> mEnclosureListeners;
+
+    public final void addEnclosureListener(EnclosureListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("enclosureListener should never be null");
+        }
+        mEnclosureListeners.add(listener);
+    }
+
+    // And can call on them whenever they need with the right amount of time.
+    public void cacophony(int seconds)
+      for (EnclosureListener listener : mEnclosureListeners) {
+          listener->makeNoise(seconds);
+      }
+    }
+  }
+  ```
+---
+# Callback Exercise
+
+- The Zookeeper has NO idea what each enclosure will do until the listener is registered and called.
+- Each enclosure separately defines how it will react to a makeNoise event.
+- The "contract" between the zookeeper and the enclosures is the defined EnclosureListener interface.
+
+---
+# Callbacks in Java
+
+- At the time Java has created the toolkit developers had *no* idea how every app would want to respond to events
+- The toolkit has pre-defined interfaces so apps or components can respond to events such as clicks or touches. For example:
+   - The `View` class defines the following Listeners as inner classes:
+      - `View.OnClickListener`
+      - `View.OnLongClickListener`
+      - `View.OnFocusChangeListener`
+      - `View.OnKeyListener`
+      - `View.OnTouchListener`  (this is used in ColorPicker and Menu by subclassing AppCompatImageView)
+      - `View.OnCreateContextMenuListener`
+
+We will come back to these in our next class.
+
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Model View Controller, Input Devices and Events
+---
+name: normal
+layout: true
+class:
+---
+# How do you think an app responds to user input?
+
+.left-column30[
+<div class="mermaid">
+  graph LR
+  ap[Application Program]
+  hlt[High Level Tools]
+  t[Toolkit]
+  w[Window System]
+  o[OS]
+  h[Hardware]
+
+  classDef yellow font-size:14pt,text-align:center
+
+  class ap,w,o,h,hlt,t yellow
+</div>
+]
+.right-column60[
+What happens at each level of the hardware stack?
+]
+---
+# How do you think an app responds to user input?
+
+.left-column30[
+<div class="mermaid">
+  graph LR
+  ap[Application Program]
+  hlt[High Level Tools]
+  t[Toolkit]
+  w[Window System]
+  o[OS]
+  h[Hardware]
+
+  classDef yellow font-size:14pt,text-align:center
+
+  class ap,w,o,h,hlt,t yellow
+</div>
+]
+.right-column60[
+What happens at each level of the hardware stack?
+- Hardware level: electronics to sense circuits closing or movement
+  - Difference between hardware (Event vs sampled)
+  - Sensor based input
+- OS: "Interrupts" that tell the Window system something happened
+   - Logical device abstraction and types of devices
+- Windows system: Tells which window received the input
+- Toolkit: defines how the app developer will use these events
+  - Events as an abstraction
+- High level tools: Defines standard components that react to events in a certain way
+- Application Program: Can use standard components OR create new interactions
+  - May define separate interaction techniques
+]
+---
+# Responding to Users: Model View Controller (MVC)
+
+.left-column30[
+<br>
+<div class="mermaid">
+graph TD
+View(View * ) --1-Input--> Presenter(Controller)
+Presenter --5-Output --> View
+Presenter --2-Updates-->Model(0,3-Model)
+Model --4-State Change-->Presenter
+
+classDef edgeLabel font-size:14pt
+classDef blue font-size:14pt,text-align:center
+classDef bluegreen font-size:14pt,text-align:center
+
+class View,Presenter blue
+class User,Model bluegreen
+</div>
+]
+
+.right-column60[
+Suppose this is a digital phone app
+
+<sup>*</sup> User interacts through View (s) (the interactor hierarchy)<br>
+<sup>0</sup> Model State: _Current person:_ Lauren; _Lock state:_ closed<br>
+<sup>1</sup> Password entry. Trigger _Event Handling_<br>
+<sup>2</sup> Change state: App unlocked<br>
+<sup>3</sup> Model State: _Current person:_ Lauren; _Lock state:_ open<br>
+<sup>4</sup> Change state of View(s)<br>
+<sup>5</sup> Trigger _Redraw_ and show
+
+]
+???
+Sketch out key concepts
+- Input -- we need to know when people are doing things. This needs to be event driven.
+- Output -- we need to show people feedback. This cannot ‘take over’ i.e. it needs to be multi threaded
+- Back end -- we need to be able to talk to the application.
+- State machine -- we need to keep track of state.
+- What don’t we need? We don’t need to know about the rest of the UI, probably, etc etc
+- Model View Controller -- this works within components (draw diagram), but also represents the overall structure (ideally) of a whole user interface
+- NOTE: Be careful to write any new vocabulary words on the board and define as they come up.
+
+---
+# Responding to Users: Model View Controller (MVC)
+
+.left-column30[
+<br>
+<div class="mermaid">
+graph TD
+View(View * ) --1-Input--> Presenter(Controller)
+Presenter --5-Output --> View
+Presenter --2-Updates-->Model(0,3-Model)
+Model --4-State Change-->Presenter
+
+classDef edgeLabel font-size:14pt
+classDef blue font-size:14pt,text-align:center
+classDef bluegreen font-size:14pt,text-align:center
+
+class View,Presenter blue
+class User,Model bluegreen
+</div>
+]
+
+.right-column60[
+Suppose this is a fancy speech-recognition based digital door lock instead
+
+
+<sup>*</sup> User interacts through View (s) (the interactor hierarchy)<br>
+<sup>0</sup> Model State: _Current person:_ Lauren; _Lock state:_ closed<br>
+<sup>1</sup> Password entry. Trigger _Event Handling_<br>
+<sup>2</sup> Change person to Lauren; App unlocked<br>
+<sup>3</sup> Model State: _Current person:_ Lauren; _Lock state:_ open<br>
+<sup>4</sup> Change state of View(s)<br>
+<sup>5</sup> Trigger _Redraw_ and show
+
+]
+???
+Sketch out key concepts
+- Input -- we need to know when people are doing things. This needs to be event driven.
+- Output -- we need to show people feedback. This cannot ‘take over’ i.e. it needs to be multi threaded
+- Back end -- we need to be able to talk to the application.
+- State machine -- we need to keep track of state.
+- What don’t we need? We don’t need to know about the rest of the UI, probably, etc etc
+- Model View Controller -- this works within components (draw diagram), but also represents the overall structure (ideally) of a whole user interface
+- NOTE: Be careful to write any new vocabulary words on the board and define as they come up.
+
+---
+# Model View Controller (MVC)
+
+From [Wikipedia]()
+
+>MVC is a software design pattern commonly used for
+developing user interfaces which divides the related program logic into three interconnected elements.
+
+- *Model* - a representation of the state of your application
+- *View* - a visual representation presented to the user
+- *Controller* - communicates between the model and the view
+  - Handles changing the model based on user input
+  - Retrieves information from the model to display on the view
+
+--
+MVC exists within each View as well as for overall interface
+
+---
+# MVC in Android
+
+.left-column30[
+
+<br>
+<div class="mermaid">
+graph TD
+View(Passive View) --user events--> Presenter(Presenter: <BR>Supervising Controller)
+Presenter --updates view--> View
+Presenter --updates model--> Model(Model)
+Model --state-change events--> Presenter
+
+classDef edgeLabel font-size:14pt
+classDef blue font-size:14pt,text-align:center
+classDef bluegreen font-size:14pt,text-align:center
+
+class View,Presenter blue
+class Model bluegreen
+</div>
+]
+.right-column60[
+Applications typically follow this architecture
+
+- What did we learn about how to do this?
+ - What causes the screen to update?
+ - How are things laid out on screen?
+]
+???
+- Relationship of MVC to Android software stack
+- Measure and layout
+- Discuss Whorfian effects
+
+--
+.right-column60[
+Responding to Users: Event Handling
+- When a user interacts with our apps, Android creates **events**
+- As app developers, we react "listening" for events and responding
+appropriately
+]
+---
+
+|Procedural | Event Driven |
+| :--: | :--: |
+|![:img Code printout saying Statement 1; Statement 2; Statement 3, 60%](img/events/procedural.png)|<br><br><br><br>![:img Code printout saying Method 1; Method 2; Method 3 with mouse and keyboard icons causing events pointed at different methods, 60%](img/events/eventdriven.png)|
+|Code is executed in sequential order |&nbsp;&nbsp;&nbsp; Code is executed based upon events|
+
+---
+
+# But what is an Event?
+
+Generally, input is harder than output
+
+- More diversity, less uniformity
+
+- More affected by human properties
+
+---
+# Where does and Event come from?
+
+Consider the "location" of an event...
+
+What is different about a joystick, a touch screen, and a mouse?
+
+???
+- Mouse was originally just a 1:1 mapping in 2 dimensions == absolute
+location; bounded
+- Joystick is relative (maps movement into rate of change in location); unbounded
+- Touch screen is absolute; bounded
+- What about today's mouse? Lifting and moving?
+
+--
+
+- Mouse was originally just a 1:1 mapping in 2 dimensions == absolute
+location; bounded
+- Joystick is relative (maps movement into rate of change in location); unbounded
+- Touch screen is absolute; bounded
+
+--
+
+What about the modern mouse? Lifting and moving?
+
+--
+
+How about a wii controller?
+
+---
+# Is this an input device?
+
+.left-column-half[![:img Picture of swipe keyboard showing text entry of satisfying, 60%](img/events/swipe.png)]
+--
+.right-column-half[No … it’s an interaction technique. Over 50 WPM!]
+
+???
+Who/what/where/etc
+Dimensionality – how many dimensions can a device sense?
+Range – is a device bounded or unbounded?
+Mapping – is a device absolute or relative?
+
+--
+.right-column-half[
+Considerations:
+- Dimensionality – how many dimensions can a device sense?
+- Range – is a device bounded or unbounded?
+- Mapping – is a device absolute or relative?
+]
+---
+# Interaction techniques / Components make input devices effective
+
+For example, consider text entry:
+- 60-80 (keyboards; twiddler)
+- ~20 (soft keyboards)
+- ~50? Swype – but is it an input device?
+---
+# Modern hardware and software starting to muddy the waters around this
+
+![:img Picture of OLED keyboard with labels on keys for gaming instead
+of typing, 30%](img/events/oled.png)
+
+???
+Add OLEDs to keys -> reconfigurable label displays
+
+---
+
+# Higher level abstraction
+
+Logical Device Approach:
+
+- Valuator (slider) -> returns a scalar value
+- Button -> returns integer value
+- Locator -> returns position on a logical view surface
+- Keyboard -> returns character string
+- Stroke -> obtain sequence of points
+
+???
+
+- Can obscure important differences -- hence use inheritance
+- Discussion of mouse vs pen -- what are some differences?
+- Helps us deal with a diversity of devices
+- Make sure everyone understands types of events
+- Make sure everyone has a basic concept of how one registers listeners
+
+
+---
+# Not really satisfactory...
+
+Doesn't capture full device diversity
+
+| Event based devices               |&nbsp;&nbsp;&nbsp;    | Sampled devices                     |
+| --                                | -- | --                                  |
+| Time of input determined by user  |    | Time of input determined by program |
+| Value changes only when activated |    | Value is continuously changing      |
+| e.g.: button                      |    | e.g.: mouse                         |
+
+???
+Capability differences
+ - Discussion of mouse vs pen
+ - what are some differences?
+
+---
+# Contents of Event Record
+
+Think about your real world event again. What do we need to know?
+
+**What**: Event Type
+
+**Where**: Event Target
+
+**When**: Timestamp
+
+**Value**: Event-specific variable
+
+**Context**: What was going on?
+
+???
+Discuss each with examples
+
+---
+# Contents of Event Record
+
+What do we need to know about each UI event?
+
+**What**: Event Type (mouse moved, key down, etc)
+
+**Where**: Event Target (the input component)
+
+**When**: Timestamp (when did event occur)
+
+**Value**: Mouse coordinates; which key; etc.
+
+**Context**: Modifiers (Ctrl, Shift, Alt, etc); Number of clicks; etc.
+
+???
+Discuss each with examples
+
+---
+
+# Input Event Goals
+
+Device Independence
+- Want / need device independence
+- Need a uniform and higher level abstraction for input
+
+Component Independence
+- Given a model for representing input, how do we get inputs delivered
+to the right component?
+???
+
+
+---
+# Summary
+- Callbacks: a programatic way to get or send information from/to our program from the system
+
+--
+- MVC: Separation of concerns for user interaction
+--
+
+- Events: logical input device abstraction
+--
+
+- We model everything as events
+- Sampled devices
+  - Handled as “incremental change” events
+  - Each measurable change: a new event with new value
+- Device differences
+  - Handled implicitly by only generating events they can generate
+- Recognition Based Input?
+  - Yes, can generate events for this too
+
+
+---
+# End of Deck
diff --git a/slides/wk04/img/accessibility/JAWS_logo.png b/slides/wk04/img/accessibility/JAWS_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..653532ed13a71afaa851d5a0c8bd119c70d12748
Binary files /dev/null and b/slides/wk04/img/accessibility/JAWS_logo.png differ
diff --git a/slides/wk04/img/accessibility/NVDA_logo.png b/slides/wk04/img/accessibility/NVDA_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..54eb3531832505478b73264830d8ea6dae708877
Binary files /dev/null and b/slides/wk04/img/accessibility/NVDA_logo.png differ
diff --git a/slides/wk04/img/accessibility/ScreenReaderIllustration.png b/slides/wk04/img/accessibility/ScreenReaderIllustration.png
new file mode 100644
index 0000000000000000000000000000000000000000..e0671e6c54528c9fea483130979260016c61a6e1
Binary files /dev/null and b/slides/wk04/img/accessibility/ScreenReaderIllustration.png differ
diff --git a/slides/wk04/img/accessibility/chart.png b/slides/wk04/img/accessibility/chart.png
new file mode 100644
index 0000000000000000000000000000000000000000..b2e1f680ee863fca1f6fe23e7b6bf933629b5295
Binary files /dev/null and b/slides/wk04/img/accessibility/chart.png differ
diff --git a/slides/wk04/img/accessibility/diverse-people.png b/slides/wk04/img/accessibility/diverse-people.png
new file mode 100644
index 0000000000000000000000000000000000000000..1717e18fce88c912b3a346a50b02ef08eebfffc0
Binary files /dev/null and b/slides/wk04/img/accessibility/diverse-people.png differ
diff --git a/slides/wk04/img/events/eventdriven.png b/slides/wk04/img/events/eventdriven.png
new file mode 100644
index 0000000000000000000000000000000000000000..67b3cebc7c86a8c61e71b16f054e56c26f5ef6c0
Binary files /dev/null and b/slides/wk04/img/events/eventdriven.png differ
diff --git a/slides/wk04/img/events/mvp-design-pattern.png b/slides/wk04/img/events/mvp-design-pattern.png
new file mode 100755
index 0000000000000000000000000000000000000000..9dd87a7f4c12553e619856dd300b307ae9e7b449
Binary files /dev/null and b/slides/wk04/img/events/mvp-design-pattern.png differ
diff --git a/slides/wk04/img/events/oled.png b/slides/wk04/img/events/oled.png
new file mode 100644
index 0000000000000000000000000000000000000000..93ff779017d7e530ef25d16b0ea8fbe6886e0e22
Binary files /dev/null and b/slides/wk04/img/events/oled.png differ
diff --git a/slides/wk04/img/events/procedural.png b/slides/wk04/img/events/procedural.png
new file mode 100644
index 0000000000000000000000000000000000000000..e7c58ac3a6f46f44c0108c3a88838fbe9ec287ed
Binary files /dev/null and b/slides/wk04/img/events/procedural.png differ
diff --git a/slides/wk04/img/events/quiz-mvc.png b/slides/wk04/img/events/quiz-mvc.png
new file mode 100644
index 0000000000000000000000000000000000000000..d8461c69af23ceebca4b045b0b1356db5049e4d2
Binary files /dev/null and b/slides/wk04/img/events/quiz-mvc.png differ
diff --git a/slides/wk04/img/events/swipe.png b/slides/wk04/img/events/swipe.png
new file mode 100644
index 0000000000000000000000000000000000000000..e34f742fd91da41607df613a4c52c934462db305
Binary files /dev/null and b/slides/wk04/img/events/swipe.png differ
diff --git a/slides/wk04/img/events/user.png b/slides/wk04/img/events/user.png
new file mode 100644
index 0000000000000000000000000000000000000000..abba33c403bb48060c5eb1027b976a9bc41a95db
Binary files /dev/null and b/slides/wk04/img/events/user.png differ
diff --git a/slides/wk04/person.zip b/slides/wk04/person.zip
new file mode 100644
index 0000000000000000000000000000000000000000..33212540315522bf36fbd37d6326b824ec591e46
Binary files /dev/null and b/slides/wk04/person.zip differ
diff --git a/slides/wk04/person/Person.java b/slides/wk04/person/Person.java
new file mode 100644
index 0000000000000000000000000000000000000000..da937458e70d3ce038e690ecaf6e21d50b18b412
--- /dev/null
+++ b/slides/wk04/person/Person.java
@@ -0,0 +1,55 @@
+import java.util.*;
+
+public class Person {
+
+   /////// Instance (non-static) methods of Person
+   private String mFirstName;
+   private String mLastName;
+   private int mAge;  
+   
+   
+   public Person(String firstName, String lastName, int age) {
+      mFirstName = firstName;
+      mLastName = lastName;
+      mAge = age;
+   }
+   
+   @Override
+   public String toString() {
+      return mFirstName + " " + mLastName + " - age " + mAge;
+   }
+   
+   public String getFirstName() {
+      return mFirstName; 
+   }
+   
+   public String getLastName() {
+      return mLastName; 
+   }
+   
+   public int getAge() {
+      return mAge; 
+   }
+   
+   
+   
+   
+   /**
+   * Ooh, fancy, an inner class!
+   * Inner classes are neat because they can access the private variables of their 
+   * outer class (Person in this case)
+   * Could we have made this its own public class in its own file, and added getters and 
+   * setters to Person?
+   *      Yes, we certainly could have. I just wanted you to see an inner class.
+   */
+   public static class FirstNameComparator implements Comparator<Person> {
+
+      @Override
+      public int compare(Person p1, Person p2) {
+         
+         // Fill me in using a known comparison method!
+         return 0;
+      }
+   }
+   
+}
\ No newline at end of file
diff --git a/slides/wk04/person/PersonClient.java b/slides/wk04/person/PersonClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..37ea4a315ceb7c3a52244b1c7eb426b2c572f4dd
--- /dev/null
+++ b/slides/wk04/person/PersonClient.java
@@ -0,0 +1,70 @@
+import java.util.*;
+
+public class PersonClient {
+   
+   /**
+   *Main method prints out various sorts
+   *@param args commandline input
+   */
+   public static void main(String[] args) {
+      Person[] people = generatePeople();
+      
+      // Print the original list.       
+      System.out.println("Original list: " + Arrays.toString(people));
+      
+      Arrays.sort(people, new PersonLastNameComparator());
+      System.out.println("Sorted by last name: " + Arrays.toString(people));
+
+      Arrays.sort(people, new Person.FirstNameComparator());
+      System.out.println("Sorted by first name: " + Arrays.toString(people));
+
+
+      Arrays.sort(people, new Comparator<Person>() {
+         @Override
+         public int compare(Person p1, Person p2) {
+         
+            return p1.getAge() - p2.getAge();
+         }
+      });
+      System.out.println("Sorted by age (ascending): " + Arrays.toString(people));
+      
+      Arrays.sort(people, 
+         (Person p1, Person p2)->{return p2.getAge() - p1.getAge();});
+      System.out.println("Sorted by age (descending): " + Arrays.toString(people));
+      
+      
+
+
+
+
+
+
+
+   }
+   
+   /**
+   *Generates a list of three people for testing purposes
+   *@return a default list of people
+   */
+   private static Person[] generatePeople() {
+
+      Person[] people = {
+         new Person("Emma", "Watson", 30), 
+         new Person("Ncuti", "Gatwa", 27), 
+         new Person("Tina", "Fey", 49), 
+         new Person("Idris", "Elba", 47),
+         new Person("Awkwafina", "", 31),
+         new Person("Michael", "Mando", 38),
+         new Person("Judi", "Dench", 85),  
+         new Person("Adam", "Driver", 36),
+         new Person("Logan", "Browning", 30), 
+         new Person("John", "Hamm", 49), 
+         new Person("Dev", "Patel", 30), 
+         new Person("Manny", "Jacinto", 32), 
+         new Person("Jennifer", "Aniston", 51),  
+         new Person("Morgan", "Freeman", 82),  
+      };
+      return people;
+   }
+
+}
diff --git a/slides/wk04/person/PersonLastNameComparator.java b/slides/wk04/person/PersonLastNameComparator.java
new file mode 100644
index 0000000000000000000000000000000000000000..ae4c461538fc47e7ebe58aac91ab459d1bc01ce3
--- /dev/null
+++ b/slides/wk04/person/PersonLastNameComparator.java
@@ -0,0 +1,10 @@
+import java.util.*;
+
+public class PersonLastNameComparator implements Comparator<Person> {
+
+   @Override
+   public int compare(Person p1, Person p2) {
+
+      return p1.getLastName().compareTo(p2.getLastName()); 
+   }
+}
\ No newline at end of file
diff --git a/slides/wk05/Counter.zip b/slides/wk05/Counter.zip
new file mode 100644
index 0000000000000000000000000000000000000000..ae4ab8d469d740ce739c5c02539ff36fea6cb14b
Binary files /dev/null and b/slides/wk05/Counter.zip differ
diff --git a/slides/wk05/event-delivery.html b/slides/wk05/event-delivery.html
new file mode 100644
index 0000000000000000000000000000000000000000..7cdc70d1f419860cddd44aebc316bc7febd45774
--- /dev/null
+++ b/slides/wk05/event-delivery.html
@@ -0,0 +1,948 @@
+---
+layout: presentation
+title: Event Handling II --  Event Delivery using the Interactor Hierarchy
+description: Describes input devices, abstractions around events, Listeners, Event Delivery
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Event Delivery using the Interactor Hierarchy
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+name: normal
+layout: true
+class:
+---
+# Accessibilty warmup
+
+Try the problem on the front of the worksheet
+
+--
+
+- TIL: Talkback will "tell" what an item on the screen is if
+  - it has a content description  (`android:contentDescription="..."`) OR
+  - is focusable (`android:focusable="true"`) OR
+  - it is clickable (`android:clickable="true"`) OR
+  - You have attached a `onClickListener` to the interactor.
+
+---
+
+
+[//]: # (Outline Slide)
+# Today's goals
+
+Discuss how Input Events are delivered
+
+- Event hierarchy
+- Input dispatch process
+- Listeners <- Prework for Wednesday
+- ~~Picking, capture and bubble~~ <- Moved to Wednesday
+
+---
+# Administrivia
+
+For Friday's examlet, you need to enable your UW GSuite account.
+
+- During class I will give out a link that will allow you to copy the Layout Examlet.
+- The Google Doc will copy to your drive.
+- You'll answer the questions in the doc.
+- You'll save the doc as a PDF
+- You'll upload the PDF to Gradescope.
+
+See this [page](https://itconnect.uw.edu/connect/email/google-apps/getting-started/) for
+information on how ensure your GSuite account is activated.
+---
+# Review: Logical Device Approach
+
+- Valuator → returns a scalar value (like a slider)
+- Button → returns integer value
+- Locator → returns position on a logical view surface
+- Keyboard → returns character string
+- Stroke → obtain sequence of points
+
+---
+# Meta notes
+
+We are working on grading the Layout Assignment.
+-  It's mostly going well.
+- A common issues we're seeing is not reading the starter code and understanding what it is doing
+- Recommedation:
+  - START EARLY: this gives you time to go to OH, read our discussion board, ask questions, and
+  get responses. (Remember responses may not be instantaneous, so you may have to work on something
+  else while you wait. )
+  - Skim the spec. Write down a list of questions the spec raises (i.e what don't you know or understand
+  at a quick glance)
+  - Accept and open the code.
+  - Understand the class hierarchy that is given to you. A visual of the hierarchy should be in the spec.
+  - Understand what is happening in the onCreate of whatever extends from `AppCompatActivity`
+  - Start implementing Part1 and look for those TODOs.
+  - REREAD the spec.
+  - Remember to read the spec one more time before turning in the assignment to make sure you got all the pieces.
+
+
+---
+# Meta notes
+
+  - Remember: this class is about Interaction Programming. Programming Android is the substrate for the discussion.
+  - We try to explicitly state when are discussing theory vs practice.
+  - Subgoal of this class: a transition or bridge to 300 level courses.
+    - Important that you learn how to read less structured specifications
+    - Important that you learn how to search for __usable__ information
+    - Is StackOverflow friend or foe?
+
+---
+.left-column[
+# Review
+
+<div class="mermaid" >
+  graph LR
+  ip[Interface Programmer]
+  w[Component Developer]
+  l[Library Extender]
+  a[Architecture Extender]
+  t[Toolkit Builder]
+
+  classDef green font-size:14pt,text-align:center
+
+  class ip,t,w,l,a green
+</div>
+]
+
+.right-column[
+<p>&nbsp;</p>
+<p>&nbsp;</p>
+
+- Which developer role were you when implementing Layout Part 1, 2, 3?
+
+- Did you take on any other developer roles for part 4?
+]
+
+---
+# Interacting with the User
+
+.left-column-half[
+Command line interfaces
+![:img Picture of a Command Line Interface, 100%](img/event-delivery/commandline.png)
+]
+
+--
+.right-column-half[
+- Think about the from 142/143 or in prior classes did they create that took user interaction
+  - e.g. Budgeter, Guessing game, Hangman
+- How would you write code to do interactivity on a command line or in the console in JGrasp?
+- What control flow structure did you use to get input repeatedly from the user?
+- Did the system continue to work or did it wait for the user input?
+]
+
+
+---
+# Interacting with the User
+.left-column-half[
+Command line interfaces
+![:img Picture of a Command Line Interface, 100%](img/event-delivery/commandline.png)
+]
+.right-column-half[
+Mac Desktop interface
+![:img Picture of a windows desktop, 100%](img/event-delivery/windows.png)|
+]
+
+???
+  - Event-Driven Interfaces (GUIs)
+  - Interaction driven by user
+  - UI constantly waiting for input events
+  - Pointing & text input, graphical output
+
+---
+# Review
+
+.left-column[
+<div class="mermaid">
+  graph LR
+  ap[Application Program]
+  hlt[High Level Tools]
+  t[Toolkit]
+  w[Window System]
+  o[OS]
+  h[Hardware]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+
+  class ap,o,h,hlt,t yellow
+  class w green
+</div>
+]
+.right-column[
+The Window System layer has several responsibilities. It
+
+- provides each view (app) with an independent drawing interface.
+- ensures that the display gets updates to reflect changes
+- recieves input from the OS and dispatches it to the appropriate widget
+
+
+
+]
+
+---
+# Review
+
+Device Independence
+- We need device independence to handle a variety of ways to get input
+- We need a uniform and higher level abstraction for input (events)
+---
+
+# Contents of Event Record
+
+Think about one of your real world events from last class again. What do we need to know?
+
+**What**: Event Type
+
+**Where**: Event Target
+
+**When**: Timestamp
+
+**Value**: Event-specific variable
+
+**Context**: What was going on?
+
+???
+Discuss each with examples
+
+---
+# Contents of Event Record
+
+Example: The cat meowed: What do we need to know?
+
+**What**: A cat's meow
+
+**Where**: My ears (this is the input target)
+
+**When**: 9:00pm
+
+**Value**: From the kitchen, near the food bowl
+
+**Context**: Whining, pacing, and generally being a pest.
+
+.footnote[It really does happen see [this video](img/event-delivery/jackhungry.mov)]
+???
+Jack wants food.
+---
+# Contents of Event Record
+
+Example: The cat meowed: What do we need to know?
+
+**What**: A cat's meow
+
+**Where**: My ears (this is the input target)
+
+**When**: 10:00am
+
+**Value**: From the hallway or following us around
+
+**Context**: Purring and rubbing up against us
+
+???
+Jack wants attention.
+---
+
+
+---
+# Another example: : Contents of Event Record
+
+Now imagine a user clicks on the previous button in our PetGallery. What would the event button look like?
+
+What do we need to know about that UI event?
+
+--
+**What**: Click (Could also think about the mouse down and mouse up separately)
+
+--
+**Where**: X,Y coordinate of the finger when the click ended
+
+--
+**When**: The timestamp when the click occured
+
+--
+**Value**: 1 Finger (or maybe None)
+
+--
+**Context**: Any possible modifiers (Ctrl, Shift, Alt, etc); Number of clicks; etc.
+
+---
+
+# Your turn
+
+Imagine you are writing a program to listen for "Hey Siri" on an Android phone.
+
+Work with your neighbor to fill in the fields of the Event Record for this event on your worksheet.
+
+**What**:
+
+**Where**:
+
+**When**:
+
+**Value**:
+
+**Context**: Any possible modifiers
+
+---
+
+# Your turn
+
+Imagine you are writing a program to ironically listen for "Hey Siri" on an Android phone.
+
+Work with your neighbor to fill in the fields of the Event Record for this event on your worksheet.
+
+**What**: Speaking starts (or speaking ends)
+
+**Where**: Normally position on screen. In this case, ill defined because this event is not dispatched positionally. Can be blank, or may hold the current cursor location.
+
+**When**: Timestamp of the audio heard
+
+**Value**: The content of the audio recorded
+
+**Context**: Any possible modifiers
+
+---
+# Review
+
+Device Independence
+- We need device independence to handle a variety of ways to get input
+- We need a uniform and higher level abstraction for input (events)
+
+Component Independence
+- Given a model for representing input, how do we get inputs delivered
+to the right component?
+  - Valuator → returns a scalar value
+  - Button → returns integer value
+  - Locator → returns position on a logical view surface
+  - Keyboard → returns character string
+  - Stroke → obtain sequence of points
+
+---
+
+## Android Events
+
+Each kind of event in Android its own class but they all implement the
+[InputEvent](https://developer.android.com/reference/android/view/InputEvent) abstract class.
+- A little hard to find all the parts defined in one place
+- Harder to deal with uniformly
+- But easily extensible for new event types
+
+.red[Artificial] events are a thing
+- Window Events
+- Search Event
+- others.
+
+---
+# Android [MotionEvent](https://developer.android.com/reference/android/view/MotionEvent)
+
+```java
+java.lang.Object
+   ↳	android.view.InputEvent
+ 	   ↳	android.view.MotionEvent
+
+public final class MotionEvent extends InputEvent implements Parcelable {
+
+  int getAction()      // up, down etc
+  int getActionIndex() // multi touch support -- which pointer
+  float getX()         // position
+  float getY()         // position
+  int getButtonState() // pressed or not, for example
+  long getDownTime()
+  float getOrientation(int pointerIndex)
+  float getPressure()
+  float getSize()      // fingers aren't pixel sized
+                       // and many more...
+}
+```
+---
+# Aside: Multiple Hierarchies discussed so far in class
+
+Can you think of them?
+
+--
+
+- Inheritance hierarchy for interactors (Viewp)
+- Inheritance hierarchy for layout
+- Inheritance hierarchy for events
+- Component hierarchy (Interactors and View Groups)
+--
+  - Also remember how the component hierarchy is used in drawing (Z-order)
+
+---
+# Events can represent abstract concepts...
+
+Can you think of any?
+
+--
+
+...Think of how the state of the app changes as you use it.
+
+--
+
+- __Create__: Android is done creating the object
+--
+- __Active__: in foreground of screen, and receives input
+--
+- __Paused__: activity lost focus (is no longer displayed on screen)
+--
+- __Stopped__:
+  - Another activity has focus
+  - Original activity remains in memory -- perfect place to save data & state
+  - Often can be *killed* by Android OS if not resumed relatively quickly
+--
+- __Inactive__: after an activity has been killed; or before it is launched
+--
+- __Timer__: Animation
+
+---
+
+# Activity State Change Events
+
+.left-column-half[
+![:img Android Activity Lifecycle,50%](img/event-delivery/activity_lifecycle.png)
+]
+.right-columns-half[
+Look familiar?
+]
+
+---
+# Thinking as a Toolkit Developer
+
+.left-column-half[
+<br>
+<div class="mermaid">
+  graph LR
+  ip[Interface Programmer]
+  w[Component Developer]
+  l[Library Extender]
+  a[Architecture Extender]
+  t[Toolkit Builder]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+
+  class ip,w,l,a green
+  class t yellow
+</div>
+]
+
+.right-column-half.font-smaller[
+<div class="mermaid">
+  graph LR
+  ap[Application Program]
+  hlt[High Level Tools]
+  t[Toolkit]
+  w[Window System]
+  o[OS]
+  h[Hardware]
+
+  classDef yellow font-size:14pt,text-align:center
+  classDef green font-size:14pt,text-align:center
+
+  class ap,o,h,hlt,w green
+  class t yellow
+</div>
+
+]
+
+---
+# How does the Toolkit Architecture deliver events?
+
+Application’s UI Thread (This is the main thread of your program)
+```java
+while (true) {
+  // Gets event from the application message queue.
+  // If the queue is empty, we just wait here.
+  Event e = GetEventFromMessageQueue();
+
+  // Dispatches the event to the appropriate application window
+  // (the destination address is in the event data).
+  DispatchEventToMessageDestination(e);
+}
+```
+--
+This code is automatically setup and managed by the UI framework you are using (e.g., .NET, WPF, Android, Swift).
+You don’t really need to worry about it (but you should know it’s there and how it functions!)
+
+---
+# Input __Dispatch__ Process
+
+Input thread:
+- When a user interacts,  __events__ are created
+- Events go into a queue
+
+???
+
+What do you think of when you hear the word "thread"? How does it relate to CS?
+
+Remember a queue is a data structure that is first in first out.
+
+---
+# Input __Dispatch__ Process
+
+Input thread
+
+Dispatch thread:
+- Front event comes off queue
+- How does a toolkit decide where to send events?
+
+--
+
+- Depends: Is it Focus or Positional input?
+ - Focus list (in order based on interest)
+ - Positional list (z-order under cursor based on interactor hierarchy)
+
+---
+.left-column-half[
+## Event Dispatch
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface, 100%](img/event-delivery/callbacks.png)]
+.right-column-half[
+Dispatch Strategies (theory)
+- Positional
+  - Bottom-up
+  - Top-down
+  - Bubble out
+- Focus-based
+]
+---
+.left-column-half[
+## Event Dispatch (theory)
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface, 100%](img/event-delivery/callbacks.png)
+]
+.right-column-half[
+- Bottom up dispatch
+  - The event is directed to the "lowest", frontmost interactor in the tree that
+contains the mouse position
+  - That interactor might not want the input, so it goes to window at the next level up the tree
+]
+---
+.left-column-half[
+## Event Dispatch (theory)
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface, 100%](img/event-delivery/callbacks.png)
+]
+.right-column-half[
+- Bottom up dispatch
+- Top down dispatch
+  - The event is directed to topmost window that contains the mouse location
+  - That window decides how to dispatch it further (recursively)
+  - Common in OO toolkits
+  - Useful in situations where the interactor is "view only" (parent wants to disable input to child)
+]
+
+---
+.left-column-half[
+## Event Dispatch (theory)
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface, 100%](img/event-delivery/callbacks.png)
+]
+.right-column-half[
+- Bottom up dispatch
+- Top down dispatch
+- Bubble-out dispatch
+  - Used when there is no clear nesting of windows and groups of interactive objects
+  - Tree is traversed as in top down approach, but bounding rectangles are hints, not guarantees
+  - Objects checked in opposite order from drawing: frontmost items are checked first
+  - Object that was hit is attached to the event, ancestors know what was selected
+]
+
+---
+.left-column-half[
+## Event Dispatch
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface, 100%](img/event-delivery/callbacks.png)
+]
+.right-column-half[
+- Bottom up dispatch
+- Top down dispatch
+- Bubble-out dispatch
+- Focus dispatch
+  - No straighforward location of where the event happened
+  - Windowing system determines which window/interactor should get the input.
+  - Common example: where should key press/release events go?
+]
+
+
+---
+.left-column-half[
+## Event Dispatch
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface and a do_action() call
+happening below the line in response to a button_pressed(), 100%](img/event-delivery/callbacks2.png)]
+.right-column-half[
+Callbacks handle *application* response to events
+- Update Application Model
+
+]
+
+---
+.left-column-half[
+## Event Dispatch
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface with do_action() replaced
+with an actionListener, 100%](img/event-delivery/callbacks3.png)]
+.right-column-half[
+Callbacks handle *application* response to events
+- Update Application Model
+- Best implemented using custom listeners
+
+]
+
+---
+template: inverse
+
+## Event Listeners
+
+### Putting theory into practice
+
+???
+- Implementation strategy
+
+- Basic goal: notify something of a change
+
+---
+# Basics of Event Listeners (1/3)
+
+- Interface on the `View` class that acts as a _callback_ method
+
+--
+
+  - Recall interfaces specify behavior (but no data) that can be inherited.
+
+--
+
+- Must be attached to a particular `View`
+
+--
+
+- Android framework triggers the method once the `View` is interacted with by the user
+
+--
+
+- A `View` can have listen for different types of interactions
+- But: the `View` must implement and registering the appropriate listeners
+
+???
+What is an interface?
+
+---
+layout: false
+
+.left-column[
+## Standard Event Listeners provided by Android
+
+More listed in the [API Documentation](https://developer.android.com/guide/topics/ui/ui-events.html)
+]
+.right-column[
+The set of Android's provided interfaces include:
+  ```java
+    // User tapped a view
+    public static interface View.OnClickListener { ... }
+
+    // User long pressed on a View
+    public static interface View.OnLongClickListener { ... }
+
+    // State of view has changed
+    // (e.g. user clicked outside a EditText input box)
+    public static interface View.OnFocusChangeListener { ... }
+  ```
+ ]
+
+---
+# Implementing clicking
+
+Create your button
+
+Register an event listener with the button
+
+---
+# Registering an Event Listener
+
+~~Three~~ five ways to register an event listener:
+
+  - Creating a separate class/file or an inner class
+  - Creating an anonymous inner class
+  - Implementing an Interface
+  - Creating an anonymous class as a parameter
+  - Lambdas
+
+Code for the following demo is [here](Counter.zip).
+This code uses a helper function
+```java
+/** Method to increment the count field */
+private void incrementCount(View v) {
+    TextView counter = findViewById(R.id.count);
+    String textCount = counter.getText().toString();
+    int count = Integer.parseInt(textCount);
+    counter.setText("" + ++count);
+
+    ((TextView)findViewById(R.id.whichButton)).setText(((Button)v).getText());
+
+}
+```
+
+---
+
+.left-column[
+## Registering a Listener - Inner class (1/2)
+
+Create the Listener subclass
+]
+.right-column[
+  ```java
+  private class MyButtonListener implements View.OnClickListener {
+      @Override
+      public void onClick(View v) {
+          incrementCount(v);
+      }
+  }
+  ```
+]
+---
+.left-column[
+## Registering a Listener  - Inner class (2/2)
+
+Create the Listener subclass
+
+Register it (by instantiating an object of that type)
+]
+.right-column[
+  ```java
+  // in onCreate...
+  Button b1 = findViewById(R.id.button_three);
+  if (b1 != null) {  // Should always check for null
+      b1.setOnClickListener(new MyButtonListener());
+  }
+  ```
+]
+
+
+---
+.left-column[
+## Create an Anonymous Inner Class
+]
+.right-column[
+```java
+public class EventExampleActivity extends AppCompatActivity {
+
+  // An anonymous inner class as a member variable in an Activity
+  View.OnClickListener mButtonClickListener = new View.OnClickListener() {
+      @Override
+      public void onClick(View v) {
+          // call the private method in EventExampleActivity
+          incrementCount(v);
+      }
+  };
+
+  protected void onCreate(Bundle savedState) {
+    Button b1 = findViewById(R.id.button_one);
+    if (b1 != null) {
+      b1.setOnClickListener(mButtonClickListener);
+    }
+  }
+}
+```
+]
+
+???
+incrementCount is a private method
+Mention that mXxxx variables are private fields and this is a quick way
+to find all private fields when searching variables in code
+---
+# Digging deeper: Creating an Anonymous Inner Class
+
+Let's take some time to parse this...
+
+```java
+  private View.OnClickListener mButtonClickListener = new View.OnClickListener() {
+```
+- `private` - it's only available inside the class that contains it (i.e. `EventExampleActivity`)
+- `View.OnClickListener` is the variable type ([Documentation](https://developer.android.com/reference/android/view/View.OnClickListener.html)) - a nested class in `View`
+- `mButtonClickListener` is the variable name which is being set to...
+- a `new View.OnClickListener()` which is an anonymous object from an abstract class
+  - For those of you who have not taken 331, that means that there are methods that have not been implemented in the class.
+  - The on method that you MUST implement (in order to create a new object) is `OnClick` which overrides the abstract method
+
+```java
+  public void OnClick(View v) { /* stuff in here does the work when a click is received! */ }
+```
+---
+
+.left-column[
+## Registering a Listener - Implement the Interface
+]
+.right-column[
+  ```java
+// Start by implementing the interface
+public class EventExampleActivity extends AppCompatActivity
+  implements View.OnClickListener { // Necessary to implement
+
+  protected void onCreate(Bundle savedState) {
+    Button b3 = findViewById(R.id.button_three);
+    if (b3 != null) {  // Should always check for null
+        b3.setOnClickListener(this);
+    }
+  }
+
+  // Here's where you do the implementation of your listener in your class
+  @Override
+   public void onClick(View v) {
+       incrementCount(v);
+   }
+  ```
+]
+---
+
+.left-column[
+## Registering a Listener - Anonymous class as a parameter
+
+Create and register the listener all at once
+]
+.right-column[
+  ```java
+  Button b4 = findViewById(R.id.button_four);
+   if (b4 != null) {  // Should always check for null
+       b4.setOnClickListener(new View.OnClickListener() {
+           public void onClick(View v) {
+               incrementCount(v);
+           }
+       });
+   }
+  ```
+]
+---
+.left-column[
+## Registering a Listener - lambda
+
+Create the and register the listener all at once with lamba syntax
+]
+.right-column[
+  ```java
+  Button b5 = findViewById(R.id.button_five);
+  if (b5 != null) {  // Should always check for null
+      b5.setOnClickListener((View v) -> incrementCount(v));
+  }
+  ```
+]
+.right-column[
+To use Lambdas you have to upgrade to Java 8. See these
+[instructions](https://developer.android.com/studio/write/java8-support) to do this.
+]
+
+---
+.left-column[
+## Registering Multiple Listeners
+]
+.right-column[
+Can register more than one listener
+
+For example:
+```java
+  View v = new View();
+  v.setOnClickListener(...);
+  v.setOnLongClickListener(...);
+  ```
+]
+---
+.left-column[
+## Many Views, Same Listener (1/3)]
+
+.right-column[
+Event callbacks are passed the `View` as a parameter
+]
+--
+
+.right-column[
+
+We can reuse a listener for views that handle the same action
+  (e.g. all 5 buttons could use the same class/method for the action)
+]
+---
+
+## Many Views, Same Listener (2/3)
+
+- And we can handle different actions by checking the `View` or its `id`:
+  ```java
+    protected void onCreate(Bundle savedState) {
+      Button b1 = (Button) findViewById(R.id.button_one);
+      if (b1 != null) {
+        b1.setOnClickListener(mButtonClickListener);
+      }
+
+      Button b2 = (Button) findViewById(R.id.button_two);
+      if (b2 != null) {
+        b2.setOnClickListener(mButtonClickListener);
+      }
+    }
+  ```
+---
+## Many Views, Same Listener (3/3)
+
+You can use the ID of the view to determine where the event originated from
+
+```java
+  View.OnClickListener mButtonClickListener = new View.OnClickListener({
+    public void onClick(View v) {
+      if (v == null) {
+        return;
+      }
+
+      int viewId = v.getId();
+
+      switch (viewId) {
+        case R.id.button_one:  // First Button
+          Log.d("Button Press", "First Button");
+          break;
+        case R.id.button_two:  // Second Button
+          Log.d("Button Press", "Second Button");
+          break;
+        default:               // Someone else is using the listener!
+          Log.d("Button Press", "Invalid Button!");
+      }
+    }
+  });
+```
+---
+.left-column[
+## Marking an event as handled
+]
+.right-column[
+This ensures only one view gets it (we talk about the algorithm behind this later)
+
+Return `boolean` value that indicate the event has been handled (`true`)
+
+  ```java
+    /**
+     * onLongClick - triggered when a view is long clicked
+     * @param v - the view long pressed
+     * @return - true if the callback consumed the long click, false otherwise.
+     **/
+    boolean onLongClick (View v) { ... };
+  ```
+]
+.footnote[[API Documentation for Long Click](https://developer.android.com/reference/android/view/View.OnLongClickListener.html)
+]
+
+---
+# End of Deck
+
+Thing to think about...
+
+How would you handle input in a circular component?
diff --git a/slides/wk05/img/event-delivery/activity_lifecycle.png b/slides/wk05/img/event-delivery/activity_lifecycle.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab0921a717d184442c96c1b8863018d46920a67c
Binary files /dev/null and b/slides/wk05/img/event-delivery/activity_lifecycle.png differ
diff --git a/slides/wk05/img/event-delivery/callbacks.png b/slides/wk05/img/event-delivery/callbacks.png
new file mode 100644
index 0000000000000000000000000000000000000000..72147534bc5ba07de7a95ffe479f5505d65814f4
Binary files /dev/null and b/slides/wk05/img/event-delivery/callbacks.png differ
diff --git a/slides/wk05/img/event-delivery/callbacks2.png b/slides/wk05/img/event-delivery/callbacks2.png
new file mode 100644
index 0000000000000000000000000000000000000000..37eeff1f958d4f711faf7ce2af0ceb9736121957
Binary files /dev/null and b/slides/wk05/img/event-delivery/callbacks2.png differ
diff --git a/slides/wk05/img/event-delivery/callbacks3.png b/slides/wk05/img/event-delivery/callbacks3.png
new file mode 100644
index 0000000000000000000000000000000000000000..c7c5e1de7d5c73ca13b8e95df99735ce5aeec7fa
Binary files /dev/null and b/slides/wk05/img/event-delivery/callbacks3.png differ
diff --git a/slides/wk05/img/event-delivery/commandline.png b/slides/wk05/img/event-delivery/commandline.png
new file mode 100644
index 0000000000000000000000000000000000000000..773bd5e16472702193d5aa0b8818d4b283f35662
Binary files /dev/null and b/slides/wk05/img/event-delivery/commandline.png differ
diff --git a/slides/wk05/img/event-delivery/cookie-monster.gif b/slides/wk05/img/event-delivery/cookie-monster.gif
new file mode 100755
index 0000000000000000000000000000000000000000..f484a992a84a146276ed1a80af3f60fd225e4ff6
Binary files /dev/null and b/slides/wk05/img/event-delivery/cookie-monster.gif differ
diff --git a/slides/wk05/img/event-delivery/jackhungry.mov b/slides/wk05/img/event-delivery/jackhungry.mov
new file mode 100644
index 0000000000000000000000000000000000000000..a41f687b0b33dd94a57a852ab9e8a82c602266fd
Binary files /dev/null and b/slides/wk05/img/event-delivery/jackhungry.mov differ
diff --git a/slides/wk05/img/event-delivery/windows.png b/slides/wk05/img/event-delivery/windows.png
new file mode 100644
index 0000000000000000000000000000000000000000..3fc19c0be90e80ae595ccc58c6a8b58116954300
Binary files /dev/null and b/slides/wk05/img/event-delivery/windows.png differ
diff --git a/slides/wk05/img/pps-geom/activity_lifecycle.png b/slides/wk05/img/pps-geom/activity_lifecycle.png
new file mode 100755
index 0000000000000000000000000000000000000000..879f51f6e8fafe75d267984680ef63f85b118dc5
Binary files /dev/null and b/slides/wk05/img/pps-geom/activity_lifecycle.png differ
diff --git a/slides/wk05/img/pps-geom/android-activity-states-01.png b/slides/wk05/img/pps-geom/android-activity-states-01.png
new file mode 100755
index 0000000000000000000000000000000000000000..614cc908ef0e4a693643d2a07d7131feab55fc13
Binary files /dev/null and b/slides/wk05/img/pps-geom/android-activity-states-01.png differ
diff --git a/slides/wk05/img/pps-geom/android-activity-states-02.png b/slides/wk05/img/pps-geom/android-activity-states-02.png
new file mode 100755
index 0000000000000000000000000000000000000000..e7042ef93ac69f8da5c7353babd93a727284541a
Binary files /dev/null and b/slides/wk05/img/pps-geom/android-activity-states-02.png differ
diff --git a/slides/wk05/img/pps-geom/callbacks.png b/slides/wk05/img/pps-geom/callbacks.png
new file mode 100644
index 0000000000000000000000000000000000000000..72147534bc5ba07de7a95ffe479f5505d65814f4
Binary files /dev/null and b/slides/wk05/img/pps-geom/callbacks.png differ
diff --git a/slides/wk05/img/pps-geom/callbacks2.png b/slides/wk05/img/pps-geom/callbacks2.png
new file mode 100644
index 0000000000000000000000000000000000000000..37eeff1f958d4f711faf7ce2af0ceb9736121957
Binary files /dev/null and b/slides/wk05/img/pps-geom/callbacks2.png differ
diff --git a/slides/wk05/img/pps-geom/callbacks3.png b/slides/wk05/img/pps-geom/callbacks3.png
new file mode 100644
index 0000000000000000000000000000000000000000..c7c5e1de7d5c73ca13b8e95df99735ce5aeec7fa
Binary files /dev/null and b/slides/wk05/img/pps-geom/callbacks3.png differ
diff --git a/slides/wk05/img/pps-geom/focus.png b/slides/wk05/img/pps-geom/focus.png
new file mode 100644
index 0000000000000000000000000000000000000000..0e3b191d6a01f296400772022e90781889482d0a
Binary files /dev/null and b/slides/wk05/img/pps-geom/focus.png differ
diff --git a/slides/wk05/img/pps-geom/messenger-bubble.gif b/slides/wk05/img/pps-geom/messenger-bubble.gif
new file mode 100755
index 0000000000000000000000000000000000000000..77defd497891e79a775a6ca3593cf33e02d2c890
Binary files /dev/null and b/slides/wk05/img/pps-geom/messenger-bubble.gif differ
diff --git a/slides/wk05/img/pps-geom/noresponse.png b/slides/wk05/img/pps-geom/noresponse.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb52157c564bfd05b70e0a9c1c2e4b1d9b5925ad
Binary files /dev/null and b/slides/wk05/img/pps-geom/noresponse.png differ
diff --git a/slides/wk05/img/pps-geom/notevent.png b/slides/wk05/img/pps-geom/notevent.png
new file mode 100644
index 0000000000000000000000000000000000000000..c610bff3b877a36f2d47fce0b250781c540e08ae
Binary files /dev/null and b/slides/wk05/img/pps-geom/notevent.png differ
diff --git a/slides/wk05/img/pps-geom/picklist.svg b/slides/wk05/img/pps-geom/picklist.svg
new file mode 100644
index 0000000000000000000000000000000000000000..b1bb184b9fa2dc7dc9a5a3a659943a137a331c70
--- /dev/null
+++ b/slides/wk05/img/pps-geom/picklist.svg
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 viewBox="0 0 184.8 195.3" style="enable-background:new 0 0 184.8 195.3;" xml:space="preserve">
+<style type="text/css">
+	.st0{fill:none;stroke:#000000;stroke-miterlimit:10;}
+	.st1{fill:#2E3192;}
+	.st2{font-family:'MyriadPro-Regular';}
+	.st3{font-size:12px;}
+	.st4{fill:#009444;}
+	.st5{fill:#D12029;}
+	.st6{fill:none;stroke:#2E3192;stroke-miterlimit:10;}
+	.st7{fill:none;stroke:#42B649;stroke-miterlimit:10;}
+	.st8{fill:none;stroke:#D12029;stroke-miterlimit:10;}
+	.st9{fill:#160C0B;}
+	.st10{fill:none;stroke:#000000;stroke-width:0.75;stroke-miterlimit:10;}
+	.st11{fill:none;stroke:#000000;stroke-width:0.75;stroke-miterlimit:10;stroke-dasharray:9.9093,9.9093;}
+	.st12{fill:none;stroke:#000000;stroke-width:0.75;stroke-miterlimit:10;stroke-dasharray:10.9093,10.9093;}
+	.st13{fill:none;stroke:#D12029;stroke-width:0.75;stroke-miterlimit:10;}
+	.st14{fill:none;stroke:#D12029;stroke-width:0.75;stroke-miterlimit:10;stroke-dasharray:10.9303,10.9303;}
+	.st15{fill:none;stroke:#D12029;stroke-width:0.75;stroke-miterlimit:10;stroke-dasharray:9.9093,9.9093;}
+</style>
+<polygon class="st0" points="179.3,190.4 3.3,190.4 3.9,4.3 179.9,4.3 "/>
+<text transform="matrix(1 0 0 1 25.2813 65.6343)" class="st1 st2 st3">V1</text>
+<text transform="matrix(1 0 0 1 52.2813 71.4978)" class="st4 st2 st3">V3</text>
+<text transform="matrix(1 0 0 1 31.2098 104.4477)" class="st5 st2 st3">V2</text>
+<text transform="matrix(1 0 0 1 82.7637 37.6707)" class="st1 st2 st3">V4</text>
+<text transform="matrix(1 0 0 1 123.6179 130.4509)" class="st2 st3">V5</text>
+<text transform="matrix(1 0 0 1 105.8968 80.1523)" class="st5 st2 st3">V6</text>
+<rect x="18.3" y="53.6" class="st6" width="73" height="80"/>
+<text transform="matrix(1 0 0 1 9.3218 19.4072)" class="st2 st3">V0</text>
+<polygon class="st7" points="87.9,84.1 45.9,84.1 46.3,58.5 88.3,58.5 "/>
+<rect x="77.5" y="25.4" class="st6" width="92.2" height="155.1"/>
+<rect x="25.3" y="91.4" class="st8" width="48.9" height="33.7"/>
+<polygon class="st0" points="152.8,136.6 133.5,158.8 110.6,135.9 129.9,113.7 "/>
+<ellipse class="st8" cx="110.8" cy="88.1" rx="33.3" ry="20.1"/>
+<circle class="st9" cx="82.8" cy="71.5" r="3.5"/>
+<g>
+	<g>
+		<polyline class="st10" points="152.6,152.6 152.6,158.6 146.6,158.6 		"/>
+		<line class="st11" x1="136.7" y1="158.6" x2="121.8" y2="158.6"/>
+		<polyline class="st10" points="116.8,158.6 110.8,158.6 110.8,152.6 		"/>
+		<line class="st12" x1="110.8" y1="141.7" x2="110.8" y2="125.3"/>
+		<polyline class="st10" points="110.8,119.9 110.8,113.9 116.8,113.9 		"/>
+		<line class="st11" x1="126.8" y1="113.9" x2="141.6" y2="113.9"/>
+		<polyline class="st10" points="146.6,113.9 152.6,113.9 152.6,119.9 		"/>
+		<line class="st12" x1="152.6" y1="130.8" x2="152.6" y2="147.2"/>
+	</g>
+</g>
+<g>
+	<g>
+		<polyline class="st13" points="144.2,103 144.2,109 138.2,109 		"/>
+		<line class="st14" x1="127.2" y1="109" x2="89" y2="109"/>
+		<polyline class="st13" points="83.5,109 77.5,109 77.5,103 		"/>
+		<line class="st15" x1="77.5" y1="93.1" x2="77.5" y2="78.2"/>
+		<polyline class="st13" points="77.5,73.3 77.5,67.3 83.5,67.3 		"/>
+		<line class="st14" x1="94.5" y1="67.3" x2="132.7" y2="67.3"/>
+		<polyline class="st13" points="138.2,67.3 144.2,67.3 144.2,73.3 		"/>
+		<line class="st15" x1="144.2" y1="83.2" x2="144.2" y2="98"/>
+	</g>
+</g>
+</svg>
diff --git a/slides/wk05/img/pps-geom/quizqs.png b/slides/wk05/img/pps-geom/quizqs.png
new file mode 100644
index 0000000000000000000000000000000000000000..27636e6e935530d985628916bda1cfc7ab67d710
Binary files /dev/null and b/slides/wk05/img/pps-geom/quizqs.png differ
diff --git a/slides/wk05/img/pps-geom/window-with-highlighted-menu.png b/slides/wk05/img/pps-geom/window-with-highlighted-menu.png
new file mode 100644
index 0000000000000000000000000000000000000000..e283f1c2cc3703e082aa33e292916c1d0dcf4bc3
Binary files /dev/null and b/slides/wk05/img/pps-geom/window-with-highlighted-menu.png differ
diff --git a/slides/wk05/img/pps-geom/window-with-menu-highlight.png b/slides/wk05/img/pps-geom/window-with-menu-highlight.png
new file mode 100644
index 0000000000000000000000000000000000000000..c98efae6cbebbc0ae06d4bf2cf959a56850b29dc
Binary files /dev/null and b/slides/wk05/img/pps-geom/window-with-menu-highlight.png differ
diff --git a/slides/wk05/img/pps-geom/window-with-menu-highlight2.png b/slides/wk05/img/pps-geom/window-with-menu-highlight2.png
new file mode 100644
index 0000000000000000000000000000000000000000..d18967a3a33292c574743985e1a44882806cc78b
Binary files /dev/null and b/slides/wk05/img/pps-geom/window-with-menu-highlight2.png differ
diff --git a/slides/wk05/img/pps-geom/window-with-scrollbar.png b/slides/wk05/img/pps-geom/window-with-scrollbar.png
new file mode 100644
index 0000000000000000000000000000000000000000..cd6cd1f015f34aed26f079a6e8bdfe0b19031eb6
Binary files /dev/null and b/slides/wk05/img/pps-geom/window-with-scrollbar.png differ
diff --git a/slides/wk05/img/pps-geom/window.png b/slides/wk05/img/pps-geom/window.png
new file mode 100644
index 0000000000000000000000000000000000000000..e1edc0bca27881e6b8a54fbdf4495b3e493886c8
Binary files /dev/null and b/slides/wk05/img/pps-geom/window.png differ
diff --git a/slides/wk05/img/whole/callbacks.png b/slides/wk05/img/whole/callbacks.png
new file mode 100644
index 0000000000000000000000000000000000000000..72147534bc5ba07de7a95ffe479f5505d65814f4
Binary files /dev/null and b/slides/wk05/img/whole/callbacks.png differ
diff --git a/slides/wk05/img/whole/callbacks2.png b/slides/wk05/img/whole/callbacks2.png
new file mode 100644
index 0000000000000000000000000000000000000000..37eeff1f958d4f711faf7ce2af0ceb9736121957
Binary files /dev/null and b/slides/wk05/img/whole/callbacks2.png differ
diff --git a/slides/wk05/img/whole/callbacks3.png b/slides/wk05/img/whole/callbacks3.png
new file mode 100644
index 0000000000000000000000000000000000000000..c7c5e1de7d5c73ca13b8e95df99735ce5aeec7fa
Binary files /dev/null and b/slides/wk05/img/whole/callbacks3.png differ
diff --git a/slides/wk05/img/whole/combined.png b/slides/wk05/img/whole/combined.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f82cd3caaf966242fa1d127118706586d6793c0
Binary files /dev/null and b/slides/wk05/img/whole/combined.png differ
diff --git a/slides/wk05/img/whole/drawing.png b/slides/wk05/img/whole/drawing.png
new file mode 100644
index 0000000000000000000000000000000000000000..1ee68b6c60c5e385f381295d075a042752076e49
Binary files /dev/null and b/slides/wk05/img/whole/drawing.png differ
diff --git a/slides/wk05/img/whole/full-solution-buffering.png b/slides/wk05/img/whole/full-solution-buffering.png
new file mode 100644
index 0000000000000000000000000000000000000000..63871837cf02c6984b3fd18308c9a20dd944c201
Binary files /dev/null and b/slides/wk05/img/whole/full-solution-buffering.png differ
diff --git a/slides/wk05/img/whole/interpolators.gif b/slides/wk05/img/whole/interpolators.gif
new file mode 100644
index 0000000000000000000000000000000000000000..ad4e46ef00ad0843547fa69de0754dbaf9a7c59b
Binary files /dev/null and b/slides/wk05/img/whole/interpolators.gif differ
diff --git a/slides/wk05/img/whole/original-new.png b/slides/wk05/img/whole/original-new.png
new file mode 100644
index 0000000000000000000000000000000000000000..3c9f19ae8050a037ba29c82249cc7f3fda1a3db9
Binary files /dev/null and b/slides/wk05/img/whole/original-new.png differ
diff --git a/slides/wk05/img/whole/redcomp.png b/slides/wk05/img/whole/redcomp.png
new file mode 100644
index 0000000000000000000000000000000000000000..81dec38e9e9408f89fddf1c850100ef978395f2a
Binary files /dev/null and b/slides/wk05/img/whole/redcomp.png differ
diff --git a/slides/wk05/img/whole/value-sat.png b/slides/wk05/img/whole/value-sat.png
new file mode 100644
index 0000000000000000000000000000000000000000..b5ffb6814dde40eb19feca12d1c5d404219c0831
Binary files /dev/null and b/slides/wk05/img/whole/value-sat.png differ
diff --git a/slides/wk05/img/whole/window-with-menu.png b/slides/wk05/img/whole/window-with-menu.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce64e0a977b63efb250de2eac8551ceaebf94f44
Binary files /dev/null and b/slides/wk05/img/whole/window-with-menu.png differ
diff --git a/slides/wk05/img/whole/window.png b/slides/wk05/img/whole/window.png
new file mode 100644
index 0000000000000000000000000000000000000000..e1edc0bca27881e6b8a54fbdf4495b3e493886c8
Binary files /dev/null and b/slides/wk05/img/whole/window.png differ
diff --git a/slides/wk05/pps-geom.html b/slides/wk05/pps-geom.html
new file mode 100644
index 0000000000000000000000000000000000000000..ff0500f9ae11a47653368092d742cca3bd3134b1
--- /dev/null
+++ b/slides/wk05/pps-geom.html
@@ -0,0 +1,1099 @@
+---
+layout: presentation
+title: Event Handling III--Essential Geometry and View Updates
+description:
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# View Updates and Essential Geometry
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout:false
+
+[//]: # (Outline Slide)
+# Today's goals
+
+- Quick follow up from Monday - Click Listeners
+- Other Android callbacks
+- Input dispatching process (toolkit architecture)
+  - Picking (alternative: Focus)
+  - Capture
+  - Bubble
+- Propositional Production Systems in implementing interactors
+- Essential Geometry
+
+---
+# Before anyone asks
+
+- Accessibility is due Thursday night. There is no reflection.
+- Examlet is on Friday (starting the last half of class).
+  - To avoid distraction this will entirely be a "take home" examlet. You may leave "class"
+  once we begin. (I will stay in class in case people need to come back in for clarifications).
+  - Instructions will be on Ed.
+  - You will be given a Google doc link to copy to your drive. You MUST have
+   [UW's GSuite enabled](https://itconnect.uw.edu/connect/email/google-apps/getting-started/).
+  - You will complete the quiz in your version of the Google doc
+  - You will your solution as a PDF (File->Download->PDF) to your machine
+  - You will then upload the quiz to Gradescope Quiz 5.
+  - Any issues will be added to an erratta document (link will also be in the ed post.)
+  - We will give you (some) more time to handle the technology.
+
+---
+
+# Review of Monday
+
+- Events: logical input device abstraction
+- Event driven code: very different from procedural programming
+- Listeners are notified about events by the system and toolkit
+- Case study: implementing View.OnClickListener
+  - Creating a separate class/file or an inner class
+  - Creating an anonymous inner class
+  - Implementing an Interface
+  - Creating an anonymous class as a parameter
+  - Lambdas
+
+Please open [Ed Sway](https://us.edstem.org/courses/381/sway/)
+
+
+---
+
+template: inverse
+
+# Other Android Callbacks
+
+---
+layout: false
+
+# Event listeners Android sets up by default (1/3)
+
+- `onCreate`
+  - called when the activity is first created
+  - we've seen this in our Doodle, Layout, and even EventExampleActivity apps:
+
+```java
+@Override
+protected void onCreate(Bundle savedInstanceState) {
+  // We want to do any view initialization work here
+  super.onCreate(savedInstanceState);
+
+  // Load the XML representation of our layout into the view
+  setContentView(R.layout.activity_main);
+
+  // Any other work we need to do like adding views or
+  // registering click listeners!
+}
+```
+
+---
+
+# Event listeners Android sets up by default (2/3)
+
+- `onStart`
+  - Called when activity is about to be visible to the user
+  - Always gets called after `onCreate` or `onRestart`
+--
+- `onResume`
+  - Called when the activity will start interacting with a use
+  - Always gets called after `onStart`
+--
+- `onPause`
+  - Called when the system is about to start resuming another previous activity
+  - __Commit changes__ to persistent data, __stop animations & intense operations__, __kill network__ requests
+  - .red[Fast implementation required!] - the next activity will not resume until this finishes in your activity
+--
+- `onStop`: Called when the activity is no longer visible to the user
+---
+# Event listeners Android sets up by default (3/3)
+
+- `onRestart`
+  - Called when the activity was previously stopped but is coming back to the user
+  - Followed by a call to `onStart`
+--
+- `onDestroy`: the final notice before your activity is .red[__destroyed__]
+--
+  .center.half-width-img[
+    ![Cookie Monster Eating](img/event-delivery/cookie-monster.gif)
+  ]
+
+
+---
+template: inverse
+
+## Input Dispatch Process
+
+---
+layout: false
+
+# Input __Dispatch__ Process
+
+Input thread:
+- When a user interacts,  __events__ are created
+- Events go into a queue
+
+---
+# Input __Dispatch__ Process
+
+Input Thread
+
+Dispatch thread:
+- Front event comes off queue
+- Event gets sent to a listener (callback) attached to a `View` or `Activity`.
+- The `View` or `Activity` implements the callback
+
+---
+.left-column-half[
+## Event Dispatch (Summary)
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface, 100%](img/pps-geom/callbacks.png)]
+.right-column-half[
+Theoretical Dispatch Strategies
+- Positional
+  - Bottom-up: The event sent to the "lowest", frontmost interactor in the tree that
+contains the mouse position. If it's not wanted there it goes up the tree.
+  - Top-down: Event is sent to the topmost interactor that contains the mouse location, then passed
+  down recursively to children.
+  - Bubble out: Traversal starts top down, bounding rectangles are hints. Event is sent to bottom most item (drawn last),
+  the event can bubble back (with knowledge of what was hit).
+- Focus-based: Windowing system determines which interactor gets the event.
+]
+---
+.left-column-half[
+## Event Dispatch
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface and a do_action() call
+happening below the line in response to a button_pressed(), 100%](img/pps-geom/callbacks2.png)]
+.right-column-half[
+Callbacks handle *application* response to events
+- Update Application Model
+
+]
+
+---
+.left-column-half[
+## Event Dispatch
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface with do_action() replaced
+with an actionListener, 100%](img/pps-geom/callbacks3.png)]
+.right-column-half[
+Callbacks handle *application* response to events
+- Update Application Model
+- Best implemented using custom listeners
+
+]
+
+---
+# Another type of event: `onTouchEvent`
+
+- `onTouchEvent` is a callback that can be implemented on a `View` to react
+to a user's touch
+- Often used when creating your own new component.
+
+```java
+public class MyView extends View extends View.OnTouchListener {
+
+  @Override
+  protected void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+    ...
+    // register the touch event
+    setOnTouchListener(this)
+  }
+  ...
+  @Override
+  public boolean onTouchEvent(MotionEvent event) {
+    // Handle the touch event here
+  }
+}
+
+```
+---
+# Example: Overlapping windows
+
+.left-column40[
+<div class="mermaid">
+graph TD
+V0((V0)) --> V1((V1))
+V0 --> V4((V4))
+V1 --> V2((V2))
+V1 --> V3((V3))
+V4 --> V5((V5))
+V4 --> V6((V6))
+
+</div>
+]
+.right-column50[
+![:img Example of what this tree might look like in graphical form with V0 at the back, 60%](img/pps-geom/picklist.svg)
+]
+---
+# How does _Android_ decide where to send events?
+
+.left-column40[
+<div class="mermaid">
+graph TD
+V0((V0)) --> V1((V1))
+V0 --> V4((V4))
+V1 --> V2((V2))
+V1 --> V3((V3))
+V4 --> V5((V5))
+V4 --> V6((V6))
+
+</div>
+]
+.right-column50[
+- Android traverses the view hierarchy (starting at root)
+- "Picks" `View` obects that respond to an input event
+- Loops through the list of `View` objects, checks if they will "capture" the event
+- If none capture the event, the event "bubbles" back up the `View`
+  object list
+]
+
+---
+# Input Process - Picking
+
+.left-column40[
+<div class="mermaid">
+graph TD
+V0((V0)) --> V1((V1))
+V0 --> V4((V4))
+V1 --> V2((V2))
+V1 --> V3((V3))
+V4 --> V5((V5))
+V4 --> V6((V6))
+
+</div>
+]
+.right-column50[
+- In what order does dispatch "pick" the `View` objects?
+]
+--
+.right-column50[
+- Hint: Post order traversal of the tree
+]
+--
+.right-column50[
+- Picked Views = {`V2`, `V3`, `V1`, `V5`, `V6`, `V4`, `V0`}
+- Order matters!
+]
+---
+# Input Process - Picking
+
+.left-column40[
+<div class="mermaid">
+graph TD
+V0((V0)) --> V1((V1))
+V0 --> V4((V4))
+V1 --> V2((V2))
+V1 --> V3((V3))
+V4 --> V5((V5))
+V4 --> V6((V6))
+</div>
+]
+
+.right-column50[
+But we can refine this! We can filter!
+
+What are some reasons to skip views?
+]
+--
+.right-column50[
+- Not inside the view
+- View doesn't care about that type of input
+
+![:img Example of what this tree might look like in graphical form with V0 at the back, 40%](img/pps-geom/picklist.svg)
+
+]
+
+---
+# Input Process - Picking only those interested
+
+.left-column40[
+
+<div class="mermaid">
+graph TD
+V0((V0)) --> V1((V1*))
+V0 --> V4((V4*))
+V1 --> V2((V2))
+V1 --> V3((V3*))
+V4 --> V5((V5))
+V4 --> V6((V6*))
+
+class V0,V2,V5 blue
+class V1,V4,V3,V6 bluegreen
+</div>
+]
+
+.footnote[*: denotes the element responds to the event because of position/type]
+
+---
+# Input Example - Capture
+
+.left-column40[
+<div class="mermaid">
+graph TD
+V0((V0)) --> V1((V1*))
+V0 --> V4((V4*))
+V1 --> V2((V2))
+V1 --> V3((V3*))
+V4 --> V5((V5))
+V4 --> V6((V6*))
+
+class V0,V2,V5 blue
+class V1,V4,V3,V6 bluegreen
+</div>
+]
+.right-column50[
+Picked Views = {`V3`, `V1`, `V6`, `V4`}
+
+What happens next?
+]
+--
+.right-column50[
+- Dispatch starts at the end of the picked `View` object list (`V4`)
+- Walking down the list, dispatch asks: will you consume this event?
+  - If `true`: the event is consumed and the event propagation __stops__
+  - If `false`: Move to the next element in the `View` list
+]
+---
+# Input Example - Capture
+
+.left-column40[
+<div class="mermaid">
+graph TD
+V0((V0)) --> V1((V1*))
+V0 --> V4((V4*))
+V1 --> V2((V2))
+V1 --> V3((V3*))
+V4 --> V5((V5))
+V4 --> V6((V6*))
+
+class V0,V2,V5 blue
+class V1,V4,V3,V6 bluegreen
+</div>
+]
+.right-column50[
+Picked Views = {`V3`, `V1`, `V6`, `V4`}
+
+- Dispatch starts at the end of the picked `View` object list (`V4`)
+- Android backtracks through the list, asking if they want to consume the event
+- Does this correspond to a top-down or bottom-up dispatch strategy?
+- What happens when we reach the last `View` in the list and no one has consumed the event?
+]
+???
+It's top-down
+
+---
+# Input Example - Bubbling
+
+.left-column40[
+<div class="mermaid">
+graph TD
+V0((V0)) --> V1((V1*))
+V0 --> V4((V4*))
+V1 --> V2((V2))
+V1 --> V3((V3*))
+V4 --> V5((V5))
+V4 --> V6((V6*))
+
+class V0,V2,V5 blue
+class V1,V4,V3,V6 bluegreen
+</div>
+]
+.right-column50[
+Picked Views = {`V3`, `V1`, `V6`, `V4`}
+]
+
+--
+.right-column50[
+- Android starts at the front of the list `V3`, asking if they want to consume the event
+- Does this correspond to a top-down or bottom-up dispatch strategy?
+
+Note: Bubbling in this case is not the bubble-out in the theoretical case.
+]
+
+???
+bottom-up!
+---
+# Input Example - Recap
+
+.left-column40[
+<div class="mermaid">
+graph TD
+V0((V0)) --> V1((V1*))
+V0 --> V4((V4*))
+V1 --> V2((V2))
+V1 --> V3((V3*))
+V4 --> V5((V5))
+V4 --> V6((V6*))
+
+class V0,V2,V5 blue
+class V1,V4,V3,V6 bluegreen
+</div>
+]
+.right-column50[
+|State           |Ordering         |
+|:---------------|:----------------|
+|*Picking*       | V3| V1 | V6 | V4|
+|*Capture Order* | 4 | 3  | 2  | 1 |
+|*Bubbling Order*| 1 | 2  | 3  | 4 |
+]
+
+---
+# Stuff to ponder: How would you handle input in a circular component?
+???
+Consumption is based on the bounding box...
+--
+
+Delivery is based on bounding box
+
+Return `false` if input is outside circle even if it's in the bounding box
+
+---
+# Stuff to ponder: How would you handle focus input?
+
+- Some event types are focus based (e.g. keyboard input)
+- Just skip picking: Focus list is globally created, and we walk it the same way
+
+---
+# Stuff to ponder: Implementing Drag and Drop
+
+Focus? Or Positional?
+
+--
+[Android's tutorial is positional](https://developer.android.com/training/gestures/scale#java)
+
+
+---
+# How does *Android* decide where to send events?
+
+- **Capture** (most things don’t) top to bottom deliver to target
+   object (bottom)
+   - example: `onInterceptTouchEvent()` in Android
+- **Pick** to identify objects of interest (or just focus())
+   - `buildTouchDispatchChildList()` in Android; happens only after capture!
+- **Bubble** (bottom to top)
+   - example: `onTouchEvent()` in Android
+- Invoke callback (wait until complete)
+  - we do this by creating a custom listener in Android
+
+.footnote[fascinating to look at [implementation in
+ViewGroup](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/view/ViewGroup.java)
+-- not very general!]
+
+---
+# Note about event records
+
+- Where
+  - Where is the location of the cursor (x,y position on the screen)
+  - For focus based events, where is often the target
+- Value is anything you might need to know (like whether it's a 1 or 2 finger swipe; or which key was pressed)
+
+Why is this important? For *picking*:
+- When input is positional, *only* interactors whose bounding box includes (x,y) -- where -- are picked
+- When input is focus based, *only* interactors in the focus list are picked. Where isn't used in dispatch
+
+
+---
+
+# Creating a new type of listener
+
+Application callbacks can be implemented as custom listeners
+
+
+```java
+// Defines a new named inner interface for listening to an interesting event
+public interface MyListener {
+    void onInterestingEvent(); // can include a parameter
+}
+
+// variable to store the listener in once registered. Could also be a list of
+// listeners that are all called if the callback is triggered.
+protected MyView.MyListener mListener;
+
+public void setMyListener(MyListener mListener) {
+    this.mListener = mListener;  // could also be stored in a list.
+}
+...
+
+// somewhere else in your code, when callback time happens
+public void someMethod() {
+  mListener.onInterestingEvent();
+}
+
+```
+---
+
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Using Input to Create Interaction Techniques
+
+## State Machines, PPS, Essential Geometry
+
+---
+layout:false
+
+# Interaction Technique
+
+A method for carrying out a specific interactive task
+
+For example: For entering a number in a range you could use...
+
+???
+have the class try to think of examples
+--
+- (simulated) slider
+- (simulated) knob
+- type in a number (text edit box)
+
+Each is a different interaction technique
+---
+# Example: Specify the end points for a line
+
+Could just specify two endpoints – click, click
+- not good: no affordance
+  - no feedback (/ feedforward)
+
+Better feedback is to use “rubber banding”
+- stretch out the line as you drag
+- at all times, shows where you would end up <br> if you “let go”
+???
+Importance of feedback vs application callback
+---
+# Implementing rubber banding
+
+```
+Accept the press for endpoint P1; P2 = P1;
+Draw line P1-P2;
+Repeat
+  Erase line P1-P2;
+  P2 = current_position(); Draw line P1-P2;
+Until release event;
+Act on line input;
+```
+
+???
+Discuss!
+Not event based
+Not in the basic event/redraw loop
+Potentially locks up the system
+---
+# Implementing rubber banding
+
+Need to get around this loop <br> absolute min of 5 times / sec
+
+– 10 times better
+
+– more would be better but might block system.
+
+???
+aside -- why 5-10 times per second?
+
+---
+# Event driven code
+
+Needs to respond to events as they arrive
+
+Needs to maintain state between events
+
+---
+# Solution: State Machine
+
+- State Machines are used to respond to incoming events and allows for us to store state between events.
+- Start state - indicated with incoming arrow
+- End state - indicated with double-layered shape (means "reset to start")
+- Transition States - indicated with single-layered shape
+- Event Arrows - indicated with an arrow between states, represent different actions taken up states.
+
+.left-column40[
+<div class="mermaid">
+graph LR
+S((.)) --> A((A))
+A -- "a" --> B((B))
+B -- "b" --> B
+B -- "b" --> C[C]
+
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+
+
+class S invisible
+class A start
+class C finish
+class B normal
+</div>
+]
+--
+.right-column50[
+Is the folowing "accepted" by the above state machine?
+
+- ab
+- abbbbbb
+- aab
+- abbbbba
+]
+---
+# Solution: State Machine
+
+- State Machines are used to respond to incoming events and allows for us to store state between events.
+- Start state - indicated with incoming arrow
+- End state - indicated with double-layered shape (means "reset to start")
+- Transition States - indicated with single-layered shape
+- Event Arrows - indicated with an arrow between states, represent different actions taken up states.
+
+
+<div class="mermaid">
+graph LR
+S((.)) --> A((A))
+A -- "Event1/Callback1()" --> B((B))
+B -- "Event2/Callback2()" --> B
+B -- "Event3/Callback3()" --> C[C]
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+
+class S invisible
+class A start
+class C finish
+class B normal
+</div>
+
+
+---
+# Propositional Production System (PPS)
+
+- State machine is just the start, stop and interim states with arrows with nothing on them.
+- PPS is a state machine with extra conditions required to fire on the arrows.
+  - ? predicate (Boolean expr) before event, adds extra conditions required to transition
+  - action calls
+- Typical notation
+
+  event : pred ? action
+
+- Example
+
+  MouseUp:inView?Start_Line()
+
+- Finite State Machine (FSM) augmented with guards is Turing complete
+
+
+---
+# PPS Example: Rubber Banding
+
+
+.left-column-half[
+Compare to previous implementation:
+
+```
+Accept the press for endpoint P1; P2 = P1;
+Draw line P1-P2;
+Repeat
+  Erase line P1-P2;
+  P2 = current_position(); Draw line P1-P2;
+Until release event;
+Act on line input;
+```
+]
+.right-column-half[
+
+- Determine the Events (triggers)
+
+- Determine the States
+
+- Determine the Actions
+
+- Determine the Queries
+]
+---
+# PPS Example: Rubber Banding
+.left-column40[
+Compare to previous implementation:
+
+```
+Accept the press for endpoint P1; P2 = P1;
+Draw line P1-P2;
+Repeat
+  Erase line P1-P2;
+  P2 = current_position(); Draw line P1-P2;
+Until release event;
+Act on line input;
+```
+]
+
+.right-column50[
+
+<div class="mermaid">
+graph TD
+S((.)) --> A((Start))
+A -- "Mouse Down:inView?Start_Line()" --> B((Drawing))
+B -- "Mouse_Move:inView?Update()" --> B
+B -- "Mouse_Release:inView?Finish_Line()" --> C[Finished]
+
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+
+class S invisible
+class A start
+class C finish
+class B normal
+</div>
+
+]
+
+---
+# PPS Example: Rubber Banding
+.left-column40[
+
+Reading a state machine: translates input sequence into action!
+- When you are in Start State, and a Mouse Down event arrives, do
+  the action `Start_line()` and go to Drawing State.
+- Update  the line end point position every time the mouse moves.
+- When it releases (Mouse Release event), finish the line (at this
+  stage a callback to the application might be appropriate)
+]
+
+.right-column50[
+
+<div class="mermaid">
+graph TD
+S((.)) --> A((Start))
+A -- "Mouse Down:?inView/Start_Line()" --> B((Drawing))
+B -- "Mouse_Move:?inView/Update()" --> B
+B -- "Mouse_Release:?inView/Finish_Line()" --> C[Finished]
+
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+
+class S invisible
+class A start
+class C finish
+class B normal
+</div>
+
+]
+
+???
+
+How could we provide a better affordance?
+
+Does it matter if we are using a mouse or a touch screen?
+
+
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Using Essential Geometry as the basis for state
+
+---
+layout:false
+
+# Using Essential Geometry as the basis for state
+
+.left-column-half[
+![:img google doc with scrollbar, 80%](img/pps-geom/window.png)
+
+]
+
+.right-column-half[
+- What is the essence (or nature) of this scrollbar? Where can you interact with it?
+]
+
+---
+
+# Using Essential Geometry as the basis for state
+
+.left-column-half[
+![:img google doc with scrollbar, 80%](img/pps-geom/window.png)
+
+]
+
+.right-column-half[
+- What is the essence (or nature) of this scrollbar? Where can you interact with it?
+  - on the thumb
+  - inside the scrollbar above the thumb
+  - inside the scrollbar below the thumb
+  - inside up arrow
+  - inside the down arrow
+]
+
+--
+.right-column-half[
+- How do we implement a scroll bar like this?
+]
+
+---
+# Scrollbar State machine with Essential Geometry
+
+<div class="mermaid">
+graph LR
+S((.)) --> START((START))
+START -- "MouseDown:InThumb?StartScroll()" --> SCROLLING((SCROLLING))
+START -- "MouseClick:InsideAboveThumb?Scrollup()" --> DONE((DONE))
+START -- "MouseClick:InsideBelowThumb?Scrolldown()" --> DONE((DONE))
+SCROLLING -- "MouseMove:updateThumbDocument()" --> SCROLLING
+SCROLLING -- "MouseUp:KeepLocation()" --> DONE
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+linkStyle 4 stroke-width:4px;
+linkStyle 5 stroke-width:4px;
+
+class S invisible
+class START start
+class SCROLLING normal
+class DONE finish
+</div>
+
+---
+# Let's try it for a button
+
+.left-column-half[
+Essential geometry is:
+- InsideButton
+- OutsideButton
+
+and methods for
+- `indentButton()` (when button is pressed)
+- `normalButton()` (when button is not pressed)
+- `invokeAction()` (when the user releases in the button)
+- `cancelAction()` (when the user releases outside the button)
+
+]
+
+---
+# You should have something like this
+
+.left-column40[
+Essential geometry is:
+- Inside
+- Outside
+
+and methods for
+- `indentButton()` (when button is pressed)
+- `normalButton()` (when button is not pressed)
+- `invokeAction()` (when the user releases in the button)
+- `cancelAction()` (when the user releases outside the button)
+
+]
+.right-column50[
+<div class="mermaid">
+graph TD
+S((.)) --> START((START))
+START -- "DOWN:Inside?indentButton()" --> PRESSED((PRESSED))
+PRESSED -- "MOVE:Outside?normalButton()" --> PRESSED
+PRESSED -- "UP:Outside?cancelAction()" --> END[END]
+PRESSED -- "UP:Inside?invokeAction()" --> END
+PRESSED -- "MOVE:Inside?indentButton()" --> PRESSED
+
+linkStyle 0 stroke-width:2px;
+linkStyle 1 stroke-width:2px;
+linkStyle 2 stroke-width:2px;
+linkStyle 3 stroke-width:2px;
+linkStyle 4 stroke-width:2px;
+linkStyle 5 stroke-width:2px;
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF;
+
+class S invisible
+class START start
+class PRESSED normal
+class END finish
+</div>
+
+]
+
+
+---
+# How do we implement this?
+.left-column-half[
+- Implement in `onTouch()` using a switch statement
+- Assume there is an
+`essentialGeometry(MotionEvent event)` method. It returns a enum that tells you what
+ part of the geometry you are in for that point.
+- Assume implementations of all the methods
+- Assume a field, `state` which is the current state of the state machine
+- enums `EssentialGeometry` and `State` for comparing against
+]
+.right-column-half[
+
+```java
+@Override
+public boolean onTouch(MotionEvent e) {
+  EssentialGeometry geometry = essentialGeometry(event);
+  switch (state) {
+    case State.START:
+      if (geometry == Geometry.INSIDE && e.getAction() == MotionEvent.ACTION_DOWN) {
+         indentButton();
+         state = State.PRESSED;
+         return true;
+      }
+      break;
+    case PRESSED
+      if (e.getAction() == MotionEvent.ACTION_MOVE) {
+        if (geometry == Geometry.INSIDE) {
+          indentButton();
+    	  } else {
+          normalButton();
+        }
+        return true;
+      }
+      else if (e.getAction() == MotionEvent.ACTION_UP) {
+        state = State.START; // note we don't actually use the END state
+        if (geometry == Geometry.INSIDE) {
+          invokeAction();
+        } else {
+          cancelAction();
+        }
+        return true;
+      }
+      break;
+    default:
+      break;
+  }
+  return false;
+}
+```
+]
+
+---
+# Enums
+
+Enums are a group of named constants
+
+- Often used for developing interactions for defining PPS States and Essential Geometry
+- Will be used in ColorPicker and in Menu assignment for interaction *and* for experimental conditions
+- Good code quality: limits choices of what a variable can be.
+
+[Documentation](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)
+
+---
+
+.left-column[
+## Harder Button
+
+![:img FB Messenger Animation, 100%](img/pps-geom/messenger-bubble.gif)
+
+]
+.right-column[
+- Determine the Events (triggers)
+
+- Determine the States
+
+- Determine the Queries (essential geometry, context)
+
+- Determine the Actions
+]
+
+???
+What constitutes an “event” varies
+
+- may be just low level events, or
+- higher level (synthesized) events
+- e.g. region-enter, press-inside
+
+What is missing? Query fields
+
+---
+.left-column[
+## Facebook Button Solution
+![:img FB Messenger Animation, 100%](img/pps-geom/messenger-bubble.gif)
+]
+--
+.right-column[
+
+Press:inside? => highlight(), start_animation(), small, active<br>
+AnimateStep ==> update(), active<br>
+AnimateFinish ==> !small, active<br>
+Release:inside,small => unhighlight(), exit()<br>
+Release:inside,!small => add_to_chat(), small, unhighlight(),
+exit()<br>
+
+__rest is unknowable from this animation__
+
+<div class="mermaid">
+  graph LR
+  S((.)) --> A((Start))
+  A -- "Press:inside?highlight(),start_animation()" --> B((Active))
+  B -- "AnimateStep,update()" --> B
+  B -- "AnimateFinish,!small"--> B
+  B -- "Release,inside:small, unhighlight" -->D(End)
+  B -- "Release,inside:!small,add_to_chat(),unhighlight()" --> D
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:2px;
+linkStyle 1 stroke-width:2px;
+linkStyle 2 stroke-width:2px;
+linkStyle 3 stroke-width:2px;
+linkStyle 4 stroke-width:2px;
+linkStyle 5 stroke-width:2px;
+
+class S invisible
+class A start
+class D finish
+class B normal
+</div>
+
+]
+
+---
+# When to use PPSs
+
+You're probably already using them, just not intentionally (and maybe
+less well as a result)
+
+PPSs are a good way to do control flow in event driven systems
+
+Can do (formal or informal) analysis
+- are all possible inputs (e.g. errors) handled from each state
+- what are next legal inputs: can use to enable / disable
+
+Can be automated based on higher level specification
+
+---
+
+# Summary
+
+State machines are very good (for this job) but do have limits
+
+State machines don't handle independent actions very well (state explosion)
+
+Mostly useful for smaller things
+
+- Great for individual components
+- Not so great for whole dialogs
+
+Path of least resistance is rigid sequencing
+ Ask: is this good for what I am doing?
+
+???
diff --git a/slides/wk05/review.html b/slides/wk05/review.html
new file mode 100644
index 0000000000000000000000000000000000000000..5b3d4aec65b5d57848e6124173f0793014f2e771
--- /dev/null
+++ b/slides/wk05/review.html
@@ -0,0 +1,222 @@
+---
+layout: presentation
+title: The whole toolkit
+description: Review of what we know about GUI toolkits
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Review slides to help studying
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout:false
+
+.left-column[
+## And Introduced Model View Controller
+]
+.right-column[
+Model
+- Model of a single interactor: Typically a field
+- Application model
+ - Separate from view model
+ - Typically more persistent (*e.g.,* a database)
+
+View
+- `onDraw()` in a single interactor
+- Interactor hierarchy in an application
+
+Controller
+- state machine in a single interactor
+- callbacks (*e.g.,* custom listeners) in an application
+]
+???
+Different for Interactor and Application
+
+---
+.left-column-half[
+## Event Dispatch
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface, 100%](img/whole/callbacks.png)]
+.right-column-half[
+Dispatch Strategies
+- Positional (Bottom-first and top-down)
+- Focus-based
+
+State Machine describes *within-view* response to events
+]
+---
+.left-column-half[
+## Event Dispatch
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface and a do_action() call
+happening below the line in response to a button_pressed(), 100%](img/whole/callbacks2.png)]
+.right-column-half[
+Callbacks handle *application* response to events
+- Update Application Model
+
+]
+
+---
+.left-column-half[
+## Event Dispatch
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface with do_action() replaced
+with an actionListener, 100%](img/whole/callbacks3.png)]
+.right-column-half[
+Callbacks handle *application* response to events
+- Update Application Model
+- Best implemented using custom listeners
+
+]
+---
+# Value of component abstraction
+
+Each component knows how to draw itself
+
+Based on what it is and its internal state
+
+Includes some common properties (inherited from a base class for all components), E.g.
+
+- position (x,y relative to parent)
+- size (w,h)
+- visible
+- Enabled
+
+Typically includes some specialized properties (declared in
+subclass)
+
+---
+# More Output/Drawing Concepts
+
+Drawing primitives – populate a pixel array (*Frame Buffer*)
+
+Coordinate transformations (translate/scale/rotate/shear) & Clipping
+
+Fonts: Archaic origins, Non standardized
+- UI toolkit implications?
+
+---
+.left-column[
+## Input/Event Concepts
+]
+.right-column[
+Devices
+
+- Logical: Valuator, Locator, Button, etc
+- Event vs. sampled devices
+- Absolute vs. Relative (and clutched)
+
+Event model to unify event and sampled devices
+- What
+- When
+- Where
+- Value
+- Context
+]
+---
+# Review: None-core concepts
+---
+layout:false
+
+# How an animation is set up
+
+Need the start and end value of the properties to be
+modified. Typically use a
+[Path](https://developer.android.com/reference/android/graphics/Path)
+for this.
+
+Need a *duration* (total time in ms for the animation)
+
+Need the *pacing function* for animation. Can explore subclasses of
+[Interpolator](https://developer.android.com/reference/android/view/animation/Interpolator)
+(or make your own!) for this
+
+---
+.left-column[
+## Example pacing functions
+![:img Picture of for types of interpolation functions provided with
+android, 100%](img/whole/interpolators.gif)
+]
+.right-column[
+<br><br><br><br>
+Slow in slow out (Accelerate/decelerate)
+
+Slow in (Accelerate)
+
+Anticipate (back up slightly, then accelerate)
+
+Anticipate Overshoot (same, then go too far and slow down)
+]
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+
+# Understanding People
+---
+layout:false
+
+# HSV
+
+RGB matches the eye (rods & cones, red green and blue)
+
+HSV is much better for *people*
+- Hue: Dominant wavelength of light
+- Saturation: Purity (how much white/black mixed in)
+- Value: Luminance or amount of light in color = max(R,G,B)
+
+---
+.left-column[
+## Example Short Answer Exam Question
+![:img Darker and lighter red boxes, 80%](img/whole/redcomp.png)
+![:img Red with varying saturation (to white) and value (to black), 80%](img/whole/value-sat.png)
+
+]
+.right-column[
+# Compare the following colors using HSV
+Which is correct?
+
+- A: Top color has different *hue* than bottom color
+- B: Top color has higher *saturation* than bottom color
+- C: Top color has higher *value* than bottom color
+]
+???
+B: Saturation
+
+---
+# Know your speeds (order of magnitude is key thing here)
+
+< ~20ms (1/50 sec) discrete images/flashes merge into continuous perception
+
+smooth animation: 24-40  frames per second
+
+< ~100-200ms seems like “instant response”
+- on web a difference of 250 ms can switch people to a competitor
+
+< 1-2 seconds typically “good response time”
+
+More than 10-15 sec is typically “bad response time”
+
+---
+# Recap of design tips
+
+- Don't rely on blue for small objects
+- Don't rely on blue for older users
+- Make sure that contrast is high enough
+- Minimize saturated colors
+- Use redundant cues
+- Make things distinct
+- Use small multiples
+- Manage expectations if you can't change response time
+- Replace subtle changes with obvious ones
+- Use well-tested visual grouping strategies
+- Minimize the number of options
+- Rely on recognition rather than recall
diff --git a/slides/wk05/unused-maybe.html b/slides/wk05/unused-maybe.html
new file mode 100644
index 0000000000000000000000000000000000000000..c18f3c32607cc0f28305f70017f9702f9dcf0663
--- /dev/null
+++ b/slides/wk05/unused-maybe.html
@@ -0,0 +1,41 @@
+
+---
+# Summary
+- MVC: Separation of concerns for user interaction
+--
+
+- Events: logical input device abstraction
+--
+
+- We model everything as events
+ - Sampled devices
+   - Handled as “incremental change” events
+   - Each measurable change: a new event with new value
+ - Device differences
+   - Handled implicitly by only generating events they can generate
+ - Recognition Based Input?
+   - Yes, can generate events for this too
+
+
+
+
+
+# End of Deck
+
+
+---
+# Input __Dispatch__ Process
+
+Input Thread
+
+Dispatch thread
+
+Components:
+- Components have to listen for events (callbacks)
+- How do components respond?
+
+???
+- remind them that component/view/interactor are interchangeable in
+  this class
+- Update application state if appropriate
+- Request repaint if needed
diff --git a/slides/wk05/whole-toolkit.html b/slides/wk05/whole-toolkit.html
new file mode 100644
index 0000000000000000000000000000000000000000..5d8aab6772e809f3b8cdda521d80b10121f02ac9
--- /dev/null
+++ b/slides/wk05/whole-toolkit.html
@@ -0,0 +1,459 @@
+---
+layout: presentation
+title: The whole toolkit
+description: Review of what we know about GUI toolkits
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# The whole toolkit
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout:false
+
+[//]: # (Outline Slide)
+# Today's goals
+
+- Update from Wednesday
+- Last bit about Essential Geometry
+- Let's look at colorpicker
+- Review and summarize core toolkit architecture
+
+---
+# Event Dispatch
+
+- Top-down, Bottom-Up, Bubble-out, Focused-based: these are theoretical Event dispatch.
+- Android does it a bit differently.
+- Capture is top-down: start on the in the biggest interactor that contains the event,
+ then narrow in on which window actually will use the event
+- Bubbling is bottom-up - start with the window at the front (the last drawn, lowest in the
+interactor tree) - see if the event is consumed by that interactor. If not, go up the tree.
+
+---
+# Other comments
+
+- layout varies depending on the specific layout container
+  - ConstraintLayouts don't need multiple passes, it's a top down structure.
+  - LinearLayout is post order for measure (measure the children, who first measure their children)
+  - In general, have to look at implementation to know for sure.
+-  `onDraw` is usually pre-order (Intuitively leaf nodes should be 'on top' of parents)
+- *Capture* is rarely used by component developers
+- *Bubbling* is far more common
+- Interface programmers just need to use callbacks, not worry about this stuff
+
+---
+# Colorpicker assignment
+
+---
+
+.left-column[
+## Have now seen *almost* all the parts of an interface
+]
+.right-column[
+
+Input
+
+- Input models (events)
+- Event dispatch
+- Event handling (state machine)
+- Callbacks to application
+
+Output
+- Interactor Hierarchy design & use
+- Drawing models (`onDraw()`)
+- Layout (`onLayout()` or `XML`)
+- Damage and redraw process
+]
+---
+.left-column-half[
+# Core Toolkit Architecture
+
+Wait for *Event*
+
+*Dispatch* may cause change to:
+- interactor state
+- interactor hierarchy
+- application model
+]
+
+???
+What do you need to know though? Mostly only if you are a component developer
+
+--
+.right-column-half[
+# Component Developer
+
+Implement event handler (e.g. `onTouch()`)
+
+Handle *Dispatch*
+- Update interactor state & model if needed
+- Notify application if application model should change (with a callback)
+- Call `invalidate()`
+]
+
+???
+What about if you are an app developer? Basically, just use callbacks
+
+---
+.left-column-half[
+# Core Toolkit Architecture
+
+If damage do
+- *layout* (may change)
+ - position
+ - size
+- If damage do *redraw*
+]
+
+--
+.right-column-half[
+# Component Developer
+
+- May need to implement `onMeasure()`  and `onLayout()` (if a container)
+- Will always implement `onDraw()` but *never call it* (call `invalidate()` instead)
+]
+
+---
+## View Update: .red[Damage/Redraw]
+
+How does the toolkit know what to redraw?
+
+What causes damage?
+???
+concrete example on next slide
+---
+.left-column[
+## View Update: .red[Damage/Redraw]
+]
+
+.right-column[
+What should be redrawn?
+
+![:img google doc with scrollbar, 50%](img/whole/window.png)
+]
+
+---
+
+.left-column[
+## View Update: .red[Damage/Redraw]
+]
+
+.right-column[
+What should be redrawn?
+
+![:img google doc with scrollbar, 50%](img/whole/window-with-menu.png)
+]
+---
+
+.left-column[
+## View Update: .red[Damage/Redraw]
+]
+
+.right-column[
+What should be redrawn?
+
+![:img google doc with scrollbar, 50%](img/whole/combined.png)
+]
+
+---
+## View Update: .red[Damage/Redraw]
+
+How does the toolkit know what to redraw?
+
+What causes damage?
+???
+Can you think about other things?
+- Window hidden and re-exposed
+- Resizing
+- redrawing
+
+--
+
+<br><br>Naive approach to redraw
+
+---
+
+## View Update: .red[Damage/Redraw]
+
+
+![:img pic of original screen and changed screen, 72%](img/whole/original-new.png)
+
+
+???
+XXX TODO ADD pic like this using divs?
+
+- Can be slow (redrawing everything unecessary)
+- Can cause flickering
+ - double buffering is better,
+ - hence the 'Canvas' abstraction or equivalent
+ - can then switch which FB is displayed (very fast)
+
+---
+## View Update: .red[Damage/Redraw]
+
+![:img pic of original screen and changed screen, 72%](img/whole/original-new.png)
+![:img pic with double buffering included, 70%](img/whole/full-solution-buffering.png)
+
+---
+## View Update: .red[Damage/Redraw]
+
+![:img pic of original screen and changed screen, 72%](img/whole/original-new.png)
+![:img pic with double buffering included, 70%](img/whole/full-solution-buffering.png)
+
+**Never** just draw:  Why not?
+
+
+???
+- Update *state*
+- Report *damage* (by calling 'repaint())
+- Wait for *toolkit to request redraw*
+ (also works if damage comes from elsewhere)
+- How does it generalize to any cause of damage (always need state!!)
+
+---
+## View Update: .red[Damage/Redraw]
+
+How does the toolkit know what to redraw?
+ - Let the component report: Damage/Redraw invoked by `invalidate()` or equivalent
+
+
+---
+## View Update: .red[Damage/Redraw]
+
+How does the toolkit know what to redraw?
+- Let the component report (`invalidate()`) **NOTE** we are *not* calling *onDraw()* directly (important for your assignment)
+- Aggregate
+- Usually calculate bounding box
+
+
+---
+## View Update: .red[Draw/Redraw]
+
+Virtual device abstraction provided by windowing system
+
+Component abstraction provided by toolkit
+- Enforced using clipping
+- Supported using coordinate system transformations
+
+
+Drawing is recursive
+- Makes it possible for parent to *decorate* kids
+- Parent responsible for making kids think they are the center of the universe (translate)
+- Clipping: intersect parent and child, also handled by parent
+
+???
+
+Allows each program to (mostly) pretend that it has the screen (frame
+buffer) to itself
+
+Allows each component to (mostly) pretend that it has the screen to
+itself
+
+
+---
+# Core Toolkit Architecture
+
+If damage do
+- *layout* (may change)
+ - position
+ - size
+- If damage do *redraw*
+ - Union of damage (any of those can cause it) used to trigger redraw of anything inside that union
+ - Drawing + clipping – standard drawing order, but only for things damaged; clipped to damage region
+ - Clear damage
+
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Using Essential Geometry as the basis for state
+
+---
+layout:false
+
+# Using Essential Geometry as the basis for state
+
+.left-column-half[
+![:img google doc with scrollbar, 80%](img/pps-geom/window.png)
+
+]
+
+.right-column-half[
+- What is the essence (or nature) of this scrollbar? Where can you interact with it?
+]
+
+---
+
+# Using Essential Geometry as the basis for state
+
+.left-column-half[
+![:img google doc with scrollbar, 80%](img/pps-geom/window.png)
+
+]
+
+.right-column-half[
+- What is the essence (or nature) of this scrollbar? Where can you interact with it?
+  - on the thumb
+  - inside the scrollbar above the thumb
+  - inside the scrollbar below the thumb
+  - inside up arrow
+  - inside the down arrow
+]
+
+--
+.right-column-half[
+- How do we implement a scroll bar like this?
+]
+
+---
+# Scrollbar State machine with Essential Geometry
+
+<div class="mermaid">
+graph LR
+S((.)) --> START((START))
+START -- "MouseDown:InThumb?StartScroll()" --> SCROLLING((SCROLLING))
+START -- "MouseClick:InsideAboveThumb?Scrollup()" --> DONE((DONE))
+START -- "MouseClick:InsideBelowThumb?Scrolldown()" --> DONE((DONE))
+SCROLLING -- "MouseMove:updateThumbDocument()" --> SCROLLING
+SCROLLING -- "MouseUp:KeepLocation()" --> DONE
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+linkStyle 4 stroke-width:4px;
+linkStyle 5 stroke-width:4px;
+
+class S invisible
+class START start
+class SCROLLING normal
+class DONE finish
+</div>
+
+---
+# Let's try it for a button
+
+.left-column-half[
+Essential geometry is:
+- InsideButton
+- OutsideButton
+
+and methods for
+- `indentButton()` (when button is pressed)
+- `normalButton()` (when button is not pressed)
+- `invokeAction()` (when the user releases in the button)
+- `cancelAction()` (when the user releases outside the button)
+
+]
+
+---
+# You should have something like this
+
+.left-column40[
+Essential geometry is:
+- Inside
+- Outside
+
+and methods for
+- `indentButton()` (when button is pressed)
+- `normalButton()` (when button is not pressed)
+- `invokeAction()` (when the user releases in the button)
+- `cancelAction()` (when the user releases outside the button)
+
+]
+.right-column50[
+<div class="mermaid">
+graph TD
+S((.)) --> START((START))
+START -- "DOWN:Inside?indentButton()" --> PRESSED((PRESSED))
+PRESSED -- "MOVE:Outside?normalButton()" --> PRESSED
+PRESSED -- "UP:Outside?cancelAction()" --> END[END]
+PRESSED -- "UP:Inside?invokeAction()" --> END
+PRESSED -- "MOVE:Inside?indentButton()" --> PRESSED
+
+linkStyle 0 stroke-width:2px;
+linkStyle 1 stroke-width:2px;
+linkStyle 2 stroke-width:2px;
+linkStyle 3 stroke-width:2px;
+linkStyle 4 stroke-width:2px;
+linkStyle 5 stroke-width:2px;
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF;
+
+class S invisible
+class START start
+class PRESSED normal
+class END finish
+</div>
+
+]
+
+
+---
+# How do we implement this?
+.left-column-half[
+- Implement in `onTouch()` using a switch statement
+- Assume there is an
+`essentialGeometry(MotionEvent event)` method. It returns a enum that tells you what
+ part of the geometry you are in for that point.
+- Assume implementations of all the methods
+- Assume a field, `state` which is the current state of the state machine
+- enums `EssentialGeometry` and `State` for comparing against
+]
+.right-column-half[
+
+```java
+@Override
+public boolean onTouch(MotionEvent e) {
+  EssentialGeometry geometry = essentialGeometry(event);
+  switch (state) {
+    case State.START:
+      if (geometry == Geometry.INSIDE && e.getAction() == MotionEvent.ACTION_DOWN) {
+         indentButton();
+         state = State.PRESSED;
+         return true;
+      }
+      break;
+    case PRESSED
+      if (e.getAction() == MotionEvent.ACTION_MOVE) {
+        if (geometry == Geometry.INSIDE) {
+          indentButton();
+    	  } else {
+          normalButton();
+        }
+        return true;
+      }
+      else if (e.getAction() == MotionEvent.ACTION_UP) {
+        state = State.START; // note we don't actually use the END state
+        if (geometry == Geometry.INSIDE) {
+          invokeAction();
+        } else {
+          cancelAction();
+        }
+        return true;
+      }
+      break;
+    default:
+      break;
+  }
+  return false;
+}
+```
+]
+
+
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# END OF DECK
diff --git a/slides/wk06/3dprinting.html b/slides/wk06/3dprinting.html
new file mode 100644
index 0000000000000000000000000000000000000000..fca37938858c5569c6bcf5068884ed03be27ccf4
--- /dev/null
+++ b/slides/wk06/3dprinting.html
@@ -0,0 +1,613 @@
+---
+layout: presentation
+title: Intro to 3D printing
+description: Description of 3D printing value on mobile phones
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Intro to 3D Printing and Physical Computing
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout:false
+
+[//]: # (Outline Slide)
+.title[Today's goals]
+.body[
+- Reminders
+  - Start on ColorPicker if you have not already
+  - Practice quiz on Accessibility/ColorPicker out on Friday - due 5/13
+  - Examlet on Accessibility/ColorPicker on Friday 5/15
+- IMPORTANT
+  - We need you to fill out
+  [this form](https://docs.google.com/forms/d/e/1FAIpQLSdQrpZx-gexgDcKEF1SRp4egObimDP9qqVwLD56w0V2sYJDpw/viewform) so we can plan for our next assignment.
+- Discuss different types of 3D models
+- Talk about how 3D printing works
+- Talk about how 3D models are converted into low level g-code
+]
+
+
+
+---
+# Story time...
+
+.left-column40[
+![:img 1997 green subaru station wagon](img/3dprinting/subaru.png)
+]
+
+--
+.right-column50[
+<br><br>
+![:img subaru station wagon dome light, 70%](img/3dprinting/subaru-light.png) &nbsp; &nbsp;![:img subaru station wagon dome light switch, 20%](img/3dprinting/subaru-switch.png)
+
+]
+
+---
+# Traditional Manufacturing
+
+<div class="mermaid">
+graph LR
+A(Materials) --> B(Factory)
+B --> D(Shipping)
+D --> E(Storage)
+E --> F(Shipping)
+F --> G(You)
+
+classDef blue font-size:14pt;
+classDef green font-size:14pt;
+
+class B,D,E,F blue
+class A,G green
+</div>
+
+---
+.left-column[
+# Legacy ... literally
+
+]
+.right-column[
+![:img used part sale for a 1997 subaru legacy dome light, 45%](img/3dprinting/subaru-legacy-part.png)
+
+]
+---
+# It worked!
+
+![:img 1997 green subaru station wagon](img/3dprinting/subaru-switch-replaced.png) &nbsp;&nbsp;
+![:img 1997 green subaru station wagon](img/3dprinting/subaru-switch-replaced-on.png)
+
+
+
+---
+# The future (is Here)
+<br>
+<div class="mermaid">
+graph LR
+A(3D Modeling, <br> e.g. OpenSCAD) -->|Prepare| B(Geometry <br> e.g. .stl file)
+B -->|Slice| D(Printer instructions<br>G-code file)
+D -->|Printer| E(Printed Object)
+
+class A,B,D blue
+class E green
+</div>
+
+- __Prepare__ for printing
+- __Slice__ the model
+- __Printer__ Controller
+
+---
+# Prepare for Printing
+
+- Create a model using any one of a number of 3D modeling packages such as Sketchup, Open SCAD,
+Rhino 3d, Meshmixer, Blender, OnShape, Minecraft, SolidWorks
+  - Some packages reprsent 3D objects as solids, others as shells and boundaries.
+- Or you can find lots of stuff in repositories, like [Thingiverse](http://www.thingiverse.com/)
+
+
+.left-column50[
+__Solids__ (image from [Wikipedia](https://en.wikipedia.org/wiki/Constructive_solid_geometry ))
+
+![:img example of what solid modeling looks like, 40%](img/3dprinting/solid-modeling.png)
+]
+
+.right-column50[
+__Shells/Boundaries__
+
+![:img A 2D nurb plane, 45%](img/3dprinting/shells.png)
+![:img A 3d scan of a male with long hair, 30%](img/3dprinting/bust.png)
+]
+
+---
+# .stl File
+
+Almost every software package can save the files as a `.stl` file (stereolithography)
+
+.left-column50[
+
+![:img open cube modeled as with surfaces, 45%](img/3dprinting/cube-shell.png)
+![:img open cube as stl file, 45%](img/3dprinting/cube-stl.png)
+
+]
+.right-column50[
+```
+solid OBJECT
+  facet normal 0 -1 0
+    outer loop
+      vertex 10 -10 0
+      vertex 0 -10 10
+      vertex 0 -10 0
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex 0 -10 10
+      vertex 10 -10 20
+      vertex 8 -10 20
+    endloop
+  endfacet
+```
+]
+
+---
+# Printer Controller
+
+The printer controller converts the `.stl` file into GCode, commands read by the printer
+
+
+.left-column50[
+```
+solid OBJECT
+  facet normal 0 -1 0
+    outer loop
+      vertex 10 -10 0
+      vertex 0 -10 10
+      vertex 0 -10 0
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex 0 -10 10
+      vertex 10 -10 20
+      vertex 8 -10 20
+    endloop
+  endfacet
+```
+]
+
+--
+.right-column50[
+
+![:img colorful magician, 50%](img/3dprinting/magician.png)
+
+]
+---
+# Printer Controller
+
+The printer controller converts the `.stl` file into GCode, commands read by the printer
+
+
+.left-column50[
+```
+solid OBJECT
+  facet normal 0 -1 0
+    outer loop
+      vertex 10 -10 0
+      vertex 0 -10 10
+      vertex 0 -10 0
+    endloop
+  endfacet
+  facet normal 0 -1 0
+    outer loop
+      vertex 0 -10 10
+      vertex 10 -10 20
+      vertex 8 -10 20
+    endloop
+  endfacet
+```
+]
+
+.right-column50[
+```
+G1 X-5.87 Y-12.69 Z0.47 F3360.0
+G1 F1200.0
+G1 E1.0
+G1 F3360.0
+M101
+G1 X-5.87 Y12.69 Z0.47 F381.198 E5.799
+G1 X-2.93 Y12.69 Z0.47 F381.198 E6.354
+G1 X-2.93 Y-12.69 Z0.47 F381.198 E11.152
+G1 X0.0 Y-12.69 Z0.47 F381.198 E11.707
+G1 X0.0 Y12.69 Z0.47 F381.198 E16.506
+G1 X2.93 Y12.69 Z0.47 F381.198 E17.06
+G1 X2.93 Y-12.69 Z0.47 F381.198 E21.859
+G1 X5.87 Y-12.69 Z0.47 F381.198 E22.414
+G1 X5.87 Y12.69 Z0.47 F381.198 E27.213
+G1 X8.8 Y12.69 Z0.47 F381.198 E27.768
+
+```
+]
+
+---
+# Results
+![:img small grey 3D printed box](img/3dprinting/grey-box.png)
+
+
+
+---
+# What do new fabrication technologies provide?
+
+.left-column50[
+New ways to create
+- Faster, easier, sometimes better
+
+New ways to customize
+- Faster iteration
+- Mass customization
+
+New materials
+
+New shapes
+]
+
+--
+.right-column50[
+Magic arms
+
+![:youtube Video of child using a 3D printed hand, WoZ2BgPVtA0]
+
+]
+
+---
+# What new fabrication technologies are not
+
+Not the startrek replicator
+
+Not as fast as the best manufacturing solutions for bulk manufacturing
+
+Not as fast as your 2d printer
+
+Often expensive
+
+Material range is limited
+
+---
+# Additive Vs Subtractive Printing
+
+.left-column50[
+- Additive printing puts down material, building up the object layer by layer
+  - Some are done with extruded plastic or other material
+  - Others are done with powders that are sealed together (powder printers)
+- Subtractive removes materials from around the object
+]
+
+.right-column50[
+![:img three 3D printed lion heads two are subtractive printing one is additive, 80%](img/3dprinting/add-subtract.png)
+
+]
+
+
+---
+# Additive Fused Deposition Modeling (FDM)
+
+.left-column50[
+![:img examples of failed additive prints, 100%](img/3dprinting/additive.png)
+
+]
+.right-column50[
+<br>
+![:youtube Time lapse video explaining 3D printing, m_QhY1aABsE]
+
+]
+
+---
+# Powder printing (@0:28)
+<br>
+![:youtube Time lapse video of powder printing, kBHsfNDsbCs?t=28]
+
+---
+# Liquid printing (@0:23)
+<br>
+![:youtube Time lapse video liquid printing, l3TgmvV2ElQ?t=23]
+
+---
+# Laser Sintering (@0:53)
+<br>
+![:youtube Time lapse video laser sintering, 9E5MfBAV_tA?t=53]
+
+---
+# Other Materials
+
+- [Lisa Harouni Talk](https://www.ted.com/talks/lisa_harouni_a_primer_on_3d_printing#t-120717) (@2:12)
+- [Powder printer](https://youtu.be/kBHsfNDsbCs?t=29s)
+- [Liquid Based additive printers](https://www.popsci.com/new-liquid-based-3d-printer-takes-minutes-not-hours/) (@1:07)
+- [Candy](https://www.youtube.com/watch?time_continue=5&v=rU6RAM0Wrck&feature=emb_logo),
+[Chocolate](http://youtu.be/BIFi8but3Vw) other [Confections](https://www.youtube.com/watch?v=U3TmrCzVZ6w)
+- [Pancake bot](https://www.youtube.com/watch?v=f3Q8nbtRNT0)
+- Cement for houses [old](https://www.youtube.com/watch?v=WzmCnzA7hnE), [new](https://www.youtube.com/watch?v=8zt_3Gs1ksg)
+- [MIT’s glass printer](https://gizmodo.com/watching-mits-glass-3d-printer-is-absolutely-mesmerizin-1725433454)
+- [Ceramics](https://www.youtube.com/watch?v=1JjaqKUUMMw) (with sound vibrations), [Sample art](https://www.foransuon.com/)
+
+---
+# More reasons to learn about it!
+
+.left-column50[
+3d Printed car
+
+![:youtube Video of car being 3D printed, daioWlkH7ZI]
+
+]
+.right-column50[
+<br>
+- [3D Printed Medical Device Saves Baby's Life](https://www.youtube.com/watch?v=zr0HGCZSgE4)
+- [Prosthetic hand](http://youtu.be/CHPuMCshkLU?t=42s) (up to ~2:10)
+- [Lots of examples quickly](https://www.youtube.com/watch?v=X5AZzOw7FwA)
+- [3D printers print ten houses in 24 hours](https://www.youtube.com/watch?v=SObzNdyRTBs)
+- [Printed body parts](http://youtu.be/jSjW-EgKOhk?t=1m8s)
+- [Printed organs](https://www.youtube.com/watch?v=4nqw1yjyKEs)
+- [3D printed pizza](http://youtu.be/dvjqmMfMU7w?t=15s)
+- [3D printed fashion](http://youtu.be/63Xozzh_uHM)
+- [3D Printing a Garden Sprinkler](https://www.youtube.com/watch?v=y9XRD3P2G-E)
+]
+
+
+---
+# Printing: Beyond plastic
+
+.left-column50[
+![:img Model for embedding a nut and bolt in a print, 50%](img/3dprinting/embedding.png)
+![:img Fabric taped down and embedded, 70%](img/3dprinting/fabric.png)
+![:img Fabric attached through holes, 50%](img/3dprinting/fabric2.png)
+
+]
+
+.right-column50[
+![:img Shorey designs embedded metal, 40%](img/3dprinting/metal-embed.jpg)&nbsp;&nbsp;
+![:img Shorey designs dragon scales, 40%](https://images.squarespace-cdn.com/content/v1/5cf88c7cc74fa800012045db/1559817320037-GI8H3Y56L8W087DD9CDG/ke17ZwdGBToddI8pDm48kLxnK526YWAH1qleWz-y7AFZw-zPPgdn4jUwVcJE1ZvWEtT5uBSRWt4vQZAgTJucoTqqXjS3CfNDSuuf31e0tVH-2yKxPTYak0SCdSGNKw8A2bnS_B4YtvNSBisDMT-TGt1lH3P2bFZvTItROhWrBJ0/aaezgif.com-video-to-gif.gif?format=1000w)
+
+[Shorey Designs](https://www.shoreydesigns.com/3d-printing-on-fabric)
+
+]
+---
+# What else to embed?
+
+.left-column-half[
+![:img Picture of tendon that can be used to bend something, 80%](img/3dprinting/tendon1.png)
+![:img Picture of tendon that has been used to bend something, 80%](img/3dprinting/tendon2.png)
+]
+.right-column-half[
+![:youtube Examples of embedded fabric, 9xqze9csLmY]
+]
+???
+- String or wire (like a tendon)
+
+---
+# What else to print?
+
+![:img Gears, 20%](img/3dprinting/gear.png) ![:img Timing wheel, 20%](img/3dprinting/wheel.png) ![:img String Drive Wheel, 20%](img/3dprinting/stringdrive.png)
+
+---
+# What not to print
+
+- Food handling articles (unless on a special printer)
+- Safety critical strong things
+- High heat tolerance things
+- Things for chemically harsh environments
+
+---
+# How does printing enhance a mobile phone?
+
+.left-column-half[
+[Etch a Sketch!](https://www.thingiverse.com/thing:3251892)
+
+![:youtube Mobile phone case to use the phone like an etch a sketch, dcaErURbyIA]
+]
+
+--
+.right-column-half[
+New ways of interacting!
+- Works by combining condutive plastic with custom interactor
+- Looks like touch input to the software
+- Gears control motion options mechanically
+]
+---
+# How does printing enhance a mobile phone?
+.left-column-half[
+[Phone trigger buttons](https://www.thingiverse.com/thing:2960274)
+![:youtube Game playing hardware --trigger buttons--,X_C1Qxjg2WI]
+]
+.right-column-half[
+New ways of interacting!
+- Similar approach, also conductive
+]
+
+---
+# How does printing enhance a mobile phone?
+.left-column-half[
+XiaoyiZhang, TracyTran, YuqianSun, IanCulhane, ShobhitJain, JamesFogarty, JenniferMankoff: [Interactiles: 3D Printed Tactile Interfaces to Enhance Mobile Touchscreen Accessibility](https://make4all.org/portfolio/interactiles/). ASSETS 2018
+
+![:img A picture of a mobile phone with a tangible scrollbar and number pad built into its case to help improve blind interaction with the phone,40% ](img/3dprinting/interactiles.png)
+]
+
+.right-column-half[
+New ways of interacting!
+- Silicon & sewn conductive thread
+- Nuts and bolts
+]
+---
+# How does printing enhance a mobile phone?
+.left-column-half[
+
+Acoustruments
+![:youtube Printed objects whose use can be sensed, C2d1pB1qlvA]
+]
+.right-column-half[
+New ways of interacting!
+- Leverages the phone's microphone
+- Uses flexible plastic with holes
+- Requires machine learning
+]
+---
+# How does printing enhance a mobile phone?
+.left-column-half[
+Tactile map for the blind
+
+![:img An interactive map with 6 black conductive touchpoints. The map
+is held in a case with 6 conductive buttons that houses a Samsung Note
+2 with a 5.5-inch screen., 40%](img/3dprinting/tactile-map.png)
+]
+.right-column-half[
+New ways of interacting!
+
+Phone as embedded computer
+- Better solution because reprinting a map is faster than making a whole new portable map for each region
+- Similar to new interaction techniques, uses conductive plastic
+]
+
+---
+# Use your phone to control general hardware
+
+[IOIO](https://learn.sparkfun.com/tutorials/ioio-otg-hookup-guide) /
+[IOIO wiki](https://github.com/ytai/ioio/wiki)
+
+![:img a development board specially designed to allow developers to add advanced hardware I/O capabilities to their Android or PC application. It features a PIC microcontroller,which acts like a bridge that connects an app on your PC or Android device to low-level peripherals. An app-level library helps you write control code for these low level peripherals in the same way you’d write any other Java app!](img/3dprinting/ioio.jpg)
+
+
+---
+# How does printing enhance a mobile phone?
+.left-column-half[
+![:img (a) 3D printed smartphone adaptor designed for the Samsung
+Galaxy Note II with a black ABS dark box comprising slots for
+droppers. (b) 3D printed cartridge composed of a white ABS piece
+comprising 4 wells and BL substrate reservoirs and a black sliding lid
+with transparent ABS windows. (c) The assembled smartphone-based
+device with running the specifically designed application for BL
+signal acquisition and analysis., 60%](img/3dprinting/biotoxicity.jpg)
+
+Many similar options -- e.g. [Ph
+Meter](https://ieeexplore.ieee.org/abstract/document/6916991);
+[Sensing sweat
+make-up](https://pubs.rsc.org/en/content/articlehtml/2014/an/c4an01612b);
+[Nanosensing by
+Nasa](https://www.nasa.gov/centers/ames/news/features/2009/cell_phone_sensors.html)
+[more examples](https://www.sciencedirect.com/science/article/pii/S0167779914000572)
+]
+.right-column-half[
+New ways of interacting
+
+Phone as embedded computer
+
+New ways of sensing
+
+- [Biotoxicity
+sensing](https://www.sciencedirect.com/science/article/pii/S0925400515305992)
+- Dark box
+- Phone case
+]
+
+???
+ By clicking the “start” button (b) the application runs and several
+  tabs can be selected (c). The “Procedure” box (d) provide to the
+  user the instructions to perform the assay, then the Begin button
+  allow to proceed to the “Checklist” box (e) where preset timers
+  guide the user through the correct incubation times before BL image
+  acquisition. The instructions can be also eluded by selecting “Test
+  sample” in the home page, which jumps the user directly to the
+  checklist. At the end of the countdown the smartphone camera is
+  activated and the user can simply touch the “Acquire” button to
+  capture the BL image of both the test and control wells. (f) The
+  acquired images are rapidly analyzed on the smartphone and the
+  sample toxicity result is displayed as “Cell viability” value and a
+  warning message (Safe, Harmful, Highly toxic). BL image and results
+  can be also saved for downstream application (i.e. sending results
+  to a central laboratory).
+
+---
+# How does printing enhance a mobile phone?
+
+.left-column50[
+[Phone for potentiostatic
+control](https://ieeexplore.ieee.org/abstract/document/6916991)
+
+![:img Arrangement used for mobile phone based ECL sensing. The audio
+jack supplies the potential to the paper microfluidic sensor while the
+resultant emission is detected by the camera in video mode. Both the
+excitation and detection processes are controlled by a software
+application which can also transmit the results via e-mail. The black
+plastic sleeve surrounding the top of the phone holds the sensor
+adjacent to the camera and blocks ambient light., 40%](img/3dprinting/potentiometric.jpg)
+ ]
+.right-column50[
+New ways of interacting
+
+Phone as embedded computer
+
+New ways of sensing
+- exploits ability to play sounds
+- serves basic functions of a potentiostat in controlling an applied
+ potential to oxidise ECL-active molecules
+- resultant photonic signal is monitored using the camera in video
+ mode.
+- combined with paper microfluidic sensors
+
+]
+???
+
+The audio jack supplies the potential to the paper microfluidic
+sensor, while the resultant emission is detected by the camera in
+video mode. Both the excitation and detection processes are controlled
+by a software application which can also transmit the results via
+e-mail. The black plastic sleeve surrounding the top of the phone
+holds the sensor adjacent to the camera and blocks ambient light.
+
+---
+# How does printing enhance a mobile phone?
+
+.left-column50[
+Printed Analytics
+![:youtube Printed objects whose use can be sensed, W1V2AgDbgTQ]
+]
+.right-column-half[
+New ways of interacting
+
+Phone as embedded computer
+
+New ways of sensing
+- uses backscatter technology
+- works in range of a modified wireless router
+]
+
+---
+# Summary: What does physical computing offer us?
+
+.left-column-half[
+New ways to interact
+- capacitive sensing facilitate by conductive plastic/thread
+- microphone + machine learning
+
+New ways to sense information
+- fluid properties
+- audio
+- backscatter
+]
+.right-column-half[
+New ways to combine devices (e.g. through bluetooth sensing of physical hardware)
+
+Benefits:
+- modify a device beyond what the manufacturer expected
+- apid prototyping of novel solutions
+]
+--
+# END OF DECK
+---
+# Moon House Video
+
+![:youtube Video of a robot 3d printing a round house, 8zt_3Gs1ksg]
+
+---
+# Accessible Game Control
+
+![:youtube Xbox adaptive controller intro, 9fcK19CAjWM]
diff --git a/slides/wk06/context.html b/slides/wk06/context.html
new file mode 100644
index 0000000000000000000000000000000000000000..c21f4f1a884b76392b763dbd6a281c727954a1bc
--- /dev/null
+++ b/slides/wk06/context.html
@@ -0,0 +1,847 @@
+---
+layout: presentation
+title: The Physical Phone --Week 8, Monday--
+description: What we know about the physical use and abilities of a phone
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+background-image: url(img/context/people-background.png)
+# The Physical Phone
+
+Jennifer Mankoff
+
+CSE 340 {{site.quarter}}
+---
+layout: false
+
+[//]: # (Outline Slide)
+.left-column[# Today's goals]
+.right-column[
+- Talk about myths about phone use
+- Talk about what a phone can sense
+]
+---
+.title[Interface Structure]
+.body[
+
+<div class="mermaid">
+graph TD
+
+I(Input) --Explicit Interaction--> A(Application)
+A --> Act(Action)
+
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+
+class U,C,A,I,S,E,Act,Act2 normal
+</div>
+]
+---
+.title[Context Aware Computing Interface Structure]
+.body[
+
+<div class="mermaid">
+graph TD
+
+I(Input) --Explicit Interaction--> A(Application)
+A --> Act(Action)
+
+U(User) --Implicit Sensing--> C(Context-Aware Application)
+S(System) --Implicit Sensing--> C
+E(Environment) --Implicit Sensing--> C
+C --> Act2(Action)
+
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+
+class U,C,A,I,S,E,Act,Act2 normal
+</div>
+]
+---
+# Example: COVID-19 Contact Tracing
+
+.left-column-half[
+![:img Picture of a COVID-19 contact tracing app showing motivational text like Join the fight and Get motivated if you come into contact with COVID-19, 100%](img/context/contact-tracing.jpg)
+]
+.right-column-half[
+- Install an app on your phone
+- Turn on bluetooth
+- Keep track of every bluetooth ID you see
+]
+
+---
+.left-column[
+![:img Picture of a COVID-19 contact tracing app showing motivational text like Join the fight and Get motivated if you come into contact with COVID-19, 100%](img/context/contact-tracing.jpg)
+]
+.right-column[
+## Context Awareness is about *Human Activity*
+- Useful, and necessary, input to context-aware systems
+- Easier and easier to collect information about human activity
+]
+
+.footnote[[Image credit](https://www.techherd.co/iot-mobile-threats/) ]
+
+???
+Improved software and inferencing
+
+Improved sensors
+---
+.left-column[
+## Computational Behavioral Imaging
+]
+.right-column[
+![:img Picture of X-ray scan of body, 30%](img/context/imaging.png)
+]
+---
+.left-column[
+## Computational Behavioral Imaging
+]
+.right-column[
+![:img Picture of X-ray scan of body, 30%](img/context/imaging.png)
+![:img Picture of a COVID-19 contact tracing app showing motivational text like Join the fight and Get motivated if you come into contact with COVID-19, 35%](img/context/contact-tracing.jpg)
+]
+---
+.left-column[
+## Computational Behavioral Imaging
+]
+.right-column[
+![:img Picture of X-ray scan of body, 30%](img/context/imaging.png) ![:img Internet of things devices, 50%](img/context/IoT.png)
+]
+---
+.left-column[
+![:img Smartphone, 100%](img/context/phone.png)
+]
+.right-column[
+## Phones
+
+People already carry them
+
+Capture many aspects of behavior
+- Interactions with information: virtual
+- Social engagement: social
+- Loads of sensors: physical
+]
+
+---
+.left-column[
+## Assumptions
+]
+.right-column[
+We have made a number of .red.bold[WRONG] assumptions about:
+- what smartphones are
+- how they are used
+]
+
+---
+.left-column[
+## Assumption #1: We all have smart phones
+
+![:img Picture of a bunch of phones (some outdated), 100%](img/context/phones.png)
+]
+.right-column[
+What is a smart phone?
+]
+???
+What do you think?
+---
+.left-column[
+## Assumption #1: We all have smart phones
+![:img Picture of a bunch of phones (some outdated), 100%](img/context/phones.png)
+
+]
+.right-column[
+What is a smart phone?
+- Runs a complete mobile OS
+- Offers computing ability and connectivity
+- Includes sensors
+]
+---
+
+# Types of Sensors
+
+.left-column-half[
+
+- Not just touches: clicks, key presses
+
+| | | |
+|--|--|--|
+|Accelerometer | Rotation | Screen|
+|Applications | Location | Telephony|
+|Battery | Magnetometer | Temperature|
+|Bluetooth | Network Usage | Traffic|
+|Calls | Orientation | WiFi|
+|Messaging | Pressure | Processor|
+|Gravity | Proximity | Humidity |
+|Gyroscope | Light |  ... Many More |
+]
+.right-column-half[
+Other Kinds of Sensors:
+
+- Microphone
+
+- Camera
+
+- Multi-touch
+
+- Connected Devices?
+
+]
+
+???
+Sampled or event based?
+---
+# Which Sensors might be useful for contact tracing? Why?
+.left-column-half[
+
+microphone/camera/multi-touch/IOT PLUS
+
+| | | |
+|--|--|--|
+|Accelerometer | Rotation | Screen|
+|Applications | Location | Telephony|
+|Battery | Magnetometer | Temperature|
+|Bluetooth | Network Usage | Traffic|
+|Calls | Orientation | WiFi|
+|Messaging | Pressure | Processor|
+|Gravity | Proximity | Humidity |
+|Gyroscope | Light |  ... Many More |
+]
+.right-column-half[
+Type your answers in chat!
+]
+---
+
+# How do you program with sensors?
+
+  - `Managers` (e.g. `LocationManager`) let us create and register a listener
+
+  - Listeners can receive updates at different intervals, etc.
+
+  - Some Sensor-specific settings
+    [https://source.android.com/devices/sensors/sensor-types.html](https://source.android.com/devices/sensors/sensor-types.html)
+
+---
+# Implementing Sensing
+
+Android [Awareness API](https://developers.google.com/awareness/)
+.left-column-half[
+## Turn it on
+
+Must enable it: [Google APIs](https://console.developers.google.com/apis/)
+
+Recent updates to documentation (from 2017): February 2020!
+]
+
+.right-column-half[
+## Set up callbacks
+
+Two types of context sensing: Snapshots/ Fences
+]
+???
+
+---
+# Snapshots
+
+Capture sensor data at a moment in time
+
+Require a single callback, to avoid hanging while sensor data is fetched:
+
+`onSnapshot(Response response)`
+
+Seting up the callback  (just like callbacks for other events)
+
+``` java
+setSnapshotListener(Awareness.getSnapshotClient(this).getDetectedActivity(),
+                    new ActivitySnapshotListener(mUpdate, mResources));
+```
+
+---
+# Fences
+
+Notify you *every time* a condition is true
+
+Conditional data
+
+3 callbacks: during, starting, stopping
+
+```java
+mActivityFenceListener = new ActivityFenceListener(
+                // during
+                DetectedActivityFence.during(DetectedActivity.WALKING),
+                // starting
+                DetectedActivityFence.starting(DetectedActivity.WALKING),
+                // stopping
+                DetectedActivityFence.stopping(DetectedActivity.WALKING),
+                this, this, mUpdate);
+```
+
+???
+What might we use for a location fence?
+Headphone fence?
+...
+
+---
+# Snapshots vs Fences for contact tracing
+
+.left-column40[
+<iframe src="https://embed.polleverywhere.com/multiple_choice_polls/mdDbVMvvYnDCcu3ugYWzh?controls=none&short_poll=true" width="800" height="600" frameBorder="0"></iframe>
+
+]
+--
+.right-column30[
+Answer: Fence
+
+We want to be notified about *every* contact so we can record it
+]
+
+---
+# Using Context-Awareness in Apps
+.left-column[
+![:img Picture of a mobile phone with a text message on screen containing a transcription of recent audio, 100%](img/context/scribe4me.jpeg)
+]
+.right-column[
+
+Capture and Access:
+- .red[Food diarying] and nutritional awareness via receipt analysis [Ubicomp 2002]
+- .bold.red[Audio Accessibility] for deaf people by supporting mobile
+sound transcription [Ubicomp 2006, CHI 2007]
+- .red[Citizen Science] volunteer data collection in the field [CSCW
+  2013, CHI
+  2015]
+- .red[Air quality assessment] and visualization [CHI 2013]
+- .red[Coordinating between patients and doctors] via wearable
+  sensing of in-home physical therapy [CHI 2014]
+]
+---
+# What might we do with today's phones?
+.left-column[
+![:img Picture of a mobile phone with an unlock gesture that also labels emails for keeping or discarding, 100%](img/context/proactive.png)
+]
+.right-column[
+
+## Adaptive Services (changing operation or timing)
+
+- .red[Adaptive Text Prediction] for assistive communication devices
+  [TOCHI 2005]
+- .red[Location prediction] based on prior behavior [Ubicomp 2014]
+- .bold.red[Pro-active task access] on lock screen based on predicted user
+  interest [MobileHCI 2014]
+]
+---
+# What might we do with today's phones?
+.left-column[
+![:img example interaction above and on the surface of a phone supported by adding a depth camera to the front of the phone -- shows
+interacting with text, 80%](img/context/airtouch.jpg)
+
+![:img example interaction above and on the surface of a phone supported by adding a depth camera to the front of the phone -- shows interacting with an image, 80%](img/context/airtouch2.jpg)
+]
+.right-column[
+## Novel Interaction
+
+- .red[Cord Input] for interacting with mobile devices  [CHI 2010]
+- .red[Smart Watch Intent to Interact] via twist'n'knock gesture [GI
+  2016]
+- .red[VR Intent to Interact] vi sensing body pose, gaze and gesture
+  [CHI 2017]
+- .red[Around Body interaction] through gestures with the phone
+  [Mobile HCI 2014]
+- .red.bold[Around phone interaction] through gestures combining on and
+  above phone surface [UIST 2014]
+
+]
+---
+# What might we do with today's phones?
+.left-column[
+![:img example interaction above and on the surface of a phone supported by adding a depth camera to the front of the phone -- shows
+interacting with text, 80%](img/context/airtouch.jpg)
+
+![:img example interaction above and on the surface of a phone supported by adding a depth camera to the front of the phone -- shows interacting with an image, 80%](img/context/airtouch2.jpg)
+]
+.right-column[
+![:youtube Interweaving touch and in-air gestures using in-air
+gestures to segment touch gestures, H5niZW6ZhTk]
+]
+
+---
+# What might we do with today's phones?
+.left-column[
+![:img Picture of an interface for simulating driving behavior providing feedback to the user about aggressive driving, 100%](img/context/driving.png)
+
+]
+.right-column[
+
+## Behavioral Imaging
+
+- .red[Detecting and Generating Safe Driving Behavior] by using
+inverse reinforcement learning to create human routine models [CHI 2016,
+2017]
+- .red[Detecting Deviations in Family Routines] such as being late to
+pick up kids [CHI 2016]
+]
+---
+# What might we do with today's phones?
+
+.left-column[
+![:img The Momento desktop platform (D) and server (S) communicate with clients (C) via SMS/MMS; HTTP; or the Context Toolkit, 100%](img/context/momento.png)
+
+]
+.right-column[
+## General Solutions for Data Collection and Response
+
+- .red[General solution for studying people in the wild] via mobile
+sensing and interaction [CHI 2007]
+- .red[Minimizing user burden] for generating adaptive services via
+  test-time feature ordering [Ubicomp 2016]
+]
+
+---
+
+<iframe src="https://embed.polleverywhere.com/multiple_choice_polls/pgjVCzFsgUO4RT0yWQJLF?controls=none&short_poll=true" width="800" height="600" frameBorder="0"></iframe>
+
+---
+# Revisiting Assumption #1: We all have smart phones
+
+.left-column[
+![:img Picture of a bunch of phones (some outdated), 100%](img/context/phones.png)
+
+]
+.right-column[
+Does this seem like a smart phone?
+
+No, it just more input devices
+
+You have to do all the work
+]
+
+--
+.corner-ribbon.brtl[All Marketing]
+---
+background-image: url(img/context/phones-background.png)
+# Dumb (Feature) Phones
+
+We live in a time of dumb phones
+
+Know almost nothing about me
+
+Explicit preferences
+
+Contacts
+
+Running applications
+
+Hardly knows when I’m mobile/fixed, charging/not charging
+
+Doesn’t know me or what I’m doing
+
+--
+.corner-ribbon.purple.tlbr[WHY NOT SMARTER???]
+---
+# Research Goal: A real smartphone!
+.left-column[
+![:img Smartphone, 100%](img/context/phone.png)
+]
+.right-column[
+Want to build a smart phone that
+
+Collects and learns a model of human behavior with every interaction
+
+From the moment the phone is purchased and turned on
+
+Uses behavior information to improve interaction and the user experience
+
+Do this opportunistically
+
+- Your noise is my signal!
+- Big Data of 1
+]
+???
+How close are we to this?
+
+- Amazing amounts of computation at hand
+- Memory and storage
+- Radios and communication
+- Sensors
+- Software
+---
+# Assumption #2: Proximity is standard
+
+We assume that users have their phones with them and turned on 24-7
+
+Which is great for things like health apps and behavior modeling
+- Mobile phone is personal and travels with the user
+- Proxy for user context
+- Proxy for user’s environment context
+- Proxy for user’s attention/display device
+- Provide always-available service
+
+---
+# Assumption #2: Proximity is standard
+
+## How much of the day is your phone on?
+
+Average user: 78-81% [Dey, 2011]
+
+- One-fifth of the time, phone is off
+- Can’t sense anything
+- Can’t show anything to the user
+
+---
+<iframe src="https://embed.polleverywhere.com/multiple_choice_polls/eB1wjPW8LGqgpi9X1mhQS?controls=none&short_poll=true" width="800" height="600" frameBorder="0"></iframe>
+---
+
+# Where is your phone right now?
+.left-column-half[
+
+![:img Picture of person holding a phone to their head,10%](img/context/armsreach.png)  Arms Reach
+
+![:img Picture of person in a room with a phone,20%](img/context/roomsreach.png) Same Room
+
+![:img Picture of person near a house with a phone,20%](img/context/AWAY.png) Further
+
+Off
+]
+.right-column-half[
+
+]
+
+---
+# When your phone is on, where is it?
+.left-column[
+![:img Picture of person holding a phone to their head,20%](img/context/armsreach.png)
+
+![:img Picture of person in a room with a phone,50%](img/context/roomsreach.png)
+
+![:img Picture of person near a house with a phone,50%](img/context/AWAY.png)
+]
+.right-column[
+- Within arm’s reach (53%)
+- Within the same room (35%)
+- Further away? (12%)
+
+![Bar plot showing 53% within arm’s reach; 35% same room; 12% further away, 100%
+](img/context/phonedist.png)
+]
+---
+# Assumption #2: Proximity is standard
+
+.left-column-half[
+## Challenges for interpreting phone data:
+
+***Can't use the phone as a proxy for the user***
+
+It's off about 20% of the time
+
+It's not in the same roomabout 12% of the time
+
+]
+--
+.left-column-half[
+***How do we implement contact tracing given this?***
+]
+
+---
+# Assumption #2: Proximity is standard
+
+.left-column-half[
+## Challenges for interpreting phone data:
+
+***Can't use the phone as a proxy for the user***
+
+It's off about 20% of the time
+
+It's not in the same roomabout 12% of the time
+
+***How do we implement contact tracing given this?***
+]
+.right-column-half[
+## May need complementary sensors
+
+Smart watch
+
+Fitbit
+
+Room level sensing
+ ]
+---
+.left-column[
+## Assumption #3: Usage is Notification Driven
+![:img People at a dinner table paying attention to their phones instead of eachother, 100%](img/context/dinner.png)
+]
+.right-column[
+What do we know about how people use their mobile devices?
+
+- “Always on the phone!”
+- “Notifications are ruining my life!”
+
+]
+---
+# Characterizing Usage: Glance
+
+.left-column-half[
+![:img Picture of different kinds of usage including glance; review; engage; and phone calls showing that almost all include glancing at the lock screen while others also include the home screen (almost all) and applicaion usage also includes app-specific stuff, 100%](img/context/usage.png)
+]
+.right-column-half[
+![:youtube Glancing at a phone without engaging, 4pXLqDZCFwo]
+]
+
+.footnote[Based on 1 months data from 10 participants]
+---
+# Characterizing Usage: Review
+
+.left-column-half[
+![:img Picture of different kinds of usage including glance; review; engage; and phone calls showing that almost all include glancing at the lock screen while others also include the home screen (almost all) and applicaion usage also includes app-specific stuff, 100%](img/context/usage.png)
+]
+.right-column-half[
+![:youtube Reviewing on a phone, vsPkU8fHp-c]
+]
+
+.footnote[Based on 1 months data from 10 participants]
+---
+# Characterizing Usage: Engage
+
+.left-column-half[
+![:img Picture of different kinds of usage including glance; review; engage; and phone calls showing that almost all include glancing at the lock screen while others also include the home screen (almost all) and applicaion usage also includes app-specific stuff, 100%](img/context/usage.png)
+]
+.right-column-half[
+![:youtube Reviewing on a phone, NCwj3__BFxQ]
+]
+
+.footnote[Based on 1 months data from 10 participants]
+---
+# Characterizing Usage
+
+.left-column-half[
+![:img Histograph of percentage of total device use sessions by
+session duration showing that most sessions are lock screen only and
+less than 60 seconds long, 100%](img/context/usage2.png)
+]
+.right-column-half[
+95% of sessions shorter than 5 minutes; most < 60 secs
+
+Notifications lead to engagement… only 25% of the time!
+
+Self-interruption therefore more common than we would think
+
+Notifications prevent unnecessary engages
+
+No good support for reviews
+]
+---
+.left-column[
+## Opportunity: Leverage real knowledge about phone use
+![:img People at a dinner table paying attention to their phones instead of eachother, 100%](img/context/dinner.png)
+]
+.right-column[
+Engage people when appropriate
+
+Avoid interrupting when not
+
+Make short interactions more powerful
+
+]
+---
+.left-column[
+![:img Picture of a mobile phone with an unlock gesture that also labels emails for keeping or discarding, 100%](img/context/proactive.png)
+]
+.right-column[
+## Example: pro-active tasks
+
+Provide access to email management, etc right on lock screen
+
+]
+---
+.left-column[
+![:img Picture of a mobile phone with an unlock gesture that also labels emails for keeping or discarding, 100%](img/context/proactive.png)
+]
+.right-column[
+## Example: pro-active tasks
+
+Provide access to email management, etc right on lock screen
+
+Study of phone use (10 users, 4 weeks)
+
+95% of sessions shorter than 5 minutes; most < 60 secs
+
+No good support for quick task completion (just viewing things)
+]
+---
+.left-column[
+## All users
+
+![:img Picture of a graph showing 3 weeks of use going from 15%
+engagement down to 6.4% engagement, 100%](img/context/proactive-results.png)
+]
+
+.right-column[
+## Results
+
+25 participants
+- 10 nonusers (4% of lockscreen views with a task or less per week)
+- 9 regular users (5-10% of lockscreen views with a task per week)
+- 5 power users (40-60% of lockscreen views!)
+]
+???
+regular users  mostly used the tasks when they had some down time, or
+when bored or nothing better to do.
+
+power users who applied actions to email in more than 1/3 of sessions
+when tasks were present on their lock screen.
+
+---
+.left-column[
+## Cleaners
+
+![:img Picture of a graph showing 3 weeks of use going from 39%
+engagement down to 22% and then back up to 50% engagement, 100%](img/context/cleaneruser.png)
+]
+.right-column[
+## Results
+
+25 participants
+- 10 nonusers (4% of lockscreen views with a task or less per week)
+- 9 regular users (5-10% of lockscreen views with a task per week)
+- 5 power users (40-60% of lockscreen views!)
+- 3 'cleaners'
+]
+???
+We also found a special kind of power users called cleaners. They rarely had any unread emails in their inbox and used ProactiveTasks to keep their inbox clear of any unwanted emails.
+
+---
+.left-column[
+## Assumption #4: Need is Necessary
+![:img People at a dinner table paying attention to their phones instead of eachother, 100%](img/context/dinner.png)
+]
+.right-column[
+
+.quote[When asked which device or platform they would not be able to
+live without, a majority (65%) chose iPhone, while only a few (1%)
+[...mentioned] facebook. Nearly 15% ...
+]
+]
+---
+.left-column[
+## Assumption #4: Need is Necessary
+![:img People at a dinner table paying attention to their phones instead of eachother, 100%](img/context/dinner.png)
+]
+.right-column[
+
+.quote[When asked which device or platform they would not be able to
+live without, a majority (65%) chose iPhone, while only a few (1%)
+[...mentioned] facebook. Nearly 40% ...  .red[said they'd rather give up their laptop
+than go for even a weekend without their iPhone]
+]
+]
+
+---
+.left-column[
+## Assumption #4: Need is Necessary
+![:img People at a dinner table paying attention to their phones instead of eachother, 100%](img/context/dinner.png)
+]
+.right-column[
+![:img barplot showing percentage of people would keep their smart
+phone over game console (72%); tablet computer (69%); Dishwasher
+(46%); Laptop computer (40%); TV (32%); Fridge (13%); and care (8%),
+60%](img/context/phone-compare.png)
+]
+---
+.left-column[
+## Assumption #4: Need is Necessary
+
+## Should we combat this? How?
+
+]
+.right-column[
+
+[Hinicker](https://www.alexishiniker.com/) (works at UW):
+- Can devices teach self-regulation, rather than trying to regulate children?
+- Why do people compulsively check their phones? Can they change this?
+
+[Burke](http://thoughtcrumbs.com/) (works at Facebook):
+- [Watching silly cat videos is good for
+  you](https://www.wsj.com/articles/why-watching-silly-cat-videos-is-good-for-you-1475602097)
+- [Online social life good for your
+  longevity](https://www.nytimes.com/2016/11/01/science/facebook-longer-life.html)
+   ... but [The Relationship Between Facebook Use and Well-Being
+  Depends on Communication Type and Tie
+  Strength](https://academic.oup.com/jcmc/article/21/4/265/4161784)
+
+
+
+]
+---
+.left-column[
+## Assumptions
+
+- Assumption #1: Phones are smart
+- Assumption #2: Proximity is standard
+- Assumption #3: Usage is notification driven
+- Assumption #4: Need is necessary
+]
+
+.right-column[
+By removing assumptions, we can recast:
+
+- the notion of what a smart phone is
+- how we can use them to improve people’s lives
+- how to leverage make (personalized) meaning from (your) big data
+]
+???
+---
+# Do you think COVID-19 has challenged the validaty of any of these assumptions?
+
+.left-column[
+## Assumptions
+
+- Assumption #1: Phones are smart
+- Assumption #2: Proximity is standard
+- Assumption #3: Usage is notification driven
+- Assumption #4: Need is necessary
+]
+
+.right-column[
+<iframe src="https://embed.polleverywhere.com/multiple_choice_polls/Omnf3hdr8zaHvaGCTpemV?controls=none&short_poll=true" width="800" height="600" frameBorder="0"></iframe>
+]
+???
+
+---
+.title[Challenges to this vision]
+.body[
+
+- Battery
+- Raw sensors not behavior data
+- Not the sensors we always want
+- Computational complexity
+- Latency in communication
+- Basic software framework to support apps that can adapt to user behavior
+- Apps that drive innovation
+- How people use phones
+]
+
+---
+
+# End of Deck
+
+---
+---
+# Places
+
+Shows you what is nearby
+
+```java
+//In MainActivity:
+setSnapshotListener(Awareness.getSnapshotClient(this).getPlaces(),
+                    new PlacesSnapshotListener(mUpdate, mResources)));
+
+//In PlacesSnapshotListener
+public void onSnapshot(PlacesResponse response) {
+        List<PlaceLikelihood> placeLikelihood = response.getPlaceLikelihoods();
+        if (placeLikelihood != null && !placeLikelihood.isEmpty()) {
+            for (PlaceLikelihood likelihood : placeLikelihood) {
+                addPlace(likelihood.getPlace().getName().toString(), likelihood.getLikelihood());
+            }
+        }
+
+        mUpdate.prependText(placeLikelihood.toString());
+    }
+```
diff --git a/slides/wk06/img/3dprinting/add-subtract.png b/slides/wk06/img/3dprinting/add-subtract.png
new file mode 100644
index 0000000000000000000000000000000000000000..6f5b26318d7eef422a90eb445d73cd709a0ad5d5
Binary files /dev/null and b/slides/wk06/img/3dprinting/add-subtract.png differ
diff --git a/slides/wk06/img/3dprinting/additive.png b/slides/wk06/img/3dprinting/additive.png
new file mode 100644
index 0000000000000000000000000000000000000000..9c184ca2202e52685fbb1b60c10e089079fa39c4
Binary files /dev/null and b/slides/wk06/img/3dprinting/additive.png differ
diff --git a/slides/wk06/img/3dprinting/biotoxicity.jpg b/slides/wk06/img/3dprinting/biotoxicity.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3c6ed987d21d9a11d7697ba9c64348262c1094bb
Binary files /dev/null and b/slides/wk06/img/3dprinting/biotoxicity.jpg differ
diff --git a/slides/wk06/img/3dprinting/bridge-overhang.png b/slides/wk06/img/3dprinting/bridge-overhang.png
new file mode 100644
index 0000000000000000000000000000000000000000..af254bfc6dc3c8f8528a07c3a77b322d8c3807a6
Binary files /dev/null and b/slides/wk06/img/3dprinting/bridge-overhang.png differ
diff --git a/slides/wk06/img/3dprinting/bridge.png b/slides/wk06/img/3dprinting/bridge.png
new file mode 100644
index 0000000000000000000000000000000000000000..db7f1d3f5cf02b0e74a22955309e0262ca720562
Binary files /dev/null and b/slides/wk06/img/3dprinting/bridge.png differ
diff --git a/slides/wk06/img/3dprinting/bust.png b/slides/wk06/img/3dprinting/bust.png
new file mode 100644
index 0000000000000000000000000000000000000000..4c4ae6d28f2290d297b2a9f2752f617896bade9a
Binary files /dev/null and b/slides/wk06/img/3dprinting/bust.png differ
diff --git a/slides/wk06/img/3dprinting/cube-shell.png b/slides/wk06/img/3dprinting/cube-shell.png
new file mode 100644
index 0000000000000000000000000000000000000000..6644e896fe81d890f86cd2cdb325379b20ba6138
Binary files /dev/null and b/slides/wk06/img/3dprinting/cube-shell.png differ
diff --git a/slides/wk06/img/3dprinting/cube-stl.png b/slides/wk06/img/3dprinting/cube-stl.png
new file mode 100644
index 0000000000000000000000000000000000000000..2144fa59e8f9f57b2b1b4c846a5ec1447858bcca
Binary files /dev/null and b/slides/wk06/img/3dprinting/cube-stl.png differ
diff --git a/slides/wk06/img/3dprinting/embedding.png b/slides/wk06/img/3dprinting/embedding.png
new file mode 100644
index 0000000000000000000000000000000000000000..5b94cfe7fb597578bd1d1be2cbd9c8631730cb4e
Binary files /dev/null and b/slides/wk06/img/3dprinting/embedding.png differ
diff --git a/slides/wk06/img/3dprinting/fabric.png b/slides/wk06/img/3dprinting/fabric.png
new file mode 100644
index 0000000000000000000000000000000000000000..7d0bc21fd9085b149aafc40fdb0b3e56ffb55f2d
Binary files /dev/null and b/slides/wk06/img/3dprinting/fabric.png differ
diff --git a/slides/wk06/img/3dprinting/fabric2.png b/slides/wk06/img/3dprinting/fabric2.png
new file mode 100644
index 0000000000000000000000000000000000000000..102da43375884c43e33cb2651171fed9df79badd
Binary files /dev/null and b/slides/wk06/img/3dprinting/fabric2.png differ
diff --git a/slides/wk06/img/3dprinting/gear.png b/slides/wk06/img/3dprinting/gear.png
new file mode 100644
index 0000000000000000000000000000000000000000..0b3b449368c5bb8b837714458a1df964eb8fa16a
Binary files /dev/null and b/slides/wk06/img/3dprinting/gear.png differ
diff --git a/slides/wk06/img/3dprinting/grey-box.png b/slides/wk06/img/3dprinting/grey-box.png
new file mode 100644
index 0000000000000000000000000000000000000000..904cdc8219d7966f0dbeb98bfe340bd8f5b67b99
Binary files /dev/null and b/slides/wk06/img/3dprinting/grey-box.png differ
diff --git a/slides/wk06/img/3dprinting/interactiles.png b/slides/wk06/img/3dprinting/interactiles.png
new file mode 100644
index 0000000000000000000000000000000000000000..0d19934e984e9c4e61aef0f7c0c9138bd3ea7bd6
Binary files /dev/null and b/slides/wk06/img/3dprinting/interactiles.png differ
diff --git a/slides/wk06/img/3dprinting/ioio.jpg b/slides/wk06/img/3dprinting/ioio.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3ff69c8a9937bf6c184222b57a5ec17d80401aff
Binary files /dev/null and b/slides/wk06/img/3dprinting/ioio.jpg differ
diff --git a/slides/wk06/img/3dprinting/magician.png b/slides/wk06/img/3dprinting/magician.png
new file mode 100644
index 0000000000000000000000000000000000000000..6eb9bc0dfe45b89a48c2a2df0ef039b852fad392
Binary files /dev/null and b/slides/wk06/img/3dprinting/magician.png differ
diff --git a/slides/wk06/img/3dprinting/metal-embed.jpg b/slides/wk06/img/3dprinting/metal-embed.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4053fc24a6fab246cd3fd731166058b88251c99e
Binary files /dev/null and b/slides/wk06/img/3dprinting/metal-embed.jpg differ
diff --git a/slides/wk06/img/3dprinting/nutbolt.png b/slides/wk06/img/3dprinting/nutbolt.png
new file mode 100644
index 0000000000000000000000000000000000000000..e86bb2b4fe5fb6940eeb7ecf394c254ccf66dc2f
Binary files /dev/null and b/slides/wk06/img/3dprinting/nutbolt.png differ
diff --git a/slides/wk06/img/3dprinting/overhang.png b/slides/wk06/img/3dprinting/overhang.png
new file mode 100644
index 0000000000000000000000000000000000000000..713e58d1c59cb8f4ac1abd5f31d0513d5303ec67
Binary files /dev/null and b/slides/wk06/img/3dprinting/overhang.png differ
diff --git a/slides/wk06/img/3dprinting/phone-sensor.gif b/slides/wk06/img/3dprinting/phone-sensor.gif
new file mode 100644
index 0000000000000000000000000000000000000000..418dcb2a5ec1de520e81e135b1ed7889faf78c90
Binary files /dev/null and b/slides/wk06/img/3dprinting/phone-sensor.gif differ
diff --git a/slides/wk06/img/3dprinting/potentiometric.jpg b/slides/wk06/img/3dprinting/potentiometric.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..1544080a61574922edf3d9943c9dd0e9f1dccd94
Binary files /dev/null and b/slides/wk06/img/3dprinting/potentiometric.jpg differ
diff --git a/slides/wk06/img/3dprinting/shells.png b/slides/wk06/img/3dprinting/shells.png
new file mode 100644
index 0000000000000000000000000000000000000000..3149f9fe2d45b210d9c8e67e62018fb000c25e7a
Binary files /dev/null and b/slides/wk06/img/3dprinting/shells.png differ
diff --git a/slides/wk06/img/3dprinting/slicing.png b/slides/wk06/img/3dprinting/slicing.png
new file mode 100644
index 0000000000000000000000000000000000000000..ef83638decfaa0492b23710aa502209c7a0c7e73
Binary files /dev/null and b/slides/wk06/img/3dprinting/slicing.png differ
diff --git a/slides/wk06/img/3dprinting/solid-modeling.png b/slides/wk06/img/3dprinting/solid-modeling.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb3326c70a5e4643d7442125062c8d1e6608e300
Binary files /dev/null and b/slides/wk06/img/3dprinting/solid-modeling.png differ
diff --git a/slides/wk06/img/3dprinting/stringdrive.png b/slides/wk06/img/3dprinting/stringdrive.png
new file mode 100644
index 0000000000000000000000000000000000000000..4cb62f6934901666864e8548e85de906be988561
Binary files /dev/null and b/slides/wk06/img/3dprinting/stringdrive.png differ
diff --git a/slides/wk06/img/3dprinting/subaru-legacy-part.png b/slides/wk06/img/3dprinting/subaru-legacy-part.png
new file mode 100644
index 0000000000000000000000000000000000000000..29430ffffff174f26865b9dcdf9cc76da7976098
Binary files /dev/null and b/slides/wk06/img/3dprinting/subaru-legacy-part.png differ
diff --git a/slides/wk06/img/3dprinting/subaru-light.png b/slides/wk06/img/3dprinting/subaru-light.png
new file mode 100644
index 0000000000000000000000000000000000000000..5861e18aa8a062d5d2edd544b695a7608498e583
Binary files /dev/null and b/slides/wk06/img/3dprinting/subaru-light.png differ
diff --git a/slides/wk06/img/3dprinting/subaru-switch-iterations.png b/slides/wk06/img/3dprinting/subaru-switch-iterations.png
new file mode 100644
index 0000000000000000000000000000000000000000..bc285f6be2d46c56483b927d1e989e7bf33c8599
Binary files /dev/null and b/slides/wk06/img/3dprinting/subaru-switch-iterations.png differ
diff --git a/slides/wk06/img/3dprinting/subaru-switch-model.png b/slides/wk06/img/3dprinting/subaru-switch-model.png
new file mode 100644
index 0000000000000000000000000000000000000000..5bb1cd88324b8e614af0a7995955fffd33265d97
Binary files /dev/null and b/slides/wk06/img/3dprinting/subaru-switch-model.png differ
diff --git a/slides/wk06/img/3dprinting/subaru-switch-replaced-on.png b/slides/wk06/img/3dprinting/subaru-switch-replaced-on.png
new file mode 100644
index 0000000000000000000000000000000000000000..dc85bbc0235f95b5ed81539a32713fe2d9f61099
Binary files /dev/null and b/slides/wk06/img/3dprinting/subaru-switch-replaced-on.png differ
diff --git a/slides/wk06/img/3dprinting/subaru-switch-replaced.png b/slides/wk06/img/3dprinting/subaru-switch-replaced.png
new file mode 100644
index 0000000000000000000000000000000000000000..0f1d0bc40a06617ec631111d6ab1a33c51c03101
Binary files /dev/null and b/slides/wk06/img/3dprinting/subaru-switch-replaced.png differ
diff --git a/slides/wk06/img/3dprinting/subaru-switch.png b/slides/wk06/img/3dprinting/subaru-switch.png
new file mode 100644
index 0000000000000000000000000000000000000000..08001dc1320648cf57a20ef424d736e6626b780d
Binary files /dev/null and b/slides/wk06/img/3dprinting/subaru-switch.png differ
diff --git a/slides/wk06/img/3dprinting/subaru.png b/slides/wk06/img/3dprinting/subaru.png
new file mode 100644
index 0000000000000000000000000000000000000000..821622a51b2f3b5603559c2433fd0b80ca46a7f6
Binary files /dev/null and b/slides/wk06/img/3dprinting/subaru.png differ
diff --git a/slides/wk06/img/3dprinting/tactile-map.png b/slides/wk06/img/3dprinting/tactile-map.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b1c229976fb0aaf6988914ff6b66e317d07a836
Binary files /dev/null and b/slides/wk06/img/3dprinting/tactile-map.png differ
diff --git a/slides/wk06/img/3dprinting/tendon1.png b/slides/wk06/img/3dprinting/tendon1.png
new file mode 100644
index 0000000000000000000000000000000000000000..b3ff5353cc4ca3191ab52d7ecba317e3cb23b993
Binary files /dev/null and b/slides/wk06/img/3dprinting/tendon1.png differ
diff --git a/slides/wk06/img/3dprinting/tendon2.png b/slides/wk06/img/3dprinting/tendon2.png
new file mode 100644
index 0000000000000000000000000000000000000000..5d9315d5cd919c6de8a08e92c7e7dbb93302cf4b
Binary files /dev/null and b/slides/wk06/img/3dprinting/tendon2.png differ
diff --git a/slides/wk06/img/3dprinting/wheel.png b/slides/wk06/img/3dprinting/wheel.png
new file mode 100644
index 0000000000000000000000000000000000000000..712f582933956ed5e22501621fc913bd121a41fd
Binary files /dev/null and b/slides/wk06/img/3dprinting/wheel.png differ
diff --git a/slides/wk06/img/buttons64dp.png b/slides/wk06/img/buttons64dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..691d9215cdec15742198a3e3c43396c8b62d1d04
Binary files /dev/null and b/slides/wk06/img/buttons64dp.png differ
diff --git a/slides/wk06/img/buttons80dp.png b/slides/wk06/img/buttons80dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..40471bbe182b078f44b2ae52e8ab64a642a4baea
Binary files /dev/null and b/slides/wk06/img/buttons80dp.png differ
diff --git a/slides/wk06/img/context/AWAY.png b/slides/wk06/img/context/AWAY.png
new file mode 100644
index 0000000000000000000000000000000000000000..a4dae68db4b02fe20d03c152abef4b6db8a1eff9
Binary files /dev/null and b/slides/wk06/img/context/AWAY.png differ
diff --git a/slides/wk06/img/context/IoT.png b/slides/wk06/img/context/IoT.png
new file mode 100644
index 0000000000000000000000000000000000000000..1c91c492c924bb12030d4722a2bfcd6bbac6fd09
Binary files /dev/null and b/slides/wk06/img/context/IoT.png differ
diff --git a/slides/wk06/img/context/airtouch.jpg b/slides/wk06/img/context/airtouch.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..9011cfef75f72996ed1b32a7ddeb12851f7cd9d2
Binary files /dev/null and b/slides/wk06/img/context/airtouch.jpg differ
diff --git a/slides/wk06/img/context/airtouch2.jpg b/slides/wk06/img/context/airtouch2.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..1f99e07245b6273cc270a864100675121b7fba37
Binary files /dev/null and b/slides/wk06/img/context/airtouch2.jpg differ
diff --git a/slides/wk06/img/context/armsreach.png b/slides/wk06/img/context/armsreach.png
new file mode 100644
index 0000000000000000000000000000000000000000..838c66594b92750af97a4e0631bab3826fa0651c
Binary files /dev/null and b/slides/wk06/img/context/armsreach.png differ
diff --git a/slides/wk06/img/context/cleaneruser.png b/slides/wk06/img/context/cleaneruser.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb97629f6d0ea7594f7ee64c71c344c6f1ef9469
Binary files /dev/null and b/slides/wk06/img/context/cleaneruser.png differ
diff --git a/slides/wk06/img/context/contact-tracing.jpg b/slides/wk06/img/context/contact-tracing.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..b43f2d9bded10709c601fd94ca46b47a2af79fe2
Binary files /dev/null and b/slides/wk06/img/context/contact-tracing.jpg differ
diff --git a/slides/wk06/img/context/dinner.png b/slides/wk06/img/context/dinner.png
new file mode 100644
index 0000000000000000000000000000000000000000..f930464d08d700d56cf93437611ff001b8d2f189
Binary files /dev/null and b/slides/wk06/img/context/dinner.png differ
diff --git a/slides/wk06/img/context/driving.png b/slides/wk06/img/context/driving.png
new file mode 100644
index 0000000000000000000000000000000000000000..68c8d71f374bac87964d3252c0255cc38079dcb6
Binary files /dev/null and b/slides/wk06/img/context/driving.png differ
diff --git a/slides/wk06/img/context/engage.png b/slides/wk06/img/context/engage.png
new file mode 100644
index 0000000000000000000000000000000000000000..60a7e4e95a9ef146d793165352f1fd2c595ed0c6
Binary files /dev/null and b/slides/wk06/img/context/engage.png differ
diff --git a/slides/wk06/img/context/glance.png b/slides/wk06/img/context/glance.png
new file mode 100644
index 0000000000000000000000000000000000000000..b16ad77a9d65fd46aca99bcdaf87a5d17c1e0860
Binary files /dev/null and b/slides/wk06/img/context/glance.png differ
diff --git a/slides/wk06/img/context/imaging.png b/slides/wk06/img/context/imaging.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe6a86ae3ac5363d8e65806be07e26dc405ce6bb
Binary files /dev/null and b/slides/wk06/img/context/imaging.png differ
diff --git a/slides/wk06/img/context/momento.png b/slides/wk06/img/context/momento.png
new file mode 100644
index 0000000000000000000000000000000000000000..f67ac277b6c40bb28933a2a4fa0e74c29e8aad07
Binary files /dev/null and b/slides/wk06/img/context/momento.png differ
diff --git a/slides/wk06/img/context/nonuser.png b/slides/wk06/img/context/nonuser.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec5ae26df2dd00a27a28ddcaa8fd347bb17c8211
Binary files /dev/null and b/slides/wk06/img/context/nonuser.png differ
diff --git a/slides/wk06/img/context/people-background.png b/slides/wk06/img/context/people-background.png
new file mode 100644
index 0000000000000000000000000000000000000000..d22eb0d03a42b0a8d48ef16e9ff7c2119641adb3
Binary files /dev/null and b/slides/wk06/img/context/people-background.png differ
diff --git a/slides/wk06/img/context/phone-compare.png b/slides/wk06/img/context/phone-compare.png
new file mode 100644
index 0000000000000000000000000000000000000000..9ebcd8a3ec026d18d7ae24afbc9be33c5f6a3f8f
Binary files /dev/null and b/slides/wk06/img/context/phone-compare.png differ
diff --git a/slides/wk06/img/context/phone.png b/slides/wk06/img/context/phone.png
new file mode 100644
index 0000000000000000000000000000000000000000..70dab7055c585ace1ec90a0810a0e41d85cda1a8
Binary files /dev/null and b/slides/wk06/img/context/phone.png differ
diff --git a/slides/wk06/img/context/phonedist.png b/slides/wk06/img/context/phonedist.png
new file mode 100644
index 0000000000000000000000000000000000000000..060747e4d1223db055b6a5216e644d236f17a103
Binary files /dev/null and b/slides/wk06/img/context/phonedist.png differ
diff --git a/slides/wk06/img/context/phones-background.png b/slides/wk06/img/context/phones-background.png
new file mode 100644
index 0000000000000000000000000000000000000000..995ed4e0f82b4042cd5fc4181940d12e8f5694ce
Binary files /dev/null and b/slides/wk06/img/context/phones-background.png differ
diff --git a/slides/wk06/img/context/phones.png b/slides/wk06/img/context/phones.png
new file mode 100644
index 0000000000000000000000000000000000000000..02ebf063e963a10179310823e209c5c21ff160e6
Binary files /dev/null and b/slides/wk06/img/context/phones.png differ
diff --git a/slides/wk06/img/context/poweruser.png b/slides/wk06/img/context/poweruser.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec5ae26df2dd00a27a28ddcaa8fd347bb17c8211
Binary files /dev/null and b/slides/wk06/img/context/poweruser.png differ
diff --git a/slides/wk06/img/context/proactive-results.png b/slides/wk06/img/context/proactive-results.png
new file mode 100644
index 0000000000000000000000000000000000000000..f72d4f87c54d6465080c212cff49247d256d9e89
Binary files /dev/null and b/slides/wk06/img/context/proactive-results.png differ
diff --git a/slides/wk06/img/context/proactive.png b/slides/wk06/img/context/proactive.png
new file mode 100644
index 0000000000000000000000000000000000000000..e029610ac82badc22dd7868951ecce12650638ab
Binary files /dev/null and b/slides/wk06/img/context/proactive.png differ
diff --git a/slides/wk06/img/context/review.png b/slides/wk06/img/context/review.png
new file mode 100644
index 0000000000000000000000000000000000000000..04c0113b13ee587f7023f8dbd9a6806b2342df28
Binary files /dev/null and b/slides/wk06/img/context/review.png differ
diff --git a/slides/wk06/img/context/roomsreach.png b/slides/wk06/img/context/roomsreach.png
new file mode 100644
index 0000000000000000000000000000000000000000..3f0cd47d1f76d15566870a3461ae185f0366abc5
Binary files /dev/null and b/slides/wk06/img/context/roomsreach.png differ
diff --git a/slides/wk06/img/context/scribe4me.jpeg b/slides/wk06/img/context/scribe4me.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..1f206a2e591bc4af4b4c78311694f21031875264
Binary files /dev/null and b/slides/wk06/img/context/scribe4me.jpeg differ
diff --git a/slides/wk06/img/context/usage.png b/slides/wk06/img/context/usage.png
new file mode 100644
index 0000000000000000000000000000000000000000..17ad608616abedceab02535967a24340703b821f
Binary files /dev/null and b/slides/wk06/img/context/usage.png differ
diff --git a/slides/wk06/img/context/usage2.png b/slides/wk06/img/context/usage2.png
new file mode 100644
index 0000000000000000000000000000000000000000..7d334162cc4668e80cadb3a891b6ba52dacd546b
Binary files /dev/null and b/slides/wk06/img/context/usage2.png differ
diff --git a/slides/wk06/img/pm/body-fitts.png b/slides/wk06/img/pm/body-fitts.png
new file mode 100644
index 0000000000000000000000000000000000000000..d310a619ce4fee899e78aac5dacbb237a89d5128
Binary files /dev/null and b/slides/wk06/img/pm/body-fitts.png differ
diff --git a/slides/wk06/img/pm/bubblekeyboard.mov b/slides/wk06/img/pm/bubblekeyboard.mov
new file mode 100644
index 0000000000000000000000000000000000000000..f83852db123306ad013c3bc7d7f5da1e2430535a
Binary files /dev/null and b/slides/wk06/img/pm/bubblekeyboard.mov differ
diff --git a/slides/wk06/img/pm/buttons.png b/slides/wk06/img/pm/buttons.png
new file mode 100644
index 0000000000000000000000000000000000000000..26675f540854d26ee061fb0f9f81a46d9766ca14
Binary files /dev/null and b/slides/wk06/img/pm/buttons.png differ
diff --git a/slides/wk06/img/pm/check.png b/slides/wk06/img/pm/check.png
new file mode 100644
index 0000000000000000000000000000000000000000..2f14733dd108bcfc41f5a0b773e9b0ed6059d90d
Binary files /dev/null and b/slides/wk06/img/pm/check.png differ
diff --git a/slides/wk06/img/pm/common-snapping-cases.png b/slides/wk06/img/pm/common-snapping-cases.png
new file mode 100644
index 0000000000000000000000000000000000000000..e8382284e1a9d00172908384b357434737a1553b
Binary files /dev/null and b/slides/wk06/img/pm/common-snapping-cases.png differ
diff --git a/slides/wk06/img/pm/cursor.png b/slides/wk06/img/pm/cursor.png
new file mode 100644
index 0000000000000000000000000000000000000000..38d621bc442c2d815049bc9bf1ed7aa2048b3464
Binary files /dev/null and b/slides/wk06/img/pm/cursor.png differ
diff --git a/slides/wk06/img/pm/debugging.png b/slides/wk06/img/pm/debugging.png
new file mode 100644
index 0000000000000000000000000000000000000000..9c4134acf8d70b865591c307d5f8d026665b17d2
Binary files /dev/null and b/slides/wk06/img/pm/debugging.png differ
diff --git a/slides/wk06/img/pm/dragpop.png b/slides/wk06/img/pm/dragpop.png
new file mode 100644
index 0000000000000000000000000000000000000000..015e0aca032107005f5a2662c1bfc361f13d33aa
Binary files /dev/null and b/slides/wk06/img/pm/dragpop.png differ
diff --git a/slides/wk06/img/pm/errors.png b/slides/wk06/img/pm/errors.png
new file mode 100644
index 0000000000000000000000000000000000000000..80826d598295060fb21eeeeb95f46f79ed472b52
Binary files /dev/null and b/slides/wk06/img/pm/errors.png differ
diff --git a/slides/wk06/img/pm/escher.png b/slides/wk06/img/pm/escher.png
new file mode 100644
index 0000000000000000000000000000000000000000..0ac5f09e3d238d5d6c1071cd3d6e9e02e4918750
Binary files /dev/null and b/slides/wk06/img/pm/escher.png differ
diff --git a/slides/wk06/img/pm/fitts.png b/slides/wk06/img/pm/fitts.png
new file mode 100644
index 0000000000000000000000000000000000000000..7b0df624e6613f3dd1f6a38fbf9d6e17e80a5784
Binary files /dev/null and b/slides/wk06/img/pm/fitts.png differ
diff --git a/slides/wk06/img/pm/font-selection.png b/slides/wk06/img/pm/font-selection.png
new file mode 100644
index 0000000000000000000000000000000000000000..04fa116a613e446c85590d056d154e57b1e05964
Binary files /dev/null and b/slides/wk06/img/pm/font-selection.png differ
diff --git a/slides/wk06/img/pm/gmail-snapping.gif b/slides/wk06/img/pm/gmail-snapping.gif
new file mode 100644
index 0000000000000000000000000000000000000000..66a17084941a6d03ad02d2dfa7b62446ec755b1d
Binary files /dev/null and b/slides/wk06/img/pm/gmail-snapping.gif differ
diff --git a/slides/wk06/img/pm/grab-cursor.png b/slides/wk06/img/pm/grab-cursor.png
new file mode 100644
index 0000000000000000000000000000000000000000..69ad61bc226d295712e677589bd0bd6e5ae0f8fe
Binary files /dev/null and b/slides/wk06/img/pm/grab-cursor.png differ
diff --git a/slides/wk06/img/pm/hiddensize.png b/slides/wk06/img/pm/hiddensize.png
new file mode 100644
index 0000000000000000000000000000000000000000..32c6dd7c59eaa2f87c1e4c29801bca196abcff74
Binary files /dev/null and b/slides/wk06/img/pm/hiddensize.png differ
diff --git a/slides/wk06/img/pm/keyboard-mouse.jpg b/slides/wk06/img/pm/keyboard-mouse.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..3b9f366194a1832a35fd8c9621dec9bf3eb2958b
Binary files /dev/null and b/slides/wk06/img/pm/keyboard-mouse.jpg differ
diff --git a/slides/wk06/img/pm/linear-pie.jpg b/slides/wk06/img/pm/linear-pie.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7b5be577b037ad1996b358bf68265ce8e9171465
Binary files /dev/null and b/slides/wk06/img/pm/linear-pie.jpg differ
diff --git a/slides/wk06/img/pm/linear-pie.png b/slides/wk06/img/pm/linear-pie.png
new file mode 100644
index 0000000000000000000000000000000000000000..99fa1c9be77105ec9a858423a8bf1bf3f92acba5
Binary files /dev/null and b/slides/wk06/img/pm/linear-pie.png differ
diff --git a/slides/wk06/img/pm/mac-expanded.png b/slides/wk06/img/pm/mac-expanded.png
new file mode 100644
index 0000000000000000000000000000000000000000..a0e0d83d0be9bb0740e8069923da73b1fd25c8eb
Binary files /dev/null and b/slides/wk06/img/pm/mac-expanded.png differ
diff --git a/slides/wk06/img/pm/mac-noedge.png b/slides/wk06/img/pm/mac-noedge.png
new file mode 100644
index 0000000000000000000000000000000000000000..b1c0e0a346e3081e971fda5e4838930f67018f8f
Binary files /dev/null and b/slides/wk06/img/pm/mac-noedge.png differ
diff --git a/slides/wk06/img/pm/macvswindows.png b/slides/wk06/img/pm/macvswindows.png
new file mode 100644
index 0000000000000000000000000000000000000000..78f6e16b617deec6df270683f2235fa9d37f0ca4
Binary files /dev/null and b/slides/wk06/img/pm/macvswindows.png differ
diff --git a/slides/wk06/img/pm/magnification.png b/slides/wk06/img/pm/magnification.png
new file mode 100644
index 0000000000000000000000000000000000000000..10228424e733844c88ba076d36f3fc8bdee249bf
Binary files /dev/null and b/slides/wk06/img/pm/magnification.png differ
diff --git a/slides/wk06/img/pm/new-zoom-leave.png b/slides/wk06/img/pm/new-zoom-leave.png
new file mode 100644
index 0000000000000000000000000000000000000000..4c00cd0546155519467a06cac83f1efb5dca05cc
Binary files /dev/null and b/slides/wk06/img/pm/new-zoom-leave.png differ
diff --git a/slides/wk06/img/pm/old-zoom-leave.png b/slides/wk06/img/pm/old-zoom-leave.png
new file mode 100644
index 0000000000000000000000000000000000000000..78c133c0e0d3751be92e497c9d6a1cd06f7a3868
Binary files /dev/null and b/slides/wk06/img/pm/old-zoom-leave.png differ
diff --git a/slides/wk06/img/pm/old-zoom-leave2.png b/slides/wk06/img/pm/old-zoom-leave2.png
new file mode 100644
index 0000000000000000000000000000000000000000..be1ba7272ba0bdb898694986e66245149aad7334
Binary files /dev/null and b/slides/wk06/img/pm/old-zoom-leave2.png differ
diff --git a/slides/wk06/img/pm/pointer-cursor.png b/slides/wk06/img/pm/pointer-cursor.png
new file mode 100644
index 0000000000000000000000000000000000000000..78e12c265671daf592eb68cfcbf6903c63d16191
Binary files /dev/null and b/slides/wk06/img/pm/pointer-cursor.png differ
diff --git a/slides/wk06/img/pm/powerpoint-toolbar.png b/slides/wk06/img/pm/powerpoint-toolbar.png
new file mode 100644
index 0000000000000000000000000000000000000000..ad67beceb109847c530752f3e696a763be9a4436
Binary files /dev/null and b/slides/wk06/img/pm/powerpoint-toolbar.png differ
diff --git a/slides/wk06/img/pm/size.png b/slides/wk06/img/pm/size.png
new file mode 100644
index 0000000000000000000000000000000000000000..f56056be3e8fc5d3b55e2bf2f4845677d899112c
Binary files /dev/null and b/slides/wk06/img/pm/size.png differ
diff --git a/slides/wk06/img/pm/size1.png b/slides/wk06/img/pm/size1.png
new file mode 100644
index 0000000000000000000000000000000000000000..40da7ad658c54dd0b4a47cd182a7cd089483f9d0
Binary files /dev/null and b/slides/wk06/img/pm/size1.png differ
diff --git a/slides/wk06/img/pm/size2.png b/slides/wk06/img/pm/size2.png
new file mode 100644
index 0000000000000000000000000000000000000000..6351479cab97a656e0b98d36e141eea51b364358
Binary files /dev/null and b/slides/wk06/img/pm/size2.png differ
diff --git a/slides/wk06/img/pm/swype.jpg b/slides/wk06/img/pm/swype.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..b9ae2648366e5bd4b59aeec898b4316f9c764862
Binary files /dev/null and b/slides/wk06/img/pm/swype.jpg differ
diff --git a/slides/wk06/img/pm/timeoverid.png b/slides/wk06/img/pm/timeoverid.png
new file mode 100644
index 0000000000000000000000000000000000000000..a633d97047b1974ec59e5811c2c768ebac148502
Binary files /dev/null and b/slides/wk06/img/pm/timeoverid.png differ
diff --git a/slides/wk06/img/pm/windows-comparison.png b/slides/wk06/img/pm/windows-comparison.png
new file mode 100644
index 0000000000000000000000000000000000000000..3dc19639799015d50a9d1152e95e020363c30f2a
Binary files /dev/null and b/slides/wk06/img/pm/windows-comparison.png differ
diff --git a/slides/wk06/img/pm/x.png b/slides/wk06/img/pm/x.png
new file mode 100644
index 0000000000000000000000000000000000000000..75e39254205b42ab016a06f3381a9a37a799ad20
Binary files /dev/null and b/slides/wk06/img/pm/x.png differ
diff --git a/slides/wk06/people-motor.html b/slides/wk06/people-motor.html
new file mode 100644
index 0000000000000000000000000000000000000000..932b22a32c991ae700063e9ce279deb83559b9cb
--- /dev/null
+++ b/slides/wk06/people-motor.html
@@ -0,0 +1,706 @@
+---
+layout: presentation
+title: Properties of People II
+description: Deriving Design Principles from Physiology of Motor Control
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Properties of People II: Motor Control & Mental Models
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout: false
+
+# Agenda
+
+- Administrivia
+  - Color Picker is due Monday 5/11 (10pm)
+  - The Accessibility and Color Picker practice quizzes are out.
+  - - **Reminder:** Please fill out this [form](https://docs.google.com/forms/d/e/1FAIpQLSdQrpZx-gexgDcKEF1SRp4egObimDP9qqVwLD56w0V2sYJDpw/viewform) by tonight, so we can plan for our next assignment - Menus.
+- Fitts' Law and implications for interface design
+
+---
+
+# Let's try an experiment
+.left-column-half[![:img Image of an interface with a red dot and many grey dots on the left
+and a dialog on right to control randomization and highlight distance
+and width in a Fitts' law experiment., 80%](img/pm/fitts.png)
+]
+.right-column-half[
+-  [Fitts' Law Experiment](http://simonwallner.at/ext/fitts/) (simonwallner.at/ext/fitts) Scroll
+   down to just below 'A word of warning'
+- Click the red circles as fast as possible
+]
+---
+
+[//]: # (Outline Slide)
+# Today's goals
+
+Experience Fitts' Law
+
+Discuss its implications for design
+
+Introduce Guiard's model of Bi-Manual Control
+
+Discuss its implications for design
+---
+.left-column-half[
+# Throughput
+
+![:img Picture of graph of fitts law data collected when I did the
+experiment. Y axis is time and x is index of difficulty (ID). It's fairly
+noisy because fitts law is designed to measure multiple
+people. However it does fit a line., 80%](img/pm/timeoverid.png)
+]
+.right-column-half[
+.jax[$$MT = a + b*log_2({Dist \over Size} + 1)$$
+]
+
+where
+- *MT* is movement time
+- ID is the *Index of Difficulty* (ID, in bits) of a movement
+.jax[$$log_2({Dist \over Size} + 1)$$]
+- *ID/MT* is the *Throughput* of a device in bits/second
+- *a* and *b* are empirically derived constants
+- Note: We will use D for Dist and W for Width throughout the rest of this lecture
+]
+???
+This is just a line
+
+Fitts’ law tells us about difficulty for pointing and selection tasks
+- Time to move the hand depends only on relative precision required
+- MT increases as __distance__ from target increases
+- MT decreases as __size__ of target increases
+- Diagram this
+
+---
+# Original Fitts' experiment
+
+.left-column-half[
+![:img Mock up of the original task in Fitt's experiment, 80%](https://upload.wikimedia.org/wikipedia/commons/1/16/Fitts_Task_English.jpg)
+.font-small[[Wikpedia](https://en.wikipedia.org/wiki/Fitts%27s_law)]
+]
+.right-column-half[
+Original experiment from Paul Morris Fitts involved tapping on plates as quickly as possible.
+]
+
+---
+
+# Compare Device Performance & Human Performance
+
+.left-column-half[
+![:img Graph of Fitts law lines for various body parts (Neck Arm Wrist
+Finger) with time on the Y axis and bits on the X axis, 100%](img/pm/body-fitts.png)
+
+]
+
+.right-column-half[
+.font-small[
+Device/Part | Study | Throughput (bits/s) | Relative to Optimal
+-------|-------|------------ | -----------
+Finger | Langolf (1976) | 38
+Wrist  | Langolf (1976) | 23
+EyeTracker| Ware & Mikaelian (1987) | 13.7 |
+Hand   | Fitts (1954) | 10.6
+Arm    | Langolf (1976) | 9.5
+Xbox 360 | Zaranek (2014) | 5 | **.47** (arm)
+Mouse  | Mackenzie (2001) | 4.9 | .46 (hand)
+Neck      | Pfaff (1985) | 4.2 |
+Trackball | Mackenzie (2001)| 3.0 | .28 (hand)
+Touchpad  | Mackenzie (2001) | 2.9 | .27 (hand)
+Head      | Hansen (2018) | 2.5 | **.51** (neck)
+Gaze      | Hansen (2018) | 2.1 | **.15** (eyetracker)
+Joystick  | Mackenzie (2001)| 1.8 | .17 (hand)
+Playstation Move | Zaranek (2014) | 1.5 | .16 (arm)
+Kinect    | Zaranek (2014) | 1 | .1 (arm)
+]
+]
+.footnote[Card, S. K., Mackinlay, J. D., & Robertson, G. G. (1991). <br>
+A morphological analysis of the design space of input devices. <br> ACM
+Transactions on Information Systems (TOIS), 9(2), 99-122.
+]
+???
+Useful to know if you're designing something like VR
+
+Doesn't have much impact on interface design
+
+Doesn't capture everything; e.g. error rate is higher for eye tracker
+
+---
+# Warnings
+
+Applies to *expert, errorless* use
+
+![:img bar chart of Average WPM for error rates of 1% to 20% in a
+study that falsely inserted typing errors is much higher for 1% than
+20%,40%](img/pm/errors.png)
+
+
+.footnote[Error rate was manipulated by faking errors.
+Ahmed Sabbir Arif and Wolfgang Stuerzlinger. CHI 2010. Predicting the cost of error correction in character-based text entry technologies. In Proceedings of the SIGCHI Conference on Human Factors in Computing Systems, April 2010
+]
+
+???
+Axis: X is faked error rates, Y is the words per minute.
+
+Shows how WPM did change in the study where error rate is being changed.
+If you know you are going to make a lot of errors you slow down your motion
+The underlying way we're designed to move is with small motions, to eliminate jerk
+We accelerate and decelerate smoothly
+Trace of motion for different body parts - after the initial motion, which is a rapid aiming motion,
+then corrective motions if you misss the target.
+Lots of those corrections, that is where you are goign to see people slow down.
+Subtle effects here – like the time to fix errors goes up as the error rate goes up…
+Act of correcting an error also takes time.
+Not worry about in the assignment, but interesting to know.
+
+---
+# Example: Arm based input
+
+Student project using a Kinect from 2012.
+Watch the movement of his arm...
+
+![:youtube Bubble keyboard implemented by Chinmay N in 2012. Users swipe with their full arm to select letters in on a keyboard, mQ-pCDr3RCw]
+
+
+---
+# Discussion: Implications of Fitts' law
+
+In your breakout groups,
+- Discuss: Why are some things harder than others to click on?
+- Add your thoughts on the bullet line with your group number in this [Google Doc](https://docs.google.com/document/d/162SuMVyuVguaTiv7hSyZUbrDhvYZUbXHJLglHvENRbM/edit?usp=sharing)
+- It's helpful if one of you share your screens.
+
+![:img Picture of mac desktop and windows desktop. Of note is the main menu bar which is at the very top of the mac desktop but at the top of *each* window on the windows desktop, 80%](img/pm/macvswindows.png)
+
+???
+Constantly relevant
+
+Intuitively, things that are closer and/or bigger are faster and
+easier to hit (and vice versa)
+
+What is different about the file location in Mac and Windows?
+
+What is the width at the top of the screen.
+
+---
+# Design Tip #1: <br>Make small targets larger
+
+![:img Pet Gallery buttons at 64dp](img/buttons64dp.png)&nbsp;&nbsp;![:img Pet Gallery buttons at 80dp](img/buttons80dp.png)
+
+What does this do to Fitts Law Predictions?
+--
+- Maximizes Size (W)
+
+Why should you not maximize all of the targets?
+
+--
+
+- Fitts' law involves a logrithmic calculation -- exponentially bigger gains for small targets, not so
+much of a gain for larger targets
+
+---
+# Design Tip #2:<br> Put commonly used things close together
+
+![:img Screenshot of the powerpoint toolbar with grouped things,100%](img/pm/powerpoint-toolbar.png)
+
+Is this minimizing Distance (D) or maximizing Size (W)? (zoom poll)
+---
+
+# Design Tip #2:<br> Put commonly used things close together
+
+.left-column50[
+![:img Image of the drag'n'pop interface which moves icons to the cursor when they are valid targets,80%](img/pm/dragpop.png)
+]
+.right-column50[
+# ... Or bring them closer to  cursor
+
+Is this minimizing Distance (D) or maximizing Size (W)? (zoom poll)
+
+]
+.footnote[
+Baudisch, P., Cutrell, E., Robbins, D., Czerwinski, M., Tandler,
+P. Bederson, B., and Zierlinger, A. Drag-and-Pop and Drag-and-Pick:
+Techniques for Accessing Remote Screen Content on Touch- and
+Pen-operated Systems. In Proceedings of Interact 2003, Zurich
+Switzerland, August 2003, pp. 57-64.
+]
+
+
+???
+Reduces Distance (D)
+
+Not good design to put everything close together
+
+No space to move all targets (contextual filtering helps)
+
+Could do with a fancy container...
+
+---
+# Design Tip #2:<br> Put commonly used things close together
+
+.left-column50[
+![:img Image of the drag'n'pop interface which moves icons to the cursor when they are valid targets,80%](img/pm/dragpop.png)
+]
+
+.right-column50[
+
+Minimizes Distance (D) in Fitts Law Predictions
+
+Why not do this to all targets?
+]
+--
+.right-column50[
+- Other usability goals matter too -- e.g. grouping related things
+- It is not good design to put everything close together
+- There is not enough space to move all targets (contextual filtering helps)
+
+How would you implement this?
+
+]
+
+
+
+---
+# We can make things *Closer* and *Larger* at the same time
+
+![:img Image of mac with doc icons magnified,100%](img/pm/mac-expanded.png)
+
+---
+# We're beating Beating Fitts' Law!
+
+How else can we do this?
+--
+
+Just don't use a mouse! Shortcut buttons; scroll wheel
+
+Or CHEAT... manipulate the interface
+- Minimize D
+- Increase W
+
+---
+
+# Do these menus minimize Distance (D) or maximize Size (W)?
+
+(zoom poll)
+Select from a menu bar at top of screen
+![Picture of the apple menu opened on a mac,80%](img/pm/mac-noedge.png)
+
+???
+Problems?
+
+- Can be tiring to reach edges of *very* large screens
+- Not all interfaces can do this (e.g. web designers)
+---
+# Design Tip #3:<br>Make use of Edges: They are Infinite
+
+.right-column[
+![:img Picture of the Windows menu in Windows 95 Windows XP and Windows 8 showing progressive improvement in the relationship between look (namely a border around the icon) and feel (can click anywhere making it an infinitely large button which is easier to hit from a Fitts law perspective), 100%](img/pm/windows-comparison.png)
+]
+
+???
+- Windows 95 bug: bottom-left corner is offset by a few pixels, can’t click on it
+- Windows XP fixes it by making Start button go all the way to the corner
+- Windows 8 uses styling to make start menu circular, but still makes entire corner clickable
+---
+# Recent Example (Zoom)
+
+Which of these do you think is a better button for maximizing size using the infinite edge?
+
+.left-column60[
+![:img Old zoom leave button which looks only like text but really is an infinite edge, 30%](img/pm/old-zoom-leave.png)
+]
+.right-column30[
+<br>
+![:img New zoom leave button which looks bigger but loses the infinite edge, 50%](img/pm/new-zoom-leave.png)
+]
+
+---
+# Recent Example (Zoom)
+
+Which of these do you think is a better button for maximizing size using the infinite edge?
+
+.left-column60[
+![:img Old zoom leave button which looks only like text but really is an infinite edge, 30%](img/pm/old-zoom-leave.png) &nbsp;&nbsp;
+![:img Old zoom leave button which displays its infinite edge/larger button when hovered over, 30%](img/pm/old-zoom-leave2.png)
+
+Although it looks like only the text is clickable, it turns out the whole edge was. Now we only have a "smaller" but brighter button to click.
+]
+.right-column30[
+<br>
+![:img New zoom leave button which looks bigger but loses the infinite edge, 50%](img/pm/new-zoom-leave.png)
+]
+
+
+
+---
+# Does this minimize Distance (D) or maximize Size (W)?
+
+Right click in place and then select (starting at :19)
+
+![:youtube Illustration of advantages of marking menus,dtH9GdFSQaw?start=19]
+
+.footnote[
+Kittenish, G., & Buxton, W. (1994, April). User learning and performance with marking menus. In CHI (Vol. 94, pp. 258-264).
+]
+???
+Minimizes D
+AND
+increases W
+(only angle matters)
+
+
+---
+# Does this minimize Distance (D) or maximize Size (W)?
+
+Why is it so rare & unfamiliar?
+
+![:img Left -- A pie menu consisting of a circle broken into eight
+wedges containing menu items like copy and undo; right-- A picture of
+a standard linear menu ,50%](img/pm/linear-pie.jpg)
+
+.footnote[
+Left example: OneNote 2013, Right example: Firefox. Taken from [Fitts
+law and user experience](https://www.smashingmagazine.com/2012/12/fittss-law-and-user-experience/)
+by
+[https://www.smashingmagazine.com/author/anastasios-karafillis/](Anastasios Karafillis)
+]
+
+---
+# Design Tip #4:<br>Use pie menus instead of context menus for expert tasks
+--
+
+Under some circumstances only...
+
+- Less than 8 options (Small target areas when too many menu entries are added)
+- Expert user (willing to memorize and gain advantage of marking
+menus)
+- Grouping not important (hard to group radially)
+
+Pie menus are often not implemented in production code
+- Needs to be seen as a high priority feature
+- Managers need to be able to assign staff to the project
+  - Sadly, project constraints define an interface. (**Shouldn't be a thing! Whorfian effects**)
+
+
+---
+
+# Does this minimize Distance (D) or maximize Size (W)?
+
+![:img video of someone moving emails into folders with snapping,60%](img/pm/gmail-snapping.gif)
+
+???
+Snapping to a target
+
+- [A] Minimize D?
+- [B] Maximize W?
+
+minimizes D
+---
+
+# Design Tip #5:<br>Use snapping to minimize distance<br> when likely targets are known
+
+![:img Picture showing drag snapping in gmail trello and chrome,40%](img/pm/common-snapping-cases.png)
+
+.font-small[
+
+Gmail | Trello | Chrome
+----- | ------ | -----
+![:img check, 10%](img/pm/check.png)Drag Handle | ![:img x, 10%](img/pm/x.png)No Handle | ![:img x, 10%](img/pm/x.png) No Handle
+![:img ,10%](img/pm/grab-cursor.png)Grab cursor | ![:img ,10%](img/pm/pointer-cursor.png)Pointer cursor | ![:img ,10%](img/pm/cursor.png)Default cursor
+![:img check, 10%](img/pm/check.png)Drop Shadow | ![:img check, 10%](img/pm/check.png)Drop Shadow | ![:img x, 10%](img/pm/x.png) No Drop Shadow
+![:img check, 10%](img/pm/check.png)Drop Target | ![:img check, 10%](img/pm/check.png)Drop Target | ![:img x, 10%](img/pm/x.png) No Drop Target
+![:img x, 10%](img/pm/x.png) No Natural Movement | ![:img check, 10%](img/pm/check.png)Natural Movement | ![:img check, 10%](img/pm/check.png) Natural Movement
+]
+
+.footnote[Examples courtesy of [Drag and Drop for Design Systems](https://uxdesign.cc/drag-and-drop-for-design-systems-8d40502eb26d)]
+
+???
+Also common in drawing programs
+
+Most sophisticated approach: dynamic semantics: Check legality and
+consequences of each result at every move don’t catch errors, prevent them
+---
+# Does this minimize Distance (D) or maximize Size (W)?
+
+Fan Cursor, Area Cursor and Bubble Cursor
+![:youtube Video showing a variety of schemes for making the cursor
+bigger including fan cursor; area cursor; and bubble
+cursor,bq1x5cRqgUc]
+
+.footnote[Su, X., Au, O. K. C., & Lau, R. W. (2014, April). The
+implicit fan cursor: a velocity dependent area cursor. In Proceedings
+of the SIGCHI Conference on Human Factors in Computing Systems
+(pp. 753-762). ACM.]
+
+---
+# Design Tip #6:<br>Separate Motor Size from Visible Size
+
+.left-column[
+![:img Picture of two versions of a dialog box; scrollbar; and
+menu, 100%](img/pm/hiddensize.png)
+]
+.right-column[
+- (a) Visual space appearance of buttons in a dialogue
+box.
+- (b) Motor space version of button design in (a) with much larger
+targets for certain buttons.
+- (c) Standard scroll-bar design.
+- (d) Visual space appearance of scroll-bar redesigned to occupy smaller
+screen space.
+- (e) Motor space version of scroll-bar design in (d) with larger targets for active areas.
+- (f) Visual space appearance of menu.
+- (g) Motor space version of the menu design in (f) with the
+distance to more important items reduced by compressing the size of less important items)
+]
+.footnote[Semantic pointing widget designs from Blanch et al. 2004]
+???
+How would you implement this?
+- Manipulate picking
+- Whorfian effects
+---
+# Would you ever make something too small virtually?
+
+--
+
+How about a cancel button?
+
+---
+# How long will this take?
+.right-column-half[
+Select 'Open New Window in Process'
+]
+.left-column[
+![:img Cascading menus. User wants to use "Open New Window" then "Open
+new window in process" -- second option-- but the most direct path takes them over "Open command prompt" which changes the displayed sub-menu causing problems, 200%](img/pm/size.png)
+]
+--
+.right-column-half[
+Steering law ... Fitts law integrated over the path you have to follow
+]
+--
+.right-column-half[
+But it's not predictive at all. Why?
+]
+--
+.right-column-half[
+It doesn't account for actual user behavior
+]
+---
+# Actual User Behavior
+
+.left-column50[
+![:img Cascading menus. User wants to use "Open New Window" then "Open
+new window in process" -- second option -- but the most direct path takes them over "Open command prompt" which changes the displayed sub-menu causing problems, 80%](img/pm/size1.png)
+]
+--
+.right-column50[
+![:img Cascading menus. User wants to use "Open New Window" then "Open
+new window in process" -- second option -- but the most direct path takes them over "Open command prompt" which changes the displayed sub-menu causing problems, 80%](img/pm/size2.png)
+]
+
+???
+Overly eager cascading menus, wrong submenu
+- Common problem w/ web menus (but not Mac or Win)
+- could brainstorm solutions (e.g. snapping? set focus somehow?)
+- whorfian effects: this is hard to implement
+
+---
+# Fitts law has a huge limitation
+
+It is only predictive of **ERROR-FREE, EXPERT** behavior
+
+Related to our discussion of [Interaction Design](people-motor.html#28)
+---
+# What else might we want to measure?
+
+--
+- Time on Task -- How long does it take people to
+complete basic tasks? (For example, find something to
+buy, create a new account, and order the item.)
+
+--
+- Accuracy -- How many mistakes did people make? (And
+were they fatal or recoverable with the right information?)
+
+--
+- How strenuous (e.g. gaze has lower throughput but is less strenuous
+than head pointing Mackenzie 2018)
+
+--
+- Recall -- How much does the person remember
+afterwards or after periods of non-use?
+
+--
+- Emotional Response -- How does the person feel about
+the tasks completed? (Confident? Stressed? Would the
+user recommend this system to a friend?)
+
+Build up a list of good UI design principals from these basics
+- Undo
+- Predictability
+- ...
+What is missing? (e.g. fun)
+
+---
+# Two Handed Interaction
+
+![:img Picture by Escher of two hands each drawing the other, 40%](img/pm/escher.png)
+???
+Used to be a norm
+
+Seems we forgotten to include it in our interfaces
+---
+# Guiard's model of bimanual control
+
+Hand | Role and Action
+---- | ----
+Non-preferred | Leads the preferred hand (in time)
+| Sets the spatial frame of reference for the preferred hand
+| Performs coarse movements
+Preferred | Follows the non-preferred hand
+| Works within established frame of reference set by the non-preferred hand
+| Performs fine movement
+
+Aside: Guiard is assuming right-handed. Tendencies somewhat less clear for left-handers,but we typically assume this still applies
+]
+.footnote[
+Seminal work
+Yves Guiard, “Asymmetric Division of Labor in Human Skilled Bimanual Action: The Kinematic Chain as a Model”, Journal of Motor Behavior, Vol. 19, No. 4, 1987, pp. 486-517.http://cogprints.org/625/
+]
+???
+non-preferred hand sets context for preferred
+coarser, slower movement
+tends to move first
+???
+Applications?
+
+- Mouse+keyboard
+- Lenses
+
+---
+# What does theory say about keyboard layout?
+
+![:img Picture of right-handed user typing on keyboard with leftside
+and rightside power keys and mouse on right side (top). Picture of
+user  mousing with same set ups (bottom). Of note is the bad angle for
+the mouse in the keyboard with the right side power keys,
+30%](img/pm/keyboard-mouse.jpg)
+
+.footnote[From [Evoluent keyboard advertisement](https://turningpointtechnology.com/KB/EV/KB1.asp)]
+---
+# Analysis of alternative keyboard layout
+
+Task | Leading Movement | Trailing/Overlapping Movement
+----|----|----
+Delete | Right hand — manipulate pointer with mouse; select by double clicking/dragging | Left hand — press DELETE (probably with little finger)
+Select an option in a window (see Figure 15) | Right hand — manipulate pointer with mouse; click option | Left hand — press ENTER (Assumes OK button is default)
+Click on a link in a browser | Left hand — navigate to link via PAGE UP and/or PAGE DOWN keys | Right hand — manipulate pointer with mouse; select link by clicking
+Open file; open folder; launch program | Right  hand — manipulate pointer with mouse; single click on icon | Right hand — press ENTER (avoids error prone double-click operation)
+
+---
+# Other Examples: Tool Stone for Magic Lenses
+
+![:youtube By manipulating a mouse and a cube (one in each hand) the user controls a lens and uses it on screen, V32SnUnAe2E]
+
+Inspired by [1994 CHI paper](https://dl.acm.org/citation.cfm?id=166126)
+Published in [UIST 2000](https://lab.rekimoto.org/projects/toolstone/)
+
+---
+# Magnification
+
+![:img Picture of a mandelbrot fractal with a lens over part of it magnifying that part, 50%](img/pm/magnification.png)
+
+---
+# Font Selection
+
+![:img Picture of a paragraph of text with a lens containing a menu of options for bold italic regular and bold italic, 40%](img/pm/font-selection.png)
+
+???
+Fitts' law implications?
+---
+# Debugging Lenses
+
+![:img Picture of a GUI application with a lens showing information about two lines including their coordinates and the option to turn on and off additional features, 40%](img/pm/debugging.png)
+
+.footnote[
+Hudson, S. E., Rodenstein, R., and Smith, I. 1997. Debugging lenses: a new class of transparent tools for user interface debugging. In Proceedings UIST '97, 179-187. http://doi.acm.org/10.1145/263407.263542
+]
+---
+# Advantages of Lenses
+
+In context interaction
+- Little or no shift in focus of attention and/or movement
+- Alternate views in context and on demand
+
+???
+- tool is at/near action point
+- can compare in context
+- useful for “detail + context” visualization techniques
+--
+
+Structured well for 2 handed input
+- non-dominant hand does course positioning (of the lens)
+- dominant hand does fine work
+
+"Spatial modes"
+- Use “where you click through” to establish meaning
+- Typically has a clear affordance for the meaning
+
+---
+# Implementing Lenses
+
+.small[
+<div class="mermaid">
+  graph TD
+  Root(Root) --> LP(Lens Parent)
+  LP --> L[Lens]
+  LP --> I(Interactor 1)
+  LP --> II(Interactor 2)
+  LP --> III(Interactor 3)
+
+</div>
+]
+.footnote[Edwards, Hudson, et al., “Systematic output modification in a 2D user interface toolkit”, UIST ’97. http://doi.acm.org/10.1145/263407.263537 ]
+???
+Can be implemented with special "lens parent" container & lens interactors
+- Lens may need to change results of picking (only positional is affected) in collusion with lens parent
+- Lens parent forwards all damage to all lenses
+- Lenses typically change any damage that overlaps them into damage of whole lens area
+- Can pass a subclass of Drawable to "ambush and modify" drawing for output effects
+---
+# Discussion: Should scrolling be dominant or non-dominant?
+
+What tasks is scrolling used for?
+
+Which precedes/follows?
+
+???
+Task | Characteristics
+Scrolling  | precedes/overlaps other tasks
+| sets the frame of reference
+| minimal precision needed (coarse)
+Selecting, editing, reading, drawing, etc. | follows/overlaps scrolling
+| works within frame of reference set by scrolling
+| demands precision (fine)
+---
+# Summary Slide
+
+Design tips for motor
+
+- Design Tip #1: Make small targets larger
+- Design Tip #2: Put commonly used things close together
+- Design Tip #3: Use edges. They are infinite in size (W)
+- Design Tip #4: Use pie menus for expert tasks (better yet, marking menus)
+- Design Tip #5: Use snapping to reduce distance (D) when targets are known
+- Design Tip #6: Separate motor and visible size
+
+Two-Handed input principles
+- Non preferred leads
+- Sets frame of reference
+- Preferred does fine movement
diff --git a/slides/wk07/behavior-change.html b/slides/wk07/behavior-change.html
new file mode 100644
index 0000000000000000000000000000000000000000..8e7ebc3d1ffb3bf9d6be995782978f39e59890f8
--- /dev/null
+++ b/slides/wk07/behavior-change.html
@@ -0,0 +1,741 @@
+---
+layout: presentation
+title: Using Mobile Phones to Persuade
+description: Using Mobile Phones to Persuade--Behavior Change through Mobile Design
+---
+layout: normal
+
+# Do this now
+
+.left-column-half[
+<br>
+<iframe src="https://embed.polleverywhere.com/multiple_choice_polls/3oPAa3YORE0gE6uCKe7mq?controls=none&short_poll=true" width="600" height="400" frameBorder="0"></iframe>
+
+]
+
+.right-column-half[
+In chat write down your current "ear worm"
+
+What song is running through your head
+or are you listening to on repeat?
+
+]
+
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# [NOTIFICATIONS](http://sitn.hms.harvard.edu/flash/2018/dopamine-smartphones-battle-time/)
+
+![:img Picture of phone screen with red dots,
+80%](img/behavior-change/dopamine.jpg)
+
+
+.footnote[Picture from [itstimetologoff.com](https://www.itstimetologoff.com/2018/03/22/why-switching-off-your-social-media-and-phone-notifications-is-your-own-mini-digital-detox/)]
+???
+Multiple kinds of notifications on your phone.
+Here's the red dot with the number of messages on it.
+What other kinds are there?
+- Toast - appears within an app only
+- Email? Easy or hard to ignore
+What do you prefer? Which are more interruptive?
+Urge to clear the red dots on the screen?
+They effect your brain the seritonin in your rain (red dots in particular)
+---
+# [Dopamine, Smartphones & You: A battle for your time](http://sitn.hms.harvard.edu/flash/2018/dopamine-smartphones-battle-time/)
+
+![:img Picture of brain looking at notification, 40%](img/behavior-change/dopamine2.png)
+
+???
+From a company's perspective, it's trying to get your attention
+Not an altruistic service
+It's not always the case, but incentives are there.
+War between companies to get your attention
+Important to think about how you use notifications if you're doing Mobile app development.
+
+---
+layout: false
+
+.left-column[
+## Using Mobile Phones to Persuade
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+]
+.right-column[
+
+
+![:img Picture of violinist in office with boy and principal with caption; I've hired this musician to play a sad melody while I give you a sob story about why I didn't do my homework. It's actually quite effective, 60%](img/behavior-change/sob.png)
+
+]
+
+---
+# Examlet 3
+
+- Examlet 3 will be released after lecture
+- Same process as Examlet 2: copy a google doc, fill it out, make a PDF and upload to gradescope
+- Different: Not as time bound: due by 10pm tonight.
+
+
+---
+# What does it take to persuade you?
+
+
+![:youtube Wildebeest arguing about a log and whether it is a crocodile, JMJXvsCLu6s]
+
+---
+.left-column[
+## Technology for persuasion
+
+Coercive: negative connotatons, patronizing, paternalistc, "we know
+what’s best for you and you will do it!"
+]
+.right-column[
+![:img Big person leaning on small person, 30%](img/behavior-change/coercion.png)
+]
+
+???
+Persuasion is changing your behavior.
+
+---
+.left-column[
+## Technology for persuasion
+
+## Is really about behavior change
+]
+.right-column[
+
+Which do you think is true?
+
+Persuasive = Coercive
+
+Persuasive >= Coercive
+
+Persuasive <= Coercive
+
+Persuasive != Coercive
+
+]
+???
+Technology that is pursuading you to do some kind of action.
+
+If you've bought something like a fitbit, you're buying into the idea of something pursuading
+you to do something.
+---
+# What does it take to persuade you?
+
+![:youtube People being persuaded to climb stairs, 2lXh2n0aPyw]
+
+???
+What kind of pursuasion is being applied here.
+Is this coercive or not coercive?
+
+---
+# What does it take to persuade you?
+
+
+.left-column50[
+![:youtube Cialdini, cFdCzN7RYbw]
+
+:54 6 shortcuts
+
+]
+???
+Tip example -
+How are they doing the study? What are the conditions?
+What are they measuring? (how much they tip)
+How do they sample?
+Are they consenting the participants like we have to do the  menus study?
+
+--
+.right-column50[
+How does this list of shortcuts apply to interface design?
+
+- reciprocity
+- scarcity
+- authority
+- consistency
+- liking
+- consensus
+
+]
+
+???
+Trying to keep people using your app
+
+---
+# What’s needed to support positive behavior change?
+.quote[
+If you cannot measure it, you cannot improve it.]
+
+Lord Kelvin
+
+???
+Not using sensor based interfaces, but we'll talk about what can we do with sensor data?
+Almost every app that you download collects data about you. Studies have been done
+about the libraries that are used in seemingly begnin apps.
+Example: Angry birds. Why do they collect location data? (Sales)
+
+Most of the data they're collecting is through third party libraries.
+
+---
+# Data Collection Options
+
+![:img Data collection Devices (fitbits; watches; etc), 40%](img/behavior-change/data-collection.png)
+
+---
+# Data Collection Options
+
+.left-column[
+
+Or we could just use one...
+
+]
+
+.right-column[
+![:img Samsung Phone, 20%](img/behavior-change/phone.png)
+
+]
+???
+We're carrying this around and letting them collect all this data.
+
+---
+.left-column[
+## Making Data Actionable
+
+## Data ]
+.right-column[
+
+![:img Speedometor with dial at 110mph, 80%](img/behavior-change/speedometer.png)
+
+]
+
+---
+.left-column[
+## Where is the value?
+
+## Data
+
+]
+.right-column[
+Most of what we get is Data
+
+![:img many graphs, 100%](img/behavior-change/mostlydata.png)
+]
+
+???
+We have to do more to turn the raw into something useful.
+Knowledge instead of just data
+
+
+---
+.left-column[
+## Making Data Actionable
+
+## Knowledge ]
+.right-column[
+
+![:img Sign comparing speed (29mph) to speed limit (25mp), 60%](img/behavior-change/sign.png)
+
+]
+
+---
+.left-column[
+## Making Data Actionable
+
+## Decision Making ]
+.right-column[
+
+![:img out of focus sign due to speeding, 50%](img/behavior-change/focus.png)
+
+Danger... you have exceded the speed limit of 80kph. <br>
+Slow down immediately or face strict disciplinary action
+
+.footnote[[Meru speed alarms in cabs](https://www.meru.in/about-us/our-philosophy)]
+
+]
+???
+
+This will be influencing based on the data
+
+---
+.left-column[
+## Making Data Actionable
+
+### Translating data into behavior change
+
+]
+.right-column[
+![:img Personal Informatics apps, 80%](img/behavior-change/personalinformatics.png)
+
+]
+.footnote[[personalinformatics.org](http://personalinformatics.org/tools)]
+
+???
+Website that has a list of all the APIs that they were aware of at the time that supports behavior change.
+
+---
+.left-column[
+## Making Data Actionable
+
+### Translating data into behavior change
+
+]
+.right-column[
+![:img five part model of personal informatics with stages
+preparation; collection; integration; reflection; action ,
+80%](img/behavior-change/personal-informatics-model.png)
+
+Developed with 68 survey participants, 11 follow-up interviews
+
+]
+.footnote[Li, Dey, Forlizzi. A Stage-Based Model of Personal
+Informatics Systems. CHI 2010.]
+
+???
+Study done at the iSchool
+Beyond notifications to get users to use an app
+
+Can't assume that everyone is at the action stage.
+
+
+---
+
+.left-column[
+## Preparation
+
+![:img person waving, 100%](img/behavior-change/alice.png)
+]
+.right-column[
+Alice!
+- **Wanted** to become active
+- **Decided** to track her physical activity
+- **Chose** to track step counts using a pedometer
+]
+
+
+.footnote[
+**Preparation**|Collection|Integration|Reflection|Action]
+
+
+---
+.left-column[
+## Collection
+
+]
+
+.right-column[
+
+| day | steps | day | steps | day | steps | day | steps | day | steps | day | steps |
+|-----|-------|-----|-------|-----|-------|-----|-------|-----|-------|-----|-------|
+| Mon | 1573  | Mon | 1209  | Mon | 12344 | Mon | ...   | Mon | ...   | Mon | ...   |
+| Tue | 4392  | Tue | 1834  | Tue | 1200  | Tue | ...   | Tue | ...   | Tue | ...   |
+| Wed | 4537  | Wed | 4341  | Wed | 4311  | Wed | ...   | Wed | ...   | Wed | ...   |
+| Thu | 5842  | Thu | 8300  | Thu | 7348  | Thu | ...   | Thu | ...   | Thu | ...   |
+| Fri | 10258 | Fri | 10300 | Fri | 9384  | Fri | ...   | Fri | ...   | Fri | ...   |
+| Sat | 7528  | Sat | 6347  | Sat | 5123  | Sat | ...   | Sat | ...   | Sat | ...   |
+| Sun | 1367  | Sun | 1231  | Sun | 1430  | Sun | ...   | Sun | ...   | Sun | ...   |
+| Mon | 1497  | Mon | 1503  | Mon | 1427  | Mon | ...   | Mon | ...   | Mon | ...   |
+| Tue | 1837  | Tue | 1717  | Tue | 1643  | Tue | ...   | Tue | ...   | Tue | ...   |
+| Wed | 4537  | Wed | 4341  | Wed | 4311  | Wed | ...   | Wed | ...   | Wed | ...   |
+| Thu | 5842  | Thu | 8300  | Thu | 7348  | Thu | ...   | Thu | ...   | Thu | ...   |
+| Fri | 10258 | Fri | 10300 | Fri | 9384  | Fri | ...   | Fri | ...   | Fri | ...   |
+| Sat | 7528  | Sat | 6347  | Sat | 5123  | Sat | ...   | Sat | ...   | Sat | ...   |
+| Sun | 1367  | Sun | 1231  | Sun | 1430  | Sun | ...   | Sun | ...   | Sun | ...   |
+| ... | ...   | ... | ...   | ... | ...   |     | ...   | ... | ...   | ... | ...   |
+]
+---
+
+.left-column[
+## Integration
+
+![:img person waving, 100%](img/behavior-change/alice.png)
+]
+.right-column[
+![:img chart of steps, 80%](img/behavior-change/chart.png)
+
+]
+
+
+.footnote[
+Preparation|Collection|**Integration**|Reflection|Action]
+
+???
+bar plot
+
+---
+
+.left-column[
+## Reflection
+
+![:img person waving, 100%](img/behavior-change/alice.png)
+]
+.right-column[
+![:img chart of steps, 80%](img/behavior-change/chart-highlights.png)
+
+]
+
+.footnote[
+Preparation|Collection|Integration|**Reflection**|Action]
+
+???
+Days when she's really outside of the mean
+
+---
+
+.left-column[
+## Action
+
+![:img person moving, 100%](img/behavior-change/aliceactive.png)
+]
+.right-column[
+
+The stage when people choose what they are going to do with their
+new-found understanding of themselves.
+]
+
+.footnote[
+Preparation|Collection|Integration|Reflection|**Action**]
+
+
+???
+How can we support this with technology?
+
+--
+.right-column[
+– Alerts
+
+– Incentives
+
+– Suggestions
+
+]
+
+???
+Context-aware computing...
+
+---
+
+.left-column50[
+![:img self tracking in context, 80%](img/behavior-change/full-model.png)
+]
+.right-column50[
+
+# Why Behavior Change is Difficult
+
+
+### Every stage presents distinct barriers
+
+Failures in one stage cascade through later stages, must design for
+entire tracking process
+
+### This occurs in a larger context of deciding to track, selecting a tool, and eventual lapsing
+]
+.footnote[Epstein, Ping, Fogarty, Munson. A Lived Informatics Model of
+Personal Informatics. UbiComp 2015.]
+
+???
+Fitbit users lapse after a time - they don't charge it.
+Not incentivised.
+Have to account for when they're lapsing
+
+
+---
+
+# Process of Change
+
+![:img Trans-theoretical change model, 80%](img/behavior-change/ttc.png)
+
+<!--
+| Precont.      | Cont.         | Prep.           | Action                | Maint.           | Adoption              |
+|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------|-----------------------|
+| Consciousness-raising | Consciousness-raising | Consciousness-raising |                       |              | Social liberation     | Social liberation     | Social liberation     | Social liberation     |                       |                       |
+         |                       |
+|                       | Self-analysis         | Self-analysis         |                       |                       |                       |
+|                       | Emotional arousal     | Emotional arousal     |                       |                       |                       |
+|                       | Positive outlook      | Positive outlook      |                       |                       |                       |
+|                       |                       | Commitment            | Commitment            | Commitment            | Commitment            |
+|                       |                       | Behavior analysis     | Behavior analysis     |                       |                       |
+|                       |                       | Goal setting          | Goal setting          | Goal setting          |                       |
+|                       |                       | Self-reevaluation     | Self-reevaluation     | Self-reevaluation     |                       |
+|                       |                       |                       | Countering            | Countering            |                       |
+|                       |                       |                       | Monitoring            | Monitoring            | Monitoring            |
+|                       |                       |                       | Environmental control | Environmental control | Environmental control |
+|                       |                       |                       | Helping relationships | Helping relationships | Helping relationships |
+|                       |                       |                       | Rewards               | Rewards               | Rewards               |
+|                       |                       |                       |                       |                       |                       |
+{: .small #small}
+-->
+
+
+???
+Using the same plan for every individual who wishes to change a behavior will not work
+
+Timing is important in the process of willful change
+
+---
+background-image: url(img/behavior-change/phoneplanet.png)
+
+# Case Study: <BR> Energy Use
+---
+# What is the responsibility of technologists to address climate change?
+![:img Picture of unhappy amazon boxes, 40%](img/behavior-change/amazon.jpeg)
+
+.footnote[[Amazon Refuses to Act on Climate Change. So We Employees Are Speaking Out](https://www.yesmagazine.org/planet/amazon-climate-change-action-jeff-bezos-20190530)]
+
+---
+# Case Study: UbiGreen - In Class activity
+
+.right-column30[
+![:img Picture of a mobile phone with a car and a tree on the sceren,40%](img/behavior-change/ubigreen.png)
+]
+
+This will be fun - a design activity!
+--
+Honest.
+--
+Don't leave...
+--
+It does involve breakout rooms.
+--
+(If you are the only one in a breakout room come back to the main room and I'll put you in another one.)
+--
+
+
+Each group will work on a page in the [shared google doc](https://docs.google.com/document/d/1SqvaQyhFYs6AsOPoDcBkG4egCRRq3jEaW17HOi0hSkM/edit?usp=sharing)
+--
+
+Case study is explained on the next slide AND in the doc.
+--
+
+One person in each breakout room should share the screen with slide, everyone should also
+be in the google doc.
+
+---
+# Case Study: UbiGreen - In Class activity
+
+.right-column30[
+![:img Picture of a mobile phone with a car and a tree on the sceren,40%](img/behavior-change/ubigreen.png)
+]
+
+Problem: High Carbon Dioxide emissions from U.S. households from personal transportation (single use
+vehicles).
+
+Goal: To create an app that will encourage users to change their behavior with respect to using
+their cars.
+
+--
+
+This was last done in 2006-9... the app needs updating...
+
+.left-column40[
+.footnote[
+based on a [CHI 2009 paper](https://dl.acm.org/doi/10.1145/1518701.1518861) by J. Froehlich,
+T. Dillahunt, P. Klasnja, J. Mankoff, S. Consolvo, B. Harrison, J. A. Landay
+]
+]
+---
+# Case Study: UbiGreen - In Class activity
+
+.right-column30[
+![:img Picture of a mobile phone with a car and a tree on the sceren,40%](img/behavior-change/ubigreen.png)
+]
+
+Your task:
+- Design an app that will
+  - Use sensing data to determine a user's behavior (what type of data would you need?)
+  - Pursuade (or coerce?) users of your app to change their behavior
+- Design a user study that will determine if your app is successful.
+  - What is your [hypothesis](https://courses.cs.washington.edu/courses/cse340/20sp/slides/wk07/menus.html#36)?
+  - What is your [method](https://courses.cs.washington.edu/courses/cse340/20sp/slides/wk07/menus.html#40)? What conditions might you have for your experiment?
+  - What might you [measure](https://courses.cs.washington.edu/courses/cse340/20sp/slides/wk07/menus.html#41)?
+  - What [data](https://courses.cs.washington.edu/courses/cse340/20sp/slides/wk07/menus.html#43) would you collect?
+  - How would you [collect the data](https://courses.cs.washington.edu/courses/cse340/20sp/slides/wk07/menus.html#49)?
+  - How would you prove your theories?
+
+
+
+
+---
+
+# Case Study: UbiGreen - actual research
+
+Sensed Transportation Behavior
+
+Ever-present Feedback
+
+Two formative studies
+- Online survey
+- In situ experience sampling method (ESM) study
+
+Three week field deployment
+
+.footnote[
+based on a [CHI 2009 paper](https://dl.acm.org/doi/10.1145/1518701.1518861) by J. Froehlich,
+T. Dillahunt, P. Klasnja, J. Mankoff, S. Consolvo, B. Harrison, J. A. Landay
+]
+
+???
+Smartest phone at the time (2006)
+
+
+---
+
+![:img Picture of a mobile phone with a car and a tree on the screen, 50%](img/behavior-change/ubigreen-explained.png)
+
+---
+
+![:img Picture of a mobile phone with a car and a tree on the screen,60%](img/behavior-change/ubigreen-system.png)
+
+---
+![:img Picture of a mobile phone with a car and a tree on the screen,60%](img/behavior-change/ubigreen-sequence.png)
+
+---
+.left-column[
+![:img Picture of a mobile phone with a car and a tree on the screen,40%](img/behavior-change/ubigreen.png)
+
+]
+
+.right-column[
+## UbiGreen
+
+2 cities; 14 participants
+
+Obtain preliminary feedback on prototype
+- Engagement
+- Potential for social use
+- Potential for changing behavior
+
+]
+
+---
+.left-column[
+![:img Picture of a mobile phone with a car and a tree on the sceren,40%](img/behavior-change/ubigreen.png)
+
+]
+
+.right-column[
+## UbiGreen
+
+
+Engagement
+.quote[It's omnipresent]
+
+Behavior Change:
+.quote[
+“It really encourages you to analyze your own performance”
+]
+
+<!-- Social
+.quote[
+“Some people at work knew about the polar bear and every day they -->
+<!-- asked me about it. ‘Did you get a seal today?’”] -->
+
+]
+???
+Introspection
+
+---
+# Personal Informatics
+![:img five part model of personal informatics with stages
+preparation; collection; integration; reflection; action ,
+80%](img/behavior-change/personal-informatics-model.png)
+
+
+???
+Apply it to ubigreen
+
+---
+# Aside: Other ways for CS to engage with sustainability
+.left-column50[
+
+## Impact: Direct ways of reducing carbon emissions
+
+- Efficiency (new technologies, new patterns of use, better buildings, etc.)
+- Carbon capture & storage
+- Alternate sources of energy
+- Carbon sinks (e.g. reforestation)
+- Better energy grid
+]
+
+.right-column50[
+
+## Solutions: Indirect ways of reducing carbon emissions
+
+- Population control
+- Economic controls (e.g., taxes)
+- Cross-cultural solutions (culturally-relevant technologies)
+- Education
+- Governmental buy in (Local laws, world treaties, etc)
+- Advancing science
+]
+.footnote[
+[Socolow &
+Pacala](http://ngm.nationalgeographic.com/2007/10/carbon-crisis/img/stabilization_wedges.pdf);
+A. Gore, Earth in the Balance
+]
+---
+.right-column[
+## My checklist for mobile ICT impact
+
+*Measure* waste and impact
+   - Example: [what happens to phones when you finish with them?](https://dl.acm.org/citation.cfm?doid=1357054.1357110)
+
+*Monitor, Model & Inform* governments as well as individuals
+  - Example: [Measuring air pollution using a mobile
+    device](https://dl.acm.org/citation.cfm?doid=1978942.1979290)
+]
+---
+.left-column[
+
+![:img therml, 100%](img/behavior-change/therml.png)
+
+Simulated impact of multiple algorithms on three month data set
+
+]
+
+.right-column[
+## My checklist for mobile ICT impact
+
+*Encourage environmentality*
+  - example [Automated thermostat  setting](https://dl.acm.org/citation.cfm?doid=2493432.2493441)
+  - automation, efficiency, re-use
+  - people (lived experience)
+  - reduce waste
+]
+.footnote[[some computer science issues in creating a sustainable world](http://www.cs.cmu.edu/~io/publications/ieee08-preprint.pdf)]
+
+---
+.left-column[
+![:img cscw, 100%](img/behavior-change/android.png)
+]
+
+.right-column[
+# My checklist for mobile ICT impact
+
+*Relevance across sectors and cultures* (residential: renters, owners, etc), business, ...)
+  - Example: [understanding conflicts between landlords and tenants  around energy use](https://dl.acm.org/citation.cfm?doid=1864349.1864376)
+  - Example: [deploying an android energy monitor to help communities &
+  individuals monitor](https://dl.acm.org/citation.cfm?doid=2531602.2531626)
+
+Goal: *Scale up* to governments, nations or more
+]
+.footnote[
+[Some computer science issues in creating a sustainable world](http://www.cs.cmu.edu/~io/publications/ieee08-preprint.pdf)
+]
+---
+
+.title[Why a digression on sustainability in a behavior change lecture?]
+.body[
+![:img five part model of personal informatics with stages
+preparation; collection; integration; reflection; action ,
+80%](img/behavior-change/personal-informatics-model.png)
+
+]
+???
+That's all there is to fix it, we need the will power at a society level
+
+Of course there's other applications of behavior change as well :)
+Health is a big one!
diff --git a/slides/wk07/img/behavior-change/alice.png b/slides/wk07/img/behavior-change/alice.png
new file mode 100644
index 0000000000000000000000000000000000000000..afca3ba696619e3701d1c19d79050ece03c69c71
Binary files /dev/null and b/slides/wk07/img/behavior-change/alice.png differ
diff --git a/slides/wk07/img/behavior-change/aliceactive.png b/slides/wk07/img/behavior-change/aliceactive.png
new file mode 100644
index 0000000000000000000000000000000000000000..31d5c2c28f1aee621909557f9695d2f835484cbe
Binary files /dev/null and b/slides/wk07/img/behavior-change/aliceactive.png differ
diff --git a/slides/wk07/img/behavior-change/amazon.jpeg b/slides/wk07/img/behavior-change/amazon.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..9d713cef9b12ee01424cdb3fb1c07dded5ee2d33
Binary files /dev/null and b/slides/wk07/img/behavior-change/amazon.jpeg differ
diff --git a/slides/wk07/img/behavior-change/android.png b/slides/wk07/img/behavior-change/android.png
new file mode 100644
index 0000000000000000000000000000000000000000..c05abc897a6ba254f4bf90cfa088dfb9de0d2569
Binary files /dev/null and b/slides/wk07/img/behavior-change/android.png differ
diff --git a/slides/wk07/img/behavior-change/chart-highlights.png b/slides/wk07/img/behavior-change/chart-highlights.png
new file mode 100644
index 0000000000000000000000000000000000000000..aa85ec73c9867b35e533f908213fe010872a4a7e
Binary files /dev/null and b/slides/wk07/img/behavior-change/chart-highlights.png differ
diff --git a/slides/wk07/img/behavior-change/chart.png b/slides/wk07/img/behavior-change/chart.png
new file mode 100644
index 0000000000000000000000000000000000000000..48bf2c80d8c82673d08dcd270513bd242f4a94f8
Binary files /dev/null and b/slides/wk07/img/behavior-change/chart.png differ
diff --git a/slides/wk07/img/behavior-change/coercion.html b/slides/wk07/img/behavior-change/coercion.html
new file mode 100644
index 0000000000000000000000000000000000000000..d04f6b052527ab854bcd2babf3e56c5bc76bc88d
--- /dev/null
+++ b/slides/wk07/img/behavior-change/coercion.html
@@ -0,0 +1,449 @@
+<!DOCTYPE html>
+<html lang="en" prefix="og: http://ogp.me/ns#">
+<head>
+
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1">
+<title>Free photo Chef Man Manager Pressure Suppression Superior - Max Pixel</title>
+<meta name="description" content="Chef Man Manager Pressure Suppression Superior photo, resolution 2603×3904 pixel, Image type PNG, free download and free for commercial use.">
+
+
+<meta name="google-site-verification" content="Je-m0JymvkSxpT3DfyirLx1O4vzwjAVMCxgR88P9OYI" />
+
+<link rel="apple-touch-icon" sizes="57x57" href="https://www.maxpixel.net/images/apple-touch-icon-57x57.png">
+<link rel="apple-touch-icon" sizes="60x60" href="https://www.maxpixel.net/images/apple-touch-icon-60x60.png">
+<link rel="apple-touch-icon" sizes="72x72" href="https://www.maxpixel.net/images/apple-touch-icon-72x72.png">
+<link rel="apple-touch-icon" sizes="76x76" href="https://www.maxpixel.net/images/apple-touch-icon-76x76.png">
+<link rel="apple-touch-icon" sizes="114x114" href="https://www.maxpixel.net/images/apple-touch-icon-114x114.png">
+<link rel="apple-touch-icon" sizes="120x120" href="https://www.maxpixel.net/images/apple-touch-icon-120x120.png">
+<link rel="apple-touch-icon" sizes="144x144" href="https://www.maxpixel.net/images/apple-touch-icon-144x144.png">
+<link rel="apple-touch-icon" sizes="152x152" href="https://www.maxpixel.net/images/apple-touch-icon-152x152.png">
+<link rel="apple-touch-icon" sizes="180x180" href="https://www.maxpixel.net/images/apple-touch-icon-180x180.png">
+
+<link rel="icon" type="image/png" href="https://www.maxpixel.net/images/favicon-32x32.png" sizes="32x32">
+<link rel="icon" type="image/png" href="https://www.maxpixel.net/images/android-chrome-192x192.png" sizes="192x192">
+<link rel="icon" type="image/png" href="https://www.maxpixel.net/images/favicon-96x96.png" sizes="96x96">
+<link rel="icon" type="image/png" href="https://www.maxpixel.net/images/favicon-16x16.png" sizes="16x16">
+
+
+<meta name="msapplication-TileColor" content="#4ea64e">
+<meta name="msapplication-TileImage" content="https://www.maxpixel.net/images/mstile-144x144.png">
+<meta name="theme-color" content="#4ea64e">
+
+<link rel="canonical" href="https://www.maxpixel.net/Chef-Man-Manager-Pressure-Suppression-Superior-3026568">
+
+
+
+<meta property="og:image" content="https://www.maxpixel.net/static/photo/640/Chef-Man-Manager-Pressure-Suppression-Superior-3026568.png">
+<meta property="og:type" content="article">
+<meta property="og:title" content="Free photo Chef Man Manager Pressure Suppression Superior - Max Pixel">
+<meta name="twitter:card" content="photo">
+<meta name="twitter:site" content="@fGreatPicture">
+<meta name="twitter:title" content="Free photo Chef Man Manager Pressure Suppression Superior - Max Pixel">
+<meta name="twitter:image" content="https://www.maxpixel.net/static/photo/640/Chef-Man-Manager-Pressure-Suppression-Superior-3026568.png">
+<meta name="twitter:image:width" content="427">
+<meta name="twitter:image:height" content="640">
+
+<link rel="stylesheet" href="https://www.maxpixel.net/css/max-pixel.min.css">
+<link rel="stylesheet" href="https://www.maxpixel.net/css/style.css">
+<!--[if lt IE 9]><script src="https://www.maxpixel.net/js/respond.min.js"></script><![endif]-->
+<style>
+  #header_inner, #footer_inner { max-width: 1620px; }
+</style>
+<script type="text/javascript">
+var base_url = 'https://www.maxpixel.net/';
+</script>
+
+</head>
+<body>
+<div id="wrapper">
+  <div id="header">
+    <div id="header_inner">
+      <div class="pure-menu pure-menu-horizontal pure-menu-open">
+        <ul>
+          <li class="pure-dropdown hide-xs hide-sm hide-md"><a href="https://www.maxpixel.net/Special-Photos" id="special-link">Special Photos</a></li>
+          <li class="pure-dropdown hide-xs hide-sm hide-md"><a><i class="icon icon_menu_dots"></i></a>
+            <ul class="pure-menu-children">
+              <li class="mm_inc"><a href="http://www.freegreatpicture.com/" target="_blank">FreeGreatPicture.com</a></li>
+              <li class="mm_inc"><a href="http://www.freegreatdesign.com/">FreeGreatDesign.com</a></li>
+            </ul>
+          </li>
+          <li class="pure-dropdown hide-lg hide-xl"><a><i class="icon icon_menu_bars"></i></a>
+            <ul id="mobile_menu" class="pure-menu-children">
+              <li><a href="https://www.maxpixel.net/Special-Photos">Special Photos</a></li>
+            </ul>
+          </li>
+        </ul>
+      </div>
+      <a id="logo" href="https://www.maxpixel.net/" class="hover_opacity"><img src="https://www.maxpixel.net/images/logo.png"></a>
+      <form class="media_search header_search" action="https://www.maxpixel.net/search" method="get">
+                <input type="submit" value=" ">
+        <div class="dd_box"><span class="image_type" style="margin-right:5px">Search</span><i class="arrow"></i></div>
+        <div class="pure-form bubble se">
+          <table>
+
+            <tr class="image_option">
+              <th>Orientation</th>
+              <td><label>
+                  <input type="checkbox" name="orientation" value="horizontal">
+                  Horizontal</label>
+                <label>
+                  <input type="checkbox" name="orientation" value="vertical">
+                  Vertical</label></td>
+            </tr>
+            <tr>
+              <th style="vertical-align:middle">Category</th>
+              <td><select name="cat">
+                                  <option value="" selected>All</option>
+                                  <option value="animals">Animals</option>
+                                  <option value="buildings">Architecture/Buildings</option>
+                                  <option value="backgrounds">Backgrounds/Textures</option>
+                                  <option value="fashion">Beauty/Fashion</option>
+                                  <option value="business">Business/Finance</option>
+                                  <option value="computer">Computer/Communication</option>
+                                  <option value="education">Education</option>
+                                  <option value="feelings">Emotions</option>
+                                  <option value="food">Food/Drink</option>
+                                  <option value="health">Health/Medical</option>
+                                  <option value="industry">Industry/Craft</option>
+                                  <option value="music">Music</option>
+                                  <option value="nature">Nature/Landscapes</option>
+                                  <option value="people">People</option>
+                                  <option value="places">Places/Monuments</option>
+                                  <option value="religion">Religion</option>
+                                  <option value="science">Science/Technology</option>
+                                  <option value="sports">Sports</option>
+                                  <option value="transportation">Transportation/Traffic</option>
+                                  <option value="travel">Travel/Vacation</option>
+                                </select></td>
+            </tr>
+            <tr class="image_option">
+              <th style="vertical-align:middle">Larger than</th>
+              <td style="ccolor:#777"><input type="text" name="min_width" value="" placeholder="Width">
+                <span class="times">&times;</span>
+                <input type="text" name="min_height" value="" placeholder="Height">
+                px </td>
+            </tr>
+            <tr class="image_option">
+              <th>Color</th>
+              <td>
+                <label>
+                  <input type="checkbox" name="colors[]" value="transparent"> Transparent
+                </label>
+                <input id="cf_grayscale" class="cf_grayscale" type="checkbox" name="colors[]" value="grayscale" style="float:none">
+                <label style="display:inline" for="cf_grayscale"> Black and white</label>
+                <div class="color_filter bg_colors">
+                                                      <input id="cf_red" type="checkbox" name="colors[]" value="red">
+                  <label for="cf_red" class="red"></label>
+                                    <input id="cf_orange" type="checkbox" name="colors[]" value="orange">
+                  <label for="cf_orange" class="orange"></label>
+                                    <input id="cf_yellow" type="checkbox" name="colors[]" value="yellow">
+                  <label for="cf_yellow" class="yellow"></label>
+                                    <input id="cf_green" type="checkbox" name="colors[]" value="green">
+                  <label for="cf_green" class="green"></label>
+                                    <input id="cf_turquoise" type="checkbox" name="colors[]" value="turquoise">
+                  <label for="cf_turquoise" class="turquoise"></label>
+                                    <input id="cf_blue" type="checkbox" name="colors[]" value="blue">
+                  <label for="cf_blue" class="blue"></label>
+                                    <input id="cf_lilac" type="checkbox" name="colors[]" value="lilac">
+                  <label for="cf_lilac" class="lilac"></label>
+                                    <input id="cf_pink" type="checkbox" name="colors[]" value="pink">
+                  <label for="cf_pink" class="pink"></label>
+                                    <input id="cf_white" type="checkbox" name="colors[]" value="white">
+                  <label for="cf_white" class="white"></label>
+                                    <input id="cf_gray" type="checkbox" name="colors[]" value="gray">
+                  <label for="cf_gray" class="gray"></label>
+                                    <input id="cf_black" type="checkbox" name="colors[]" value="black">
+                  <label for="cf_black" class="black"></label>
+                                    <input id="cf_brown" type="checkbox" name="colors[]" value="brown">
+                  <label for="cf_brown" class="brown"></label>
+                                  </div></td>
+            </tr>
+            <tr>
+              <th style="font-weight:normal"><a href="#" onclick="$('#search_syntax').slideToggle(200);return false;">more...</a></th>
+              <td style="min-width:200px;max-width:250px"><div id="search_syntax" style="display:none;white-space:normal"> You can use AND, OR, NOT and () to refine your search results:
+                  <p style="white-space:nowrap"><i>flower AND (red OR blue) NOT rose</i></p>
+                </div></td>
+            </tr>
+          </table>
+        </div>
+        <div>
+          <input type="text" name="q" value="" placeholder="Typing your keyword..." data-autofocus>
+          <input type="hidden" name="order" value="popular">
+        </div>
+      </form>
+    </div>
+  </div>
+      <div id="content" class="clearfix">
+    <div id="media_show" class="photo">
+      <div class="left">
+        <div class="inside">
+          <div style="text-align:center">
+            <div id="media_container" class="init" itemscope itemtype="schema.org/ImageObject">
+              <meta itemprop="license" content="https://creativecommons.org/licenses/publicdomain/">
+              <img itemprop="contentURL" srcset="https://www.maxpixel.net/static/photo/1x/Chef-Man-Manager-Pressure-Suppression-Superior-3026568.png 1x, https://www.maxpixel.net/static/photo/2x/Chef-Man-Manager-Pressure-Suppression-Superior-3026568.png 2x" src="https://www.maxpixel.net/static/photo/1x/Chef-Man-Manager-Pressure-Suppression-Superior-3026568.png" alt="Pressure, Suppression, Superior, Manager, Chef, Man">
+              <div class="overlay"><em>×</em>
+                <table style="height:100%">
+                  <tr>
+                    <td>
+                      <div id="support_overlay" style="color:#fff;font-size:20px">
+                        <p class="hide_on_small_img" style="margin:0 0 40px;font-size:34px;text-shadow:0 1px 10px rgba(0,0,0,.7)"><b>Support Max Pixel</b></p>
+                        <p style="margin:0 0 8px">Buy us a cup of coffee</p>
+                        <a href="https://www.maxpixel.net/utility/donate/geralt-9301" target="_blank"><span class="pure-button" style="min-width:120px;font-size:18px"><img src="https://www.maxpixel.net/images/paypal.svg" style="vertical-align:middle;height:24px" alt=""> Coffee</span></a>
+                      </div>
+                      <div id="img_click_overlay">
+                        <div id="like_buttons_clone"></div>
+                        <div id="download_menu_clone"></div>
+                      </div>
+                    </td>
+                  </tr>
+                </table>
+              </div>
+              <h3>
+                                                <a href="https://www.maxpixel.net/tag/Pressure">Pressure</a>
+                                <a href="https://www.maxpixel.net/tag/Suppression">Suppression</a>
+                                <a href="https://www.maxpixel.net/tag/Superior">Superior</a>
+                                <a href="https://www.maxpixel.net/tag/Manager">Manager</a>
+                                <a href="https://www.maxpixel.net/tag/Chef">Chef</a>
+                                <a href="https://www.maxpixel.net/tag/Man">Man</a>
+                              </h3>
+            </div>
+            <a style="position:absolute;left:-9999px" rel="license" about="https://www.maxpixel.net/static/photo/1x/Chef-Man-Manager-Pressure-Suppression-Superior-3026568.png" href="https://creativecommons.org/licenses/publicdomain/">Public Domain</a>
+          </div>
+          <h1>Chef Man Manager Pressure Suppression Superior</h1>
+          <div class="mmo mmo-zoom" slot-id="9569266757" slot-name="detail 1"></div>
+
+          <p>You can also exhort them by <a href="https://www.maxpixel.net/utility/donate/geralt-9301" rel="nofollow" target="_blank">inviting our photographers one cup of Coffee</a>. If it is so great, please share with your friends.</p>
+<p>License to use <a href="https://creativecommons.org/publicdomain/zero/1.0/deed.en" target="_blank" rel="nofollow">Creative Commons Zero - CC0</a>. You are free to use for many purposes without worrying issues licenses because this picture is TRUE FREE. We just want you to back a referral link to Max Pixel (optional).</p>
+<p>It was archived in the category "<a href="https://www.maxpixel.net/people"><strong>People</strong></a>", maximum resolution is <em>2603×3904</em> pixels, you can download it to PNG format. We were tagged: Pressure, Suppression, Superior, Manager, Chef, Man.</p>
+
+          <h4>Our team would like to recommend to you a few pictures in the same category:</h4>
+
+                              <p class="related">
+            <a href="https://www.maxpixel.net/Yoke-Forced-Burnout-Pressure-Nanny-Dependency-62283" title="Pressure, Burnout, Dependency, Yoke, Forced, Nanny"><img src="https://www.maxpixel.net/static/photo/640/Yoke-Forced-Burnout-Pressure-Nanny-Dependency-62283.png" alt="Pressure, Burnout, Dependency, Yoke, Forced, Nanny"></a>
+            <span>Pressure, Burnout, Dependency, Yoke, Forced, Nanny</span>
+          </p>
+                                        <p class="related">
+            <a href="https://www.maxpixel.net/Pressure-Suppression-Stress-Fear-Professions-65336" title="Pressure, Suppression, Stress, Professions, Fear"><img src="https://www.maxpixel.net/static/photo/640/Pressure-Suppression-Stress-Fear-Professions-65336.png" alt="Pressure, Suppression, Stress, Professions, Fear"></a>
+            <span>Pressure, Suppression, Stress, Professions, Fear</span>
+          </p>
+                                        <p class="related">
+            <a href="https://www.maxpixel.net/Violent-Containing-Distress-Shield-Stop-Coercion-144103" title="Containing, Stop, Shield, Violent, Distress, Coercion"><img src="https://www.maxpixel.net/static/photo/640/Violent-Containing-Distress-Shield-Stop-Coercion-144103.png" alt="Containing, Stop, Shield, Violent, Distress, Coercion"></a>
+            <span>Containing, Stop, Shield, Violent, Distress, Coercion</span>
+          </p>
+                                        <p class="related">
+            <a href="https://www.maxpixel.net/Violent-Containing-Woman-Stop-Move-Tattoo-144106" title="Woman, Move, Tattoo, Containing, Stop, Violent"><img src="https://www.maxpixel.net/static/photo/640/Violent-Containing-Woman-Stop-Move-Tattoo-144106.png" alt="Woman, Move, Tattoo, Containing, Stop, Violent"></a>
+            <span>Woman, Move, Tattoo, Containing, Stop, Violent</span>
+          </p>
+                                        <p class="related">
+            <a href="https://www.maxpixel.net/Abuse-Child-Containing-Person-Torture-Rape-334307" title="Child, Person, Containing, Abuse, Rape, Torture"><img src="https://www.maxpixel.net/static/photo/640/Abuse-Child-Containing-Person-Torture-Rape-334307.png" alt="Child, Person, Containing, Abuse, Rape, Torture"></a>
+            <span>Child, Person, Containing, Abuse, Rape, Torture</span>
+          </p>
+                                        <p class="related">
+            <a href="https://www.maxpixel.net/Torture-Person-Containing-Rape-Child-Abuse-334309" title="Child, Person, Containing, Abuse, Rape, Torture"><img src="https://www.maxpixel.net/static/photo/640/Torture-Person-Containing-Rape-Child-Abuse-334309.png" alt="Child, Person, Containing, Abuse, Rape, Torture"></a>
+            <span>Child, Person, Containing, Abuse, Rape, Torture</span>
+          </p>
+                    <div class="mmo mmo-zoom" slot-id="2045999954" slot-name="detail 2"></div>
+          <br>
+                                        <p class="related">
+            <a href="https://www.maxpixel.net/Bullying-Bully-Aggression-Tease-Abuse-Attack-655659" title="Bully, Attack, Aggression, Bullying, Abuse, Tease"><img src="https://www.maxpixel.net/static/photo/640/Bullying-Bully-Aggression-Tease-Abuse-Attack-655659.png" alt="Bully, Attack, Aggression, Bullying, Abuse, Tease"></a>
+            <span>Bully, Attack, Aggression, Bullying, Abuse, Tease</span>
+          </p>
+                                        <p class="related">
+            <a href="https://www.maxpixel.net/Tease-Aggression-Attack-Abuse-Bullying-Bully-655660" title="Bully, Attack, Aggression, Bullying, Abuse, Tease"><img src="https://www.maxpixel.net/static/photo/640/Tease-Aggression-Attack-Abuse-Bullying-Bully-655660.png" alt="Bully, Attack, Aggression, Bullying, Abuse, Tease"></a>
+            <span>Bully, Attack, Aggression, Bullying, Abuse, Tease</span>
+          </p>
+                                        <p class="related">
+            <a href="https://www.maxpixel.net/Tool-Screw-Clamp-Person-Terminal-Silhouette-Man-790474" title="Screw Clamp, Terminal, Tool, Silhouette, Man, Person"><img src="https://www.maxpixel.net/static/photo/640/Tool-Screw-Clamp-Person-Terminal-Silhouette-Man-790474.png" alt="Screw Clamp, Terminal, Tool, Silhouette, Man, Person"></a>
+            <span>Screw Clamp, Terminal, Tool, Silhouette, Man, Person</span>
+          </p>
+                                        <p class="related">
+            <a href="https://www.maxpixel.net/Rape-Person-Torture-Abuse-Containing-Child-1223678" title="Child, Person, Containing, Abuse, Rape, Torture"><img src="https://www.maxpixel.net/static/photo/640/Rape-Person-Torture-Abuse-Containing-Child-1223678.png" alt="Child, Person, Containing, Abuse, Rape, Torture"></a>
+            <span>Child, Person, Containing, Abuse, Rape, Torture</span>
+          </p>
+                                        <p class="related">
+            <a href="https://www.maxpixel.net/Torture-Rape-Abuse-Person-Child-Containing-1223680" title="Child, Person, Containing, Abuse, Rape, Torture"><img src="https://www.maxpixel.net/static/photo/640/Torture-Rape-Abuse-Person-Child-Containing-1223680.png" alt="Child, Person, Containing, Abuse, Rape, Torture"></a>
+            <span>Child, Person, Containing, Abuse, Rape, Torture</span>
+          </p>
+                                        <p class="related">
+            <a href="https://www.maxpixel.net/Suppression-Education-Fear-Terror-Violent-Child-1439468" title="Child, Education, Fear, Terror, Violent, Suppression"><img src="https://www.maxpixel.net/static/photo/640/Suppression-Education-Fear-Terror-Violent-Child-1439468.png" alt="Child, Education, Fear, Terror, Violent, Suppression"></a>
+            <span>Child, Education, Fear, Terror, Violent, Suppression</span>
+          </p>
+                    
+          <p class="tags">
+                        <a href="https://www.maxpixel.net/tag/Pressure">Pressure</a>
+                        <a href="https://www.maxpixel.net/tag/Suppression">Suppression</a>
+                        <a href="https://www.maxpixel.net/tag/Superior">Superior</a>
+                        <a href="https://www.maxpixel.net/tag/Manager">Manager</a>
+                        <a href="https://www.maxpixel.net/tag/Chef">Chef</a>
+                        <a href="https://www.maxpixel.net/tag/Man">Man</a>
+                        <a href="https://www.maxpixel.net/tag/Boss">Boss</a>
+                        <a href="https://www.maxpixel.net/tag/Employer">Employer</a>
+                        <a href="https://www.maxpixel.net/tag/Press">Press</a>
+                        <a href="https://www.maxpixel.net/tag/Keep-It-Small">Keep It Small</a>
+                        <a href="https://www.maxpixel.net/tag/Power">Power</a>
+                        <a href="https://www.maxpixel.net/tag/Authority">Authority</a>
+                        <a href="https://www.maxpixel.net/tag/Employee">Employee</a>
+                        <a href="https://www.maxpixel.net/tag/Subordinate">Subordinate</a>
+                        <a href="https://www.maxpixel.net/tag/The-Exercise-Of-Power">The Exercise Of Power</a>
+                        <a href="https://www.maxpixel.net/tag/Powerful">Powerful</a>
+                        <a href="https://www.maxpixel.net/tag/Violent">Violent</a>
+                        <a href="https://www.maxpixel.net/tag/Silhouette">Silhouette</a>
+                        <a href="https://www.maxpixel.net/tag/Tie">Tie</a>
+                        <a href="https://www.maxpixel.net/">Free Photos</a>
+            <a href="https://www.maxpixel.net/">Free Images</a>
+            <a href="https://www.maxpixel.net/">Max Pixel</a>
+          </p>
+        </div>
+      </div>
+      <div class="right">
+
+                <div style="padding:15px 20px;background:#f7f8fa">
+          <table id="details">
+                        <tr>
+              <th>Category</th>
+              <td><a href="https://www.maxpixel.net/people">People</a></td>
+            </tr>
+                                    <tr>
+              <th style="white-space:nowrap">Image type</th>
+              <td>PNG</td>
+            </tr>
+                                    <tr>
+              <th>Resolution</th>
+              <td>2603×3904</td>
+            </tr>
+                        <tr style="display:none">
+              <th>Downloads</th>
+              <td>0</td>
+            </tr>
+          </table>
+        </div>
+
+        <div class="mmo mmo-zoom" slot-id="8092533553" slot-name="sidebar 1" style="margin-top: 20px;"></div>
+        
+        <div class="download_menu" data-type="photos">
+          <span class="pure-button button-green" style="display:block;max-width:310px;margin:10px 0 0"><i class="icon icon_download"></i> Free Download</span>
+          <div class="bubble">
+            <form action="https://www.maxpixel.net/Chef-Man-Manager-Pressure-Suppression-Superior-3026568" method="post" target="_blank">
+            <table>
+                            <tr>
+                <td><input type="radio" name="download" value="https://cdn.pixabay.com/photo/2017/12/18/17/03/pressure-3026568_640.png">
+                   427×640</td>
+                <td>PNG</td>
+                <td>45 kB</td>
+              </tr>
+                            <tr>
+                <td><input type="radio" name="download" value="pressure-3026568_1280.png">
+                   853×1280</td>
+                <td>PNG</td>
+                <td>148 kB</td>
+              </tr>
+                            <tr>
+                <td><input type="radio" name="download" value="pressure-3026568_1920.png">
+                   1280×1920</td>
+                <td>PNG</td>
+                <td>315 kB</td>
+              </tr>
+                            <tr class="no_default">
+                <td><input type="radio" name="download" value="pressure-3026568.png">
+                   2603×3904</td>
+                <td>PNG</td>
+                <td>382 kB</td>
+              </tr>
+                          </table>
+            <input type="submit" name="submit_view" value="View" class="view_btn pure-button" data-w="300" style="display:inline-block;width:49%;float:right" /> <input type="submit" name="submit_download" value="Download" class="dl_btn pure-button button-green" data-w="300" style="display:inline-block;width:49%;" />
+            </form>
+          </div>
+                  </div>
+
+        <div class="like_buttons">
+          <span data-href="https://www.maxpixel.net/utility/share?photo_id=3026568" class="pure-button button-sm dd_box ajax" data-target=".share_links" title="Share">Share this photo <i class="icon icon_share"></i></span>
+          <div class="share_links" style="width:260px;padding:15px"></div>
+          <!-- <div class="fb-follow" data-href="https://www.facebook.com/freegreatpicture/" data-height="28" data-layout="button" data-size="large" data-show-faces="false"></div> -->
+          <div class="fb-like" data-href="https://www.facebook.com/freegreatpicture/" data-layout="button" data-action="like" data-size="large" data-show-faces="false" data-share="false"></div>
+        </div>
+
+        <div style="margin:20px 0 10px;padding:15px 20px;background:#f7f8fa;line-height:1.5"> <i class="icon icon_cc0"></i> CC0 Public Domain
+          <div style="margin-top:4px;font-size:14px">
+            Free for commercial use <br>
+            Link referral required
+          </div>
+        </div>
+        
+        
+        
+
+                <h4 style="margin-top:15px; margin-bottom:0px; font-size:13px;padding:5px 15px;background:#f7f8fa;border-bottom: 1px solid #eeeff2">Random special photos</h4>
+        <div class="flex_grid related_photos_sidebar" style="margin:0px -6px 15px -5px">
+                              <div class="item" data-w="640" data-h="426"><a href="https://www.maxpixel.net/Choose-Autumn-Large-Cucurbita-Maxima-Fruit-Pumpkin-3678820"> <img title="Pumpkin, Fruit, Autumn, Cucurbita Maxima, Choose, Large" src="https://www.maxpixel.net/images/blank.gif" alt="Choose Autumn Large Cucurbita Maxima Fruit Pumpkin" data-src="https://thumb.maxpixel.net/1314/Choose-Autumn-Large-Cucurbita-Maxima-Fruit-Pumpkin-3678820.jpg"> <em>Pumpkin, Fruit, Autumn, Cucurbita Maxima, Choose, Large</em> </a></div>
+                              <div class="item" data-w="640" data-h="426"><a href="https://www.maxpixel.net/Landscape-Sunset-Desert-Horizon-Sun-Dune-Travel-2774945"> <img title="Desert, Sun, Landscape, Sunset, Dune, Travel, Horizon" src="https://www.maxpixel.net/images/blank.gif" alt="Landscape Sunset Desert Horizon Sun Dune Travel" data-src="https://thumb.maxpixel.net/997/Landscape-Sunset-Desert-Horizon-Sun-Dune-Travel-2774945.jpg"> <em>Desert, Sun, Landscape, Sunset, Dune, Travel, Horizon</em> </a></div>
+                              <div class="item" data-w="640" data-h="427"><a href="https://www.maxpixel.net/Sitting-White-Mammal-Looking-Cat-Animal-Feline-3591348"> <img title="Cat, White, Animal, Mammal, Feline, Sitting, Looking" src="https://www.maxpixel.net/images/blank.gif" alt="Sitting White Mammal Looking Cat Animal Feline" data-src="https://thumb.maxpixel.net/1268/Sitting-White-Mammal-Looking-Cat-Animal-Feline-3591348.jpg"> <em>Cat, White, Animal, Mammal, Feline, Sitting, Looking</em> </a></div>
+                              <div class="item" data-w="426" data-h="640"><a href="https://www.maxpixel.net/Mackerel-Pet-Animal-Domestic-Cat-Cat-Portrait-3523992"> <img title="Cat, Domestic Cat, Mackerel, Pet, Animal, Portrait" src="https://www.maxpixel.net/images/blank.gif" alt="Mackerel Pet Animal Domestic Cat Cat Portrait" data-src="https://thumb.maxpixel.net/1256/Mackerel-Pet-Animal-Domestic-Cat-Cat-Portrait-3523992.jpg"> <em>Cat, Domestic Cat, Mackerel, Pet, Animal, Portrait</em> </a></div>
+                              <div class="item" data-w="640" data-h="254"><a href="https://www.maxpixel.net/Goose-Plumage-Waterfowl-Waterbird-Bird-Animal-3526503"> <img title="Goose, Waterbird, Waterfowl, Bird, Animal, Plumage" src="https://www.maxpixel.net/images/blank.gif" alt="Goose Plumage Waterfowl Waterbird Bird Animal" data-src="https://thumb.maxpixel.net/1256/Goose-Plumage-Waterfowl-Waterbird-Bird-Animal-3526503.jpg"> <em>Goose, Waterbird, Waterfowl, Bird, Animal, Plumage</em> </a></div>
+                              <div class="item" data-w="640" data-h="427"><a href="https://www.maxpixel.net/Herb-Spice-Green-Plant-Basil-Kitchen-Herb-Cook-3532424"> <img title="Basil, Herb, Kitchen Herb, Spice, Cook, Green, Plant" src="https://www.maxpixel.net/images/blank.gif" alt="Herb Spice Green Plant Basil Kitchen Herb Cook" data-src="https://thumb.maxpixel.net/1258/Herb-Spice-Green-Plant-Basil-Kitchen-Herb-Cook-3532424.jpg"> <em>Basil, Herb, Kitchen Herb, Spice, Cook, Green, Plant</em> </a></div>
+                              <div class="item" data-w="640" data-h="426"><a href="https://www.maxpixel.net/About-Time-To-Stumble-Jump-Time-Man-Alarm-Clock-2743994"> <img title="Time, Man, Jump, Alarm Clock, About Time To Stumble" src="https://www.maxpixel.net/images/blank.gif" alt="About Time To Stumble Jump Time Man Alarm Clock" data-src="https://thumb.maxpixel.net/986/About-Time-To-Stumble-Jump-Time-Man-Alarm-Clock-2743994.jpg"> <em>Time, Man, Jump, Alarm Clock, About Time To Stumble</em> </a></div>
+                              <div class="item" data-w="640" data-h="427"><a href="https://www.maxpixel.net/Pumpkin-Vegetables-Orange-Autumn-Food-Hokkaido-3636239"> <img title="Pumpkin, Hokkaido, Orange, Autumn, Vegetables, Food" src="https://www.maxpixel.net/images/blank.gif" alt="Pumpkin Vegetables Orange Autumn Food Hokkaido" data-src="https://thumb.maxpixel.net/1268/Pumpkin-Vegetables-Orange-Autumn-Food-Hokkaido-3636239.jpg"> <em>Pumpkin, Hokkaido, Orange, Autumn, Vegetables, Food</em> </a></div>
+                              <div class="item" data-w="640" data-h="427"><a href="https://www.maxpixel.net/Nature-Flower-Outdoors-Summer-Anemone-Plant-3616880"> <img title="Anemone, Flower, Plant, Nature, Summer, Outdoors" src="https://www.maxpixel.net/images/blank.gif" alt="Nature Flower Outdoors Summer Anemone Plant" data-src="https://thumb.maxpixel.net/1268/Nature-Flower-Outdoors-Summer-Anemone-Plant-3616880.jpg"> <em>Anemone, Flower, Plant, Nature, Summer, Outdoors</em> </a></div>
+                              <div class="item" data-w="640" data-h="426"><a href="https://www.maxpixel.net/Dahlia-Garden-Bud-Dahlia-Dahlias-Bud-Flower-3524115"> <img title="Dahlia, Dahlias Bud, Flower, Bud, Dahlia Garden" src="https://www.maxpixel.net/images/blank.gif" alt="Dahlia Garden Bud Dahlia Dahlias Bud Flower" data-src="https://thumb.maxpixel.net/1255/Dahlia-Garden-Bud-Dahlia-Dahlias-Bud-Flower-3524115.jpg"> <em>Dahlia, Dahlias Bud, Flower, Bud, Dahlia Garden</em> </a></div>
+                              <div class="item" data-w="640" data-h="213"><a href="https://www.maxpixel.net/Air-Dramatic-Sky-Atmosphere-Clouds-Weather-3526558"> <img title="Clouds, Sky, Dramatic, Air, Atmosphere, Weather" src="https://www.maxpixel.net/images/blank.gif" alt="Air Dramatic Sky Atmosphere Clouds Weather" data-src="https://thumb.maxpixel.net/1256/Air-Dramatic-Sky-Atmosphere-Clouds-Weather-3526558.jpg"> <em>Clouds, Sky, Dramatic, Air, Atmosphere, Weather</em> </a></div>
+                              <div class="item" data-w="640" data-h="426"><a href="https://www.maxpixel.net/Pallets-Structure-Texture-Pattern-Background-Wall-3614890"> <img title="Texture, Pattern, Background, Pallets, Wall, Structure" src="https://www.maxpixel.net/images/blank.gif" alt="Pallets Structure Texture Pattern Background Wall" data-src="https://thumb.maxpixel.net/1291/Pallets-Structure-Texture-Pattern-Background-Wall-3614890.jpg"> <em>Texture, Pattern, Background, Pallets, Wall, Structure</em> </a></div>
+                  </div>
+        
+      </div>
+      
+    </div>
+  </div>  <div id="push"></div>
+</div>
+<div id="footer">
+  <div id="footer_inner">
+    <div class="hover_links hide-xs hide-sm" style="float:right;margin:2px 0 0 30px"> <a href="https://www.facebook.com/freegreatpicture/" target="_blank"><i class="icon icon_facebook"></i></a> <a href="https://twitter.com/fGreatPicture" target="_blank"><i class="icon icon_twitter"></i></a> <a href="#" target="_blank" title="Process time: 0.0514 Seconds - Memory: 2.47MB - Sql: 6"><i class="icon icon_google_plus"></i></a> </div>
+    <span style="margin-right:30px">© 2016 MaxPixel.net</span>
+    <a style="margin-right:30px" href="https://www.maxpixel.net/">Max Pixel</a>
+    <a style="margin-right:30px" href="http://www.freegreatpicture.com/about" target="_blank">About</a>
+    <a style="margin-right:30px" href="http://www.freegreatpicture.com/contact" target="_blank">Contact</a>
+    <a style="margin-right:30px" href="http://www.freegreatpicture.com/join" target="_blank">Join</a>
+    <a style="margin-right:30px" href="http://www.freegreatpicture.com/term-of-service" target="_blank">TOS</a>
+    <a href="https://www.maxpixel.net/rid">RID</a>
+  </div>
+</div>
+<div id="fb-root"></div>
+<a id="toTop">â–²</a> 
+<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script> 
+<script>
+    window.jQuery || document.write('<script src="https://www.maxpixel.net/js/jquery.min.js"><\/script>');
+    var LANG = 'en', I18N_DELETE = 'Really delete?';
+    var show_captcha=0;auth_user=1;
+    var show_ga = '1' == '1';
+</script> 
+<script src="https://www.maxpixel.net/js/max-pixel.min.js"></script>
+<script src="https://www.maxpixel.net/js/utility.js"></script>
+<script>
+
+        $('.header_search').find('input[type="text"], input:checked, select, input[type="hidden"]').each(function(){
+            var i = this;
+            $('.add_search_params').each(function(){
+                if (i.value && (!$(this).hasClass('filter') || i.name != 'colors' && i.name != 'min_width' && i.name != 'min_height'))
+                    $(this).append($('<input type="hidden" name="'+i.name+'">').val(i.value));
+            });
+        });
+    
+        if ($(window).innerWidth() > 767) document.write('<script src="//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.8&appId=1818229235120698" async defer><\/script>');
+        else $('#fb_like_widget').hide();
+
+  
+  $('#special-link').unbind( "click" );
+</script>
+
+<!-- Global site tag (gtag.js) - Google Analytics -->
+<script async src="https://www.googletagmanager.com/gtag/js?id=UA-17673201-26"></script>
+<script>
+  window.dataLayer = window.dataLayer || [];
+  function gtag(){dataLayer.push(arguments);}
+  gtag('js', new Date());
+
+  gtag('config', 'UA-17673201-26');
+</script>
+
+</body>
+</html>
+<!-- 11:07:04 30/05/2019 -->
\ No newline at end of file
diff --git a/slides/wk07/img/behavior-change/coercion.png b/slides/wk07/img/behavior-change/coercion.png
new file mode 100644
index 0000000000000000000000000000000000000000..9329a4a28cae887cf7acdb773a8be917a4268eed
Binary files /dev/null and b/slides/wk07/img/behavior-change/coercion.png differ
diff --git a/slides/wk07/img/behavior-change/data-collection.png b/slides/wk07/img/behavior-change/data-collection.png
new file mode 100644
index 0000000000000000000000000000000000000000..053253dc161cfb1617aebba4b576d627a220541d
Binary files /dev/null and b/slides/wk07/img/behavior-change/data-collection.png differ
diff --git a/slides/wk07/img/behavior-change/dopamine.jpg b/slides/wk07/img/behavior-change/dopamine.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..9f0170b483fbf5145719c0aad3c6ee674ab95bf3
Binary files /dev/null and b/slides/wk07/img/behavior-change/dopamine.jpg differ
diff --git a/slides/wk07/img/behavior-change/dopamine2.png b/slides/wk07/img/behavior-change/dopamine2.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b2461b22eb13dd1721bbf22b506b009a76a4e24
Binary files /dev/null and b/slides/wk07/img/behavior-change/dopamine2.png differ
diff --git a/slides/wk07/img/behavior-change/energycost.png b/slides/wk07/img/behavior-change/energycost.png
new file mode 100644
index 0000000000000000000000000000000000000000..ac66819963e3c9d66b0f4a2d63760e465edce127
Binary files /dev/null and b/slides/wk07/img/behavior-change/energycost.png differ
diff --git a/slides/wk07/img/behavior-change/focus.png b/slides/wk07/img/behavior-change/focus.png
new file mode 100644
index 0000000000000000000000000000000000000000..7241d58e49cb8101cfcd19c8172e9a3b61341f1f
Binary files /dev/null and b/slides/wk07/img/behavior-change/focus.png differ
diff --git a/slides/wk07/img/behavior-change/full-model.png b/slides/wk07/img/behavior-change/full-model.png
new file mode 100644
index 0000000000000000000000000000000000000000..8379c6e681e3829bc3dc6ae6978cad2d42fef176
Binary files /dev/null and b/slides/wk07/img/behavior-change/full-model.png differ
diff --git a/slides/wk07/img/behavior-change/house-background.png b/slides/wk07/img/behavior-change/house-background.png
new file mode 100644
index 0000000000000000000000000000000000000000..f34aa9bad1b8985effc10bd20a57faa4ebd38284
Binary files /dev/null and b/slides/wk07/img/behavior-change/house-background.png differ
diff --git a/slides/wk07/img/behavior-change/mostlydata.png b/slides/wk07/img/behavior-change/mostlydata.png
new file mode 100644
index 0000000000000000000000000000000000000000..c25fbbf622a32fad4d8f7d58d8e5c87e0d77f22d
Binary files /dev/null and b/slides/wk07/img/behavior-change/mostlydata.png differ
diff --git a/slides/wk07/img/behavior-change/personal-informatics-model.png b/slides/wk07/img/behavior-change/personal-informatics-model.png
new file mode 100644
index 0000000000000000000000000000000000000000..b7ec7714d914b333ceda3cb2146c805e38cd7107
Binary files /dev/null and b/slides/wk07/img/behavior-change/personal-informatics-model.png differ
diff --git a/slides/wk07/img/behavior-change/personalinformatics.png b/slides/wk07/img/behavior-change/personalinformatics.png
new file mode 100644
index 0000000000000000000000000000000000000000..f4d2f71c3686a00298b88616e41b5b8c8a4ab215
Binary files /dev/null and b/slides/wk07/img/behavior-change/personalinformatics.png differ
diff --git a/slides/wk07/img/behavior-change/phone.png b/slides/wk07/img/behavior-change/phone.png
new file mode 100644
index 0000000000000000000000000000000000000000..3d5fe57f8e4f487d780319dcb35e1041143ed733
Binary files /dev/null and b/slides/wk07/img/behavior-change/phone.png differ
diff --git a/slides/wk07/img/behavior-change/phoneplanet.png b/slides/wk07/img/behavior-change/phoneplanet.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5ee683695016659a255fefce6d78342b0cf781a
Binary files /dev/null and b/slides/wk07/img/behavior-change/phoneplanet.png differ
diff --git a/slides/wk07/img/behavior-change/scalability.png b/slides/wk07/img/behavior-change/scalability.png
new file mode 100644
index 0000000000000000000000000000000000000000..71099b41f5e5d7e06c14098df1d61746b6a05fca
Binary files /dev/null and b/slides/wk07/img/behavior-change/scalability.png differ
diff --git a/slides/wk07/img/behavior-change/sign.png b/slides/wk07/img/behavior-change/sign.png
new file mode 100644
index 0000000000000000000000000000000000000000..297f165ca97205d17d2a3689cd5dc5826b10d5af
Binary files /dev/null and b/slides/wk07/img/behavior-change/sign.png differ
diff --git a/slides/wk07/img/behavior-change/sob.png b/slides/wk07/img/behavior-change/sob.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a26631b30f839f30b4ba441c94d4c9f5c8a036f
Binary files /dev/null and b/slides/wk07/img/behavior-change/sob.png differ
diff --git a/slides/wk07/img/behavior-change/speedometer.png b/slides/wk07/img/behavior-change/speedometer.png
new file mode 100644
index 0000000000000000000000000000000000000000..1372078f6fe156475574d114393aaee8dcc9259e
Binary files /dev/null and b/slides/wk07/img/behavior-change/speedometer.png differ
diff --git a/slides/wk07/img/behavior-change/stepcounter.png b/slides/wk07/img/behavior-change/stepcounter.png
new file mode 100644
index 0000000000000000000000000000000000000000..8ccae1efa533d286827cd8b1685e25d868824a31
Binary files /dev/null and b/slides/wk07/img/behavior-change/stepcounter.png differ
diff --git a/slides/wk07/img/behavior-change/therml.png b/slides/wk07/img/behavior-change/therml.png
new file mode 100644
index 0000000000000000000000000000000000000000..5a9f21011cb1aa7094d2980336e87a517cccdcb5
Binary files /dev/null and b/slides/wk07/img/behavior-change/therml.png differ
diff --git a/slides/wk07/img/behavior-change/ttc.png b/slides/wk07/img/behavior-change/ttc.png
new file mode 100644
index 0000000000000000000000000000000000000000..85dbaecb8294e0d57642e8d402a40d88dfa92459
Binary files /dev/null and b/slides/wk07/img/behavior-change/ttc.png differ
diff --git a/slides/wk07/img/behavior-change/ubigreen-explained.png b/slides/wk07/img/behavior-change/ubigreen-explained.png
new file mode 100644
index 0000000000000000000000000000000000000000..229ce0bfdc89411a311439c0697cbeacec400678
Binary files /dev/null and b/slides/wk07/img/behavior-change/ubigreen-explained.png differ
diff --git a/slides/wk07/img/behavior-change/ubigreen-sequence.png b/slides/wk07/img/behavior-change/ubigreen-sequence.png
new file mode 100644
index 0000000000000000000000000000000000000000..87ba1b88ba963277fc93fbbf467885dee5ffcf2e
Binary files /dev/null and b/slides/wk07/img/behavior-change/ubigreen-sequence.png differ
diff --git a/slides/wk07/img/behavior-change/ubigreen-system.png b/slides/wk07/img/behavior-change/ubigreen-system.png
new file mode 100644
index 0000000000000000000000000000000000000000..0883880cf4dc9b90d92e49d815c66ce89bf5febd
Binary files /dev/null and b/slides/wk07/img/behavior-change/ubigreen-system.png differ
diff --git a/slides/wk07/img/behavior-change/ubigreen.png b/slides/wk07/img/behavior-change/ubigreen.png
new file mode 100644
index 0000000000000000000000000000000000000000..5aac2bf2d689162115ee8c8d0f3565917733c826
Binary files /dev/null and b/slides/wk07/img/behavior-change/ubigreen.png differ
diff --git a/slides/wk07/img/interaction/buttons.png b/slides/wk07/img/interaction/buttons.png
new file mode 100644
index 0000000000000000000000000000000000000000..26675f540854d26ee061fb0f9f81a46d9766ca14
Binary files /dev/null and b/slides/wk07/img/interaction/buttons.png differ
diff --git a/slides/wk07/img/interaction/chickens.png b/slides/wk07/img/interaction/chickens.png
new file mode 100644
index 0000000000000000000000000000000000000000..abe1ac534082651d0413623e7036a5bedd2ca672
Binary files /dev/null and b/slides/wk07/img/interaction/chickens.png differ
diff --git a/slides/wk07/img/interaction/cnn-small-x.png b/slides/wk07/img/interaction/cnn-small-x.png
new file mode 100644
index 0000000000000000000000000000000000000000..7d5ee37abfc88bf5ed09597d3b5105c4b11a3994
Binary files /dev/null and b/slides/wk07/img/interaction/cnn-small-x.png differ
diff --git a/slides/wk07/img/interaction/desktop-new.png b/slides/wk07/img/interaction/desktop-new.png
new file mode 100644
index 0000000000000000000000000000000000000000..be7bbd22e62f47e2bca4ed24adaee67f1565ccb8
Binary files /dev/null and b/slides/wk07/img/interaction/desktop-new.png differ
diff --git a/slides/wk07/img/interaction/desktop.png b/slides/wk07/img/interaction/desktop.png
new file mode 100644
index 0000000000000000000000000000000000000000..dfc1e2e0dc980cf5aa5068ccc2d444bfdea374a6
Binary files /dev/null and b/slides/wk07/img/interaction/desktop.png differ
diff --git a/slides/wk07/img/interaction/feedforward.png b/slides/wk07/img/interaction/feedforward.png
new file mode 100644
index 0000000000000000000000000000000000000000..20517d5296f0aacc0cd60dfe701fed9cc139ddee
Binary files /dev/null and b/slides/wk07/img/interaction/feedforward.png differ
diff --git a/slides/wk07/img/interaction/flat-doorknob.png b/slides/wk07/img/interaction/flat-doorknob.png
new file mode 100644
index 0000000000000000000000000000000000000000..b7fa0fcc0b4a0daed1e12d9f5fdb49318a4aed07
Binary files /dev/null and b/slides/wk07/img/interaction/flat-doorknob.png differ
diff --git a/slides/wk07/img/interaction/freezer-feedback.png b/slides/wk07/img/interaction/freezer-feedback.png
new file mode 100644
index 0000000000000000000000000000000000000000..d29834b5265e906ceb85481ad79082036120a25b
Binary files /dev/null and b/slides/wk07/img/interaction/freezer-feedback.png differ
diff --git a/slides/wk07/img/interaction/fridge-freezer-controls.png b/slides/wk07/img/interaction/fridge-freezer-controls.png
new file mode 100644
index 0000000000000000000000000000000000000000..29d878c73d8c7f30e5d4127561505548b96082e5
Binary files /dev/null and b/slides/wk07/img/interaction/fridge-freezer-controls.png differ
diff --git a/slides/wk07/img/interaction/fridge-freezer-mental-model.png b/slides/wk07/img/interaction/fridge-freezer-mental-model.png
new file mode 100644
index 0000000000000000000000000000000000000000..7eca6c06d956b7980b5281e76c1bbb41a27226a5
Binary files /dev/null and b/slides/wk07/img/interaction/fridge-freezer-mental-model.png differ
diff --git a/slides/wk07/img/interaction/fridge-freezer-valve.png b/slides/wk07/img/interaction/fridge-freezer-valve.png
new file mode 100644
index 0000000000000000000000000000000000000000..d367548be66857dc1edb0a88f5a0eb5e7307f16b
Binary files /dev/null and b/slides/wk07/img/interaction/fridge-freezer-valve.png differ
diff --git a/slides/wk07/img/interaction/gmail-snapping.gif b/slides/wk07/img/interaction/gmail-snapping.gif
new file mode 100644
index 0000000000000000000000000000000000000000..66a17084941a6d03ad02d2dfa7b62446ec755b1d
Binary files /dev/null and b/slides/wk07/img/interaction/gmail-snapping.gif differ
diff --git a/slides/wk07/img/interaction/gym-doors.png b/slides/wk07/img/interaction/gym-doors.png
new file mode 100644
index 0000000000000000000000000000000000000000..99ffb06c3f14d3adee83426b9a59dc4b1291d8c6
Binary files /dev/null and b/slides/wk07/img/interaction/gym-doors.png differ
diff --git a/slides/wk07/img/interaction/knurling.png b/slides/wk07/img/interaction/knurling.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa34dcaa22ec90dab6cab130a5170f94c616178c
Binary files /dev/null and b/slides/wk07/img/interaction/knurling.png differ
diff --git a/slides/wk07/img/interaction/mental1.png b/slides/wk07/img/interaction/mental1.png
new file mode 100644
index 0000000000000000000000000000000000000000..a3c23c4e46f70202c6a8117ed0607dc2f8e1f373
Binary files /dev/null and b/slides/wk07/img/interaction/mental1.png differ
diff --git a/slides/wk07/img/interaction/mental2.png b/slides/wk07/img/interaction/mental2.png
new file mode 100644
index 0000000000000000000000000000000000000000..58c9cc1a547ec69cd2652c456c8cb040b5e6a0bd
Binary files /dev/null and b/slides/wk07/img/interaction/mental2.png differ
diff --git a/slides/wk07/img/interaction/mental3.png b/slides/wk07/img/interaction/mental3.png
new file mode 100644
index 0000000000000000000000000000000000000000..07a7d35cca9dbe1309fe9c5809ce3ac2e2e684d6
Binary files /dev/null and b/slides/wk07/img/interaction/mental3.png differ
diff --git a/slides/wk07/img/interaction/mental4.png b/slides/wk07/img/interaction/mental4.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e40a86ffb987d0e45c5420bc8d87f34c46e62e0
Binary files /dev/null and b/slides/wk07/img/interaction/mental4.png differ
diff --git a/slides/wk07/img/interaction/mental5.png b/slides/wk07/img/interaction/mental5.png
new file mode 100644
index 0000000000000000000000000000000000000000..e8b861ac7042b4cc0b3bd2ab312ef120c1225564
Binary files /dev/null and b/slides/wk07/img/interaction/mental5.png differ
diff --git a/slides/wk07/img/interaction/mental6.png b/slides/wk07/img/interaction/mental6.png
new file mode 100644
index 0000000000000000000000000000000000000000..5baea3ac170bd237ee0c35101160347918f32c04
Binary files /dev/null and b/slides/wk07/img/interaction/mental6.png differ
diff --git a/slides/wk07/img/interaction/mental7.png b/slides/wk07/img/interaction/mental7.png
new file mode 100644
index 0000000000000000000000000000000000000000..9bb9a6c4bd2bf569e84b6de7d2d7e73f0e9ecc09
Binary files /dev/null and b/slides/wk07/img/interaction/mental7.png differ
diff --git a/slides/wk07/img/interaction/messenger-bubble.gif b/slides/wk07/img/interaction/messenger-bubble.gif
new file mode 100755
index 0000000000000000000000000000000000000000..77defd497891e79a775a6ca3593cf33e02d2c890
Binary files /dev/null and b/slides/wk07/img/interaction/messenger-bubble.gif differ
diff --git a/slides/wk07/img/interaction/norman-d-human-action-cycle.png b/slides/wk07/img/interaction/norman-d-human-action-cycle.png
new file mode 100644
index 0000000000000000000000000000000000000000..f5748a294e9e8786e3337bc8404b71364d1db0f9
Binary files /dev/null and b/slides/wk07/img/interaction/norman-d-human-action-cycle.png differ
diff --git a/slides/wk07/img/interaction/round-doorknob.png b/slides/wk07/img/interaction/round-doorknob.png
new file mode 100644
index 0000000000000000000000000000000000000000..8413e79008f7f0537894d637cd1810b0b460239e
Binary files /dev/null and b/slides/wk07/img/interaction/round-doorknob.png differ
diff --git a/slides/wk07/img/interaction/search.png b/slides/wk07/img/interaction/search.png
new file mode 100644
index 0000000000000000000000000000000000000000..d5a1729071b75a1d9d7a57a6c7941c8ce6d405bb
Binary files /dev/null and b/slides/wk07/img/interaction/search.png differ
diff --git a/slides/wk07/img/interaction/sensor-explanation.png b/slides/wk07/img/interaction/sensor-explanation.png
new file mode 100644
index 0000000000000000000000000000000000000000..54aabcd68aae660cd58fb7f222bccb24dd1ed0e5
Binary files /dev/null and b/slides/wk07/img/interaction/sensor-explanation.png differ
diff --git a/slides/wk07/img/interaction/sensor.jpg b/slides/wk07/img/interaction/sensor.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..34ae8df13304ec11c0b7739993c0d8f13d27ca90
Binary files /dev/null and b/slides/wk07/img/interaction/sensor.jpg differ
diff --git a/slides/wk07/img/interaction/virtual-buttons.png b/slides/wk07/img/interaction/virtual-buttons.png
new file mode 100644
index 0000000000000000000000000000000000000000..6e7cbd65b1a64b7e9ceec6e3f49a50868aedb17c
Binary files /dev/null and b/slides/wk07/img/interaction/virtual-buttons.png differ
diff --git a/slides/wk07/img/interaction/virtual-knurling.png b/slides/wk07/img/interaction/virtual-knurling.png
new file mode 100644
index 0000000000000000000000000000000000000000..c5e89ee2d5efdf43386d3fcdc9ba547592ce3ceb
Binary files /dev/null and b/slides/wk07/img/interaction/virtual-knurling.png differ
diff --git a/slides/wk07/img/interaction/web-button.png b/slides/wk07/img/interaction/web-button.png
new file mode 100644
index 0000000000000000000000000000000000000000..1fa271f4371784721ce8b933ea09c800842ae15c
Binary files /dev/null and b/slides/wk07/img/interaction/web-button.png differ
diff --git a/slides/wk07/img/interaction/webex.png b/slides/wk07/img/interaction/webex.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ab83c87aa26dfdafab3eff2e7e440e1eb574a72
Binary files /dev/null and b/slides/wk07/img/interaction/webex.png differ
diff --git a/slides/wk07/img/menus/Edgewrite.png b/slides/wk07/img/menus/Edgewrite.png
new file mode 100644
index 0000000000000000000000000000000000000000..d667210ad2a378b2158d5ed08c97edb01efec834
Binary files /dev/null and b/slides/wk07/img/menus/Edgewrite.png differ
diff --git a/slides/wk07/img/menus/Grafitti.png b/slides/wk07/img/menus/Grafitti.png
new file mode 100644
index 0000000000000000000000000000000000000000..af6a460e7db587130d59a195b06160ceadbbef9d
Binary files /dev/null and b/slides/wk07/img/menus/Grafitti.png differ
diff --git a/slides/wk07/img/menus/alert.jpg b/slides/wk07/img/menus/alert.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4fe4de37301fdc45319402cbaad9136cc8ea14ad
Binary files /dev/null and b/slides/wk07/img/menus/alert.jpg differ
diff --git a/slides/wk07/img/menus/alert1.jpg b/slides/wk07/img/menus/alert1.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f9a48ff3e25c781d6b98b566f1d325cf0084a514
Binary files /dev/null and b/slides/wk07/img/menus/alert1.jpg differ
diff --git a/slides/wk07/img/menus/facebook.png b/slides/wk07/img/menus/facebook.png
new file mode 100644
index 0000000000000000000000000000000000000000..92d3ad836dedbe70081798da7ce6287a9097cbc6
Binary files /dev/null and b/slides/wk07/img/menus/facebook.png differ
diff --git a/slides/wk07/img/menus/facebook2.png b/slides/wk07/img/menus/facebook2.png
new file mode 100644
index 0000000000000000000000000000000000000000..f822bd03ce290e60d1f26fac0d3929c049b00958
Binary files /dev/null and b/slides/wk07/img/menus/facebook2.png differ
diff --git a/slides/wk07/img/menus/histogram.png b/slides/wk07/img/menus/histogram.png
new file mode 100644
index 0000000000000000000000000000000000000000..ddd96c9ea5ad7e74414f5bfd39e07df94914bbfd
Binary files /dev/null and b/slides/wk07/img/menus/histogram.png differ
diff --git a/slides/wk07/img/menus/menu.png b/slides/wk07/img/menus/menu.png
new file mode 100644
index 0000000000000000000000000000000000000000..9116a28ebb90342f5fe20ad2d4f65de129cdd799
Binary files /dev/null and b/slides/wk07/img/menus/menu.png differ
diff --git a/slides/wk07/img/menus/menus-data.png b/slides/wk07/img/menus/menus-data.png
new file mode 100644
index 0000000000000000000000000000000000000000..f302bbe8693d7b7c6b7bee1b86bac38cceef22ac
Binary files /dev/null and b/slides/wk07/img/menus/menus-data.png differ
diff --git a/slides/wk07/img/menus/pie.jpg b/slides/wk07/img/menus/pie.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..c8cf9639f66f1fda66da123cc15ed99b51689da5
Binary files /dev/null and b/slides/wk07/img/menus/pie.jpg differ
diff --git a/slides/wk07/interaction.html b/slides/wk07/interaction.html
new file mode 100644
index 0000000000000000000000000000000000000000..62124801a0d5feb3487345e5238559f80085d8a3
--- /dev/null
+++ b/slides/wk07/interaction.html
@@ -0,0 +1,535 @@
+---
+layout: presentation
+title: Interactive Application Design
+description: Description of principals for creating an understandable application
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Interactive Application Design
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout: false
+# Fitts' Law Revisited
+
+Example of how Marking Menus are used in practice (Maya)
+![:youtube Example of marking menu in Maya, r8PQy8cX9dc]
+
+---
+# Fitts' Law Revisited
+
+.left-column-half[
+![:img CNN website marketing using a small x to close the pop up marketing that obscures the screen,85%](img/interaction/cnn-small-x.png)
+]
+
+.right-column-half[
+- Fitts' Law can be employed to help users be more productive by allowing them to interact with items easier.
+- How is the CNN marketing group using Fitts' law in this situation?
+]
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Design Principles and Metaphors
+
+---
+layout: false
+
+# Hall of Shame/Hall of Fame
+
+.left-column[
+Is this physical or virtual? Ubicomp!
+
+![:img faucet with IR sensor, 110%](img/interaction/sensor.jpg )
+]
+
+.right-column[
+![:img Sign explaining how to use the sensor, 50%](img/interaction/sensor-explanation.png)
+]
+
+???
+
+- Realworld example, fails to work effectively.
+- Sign found right next to the fountain. Also sign on the fountain.
+- Good or bad example of interface design? Do you normally have to read instructions to use a water fountain?
+- What about an IR faucet?
+- Often, person using the interface feels stupid or that they shouldn't use it
+- Who can use your interface and who can't. As designers you have the power to make an interfaace usable.
+
+
+---
+[//]: # (Outline Slide)
+# Today's goals
+
+- Metaphor
+- Creating good mental models
+- Design Tips for Interaction Design
+ - Feedback
+ - Feedforward
+
+---
+# Metaphor
+
+.right-column[
+Lakoff & Johnson, Metaphors We Live By
+
+.quote[“...the way we think, what we experience,and what we do every day
+is very much a matter of metaphor.” ]
+]
+---
+# Metaphor
+
+.left-column[
+![:img Picture of 4 chickens in a chicken coop,100%](img/interaction/chickens.png)
+]
+
+.right-column[
+
+Have you ever noticed how many chicken metaphors are in the English language?
+
+.font-small[
+- “A hen is only an egg's way of making another egg.” - Samuel Butler
+- “The key to everything is patience. You get the chicken by hatching the egg, not by smashing it.” - unknown
+- "Regard it as just as desirable to build a chicken house as to build a cathedral." - Frank Lloyd Wright
+- "A chicken in every pot" - 1928 Republican Party campaign slogan
+- "Don't have a pot to put it in" - 1928 Democratic Party response slogan
+- Nest egg - to save a little money each week
+- Scratching out a living - to earn enough to get by on
+- Don't count your chickens before they hatch - don't plan on an outcome before it actually happens.
+- Don't put all your eggs in one basket - don't plan on an outcome before it actually happens.
+- Feather your nest - saving for the future
+- Mother hen - very protective
+- Flew the coop - gone
+- Walking on eggshells- treading softly where certain people are concerned; trying not to upset someone
+- Like a chicken with it's head cut off - running around with no direction
+- You're chicken! - being afraid
+- Hard-boiled - tough attitude
+- Ruffle your feathers - something annoys you
+- No spring chicken - you're old. Plain and simple.
+- Hatch an idea - put a plan into motion
+- Pecking order - finding your place
+- Brood over it - to worry; to hover over a problem
+- Chicken scratch - poor handwriting
+- Stick your neck out - go to bat for someone else
+- Stuck in your craw - upset about something and won't verbalize what's going on inside you; carrying a grudge.
+- Bad egg - less than honest person; poor moral standards
+- In a stew - got yourself in trouble
+- Raise your hackle feathers - visibly annoyed
+- Nesting behavior- preparing a home (especially pregnant women just before a baby is due)
+- Empty nest syndrome - depression and loneliness when children leave home
+- Made from scratch - made from raw materials by hand
+]]
+
+---
+# Desktop Metaphor (Magic Cap)
+.body[
+![:img Picture of a very literal desktop metaphor,60%](img/interaction/desktop.png)
+
+Critique!
+
+]
+???
+- Is this a good interface or not?
+- What are some of the challenges of this?
+  - Unwieldy,
+  - Not great use of screen real estate
+  - Other?
+---
+# Are these better?
+
+.left-column-half[
+![:img Packard Bell Navigator Workspace interface,80%](http://pbclub.pwcsite.com/wiki/images/b/bd/Navigator_3.5.png)
+]
+
+.right-column-half[
+
+![:img Packard Bell Navigator Kidspace interface, 90%](https://external-preview.redd.it/e_qbSsuqodAhlG0h6C3tS5bRv4WbMrlDAQfwwyQdA8U.jpg?width=960&crop=smart&auto=webp&s=3f1618ae0182d466c146b90c7ff97ff434d4b58a)
+
+]
+
+.footnote[[Packard Bell Planet Wiki](http://pbclub.pwcsite.com/wiki/index.php/Packard_Bell_Navigator),
+[reddit](https://www.reddit.com/r/nostalgia/comments/6w951x/packard_bell_navigators_kidspace/)]
+
+
+---
+# Is this a better option?
+
+.right-column-half[
+
+Can use metaphors to leverage existing conceptual models
+
+- Not really an attempt to simulate a real desktop
+- Leverages existing knowledge about files, folders, trash
+- A way to explain why some windows seem blocked
+]
+
+.left-column-half[
+![:img Jens Mac desktop, 90%](img/interaction/desktop-new.png)
+]
+
+---
+# How else can we minimize errors?
+???
+Key concept: mental models
+---
+.left-column[
+# Every system has at least 3 different models
+]
+
+.right-column[
+<div class="mermaid">
+graph TD
+  S[System Image: <br>Your Implementation&nbsp;] --> |System Feedback&nbsp;| U[User Model: How the user thinks&nbsp; <br>the system works]
+  D[Design Model: How you <br>intend the system to work&nbsp;]-->S
+  U -->|User Feedback&nbsp;| S
+</div>
+
+]
+
+---
+# Relating the Human and the Interaction
+
+
+
+.left-column-half[
+
+![img: Gym doors with few affordances of where you can open them and whether there is an accessible way to use the doors,10%](img/interaction/gym-doors.png)
+
+]
+
+--
+
+.right-column-half[
+![img: Don Norman's Human Action Cycle,10%](img/interaction/norman-d-human-action-cycle.png)
+]
+
+.footnote[[Don Norman, When Three World Collide: A model of the Tangible Interaction Process, 2009](https://www.researchgate.net/publication/221332102_When_three_worlds_collide_A_model_of_the_tangible_interaction_process)]
+
+???
+Note to instructors: Need to change image  to mermaid
+
+
+---
+# Relating the Human and the Interaction
+
+
+.left-column-half[
+<br>
+<br>
+
+**Gulf of Execution** is the user's belief in functions the system _doesn't have_
+  - This is the users 'error' region
+
+**Gulf of Evaluation** is where the user _doesn't realize the system HAS a functionality_.
+]
+
+
+.right-column-half[
+![img: Don Norman's Human Action Cycle,10%](img/interaction/norman-d-human-action-cycle.png)
+]
+
+---
+
+# Model of Mental Models
+
+![:img A box showing the design (white),50%](img/interaction/mental1.png)
+
+---
+# Model of Mental Models
+
+![:img A box showing the design (white) and actual function (blue missing a little bit of the white),50%](img/interaction/mental2.png)
+
+---
+# Model of Mental Models
+
+![:img A box showing the design (white) and actual function (blue missing
+a little bit of the white) with a grey circle added in the center
+labeled "Frequently Used (Well understood) Part of System Functionality",50%](img/interaction/mental3.png)
+
+---
+# Model of Mental Models
+
+![:img A box showing the design (white) and actual function (blue missing
+a little bit of the white) with a grey circle added in the center
+labeled "Frequently Used (Well understood) Part of System Functionality",50%](img/interaction/mental4.png)
+
+
+---
+# Model of Mental Models
+
+![:img A box showing the design (white) and actual function (blue missing
+a little bit of the white) with a grey circle added in the center
+labeled "Frequently Used (Well understood) Part of System
+Functionality" a dark blue cloud labeled "Occasionally Used Part of
+System Functionality" around the user's well understood region,50%](img/interaction/mental5.png)
+
+---
+# Model of Mental Models
+
+.left-column50[
+![:img A box showing the design (white) and actual function (blue missing
+a little bit of the white) with a grey circle added in the center
+labeled "Frequently Used (Well understood) Part of System
+Functionality" a dark blue cloud labeled "Occasionally Used Part of
+System Functionality" around the user's well understood region and
+another cloud further out with errors (regions outside the blue system
+box) labeled "Users full model of what the system does",100%](img/interaction/mental6.png)
+
+]
+
+.right-column50[
+- Where are the gulf of evaluation and gulf of execution in this
+  image?
+]
+
+--
+.right-column50[
+- Gulf of execution is the user 'error' region (user requests
+  function the __system DOESNT HAVE__), gulf of
+  evaluation is when the user __doesn't realize the system HAS a
+  functionality__.
+
+- How does an undo feature help the user bridge them?
+]
+---
+# Model of Mental Models
+
+What happens when the user does something they think is core but is really not supported?
+
+![:img A box showing the design (white) and actual function (blue missing
+a little bit of the white) with a grey circle added in the center
+labeled "Frequently Used (Well understood) Part of System
+Functionality" a cloud further out with errors (regions outside the blue system
+box) and an arrow pointing from the part they really understand to the part outside
+of the application,50%](img/interaction/mental7.png)
+
+--
+
+.right-column50[
+- Need to undo!
+]
+
+
+---
+# Refridgerator/Freezer Example
+
+.left-column[
+<div class="mermaid">
+  graph LR
+  F[Freezer<br><br>]
+  Fr[Fridge&nbsp;<br><br><br><br><br><br><br><br>]
+
+</div>
+]
+
+.right-column[
+Problem:
+- Freezer too cold
+- Fridge just right
+]
+
+---
+# Refridgerator/Freezer Goal
+.left-column-half[
+![img: Freezer controls and instructions on how to set temperatures,70%](img/interaction/fridge-freezer-controls.png)
+]
+
+--
+
+.right-column-half[
+Goal:
+- Want to make the freezer warmer
+- Want the refridgerator to stay the same temperature
+]
+
+.footnote[Don Norman, Design of Everyday Things]
+
+---
+
+# Refridgerator/Freezer Mental Model
+.left-column-half[
+![img: Mental model of how to set the fridge and freezer temperatures,70%](img/interaction/fridge-freezer-mental-model.png)
+]
+
+--
+
+.right-column-half[
+Mental model:
+- Fridge control controls fridge temperature
+- Freezer control controls freezer temperature
+]
+
+.footnote[Don Norman, Design of Everyday Things]
+
+---
+# Refridgerator/Freezer System Model
+.left-column-half[
+![img: System model of how to set the fridge and freezer temperatures,70%](img/interaction/fridge-freezer-valve.png)
+]
+
+.right-column-half[
+Valve controls the flow of cold air from one cooling unit.
+]
+
+.footnote[Don Norman, Design of Everyday Things]
+---
+# Refridgerator/Freezer Feedback
+.left-column-half[
+![img: It takes 24 hours to get the feedback that new settings worked,70%](img/interaction/freezer-feedback.png)
+]
+
+.right-column-half[
+24 HOURS?!??!
+]
+
+.footnote[Don Norman, Design of Everyday Things]
+---
+
+Design Tip #1: Consistency is Critical
+
+.left-column[
+What mental model error is this likely to create?
+]
+
+.right-column[
+![:img a screenshot from WebEx. Weve selected “Do not record a
+teleconference” but to continue we have to hit the “Start Recording”
+button. So we have a conflict in the mental model
+here.,60%](img/interaction/webex.png)
+]
+
+---
+# Causes of Gulf of Evaluation
+
+What can cause a user's Gulf of Evaluation?
+
+--
+- Hard to understand visual feedback
+- Poor use of colors
+- Bad layout, poor grouping
+- Unfamiliar display of information
+- Unfamiliar design patterns, or doesn’t follow convention
+- Forcing people to remember lots of things
+- Lack of feedback in response to inputs
+- Might not see visual updates
+- Can’t find info on screen
+- Might look same as unimportant
+- Irrelevant info on screen / important info missing
+
+???
+Recall: the user _doesn't realize the system HAS a functionality_.
+
+---
+# Causes of Gulf of Execution
+
+What can cause a user's Gulf of Execution?
+
+--
+- Unfamiliar devices and inputs
+- Don’t know what is possible
+- Unfamiliar GUI components
+- Solvable with experience
+- Unfamiliar interaction patterns
+- Also solvable with experience
+- Example patterns: Dialogs, Shopping Carts
+
+???
+Recall: the user's belief in functions the system _doesn't have_
+
+---
+# Affordances
+
+Good Affordance| Bad Affordance
+----|----
+![:img Picture of a round doorknob, 40%](img/interaction/round-doorknob.png) | ![:img Picture of a flat doorknob, 40%](img/interaction/flat-doorknob.png)
+
+Well-designed objects have affordances
+- Clues to their operation that are readily apparent
+- Often visual, but not always (e.g., speech)
+- Allows and promotes certain actions
+
+
+???
+Opportunities to act which are readily apparent to the user ... and
+appropriate to the user’s abilities
+
+Form “affords” certain actions and makes that apparent
+---
+Design Tip #2: Use *Affordances* to minimize errors
+
+Action | Physical Affordance | Virtual Affordance |  Minimal Design
+----|----|----|----
+Gripping | ![:img picture of knurling on a knob,45%](img/interaction/knurling.png) | ![:img Image of lines indicating a grabbable corner by imitating knurling,50%](img/interaction/virtual-knurling.png)
+Pushing | ![:img picture of buttons on a phone,55%](img/interaction/buttons.png) | ![:img Similar buttons on a webpage,55%](img/interaction/virtual-buttons.png)|![:img picture of web buttons on a flat-style page,55%](img/interaction/web-button.png)
+Search | ![:img magnifying glass](https://upload.wikimedia.org/wikipedia/commons/thumb/8/87/Magnifying_glass_icon_mgx2.svg/200px-Magnifying_glass_icon_mgx2.svg.png) || ![:img Text area for search. Uses greyed out text to suggest what should go in it, 55%](img/interaction/search.png)
+
+
+???
+Knurling: increases friction/affords gripping
+
+don't kneed to know the word to get it
+
+---
+Design Tip #3: Make the Conceptual Model Visible
+
+Explicitly design a conceptual model
+
+Use affordance and feedback (and everything else you have) to reinforce it
+
+---
+# Feedback
+
+Response by the system to the actions of the user – Cause and effect
+
+Essential for forming mental models
+
+Makes “system state” visible
+
+Messenger Feedback | and | Gmail Feedback
+----|----|----
+![:img Facebook messenger showing feedback as the user clicks on the thumbs up button](img/interaction/messenger-bubble.gif)||![:img User selecting and dragging two conversations in gmail with feedback,50%](img/interaction/gmail-snapping.gif)
+]
+
+---
+# Feed Forward
+
+.right-column[
+What will happen if you execute action
+- Ex. Web page mouseover
+- Ex. Word processing I-bar
+- Ex. Label on a button
+
+Help people predict what will happen
+- Need feedforward at all scales
+- GUI widgets will handle basic feedforward
+- Don’t forget feedforward for screens
+]
+
+.left-column[
+![:img Picture of two icons showing additional visual feedback when the cursor hovers over them, 70%](img/interaction/feedforward.png)
+]
+
+---
+# Revisit: What is this an example of?
+
+.left-column[
+Is this physical or virtual? Ubicomp!
+
+![:img faucet with IR sensor, 110%](img/interaction/sensor.jpg )
+]
+
+.right-column[
+![:img Sign explaining how to use the sensor, 50%](img/interaction/sensor-explanation.png)
+]
+---
+# Application Design Tips
+
+- Design Tip #1: Consistency is Critical
+- Design Tip #2: Use *Affordances* to minimize errors
+- Design Tip #3: Make the Conceptual Model Visible
diff --git a/slides/wk07/menus.html b/slides/wk07/menus.html
new file mode 100644
index 0000000000000000000000000000000000000000..e11bc0995ffa85bfb642245384168fa3a13d4823
--- /dev/null
+++ b/slides/wk07/menus.html
@@ -0,0 +1,872 @@
+---
+layout: presentation
+title: Interaction Technique Design --Week 7, Wednesday--
+description: Description of Interaction Technique Design
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+layout:false
+
+# Why is selection (and testing) important .red[*]
+.left-column50[
+
+![:img False alarm in hawaii that led everyone to think there wsa a nuclear event, 75%](img/menus/alert1.jpg)
+]
+--
+.right-column50[
+![:img Screen showing what led to this error, 85%](img/menus/alert.jpg)
+]
+
+.footnote[.red[*] [Washington Post Article](https://www.washingtonpost.com/news/morning-mix/wp/2018/01/16/that-was-no-wrong-button-in-hawaii-take-a-look/?utm_term=.1848969db923)
+]
+---
+class: center, middle, inverse
+
+# Interaction Technique Design
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout: false
+
+[//]: # (Outline Slide)
+# Today's Agenda
+- Administrivia
+  - ColorPicker due at 10pm
+  - Practice quizzes (there are 2) due Wednesday 10pm
+  - Menus to be released tonight
+  - Examlet Friday
+- Introducing key concepts for menus assignment
+- Using key properties of people to predict design outcomes
+
+---
+# Menus Assignment
+
+Goal: to compare pie menus, linear menus, and a custom menu you make!
+
+We provide support for running the experiment in MainActivity (and a testing harness in TestActivity)
+
+You implement a variety of menus
+
+---
+# Menus Assignment
+
+<div class="mermaid">
+classDiagram
+
+class MenuExperimentView {
+  onTouchEvent()
+  startSelection()
+  endSelection()
+  updateModel()
+  onDraw()
+}
+
+
+AbstractMenuExperimentView <|-- MenuExperimentView
+
+AbstractMainActivity <|-- MainActivity
+AbstractMainActivity <|-- TestActivity
+MenuExperimentView <|-- PieMenuView
+MenuExperimentView <|-- NormalMenuView
+MenuExperimentView <|-- CustomMenuView
+
+
+</div>
+
+---
+
+# What is a Menu in theory?
+
+???
+- Supports selection of an item from a fixed set of options
+- Options are set and determined in advance
+- Typically used for “commands” (verbs, things to do)
+- Occasionally for selecting a value (e.g., picking a font)
+
+--
+.left-column-half[
+- Supports selection of an item from a fixed set of options
+- Options are set and determined in advance
+- Typically used for “commands” (verbs, things to do)
+- Occasionally for selecting a value <br> (e.g., picking a font)
+]
+--
+<div class="mermaid">
+graph TD
+S((.)) --> A(Start)
+A -- "Press?startSelection()" --> I(Selecting)
+I -- "Release:endSelection()" --> E[End]
+I -- "Drag:updateModel()" --> I
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+class S invisible
+class A start
+class E finish
+class I normal
+</div>
+
+???
+
+Implemented in MenuExperimentView
+
+Works in all Menus!
+
+---
+
+# What is a Menu in theory?
+
+.left-column-half[
+- Supports selection of an item from a fixed set of options
+- Options are set and determined in advance
+- Typically used for “commands” (verbs, things to do)
+- Occasionally for selecting a value <br> (e.g., picking a font)
+
+Implemented in MenuExperimentView
+
+Works in all Menus!
+]
+
+<div class="mermaid">
+graph TD
+S((.)) --> A(Start)
+A -- "Press?startSelection()" --> I(Selecting)
+I -- "Release:endSelection()" --> E[End]
+I -- "Drag:updateModel()" --> I
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+class S invisible
+class A start
+class E finish
+class I normal
+</div>
+
+
+---
+# Aside: Enums
+
+.left-column-half[
+Group of named constants
+
+- Used for PPS in ColorPicker (PPS States; Essential Geometry)
+
+- Used for PPS in Menu assignment *and* for experimental conditions
+
+- Easy to inspect if you want to (can use to determine possible states, number items, etc)
+
+[Documentation](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)
+]
+.right-column-half[
+<div class="mermaid">
+classDiagram
+
+class TaskType {
+  LINEAR
+  RELATIVE
+  UNCLASS
+}
+
+class State {
+  START
+  SELECTING
+}
+
+class MenuType {
+  NORMAL
+  PIE
+  CUSTOM
+}
+
+</div>
+
+]
+
+---
+# How do we draw a menu?
+
+.left-column30[
+<br>
+<div class="mermaid">
+classDiagram
+
+MenuExperimentView <|.. PieMenuView :  onDraw translates  and calls drawMenu
+
+class PieMenuView {
+  Canvas: 0,0 at first touch point.
+  Clipping rect: Whole screen
+  drawMenu()
+}
+
+class MenuExperimentView {
+   Canvas : 0,0 at top left of screen;
+   Clipping rect: Whole screen
+   onDraw() translate
+}
+</div>
+]
+
+.right-column60[
+- Important! MenuExperimentView set to `MATCH_PARENT`
+  - Makes drawing tricky!
+- Translate (like a parent view does for children)
+- `onDraw` in `MenuExperimentView` calls `drawMenu` in child classes.
+]
+
+--
+.right-column60[
+
+Do we have to rotate/translate the `Canvas` back?
+]
+
+--
+
+.right-column60[
+We don't strictly have to rotate or translate back because this is
+an inheritance drawing trick, not an interactor hierarchy drawing implementation
+]
+
+---
+# Aside: Custom Listeners
+
+- Used in ColorPicker and Menus
+
+- Why create custom listeners?
+
+--
+ - Lets you execute code when the view's model has changed
+ - No other way to know that has happened
+
+---
+# Review: How to implement custom listeners
+
+The Custom View needs to
+- define the custom interface
+- keep track of listeners
+
+--
+Anything *using* the view needs to
+- implement the interface (specifically, the method in that interface that will be called)
+- register itself as a listener with the view
+
+---
+# Example Custom View -- ColorPicker
+
+In ColorPicker, we setup the Custom View side for you
+
+```java
+    // Currently registered ColorListener instance or null.
+    private List<ColorChangeListener> mColorChangeListeners;
+
+    // Class which defines a listener to be called when a new color is selected.
+    public interface ColorChangeListener {
+        void onColorSelected(@ColorInt int color);
+    }
+
+    // Registers a new listener
+    public final void addColorChangeListener(@NonNull ColorChangeListener colorChangeListener) {
+        mColorChangeListeners.add(colorChangeListener);
+    }
+```
+
+---
+# Example Custom Listener -- ColorPicker:
+
+You implemented this
+
+.left-column-half[
+```
+// TODO: Register callback to update {color,label}
+// View when color changed.`
+```
+
+What method do we call to register the callback?  <br>`addColorChangeListener()`
+
+]
+.right-column-half[
+<div class="mermaid">
+classDiagram
+MainActivity ..> ColorPickerView : addColorChangeListener()
+MainActivity --> ColorChangeListener : Contains
+class ColorChangeListener {
+  onColorChanged()
+}
+class ColorPickerView {
+  addColorChangeListener()
+}
+class MainActivity {
+  ColorPickerView view
+}
+
+</div>
+]
+---
+# Example Custom Listener -- ColorPicker:
+
+You implemented this
+
+.left-column-half[
+```
+// TODO: Register callback to update {color,label}
+// View when color changed.`
+```
+
+What method do we call to register the callback?  `addColorChangeListener()`
+
+What do we usually do in a callback? <br>update application's (`MainActivity`) model
+]
+.right-column-half[
+<div class="mermaid">
+classDiagram
+ColorPickerView ..> ColorChangeListener : onColorChanged()
+ColorChangeListener ..> MainActivity : update model
+
+class ColorChangeListener {
+  onColorChanged()
+}
+
+class MainActivity {
+  ColorPickerView view
+}
+</div>
+]
+
+---
+# You will do this yourself in Menus
+
+```java
+// TODO: register a new listener with the menu so that the application knows when a selection is made
+
+// TODO: implement the listener. When the user completes a trial, the menu listener should store
+// the results of the trial, and setup for the next trial
+```
+
+---
+class: center, middle, inverse
+
+# Experimenting with Interfaces
+
+Important part of building interfaces is experimenting
+
+Need structured ways to decide what's better
+
+---
+# Experiments should be tied to *hypotheses* based on *theories* what will go better
+
+- Fitts Law (compare distance and size; check for infinite size)
+- Steering Law (distance and size over a path)
+- Cognitive modeling (complex multi-step model of expert behavior)
+ - Does someone have to 'check' something? More than once?
+ - Do they have to move? More than once
+- Gestalt Psychology (will they see it at all?)
+- Errors (will they be reduced)
+
+???
+why theory and not intuition?
+
+---
+# Which is better and which laws explain it?
+.left-column50[
+## A. Pie Menu
+![:img Pie Menu, 80%](img/menus/pie.jpg)
+]
+.right-column50[
+## B. Pull down Menu
+![:img Traditional Menu inside a web browser, 80%](img/menus/menu.png)
+]
+???
+
+What analysis methods can we use to predict?
+
+- Fitts Law (compare distance and size; check for infinite size)
+- *Steering Law* (distance and size over a path)
+- Cognitive modeling (complex multi-step model of expert behavior)
+ - Does someone have to 'check' something? More than once?
+ - Do they have to move? More than once
+- Gestalt Psychology (will they see it at all?)
+- Errors (will they be reduced)
+
+---
+# Steering Law (based on Fitts' law)
+.left-column50[
+## A. Pie Menu
+![:img Pie Menu, 80%](img/menus/pie.jpg)
+]
+.right-column50[
+## B. Pull down Menu
+![:img Traditional Menu inside a web browser, 80%](img/menus/menu.png)
+]
+
+---
+# Which is better and which law explains it?
+.left-column50[
+## A. Pie Menu
+![:img Pie Menu, 80%](img/menus/pie.jpg)
+]
+.right-column50[
+## B. Marking Menu
+![:youtube Video assigned before class, 8c58bN6ajJ4?t=30]
+]
+???
+
+- Fitts Law (compare distance and size; check for infinite size)
+- Steering Law (distance and size over a path)
+- Cognitive modeling (complex multi-step model of expert behavior)
+ - **Does someone have to 'check' something? More than once?**
+ - **Do they have to move? More than once**
+- Gestalt Psychology (will they see it at all?)
+- Errors (will they be reduced)
+---
+# Cognitive modeling (less double checking)
+
+.left-column50[
+## A. Pie Menu
+![:img Pie Menu, 80%](img/menus/pie.jpg)
+]
+.right-column50[
+## B. Marking Menu
+![:youtube Video assigned before class, 8c58bN6ajJ4?t=30]
+]
+
+---
+# Which is better and which laws explain it?
+
+A: Tapping &nbsp;&nbsp; B: Crossing
+![:youtube Video of using crossing for selection, kp2Zl4ONuik]
+
+???
+
+- **Fitts Law (compare distance and size; check for infinite size)**
+- Steering Law (distance and size over a path)
+- Cognitive modeling (complex multi-step model of expert behavior)
+ - Does someone have to 'check' something? More than once?
+ - Do they have to move? More than once
+- Gestalt Psychology (will they see it at all?)
+- Errors (will they be reduced)
+
+---
+# Fitts' Law (infinite width)
+
+A: Tapping &nbsp;&nbsp; B: Crossing
+![:youtube Video of using crossing for selection, kp2Zl4ONuik]
+
+---
+# Which is better and which laws explain it?
+.left-column50[
+## A.
+
+![:img Picture of the Graffiti gesture recognition alphabet from the Palm Pilot, 100%](img/menus/Grafitti.png)
+]
+.right-column50[
+## B.
+
+![:img Picture of the Edgewrite gesture recognition alphabet, 50%](img/menus/Edgewrite.png)
+
+]
+???
+
+- Fitts Law (compare distance and size; check for infinite size)
+- Steering Law (distance and size over a path)
+- Cognitive modeling (complex multi-step model of expert behavior)
+ - Does someone have to 'check' something? More than once?
+ - Do they have to move? More than once
+- Gestalt Psychology (will they see it at all?)
+- **Errors (will they be reduced)**
+---
+# Errors (better physical feedback during motor task)
+
+.left-column50[
+## A.
+
+![:img Picture of the Graffiti gesture recognition alphabet from the Palm Pilot, 100%](img/menus/Grafitti.png)
+]
+.right-column50[
+## B.
+
+![:img Picture of the Edgewrite gesture recognition alphabet, 50%](img/menus/Edgewrite.png)
+
+]
+
+---
+# Which is better and which laws explain it?
+
+.left-column50[
+## A.
+![:img Old facebook security page with icons and text mixed
+up,80%](img/menus/facebook.png)
+]
+.right-column50[
+## B.
+
+![:img March 2019 facebook security page with icons and
+text clearly aligned, 80%](img/menus/facebook2.png)
+]
+???
+
+- Fitts Law (compare distance and size; check for infinite size)
+- Steering Law (distance and size over a path)
+- Cognitive modeling (complex multi-step model of expert behavior)
+ - Does someone have to 'check' something? More than once?
+ - Do they have to move? More than once
+- **Gestalt Psychology (group?)**
+- **Errors (will they be reduced)**
+---
+# Gestalt Psychology (better grouping strategies)
+
+.left-column50[
+## A.
+![:img Old facebook security page with icons and text mixed
+up,80%](img/menus/facebook.png)
+]
+.right-column50[
+## B.
+
+![:img March 2019 facebook security page with icons and
+text clearly aligned, 80%](img/menus/facebook2.png)
+]
+
+---
+# Back to comparing menus
+
+Kurtenbach: What did they study here?
+
+![:youtube Illustration of advantages of marking menus,dtH9GdFSQaw]
+
+---
+# How do we prove our theories? Hypothesis
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis(Hypothesis)
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+
+
+class S invisible
+class Hypothesis start
+</div>
+
+Discuss
+
+--
+
+Marking Menus are better than Pie Menus
+
+--
+Marking Menus are *faster* than Pie Menus
+
+--
+Pie Menus are faster than Linear Menus for less than 8 items that have no obvious order
+
+---
+.left-column-half[
+# What conditions does this experiment have?
+
+
+`MenuType`
+
+`TaskType` (could be a condition)
+]
+.right-column-half[
+# What might we measure? (from POP-Motor)
+]
+--
+.right-column-half[
+- Time on Task
+- Accuracy
+- How strenuous
+- Recall
+- Emotional Response
+
+]
+
+<!-- --- -->
+<!-- # Classes that handle experimentation -->
+
+<!-- We provide most of the implementation for this -->
+
+<!-- <div class="mermaid"> -->
+<!-- classDiagram -->
+
+<!-- class MainActivity { -->
+<!--   showMenuForTrial() -->
+<!-- } -->
+<!-- class AbstractMainActivity { -->
+<!--   clearCSV() -->
+<!-- } -->
+<!-- class MainActivity { -->
+<!--   showMenuForTrial() -->
+<!-- } -->
+<!-- class TestActivity { -->
+<!--   showMenu() -->
+<!-- } -->
+
+<!-- class TrialListener { -->
+<!--   onTrialCompleted() -->
+<!-- } -->
+
+<!-- AbstractMainActivity <|-- MainActivity -->
+<!-- AbstractMainActivity <|-- TestActivity -->
+
+<!-- class ExperimentSession { -->
+<!--  createTrials() -->
+<!--  getNext() -->
+<!--  next() -->
+<!-- } -->
+
+<!-- </div> -->
+
+
+---
+# How do we prove our theories? Method
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis(Hypothesis)
+Hypothesis -- "Study Design" --> Method(Method)
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+
+
+class S invisible
+class Hypothesis start
+class Method normal
+</div>
+
+Compare specific conditions
+
+| MenuType | 8 items | 12 items |
+|----------|---------|----------|
+| Linear   |         |          |
+| Pie      |         |          |
+| Marking  |         |          |
+
+What if we wanted to do length AND ordered vs not?
+
+Want to consider every combination, or run twice (menuType x length and menuType x ordering)
+
+---
+# How do we prove our theories? Data
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis(Hypothesis)
+Hypothesis -- "Study Design" --> Method(Method)
+Method -- "Run Study" --> Data(Data)
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+
+
+class S invisible
+class Hypothesis start
+class Method,Data normal
+</div>
+
+What might we want to measure?
+
+--
+- Time on task -- how long to complete basic tasks? (For example, find something to buy, create a new account, and order the item.)
+
+--
+- Accuracy -- How many mistakes did people make? (And were they fatal or recoverable with the right information?)
+
+--
+- How strenuous (e.g. gaze has lower throughput but is less strenuous than head pointing (Mackenzie 2018)
+
+--
+- Recall -- How much does the person remember afterwards or after periods of non-use?
+
+--
+- Emotional Response -- How does the person feel about the tasks completed? (Confident? Stressed? Would the user recommend this system to a friend?)
+
+???
+Build up a list of good UI design principals from these basics
+
+Undo
+Predictability
+... What is missing? (e.g. fun)
+---
+# How to get such data?
+
+- Video
+- Timestamps
+- Notes
+- Can transcribe and analyze interviews with users
+- Can look for patterns across users
+
+---
+# How do we prove our theories? Analysis
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis(Hypothesis)
+Hypothesis -- "Study Design" --> Method(Method)
+Method -- "Run Study" --> Data(Data)
+Data -- "Clean and Prep" --> Analysis(Analysis)
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+
+
+class S invisible
+class Hypothesis start
+class Method,Data,Analysis normal
+</div>
+
+![:img sample data from the menus experiement, 80%](img/menus/menus-data.png)
+
+---
+# How do we prove our theories? Conclusions
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis(Hypothesis)
+Hypothesis -- "Study Design" --> Method(Method)
+Method -- "Run Study" --> Data(Data)
+Data -- "Clean and Prep" --> Analysis(Analysis)
+Analysis --> Conclusions(Conclusions)
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+linkStyle 4 stroke-width:4px;
+
+class S invisible
+class Hypothesis,Conclusions start
+class Method,Data,Analysis normal
+</div>
+
+![:img sample data from the menus experiement, 30%](img/menus/histogram.png)
+
+
+
+---
+# Design an experiment
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis(Hypothesis)
+Hypothesis -- "Study Design" --> Method(Method)
+Method -- "Run Study" --> Data(Data)
+Data -- "Clean and Prep" --> Analysis(Analysis)
+Analysis --> Conclusions(Conclusions)
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+linkStyle 4 stroke-width:4px;
+
+class S invisible
+class Hypothesis,Conclusions start
+class Method,Data,Analysis normal
+</div>
+
+.left-column50[
+## A.
+![:img Picture of the Graffiti gesture recognition alphabet from the Palm Pilot, 100%](img/menus/Grafitti.png)
+]
+.right-column50[
+## B.
+![:img Picture of the Edgewrite gesture recognition alphabet, 50%](img/menus/Edgewrite.png)
+]
+
+???
+Hypothesis: Errors (will they be reduced)
+Method:??
+Data:??
+Analysis??
+Conclusions??
+
+---
+# Design an experiment
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis(Hypothesis)
+Hypothesis -- "Study Design" --> Method(Method)
+Method -- "Run Study" --> Data(Data)
+Data -- "Clean and Prep" --> Analysis(Analysis)
+Analysis --> Conclusions(Conclusions)
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+linkStyle 4 stroke-width:4px;
+
+class S invisible
+class Hypothesis,Conclusions start
+class Method,Data,Analysis normal
+</div>
+
+.left-column50[
+## A. Pie Menu
+![:img Pie Menu, 80%](img/menus/pie.jpg)
+]
+.right-column50[
+## B. Pull down Menu
+![:img Traditional Menu inside a web browser, 80%](img/menus/menu.png)
+]
+
+???
+
+Hypothesis: Errors will be reduced;
+Hypothesis: Motion will be faster due to low level motor things
+Hypothesis: fewer cognitive checks needed
+Method:??
+Data:??
+Analysis??
+Conclusions??
diff --git a/slides/wk07/slides22 - persuasive tech copy.pdf b/slides/wk07/slides22 - persuasive tech copy.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..6eaf11a25a0f3b1e404c2eb54823c09b195efdb3
Binary files /dev/null and b/slides/wk07/slides22 - persuasive tech copy.pdf differ
diff --git a/slides/wk08/img/studies/chart.png b/slides/wk08/img/studies/chart.png
new file mode 100644
index 0000000000000000000000000000000000000000..51340bdc387fdb4390c0dc45310c8c853a29ea6a
Binary files /dev/null and b/slides/wk08/img/studies/chart.png differ
diff --git a/slides/wk08/img/studies/import.png b/slides/wk08/img/studies/import.png
new file mode 100644
index 0000000000000000000000000000000000000000..a8e25213ae79c9f00bb100df23d69fa375602803
Binary files /dev/null and b/slides/wk08/img/studies/import.png differ
diff --git a/slides/wk08/img/studies/raw.png b/slides/wk08/img/studies/raw.png
new file mode 100644
index 0000000000000000000000000000000000000000..369cb3f5dfd935cc8f5c8bd32592cd67627e3001
Binary files /dev/null and b/slides/wk08/img/studies/raw.png differ
diff --git a/slides/wk08/img/studies2/cagelation.png b/slides/wk08/img/studies2/cagelation.png
new file mode 100644
index 0000000000000000000000000000000000000000..2e41c1d7acd62d868f2df55f859d29fd9fb73bfe
Binary files /dev/null and b/slides/wk08/img/studies2/cagelation.png differ
diff --git a/slides/wk08/img/studies2/chart.png b/slides/wk08/img/studies2/chart.png
new file mode 100644
index 0000000000000000000000000000000000000000..51340bdc387fdb4390c0dc45310c8c853a29ea6a
Binary files /dev/null and b/slides/wk08/img/studies2/chart.png differ
diff --git a/slides/wk08/img/studies2/correlation-cartoon.png b/slides/wk08/img/studies2/correlation-cartoon.png
new file mode 100644
index 0000000000000000000000000000000000000000..1242708b466c0531b9effa97b1a572c70e044d2f
Binary files /dev/null and b/slides/wk08/img/studies2/correlation-cartoon.png differ
diff --git a/slides/wk08/img/studies2/correlation-demo.png b/slides/wk08/img/studies2/correlation-demo.png
new file mode 100644
index 0000000000000000000000000000000000000000..c28ef774a0faf9eb1501765e37934af5674713b1
Binary files /dev/null and b/slides/wk08/img/studies2/correlation-demo.png differ
diff --git a/slides/wk08/img/studies2/correlation.png b/slides/wk08/img/studies2/correlation.png
new file mode 100644
index 0000000000000000000000000000000000000000..c69cafbf23b3485a7c324f03ea4a19ce20e85e4a
Binary files /dev/null and b/slides/wk08/img/studies2/correlation.png differ
diff --git a/slides/wk08/img/studies2/histogram.png b/slides/wk08/img/studies2/histogram.png
new file mode 100644
index 0000000000000000000000000000000000000000..6f7e8740d3aa89ea7208ad05269baf77df275f25
Binary files /dev/null and b/slides/wk08/img/studies2/histogram.png differ
diff --git a/slides/wk08/img/studies2/normal-only.png b/slides/wk08/img/studies2/normal-only.png
new file mode 100644
index 0000000000000000000000000000000000000000..a699b9b891468b7eb9e624d6f630908fc60df575
Binary files /dev/null and b/slides/wk08/img/studies2/normal-only.png differ
diff --git a/slides/wk08/img/studies2/pie-only.png b/slides/wk08/img/studies2/pie-only.png
new file mode 100644
index 0000000000000000000000000000000000000000..b9ec62ba9f84f0178670efd4e34c5b436b7a4488
Binary files /dev/null and b/slides/wk08/img/studies2/pie-only.png differ
diff --git a/slides/wk08/img/studies2/pivot1.png b/slides/wk08/img/studies2/pivot1.png
new file mode 100644
index 0000000000000000000000000000000000000000..bca708fc3cd0e423730c0035e723a48999a08cd7
Binary files /dev/null and b/slides/wk08/img/studies2/pivot1.png differ
diff --git a/slides/wk08/img/studies2/pivot2.png b/slides/wk08/img/studies2/pivot2.png
new file mode 100644
index 0000000000000000000000000000000000000000..097489384473e677bf085338864849c35fcc3300
Binary files /dev/null and b/slides/wk08/img/studies2/pivot2.png differ
diff --git a/slides/wk08/img/studies2/priors.png b/slides/wk08/img/studies2/priors.png
new file mode 100644
index 0000000000000000000000000000000000000000..780996fe4bd6e438d726e9ba3b13f7dcc48ab919
Binary files /dev/null and b/slides/wk08/img/studies2/priors.png differ
diff --git a/slides/wk08/img/studies2/samples1.png b/slides/wk08/img/studies2/samples1.png
new file mode 100644
index 0000000000000000000000000000000000000000..49501eff4390ef68cf89dcc87031daece7975bea
Binary files /dev/null and b/slides/wk08/img/studies2/samples1.png differ
diff --git a/slides/wk08/img/studies2/samples2.png b/slides/wk08/img/studies2/samples2.png
new file mode 100644
index 0000000000000000000000000000000000000000..7964a305be364fdd74536c64219dfdfbc0e281d7
Binary files /dev/null and b/slides/wk08/img/studies2/samples2.png differ
diff --git a/slides/wk08/img/studies2/samples3.png b/slides/wk08/img/studies2/samples3.png
new file mode 100644
index 0000000000000000000000000000000000000000..386bfcdd2dc112661ae57d9f1ea603ddbac4211f
Binary files /dev/null and b/slides/wk08/img/studies2/samples3.png differ
diff --git a/slides/wk08/img/studies2/samples4.png b/slides/wk08/img/studies2/samples4.png
new file mode 100644
index 0000000000000000000000000000000000000000..c7964ba49e0f2a6daa9437d6dfb2da9e29ea37e8
Binary files /dev/null and b/slides/wk08/img/studies2/samples4.png differ
diff --git a/slides/wk08/img/studies2/samples5.png b/slides/wk08/img/studies2/samples5.png
new file mode 100644
index 0000000000000000000000000000000000000000..386bfcdd2dc112661ae57d9f1ea603ddbac4211f
Binary files /dev/null and b/slides/wk08/img/studies2/samples5.png differ
diff --git a/slides/wk08/img/studies2/samples6.png b/slides/wk08/img/studies2/samples6.png
new file mode 100644
index 0000000000000000000000000000000000000000..a0c4949d6f4f5ef9623036312aaf19f4fb6b718a
Binary files /dev/null and b/slides/wk08/img/studies2/samples6.png differ
diff --git a/slides/wk08/img/studies2/samples7.png b/slides/wk08/img/studies2/samples7.png
new file mode 100644
index 0000000000000000000000000000000000000000..c34a788058ea4c3f244c3e7c03684dd6d2b27594
Binary files /dev/null and b/slides/wk08/img/studies2/samples7.png differ
diff --git a/slides/wk08/img/undo/callbacks.png b/slides/wk08/img/undo/callbacks.png
new file mode 100644
index 0000000000000000000000000000000000000000..72147534bc5ba07de7a95ffe479f5505d65814f4
Binary files /dev/null and b/slides/wk08/img/undo/callbacks.png differ
diff --git a/slides/wk08/img/undo/callbacks2.png b/slides/wk08/img/undo/callbacks2.png
new file mode 100644
index 0000000000000000000000000000000000000000..37eeff1f958d4f711faf7ce2af0ceb9736121957
Binary files /dev/null and b/slides/wk08/img/undo/callbacks2.png differ
diff --git a/slides/wk08/img/undo/callbacks3.png b/slides/wk08/img/undo/callbacks3.png
new file mode 100644
index 0000000000000000000000000000000000000000..c7c5e1de7d5c73ca13b8e95df99735ce5aeec7fa
Binary files /dev/null and b/slides/wk08/img/undo/callbacks3.png differ
diff --git a/slides/wk08/img/undo/flatland-roads.png b/slides/wk08/img/undo/flatland-roads.png
new file mode 100644
index 0000000000000000000000000000000000000000..77655503c0c8225654cb4f6422960727363bcfd4
Binary files /dev/null and b/slides/wk08/img/undo/flatland-roads.png differ
diff --git a/slides/wk08/img/undo/flatland.png b/slides/wk08/img/undo/flatland.png
new file mode 100644
index 0000000000000000000000000000000000000000..60c84737008f5acfa50d6a39be07a439ef2fc372
Binary files /dev/null and b/slides/wk08/img/undo/flatland.png differ
diff --git a/slides/wk08/img/undo/gym-doors.png b/slides/wk08/img/undo/gym-doors.png
new file mode 100644
index 0000000000000000000000000000000000000000..99ffb06c3f14d3adee83426b9a59dc4b1291d8c6
Binary files /dev/null and b/slides/wk08/img/undo/gym-doors.png differ
diff --git a/slides/wk08/img/undo/mental1.png b/slides/wk08/img/undo/mental1.png
new file mode 100644
index 0000000000000000000000000000000000000000..a3c23c4e46f70202c6a8117ed0607dc2f8e1f373
Binary files /dev/null and b/slides/wk08/img/undo/mental1.png differ
diff --git a/slides/wk08/img/undo/mental2.png b/slides/wk08/img/undo/mental2.png
new file mode 100644
index 0000000000000000000000000000000000000000..58c9cc1a547ec69cd2652c456c8cb040b5e6a0bd
Binary files /dev/null and b/slides/wk08/img/undo/mental2.png differ
diff --git a/slides/wk08/img/undo/mental3.png b/slides/wk08/img/undo/mental3.png
new file mode 100644
index 0000000000000000000000000000000000000000..07a7d35cca9dbe1309fe9c5809ce3ac2e2e684d6
Binary files /dev/null and b/slides/wk08/img/undo/mental3.png differ
diff --git a/slides/wk08/img/undo/mental4.png b/slides/wk08/img/undo/mental4.png
new file mode 100644
index 0000000000000000000000000000000000000000..1e40a86ffb987d0e45c5420bc8d87f34c46e62e0
Binary files /dev/null and b/slides/wk08/img/undo/mental4.png differ
diff --git a/slides/wk08/img/undo/mental5.png b/slides/wk08/img/undo/mental5.png
new file mode 100644
index 0000000000000000000000000000000000000000..e8b861ac7042b4cc0b3bd2ab312ef120c1225564
Binary files /dev/null and b/slides/wk08/img/undo/mental5.png differ
diff --git a/slides/wk08/img/undo/mental6.png b/slides/wk08/img/undo/mental6.png
new file mode 100644
index 0000000000000000000000000000000000000000..5baea3ac170bd237ee0c35101160347918f32c04
Binary files /dev/null and b/slides/wk08/img/undo/mental6.png differ
diff --git a/slides/wk08/img/undo/mental7.png b/slides/wk08/img/undo/mental7.png
new file mode 100644
index 0000000000000000000000000000000000000000..9bb9a6c4bd2bf569e84b6de7d2d7e73f0e9ecc09
Binary files /dev/null and b/slides/wk08/img/undo/mental7.png differ
diff --git a/slides/wk08/img/undo/norman-d-human-action-cycle.png b/slides/wk08/img/undo/norman-d-human-action-cycle.png
new file mode 100644
index 0000000000000000000000000000000000000000..f5748a294e9e8786e3337bc8404b71364d1db0f9
Binary files /dev/null and b/slides/wk08/img/undo/norman-d-human-action-cycle.png differ
diff --git a/slides/wk08/studies.html b/slides/wk08/studies.html
new file mode 100644
index 0000000000000000000000000000000000000000..3b60f194ba7e79e0ec6cef2c70956897c731079f
--- /dev/null
+++ b/slides/wk08/studies.html
@@ -0,0 +1,470 @@
+---
+layout: presentation
+title: Running a Quantitative Study
+description: Description of how to test a hypothesis in a study, all steps
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Running a Quantitative Study
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout: false
+
+# Today's goals
+
+- Review our designs from Friday
+- Discuss steps of running a study
+- Practice onboarding participants
+- Practice data analysis
+- Go over parts 5 & 6 of Menus
+
+---
+# Case Study: UbiGreen - In Class activity
+
+Take 2 minutes to go back into our [shared google doc](https://docs.google.com/document/d/1SqvaQyhFYs6AsOPoDcBkG4egCRRq3jEaW17HOi0hSkM/edit?usp=sharing)
+
+Find a design by a different group than you were in. Use the google doc comment feature to leave
+a short critique.
+
+Phrases to get you started
+
+- I like ...
+- I wish ...
+- What if...
+
+.footnote[I like I wish critique method from [Stanford Design School](https://www.youtube.com/watch?v=QkWM2--3TQo)]
+
+---
+# Experiment Design
+
+<div class="mermaid">
+graph LR
+S(.) --> Hypothesis(Hypothesis)
+Hypothesis -- "Study Design" --> Method(Method)
+Method -- "Run Study" --> Data(Data)
+Data -- "Clean and Prep" --> Analysis(Analysis)
+Analysis --> Conclusions(Conclusions)
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px,font-size:.7em,height:2.5em;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:3px;
+linkStyle 1 stroke-width:3px;
+linkStyle 2 stroke-width:3px;
+linkStyle 3 stroke-width:3px;
+linkStyle 4 stroke-width:3px;
+
+class S invisible
+class Hypothesis,Conclusions start
+class Method,Data,Analysis normal
+</div>
+
+&zwj;Think: What is the Hypothesis for the Menus assignment
+--
+
+&zwj;Pair: We'd chat for a minute in person but I'm not putting you in breakouts for this question...
+--
+
+&zwj;Share: Type your thoughts in the chat window
+
+---
+# Method
+<div class="mermaid">
+graph LR
+S(.) --> Hypothesis(Hypothesis <br>Decreased seek <br>time and errors)
+Hypothesis -- "Study Design" --> Method(Method)
+Method -- "Run Study" --> Data(Data)
+Data -- "Clean and Prep" --> Analysis(Analysis)
+Analysis --> Conclusions(Conclusions)
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px,font-size:.7em,height:5em;
+classDef startsmall fill:#d1e0e0,stroke:#333,stroke-width:4px,font-size:.7em,height:2.5em;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:3px;
+linkStyle 1 stroke-width:3px;
+linkStyle 2 stroke-width:3px;
+linkStyle 3 stroke-width:3px;
+linkStyle 4 stroke-width:3px;
+
+class S invisible
+class Hypothesis start
+class Conclusions startsmall
+class Method,Data,Analysis normal
+</div>
+
+- 3 tasks x 3 menu types = 9 *conditions*
+- Each condition will have a total of totalTrials = `ITEM_MAX` x `NUM_REPEATS`
+  - In each *condition* we test `ITEM_MAX` different menu items
+  - For each menu item, we repeat `NUM_REPEATS` times
+
+| | Normal | Pie | Custom |
+|--|--|--|--|
+| **Linear** | totalTrials | totalTrials | totalTrials |
+| **Relational** | totalTrials | totalTrials  | totalTrials |
+| **Unclassified** | totalTrials | totalTrials | totalTrials |
+
+---
+# Other Method considerations
+
+For Menus Part 5-6, an experimental *session* consists of 3 tasks x 3 menu types x
+`ITEM_MAX` items x `NUM_REPEATS` repetitions = 108 *trials*
+
+You have to run at least three participants through a complete session = 108 x 3 or 324 data points.
+
+--
+In some experimental designs, participants only do some conditions
+- Called *between subjects design*
+
+Our participants do *all* trials
+- Our study is a *within subjects design*
+
+Order of presentation of conditions and items is randomized (why?)
+
+
+???
+Between subjects design: Person A compared to person B doing different tasks
+
+---
+# Document all of this in your [report]({{site.baseurl}}/assignments/menu-report)
+
+Introduce study purpose
+
+`Write two sentences describing the purpose of the experiment. This
+can be the same text you use in your consent form`
+
+---
+# Document all of this in your [report]({{site.baseurl}}/assignments/menu-report)
+
+Introduce study method - menus
+
+`Mention that there are three types of menus, Pie, Linear and Custom.
+Then describe your custom menu and include an screenshots of your custom menu in both a selected
+and unselected state. Describe some of the design choices you made when you were conceiving your
+custom menu and how your final product match (or didn’t) your original vision? Be sure to explain
+clearly how your custom menu works and how a user interacts with it?`
+
+Introduce study method - tasks
+
+`Describe the 9 conditions of the study. Explain how many
+items were selected per menu, and how many times each item was
+repeated. Describe how many trials each participant completed.`
+
+---
+# Study Ethics
+<div class="mermaid">
+graph LR
+S(.) --> Hypothesis(Hypothesis:<br>Decreased seek <br>time and errors)
+Hypothesis -- "Study Design" --> Method(3 menus x <br> 3 task conditions )
+Method -- "Run Study" --> Data(Data)
+Data -- "Clean and Prep" --> Analysis(Analysis)
+Analysis --> Conclusions(Conclusions)
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+classDef normalbig fill:#e6f3ff,stroke:#333,stroke-width:2px,font-size:.7em,height:4em;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px,font-size:.7em,height:5em;
+classDef startsmall fill:#d1e0e0,stroke:#333,stroke-width:4px,font-size:.7em,height:2.5em;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:3px;
+linkStyle 1 stroke-width:3px;
+linkStyle 2 stroke-width:3px;
+linkStyle 3 stroke-width:3px;
+linkStyle 4 stroke-width:3px;
+
+class S invisible
+class Hypothesis start
+class Conclusions startsmall
+class Method normalbig
+class Data,Analysis normal
+</div>
+
+Ethical Principles for running participants. Driven by
+[Criminal/Racist/Harmful studies](https://www.nytimes.com/2017/05/22/science/social-science-research-institutional-review-boards-common-rule.html)
+ - Nazi war crimes
+ - Tuskegee Syphilis study
+ - Epilepsy studies of institutionalized children
+ - [16,000 people involuntarily included in radiation
+   studies](https://www.nytimes.com/1995/08/20/us/count-of-subjects-in-radiation-experiments-is-raised-to-16000.html?module=inline)
+ - [Milgram's study of electric shocking](https://www.simplypsychology.org/milgram.html)
+ - [Stanford prison experiment](https://www.simplypsychology.org/zimbardo.html)
+
+
+???
+IRB = Institutional Review Board Protocol (and get it approved.)
+
+---
+# Study Ethics
+<div class="mermaid">
+graph LR
+S(.) --> Hypothesis(Hypothesis:<br>Decreased seek <br>time and errors)
+Hypothesis -- "Study Design" --> Method(3 menus x <br> 3 task conditions )
+Method -- "Run Study" --> Data(Data)
+Data -- "Clean and Prep" --> Analysis(Analysis)
+Analysis --> Conclusions(Conclusions)
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+classDef normalbig fill:#e6f3ff,stroke:#333,stroke-width:2px,font-size:.7em,height:4em;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px,font-size:.7em,height:5em;
+classDef startsmall fill:#d1e0e0,stroke:#333,stroke-width:4px,font-size:.7em,height:2.5em;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:3px;
+linkStyle 1 stroke-width:3px;
+linkStyle 2 stroke-width:3px;
+linkStyle 3 stroke-width:3px;
+linkStyle 4 stroke-width:3px;
+
+class S invisible
+class Hypothesis start
+class Conclusions startsmall
+class Method normalbig
+class Data,Analysis normal
+</div>
+
+
+Basic ethics ([Belmont Report](https://www.hhs.gov/ohrp/regulations-and-policy/belmont-report/read-the-belmont-report/index.html))
+- Beneficence -->
+ - Value of research higher than risks
+ - Do no harm
+- Respect for Persons -->
+ - Fully informed of intent and purpose
+ - Informed consent
+ - May opt out at any time, for any reason
+- Justice -->
+ - Equitable, representative selection of participants
+
+
+---
+# Consent
+
+Write your [consent]({{site.baseurl}}/assignments/consent) form
+
+- Purpose of study (Beneficience)
+- Requirements for participation (Respect for Persons)
+- Study procedures (Respect for Persons)
+- Voluntariness (Respect for Persons)
+- Benefits to Society (Beneficience)
+- Contact (of IRB typically; Me in this case)
+
+
+???
+- Beneficence -->
+ - Value of research higher than risks
+ - Do no harm
+- Respect for Persons -->
+ - Fully informed of intent and purpose
+ - Informed consent
+ - May opt out at any time, for any reason
+- Justice
+ - equitable, representative selection of participants
+
+---
+# Choosing and Consenting Participants
+
+For 20sp only, we are assigning you in "groups" to help you find testers.
+- If you can not safely test your app with someone who is co-present you will need to ask your [groupmates](https://docs.google.com/document/d/11nsEWs3TubV5Zy0zOIGguqZJohkS34uizIrDv-bgnYs/edit)
+- Consenting your participants will be very similar whether they are co-present or remote.
+  - Set up a time when can speak to your participant (in real time) - phone or video call
+  - For a co-present tester - print out two copies of the consent form for each participant -- one for them and one for you.
+  - For remote testers - send a copy of the consent form to the participant prior to your phone call
+or video meeting.
+
+---
+# Choosing and Consenting Participants
+
+During the consent meeting
+- Briefly explain what your user study is about,
+- Ensure participants understand their participation in the study is voluntary.
+  - Do not *coerce* anyone into participating in your study.
+  - Make sure they know they have a choice, and have read the consent form.
+- Participants must acknowledge their consent by "signing" via the Google form (linked
+at the bottom of the consent form template).
+  - This form should send you an anonymized copy of their
+consent in email, which you can save and turn in with the rest of your report and reflection.
+
+---
+# Choosing and Consenting Participants
+
+If you are unable to find 3 partipants from your friends, family, or pre-assigned group
+- Please reach out to a TA during Office Hours or to have them be a partipipant.
+- You may also reach out to other students in the class via Ed.
+
+
+---
+# Document your participants in your [report]({{site.baseurl}}/assignments/menu-report)
+
+Method - Participants
+
+`Describe your participants (without identifying
+them). How were they recruited? How many were there?  Were
+they consented? You can also add
+some optional information such as: What was there average age? What
+genders were present? How experienced were they with android?`
+
+---
+# Data Collection
+
+<div class="mermaid">
+  graph LR
+  S(.) --> Hypothesis(Hypothesis:<br>Decreased seek <br>time and errors)
+  Hypothesis -- "Study Design" --> Method(3 menus x <br> 3 task conditions )
+  Method -- "Run Study" --> Data(Data)
+  Data -- "Clean and Prep" --> Analysis(Analysis)
+  Analysis --> Conclusions(Conclusions)
+
+  classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+  classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+  classDef normalbig fill:#e6f3ff,stroke:#333,stroke-width:2px,font-size:.7em,height:4em;
+  classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px,font-size:.7em,height:5em;
+  classDef startsmall fill:#d1e0e0,stroke:#333,stroke-width:4px,font-size:.7em,height:2.5em;
+  classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+  linkStyle 0 stroke-width:3px;
+  linkStyle 1 stroke-width:3px;
+  linkStyle 2 stroke-width:3px;
+  linkStyle 3 stroke-width:3px;
+  linkStyle 4 stroke-width:3px;
+
+  class S invisible
+  class Hypothesis start
+  class Conclusions startsmall
+  class Method normalbig
+  class Data,Analysis normal
+</div>
+
+If you have co-present users:
+
+1. **Clear your data** file before you start the **first participant
+only**
+2. Have participant read and sign the consent form
+3. Emphasize key points verbally
+4. Be Consistent in how you present the study
+5. Download result (you can use a tool window called `Device File Manager`)
+
+---
+# Data Collection
+
+<div class="mermaid">
+  graph LR
+  S(.) --> Hypothesis(Hypothesis:<br>Decreased seek <br>time and errors)
+  Hypothesis -- "Study Design" --> Method(3 menus x <br> 3 task conditions )
+  Method -- "Run Study" --> Data(Data)
+  Data -- "Clean and Prep" --> Analysis(Analysis)
+  Analysis --> Conclusions(Conclusions)
+
+  classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+  classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+  classDef normalbig fill:#e6f3ff,stroke:#333,stroke-width:2px,font-size:.7em,height:4em;
+  classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px,font-size:.7em,height:5em;
+  classDef startsmall fill:#d1e0e0,stroke:#333,stroke-width:4px,font-size:.7em,height:2.5em;
+  classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+  linkStyle 0 stroke-width:3px;
+  linkStyle 1 stroke-width:3px;
+  linkStyle 2 stroke-width:3px;
+  linkStyle 3 stroke-width:3px;
+  linkStyle 4 stroke-width:3px;
+
+  class S invisible
+  class Hypothesis start
+  class Conclusions startsmall
+  class Method normalbig
+  class Data,Analysis normal
+</div>
+
+If you have a remote user
+
+1. Generate your APK
+2. Consent your user via phone or video conference.
+3. Send your APK to the participant so they can load it onto their own device or into their own
+ emulator
+  - You can't email your APK through UW's servers, so upload the APK to your Google Drive or One Drive and send your participant
+ a link to download it for testing.
+4. Have your participant use the hamburger menu to select `Clear Result CSV` before starting
+ your study
+5. Have your participant run one experiment session.
+6. When the study is done, your participant will need to download their data
+and send it back for analysis.
+7. Combine the three participants' data into one common .csv file.
+
+
+---
+layout: true
+class: center, middle
+---
+# Collecting data file (Demo)
+---
+layout: false
+
+# Document what all of this in your [report]({{site.baseurl}}/assignments/menu-report)
+
+Method - Setting
+`What device was used? Was it an emulator? Where did the experiment take place?`
+
+Method - Data Collected
+`What information was collected (time, errors, etc)`
+
+---
+# Data Collection
+.left-column[
+
+![:img Picture of a dialogue box called Import file showing that you should replace current sheet and automatically detect separator type and convert text to numbers dates and formulas,100%](img/studies/import.png)
+]
+
+.right-column[
+
+Select the 'raw' sheet of your spreadsheet then load your file into the spreadsheet
+
+![:img Picture of a spreadsheet with the tab titled 'Raw' selected](img/studies/raw.png)
+
+]
+---
+# Data Collection
+.left-column[
+
+![:img Image of bar chart comparing tasks to menu type showing that
+normal menus get progressively slower as items become nonlinear while
+pie menus are about the same, 100%](img/studies/chart.png)
+]
+.right-column[
+
+
+Now click on `Example Chart`. Here you can
+
+- Analyze and chart data: Simple Statistics
+  - Min, Max, Mean (Sum/#), Median (Middle #), Mode (Most Common #)
+
+Demo
+
+Do this for speed *and* error.
+
+]
+
+
+---
+# Document what all of this in your [report]({{site.baseurl}}/assignments/menu-report)
+
+Speed Results
+
+`Describe your thoughts about overall speed in different
+conditions. Use at least one chart to illustrate what you say. Here is
+an example chart generated using our data, when you paste your data
+into the spreadsheet you’ll see that it updates to reflect your data`
+
+Error Results
+
+`Describe what happened in terms of errors -- provide at least one chart showing
+what you learned about errors in different conditions`
diff --git a/slides/wk08/studies2.html b/slides/wk08/studies2.html
new file mode 100644
index 0000000000000000000000000000000000000000..f3c583a7bb22a054e44f4def6eb18ffba8b9c4ca
--- /dev/null
+++ b/slides/wk08/studies2.html
@@ -0,0 +1,468 @@
+---
+layout: presentation
+title: Understanding Quantitative Data
+description: Description of how to analyze study data and draw conclusions
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Analyzing Quantitative Data
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout:false
+
+[//]: # (Outline Slide)
+# Today's goals
+
+- How to use the Menus spreadsheet
+- Dependent and independent variables
+- Discuss how we determine causality
+- Practice onboarding participants
+- Practice data analysis
+
+
+---
+# Data Collection
+.left-column[
+
+![:img Image of bar chart comparing tasks to menu type showing that
+normal menus get progressively slower as items become nonlinear while
+pie menus are about the same, 100%](img/studies2/chart.png)
+]
+.right-column[
+
+
+Now click on `Example Chart`. Here you can
+
+- Analyze and chart data: Simple Statistics
+  - Min, Max, Mean (Sum/#), Median (Middle #), Mode (Most Common #)
+
+Demo
+
+Do this for speed *and* error.
+
+]
+
+---
+# Document what all of this in your [report]({{site.baseurl}}/assignments/menu-report)
+
+Speed Results
+
+`Describe your thoughts about overall speed in different
+conditions. Use at least one chart to illustrate what you say. Here is
+an example chart generated using our data, when you paste your data
+into the spreadsheet you’ll see that it updates to reflect your data`
+
+Error Results
+
+`Describe what happened in terms of errors -- provide at least one chart showing
+what you learned about errors in different conditions`
+
+
+---
+# Use charts to check your assumptions
+
+![:img Image of bar chart comparing tasks to menu type showing that
+normal menus get progressively slower as items become nonlinear while
+pie menus are about the same, 50%](img/studies2/chart.png)
+
+
+---
+# Using the right chart matters
+
+.left-column40[
+
+![:img Histogram of data about speed of pie menu selection and linear
+menu selection for each task type, 70%](img/studies2/histogram.png)
+]
+
+.right-column50[
+|Normal | Pie|
+|--|--|
+|![:img Histogram of data about speed of pie menu selection and linear menu selection for each task type,100%](img/studies2/normal-only.png)|![:img Histogram of data about speed of pie menu selection and linear menu selection for each task type, 100%](img/studies2/pie-only.png)|
+
+]
+
+
+---
+# Can we determine *causality*?
+
+We'd like to be able to argue the task/menu type influenced the speed and error results.
+
+--
+This implies *dependence* between speed/error, task, and menu type
+
+--
+And it assumes you have measured the right variables!
+
+---
+
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Determining Causality
+
+## thinking theoretically...
+
+
+---
+layout:false
+
+
+# Dependence/independence
+
+Events that are independent
+- Flipping heads and then tails
+- Day of week and whether a patient had a heart attack (probably?)
+
+Events that are dependent
+- Vice presidential candidate and presidential nominee
+- Diagnostic test being positive and whether patient has a disease
+
+--
+What are some dependent and indepenent relationships in the Menus study?
+
+???
+Think about a coin flip: one flip does not depend on another.
+What if we collect this kind of data, what might be true about it?
+
+
+---
+# What might we expect to see is true of dependent variables?
+
+- When one changes, the other changes at the same rate
+- When one changes, the other changes at a faster rate
+- When one changes, the other does the opposite
+
+???
+Called a correlation
+We can see it in a scatter plot
+Go look at data and make one
+
+---
+# This is called *Correlation*
+
+We can see it in a *scatterplot*
+
+![:img Example of correlations for heigh vs age (positively correlated) and
+height vs birth month (uncorrelated),60%](img/studies2/correlation.png)
+
+---
+# Correlation (active) Demo
+
+[OpenSecrets.org data set on internet privacy resolution](https://www.opensecrets.org/featured-datasets/5)
+
+Active demo:
+
+Open it yourself: [tinyurl.com/cse340-ipdata](https://tinyurl.com/cse340-ipdata)
+
+Make a copy of this sheet to your own drive using File->Make a copy.
+
+(You must be logged into a Google account to make a copy)
+---
+# Correlation demo
+
+[OpenSecrets.org data set on internet privacy resolution](https://www.opensecrets.org/featured-datasets/5)
+
+- Select two columns (use command/control click to select 2 columns)
+- Use Insert->Chart - Make sure this is a scatterplot
+
+--
+![:img Correlation of company giving,60%](img/studies2/correlation-demo.png)
+
+Is there a correllation?
+
+
+---
+# Correlation != Causation
+
+![:img Correlation of number of people who drowned per year and films
+nicolas cage appeared in, 80%](img/studies2/cagelation.png)
+
+---
+# Correlation != Causation
+
+![:img Two people talking. Says one: I used to think correlation
+implied causation. Says the other: Then I took a statistics
+course. Now I don't. Says the other: Sounds like the class
+helped. Says the first: Well maybe, 50%](img/studies2/correlation-cartoon.png)
+
+.footnote[[XKCD](https://xkcd.com/552/)]
+
+---
+# Grouping for analysis
+
+Pivot Tablest demo
+[tinyurl.com/cse340-ipdata](https://tinyurl.com/cse340-ipdata)
+
+--
+![:img Giving vs party for diff votes, 30%](img/studies2/pivot1.png)
+
+---
+# Grouping and charting helps you check your assumptions
+
+![:img Image of bar chart  tasks to menu type showing that
+normal menus get progressively slower as items become nonlinear while
+pie menus are about the same, 40%](img/studies2/chart.png)
+
+What do you see in the difference between tasks on each of these menus types?
+
+--
+Charting gives you a place to start, what questions you might want to ask.
+
+---
+# Grouping and charting helps you check your assumptions
+
+[20sp Sample data](https://docs.google.com/spreadsheets/d/1JqfKhHugIF-kebs_bVztCnkUe0CizXN8PU_Ar3kXtK4/edit?usp=sharing)
+
+Not that different in this sample set (just Jen doing it 3 times).
+
+You likely will get better results with your data
+
+We will get even better results with ALL of the data merged together
+
+(Remember to turn your CSV into the Canvas Assignment)
+
+---
+
+# Comparing groups to see if they are different
+
+Bar charts  are not enough to assess difference though. Need to see the *distribution*
+
+A distribution is looking at how the people we are studying distributed over a specific variable we care about.
+
+A histogram graphically shows a distribution.
+
+---
+# Histogram shows you a *distribution*
+
+Pivot Tablest demo
+[tinyurl.com/cse340-ipdata](https://tinyurl.com/cse340-ipdata)
+
+--
+![:img Histogram of amount vs party, 40%](img/studies2/pivot2.png)
+
+
+---
+# But having the right chart matters
+
+![:img Histogram of data about speed of pie menu selection and linear
+menu selection for each task type, 40%](img/studies2/histogram.png)
+
+
+---
+# Normal Vs Pie
+
+|Normal | Pie|
+|--|--|
+|![:img Histogram of data about speed of pie menu selection and linear menu selection for each task type,100%](img/studies2/normal-only.png)|![:img Histogram of data about speed of pie menu selection and linear menu selection for each task type, 100%](img/studies2/pie-only.png)|
+
+The cause of the difference only shows here.
+
+---
+
+# What do we learn from a histogram?
+
+![:img two distributions, 50%](img/studies2/samples1.png)
+
+???
+- shows a distribution
+- helps us tell if things are INDEPENDENT
+
+---
+#  Histograms
+
+What do we learn from a histogram?
+- shows a distribution
+- helps us tell if things are INDEPENDENT
+
+---
+# Comparing two groups
+
+![:img two distributions showing overlapping 95% confidence intervals,
+50%](img/studies2/samples2.png)
+
+
+---
+# Comparing two groups
+
+![:img two distributions with less overlapping intervals (because more
+data is present), 50%](img/studies2/samples3.png)
+
+---
+# Comparing two groups
+
+![:img two distributions with more data but overlapping histograms
+thus hard to differentiate, 50%](img/studies2/samples4.png)
+
+---
+# Comparing two groups
+
+![:img two distributions with less overlapping intervals (because more
+data is present), 50%](img/studies2/samples5.png)
+
+---
+# Comparing two groups
+
+![:img two distributions not overlapping at all, 50%](img/studies2/samples6.png)
+
+---
+# Comparing two groups
+
+![:img same two distributions with difference between means marked as
+effect size, 50%](img/studies2/samples7.png)
+
+---
+# Common Statistical Test for comparison: t-test
+
+Tests for difference between two samples
+
+Best used to determine what is ‘worthy of a second look’
+
+Limited in its applicability to normal, independent data
+
+Does not help to document effect size [the actual difference between groups], just effect likelihood
+
+---
+.left-column[
+## Problems with t-tests
+
+The more implausible the hypothesis, the greater chance that it is a
+‘false alarm’
+]
+.right-column[
+![:img A picture of the likelihood of a positive t-test as influenced by
+priors (the expected likelihood of an outcome), 80%](img/studies2/priors.png)
+
+]
+???
+Top row: Prior (what's known to be true before the experiment)
+bottom row: Calculated p-value
+
+Notice the middle column, where something that is a toss-up has higher
+plausability than we would expect. This is a "Type 1 error"
+
+Alternatively, a small sample may cause a Type II error (failure to
+detect a true difference) due to random sampling bias
+
+---
+.left-column[
+## Problems with t-tests
+]
+.right-column[
+- Doesn’t take prior knowledge into account
+- Susceptible to ‘data dredging’
+ - The more tests you conduct the more likely you will find a result
+   even if one is not there
+ - Adjustments mid experiment
+- Gives a yes or no answer: Either the null hypothesis is rejected (the result would be unlikely in a world where the null hypothesis was true) or it cannot be rejected
+- Based on assumed ‘average’ sample
+]
+---
+# Which problems might affect our study?
+
+???
+Too many comparisons
+--
+
+18 separate comparisons (3x3 conditions, 2 measures)
+
+ANOVA (**An**alysis **O**f **Va**riance): Fancy t-test that accounts for the whole group effect before
+doing pairwise comparisons
+
+???
+- Doesn’t take prior knowledge into account
+- Susceptible to ‘data dredging’
+ - The more tests you conduct the more likely you will find a result
+   even if one is not there
+ - Adjustments mid experiment
+- Gives a yes or no answer: Either the null hypothesis is rejected (the result would be unlikely in a world where the null hypothesis was true) or it cannot be rejected
+- Based on assumed ‘average’ sample
+
+---
+# Demo of t-tests in our spreadsheet
+
+[20sp Sample data](https://docs.google.com/spreadsheets/d/1JqfKhHugIF-kebs_bVztCnkUe0CizXN8PU_Ar3kXtK4/edit?usp=sharing)
+
+---
+.left-column[
+## Document what all of this in your [report]({{site.baseurl}}/assignments/menu-report)
+]
+.right-column[
+
+- Describe your hypothesis
+- Illustrate with graphs
+- Optional: use Table of results found in `Speed Analysis` and `Error Analysis` to describe Statistical Significance:
+
+`Pie menus were twice as fast as normal menus (M=.48s vs M=.83s), F(1,43)=295.891, p<.05. Unclassified menu items were harder to find than linear and relative ones (M=.84s, .59s, and .59s respectively), F(2,43)=93.778, p<0.5. We also found an interaction effect between menu and task (as illustrated in the chart above), F(5, 43) = 51.945, p<.001.`
+
+]
+
+
+---
+# Drawing Conclusions
+
+<div class="mermaid" style="font-size:.5em">
+graph LR
+S(.) --> Hypothesis(Hypothesis:<br>Decreased seek <br>time and errors)
+Hypothesis -- "Study Design" --> Method(3 menus x <br> 3 task conditions )
+Method -- "Run Study" --> Data(Data)
+Data -- "Clean and Prep" --> Analysis(Analysis)
+Analysis --> Conclusions(Conclusions)
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px,font-size:.7em,height:2.5em;
+classDef normalbig fill:#e6f3ff,stroke:#333,stroke-width:2px,font-size:.7em,height:4em;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px,font-size:.7em,height:5em;
+classDef startsmall fill:#d1e0e0,stroke:#333,stroke-width:4px,font-size:.7em,height:2.5em;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:3px;
+linkStyle 1 stroke-width:3px;
+linkStyle 2 stroke-width:3px;
+linkStyle 3 stroke-width:3px;
+linkStyle 4 stroke-width:3px;
+
+class S invisible
+class Hypothesis start
+class Conclusions startsmall
+class Method normalbig
+class Data,Analysis normal
+</div>
+
+- Describe your hypothesis
+- Illustrate with graphs
+- Optional: Statistical Significance
+
+Draw Conclusions
+- Were errors less?
+- Was time faster?
+
+`Describe your conclusions. Do you think we should use pie menus more? What can we conclude from your data?`
+
+
+---
+# Limitations of Laboratory Studies
+
+???
+Simulate real world environments
+- Location and equipment may be unfamiliar to participant [Coyne & Nielsen 2001]
+- Observation may effect performance - “Hawthorne Effect” [Mayo 1933]
+- Participant may become fatigued and not take necessary rest - “Demand Effect” [Orne 1962]
+- Tasks frequently artificial and repetitive, which may bore participants and negatively effect performance
+Studying real world use removes these limitations
+
+--
+
+Simulate real world environments
+- Location and equipment may be unfamiliar to participant [Coyne & Nielsen 2001]
+- Observation may effect performance - “Hawthorne Effect” [Mayo 1933]
+- Participant may become fatigued and not take necessary rest - “Demand Effect” [Orne 1962]
+- Tasks frequently artificial and repetitive, which may bore participants and negatively effect performance
+Studying real world use removes these limitations
diff --git a/slides/wk08/undoSlides.html b/slides/wk08/undoSlides.html
new file mode 100644
index 0000000000000000000000000000000000000000..b70972746a79053d092664fadeed8c7a6bc968f3
--- /dev/null
+++ b/slides/wk08/undoSlides.html
@@ -0,0 +1,541 @@
+---
+layout: presentation
+title: Undo
+description: Why Undo/How Undo/What Undo
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Undo reasoning and implementation
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout: false
+
+[//]: # (Outline Slide)
+# Today's goals
+
+- Introduce need for Undo by reviewing mental models
+- Introduce Undo conceptually
+- Describe Implementation details for assignment
+
+
+---
+.left-column[
+# Review: Every system has at least 3 different models
+]
+
+.right-column[
+<div class="mermaid">
+graph TD
+  S[System Image: <br>Your Implementation&nbsp;] --> |System Feedback&nbsp;| U[User Model: How the user thinks&nbsp; <br>the system works]
+  D[Design Model: How you <br>intend the system to work&nbsp;]-->S
+  U -->|User Feedback&nbsp;| S
+</div>
+
+]
+
+---
+# Relating the Human and the Interaction
+
+
+.left-column-half[
+
+![img: Gym doors with few affordances of where you can open them and whether there is an accessible way to use the doors,10%](img/undo/gym-doors.png)
+
+]
+
+--
+
+.right-column-half[
+![img: Don Norman's Human Action Cycle,10%](img/undo/norman-d-human-action-cycle.png)
+]
+
+.footnote[[Don Norman, When Three World Collide: A model of the Tangible Interaction Process, 2009](https://www.researchgate.net/publication/221332102_When_three_worlds_collide_A_model_of_the_tangible_interaction_process)]
+
+???
+Note to instructors: Need to change image  to mermaid
+
+
+---
+# Relating the Human and the Interaction
+
+
+.left-column-half[
+<br>
+<br>
+
+**Gulf of Execution** is the user's believe in the functions the system _doesn't have_
+  - This is the users 'error' region
+
+**Gulf of Evaluation** is where the user _doesn't realize the system HAS a functionality_.
+]
+
+
+.right-column-half[
+![img: Don Norman's Human Action Cycle,10%](img/undo/norman-d-human-action-cycle.png)
+]
+
+---
+
+# Model of Mental Models
+
+.left-column50[
+![:img A box showing the design (white),100%](img/undo/mental1.png)
+]
+---
+# Model of Mental Models
+
+.left-column50[
+![:img A box showing the design (white) and actual function (blue missing a little bit of the white),100%](img/undo/mental2.png)
+]
+---
+# Model of Mental Models
+
+.left-column50[
+![:img A box showing the design (white) and actual function (blue missing
+a little bit of the white) with a grey circle added in the center
+labeled "Frequently Used (Well understood) Part of System Functionality",100%](img/undo/mental3.png)
+]
+---
+# Model of Mental Models
+
+.left-column50[
+![:img A box showing the design (white) and actual function (blue missing
+a little bit of the white) with a grey circle added in the center
+labeled "Frequently Used (Well understood) Part of System Functionality",100%](img/undo/mental4.png)
+]
+
+---
+# Model of Mental Models
+
+.left-column50[
+![:img A box showing the design (white) and actual function (blue missing
+a little bit of the white) with a grey circle added in the center
+labeled "Frequently Used (Well understood) Part of System
+Functionality" a dark blue cloud labeled "Occasionally Used Part of
+System Functionality" around the user's well understood region,100%](img/undo/mental5.png)
+]
+
+---
+# Model of Mental Models
+
+.left-column50[
+![:img A box showing the design (white) and actual function (blue missing
+a little bit of the white) with a grey circle added in the center
+labeled "Frequently Used (Well understood) Part of System
+Functionality" a dark blue cloud labeled "Occasionally Used Part of
+System Functionality" around the user's well understood region and
+another cloud further out with errors (regions outside the blue system
+box) labeled "Users full model of what the system does",100%](img/undo/mental6.png)
+]
+
+???
+- Where are the gulf of evaluation and gulf of execution in this
+  image?
+- Gulf of execution is the user 'error' region (user requests
+  function the __system DOESNT HAVE__), gulf of
+  evaluation is when the user __doesn't realize the system HAS a
+  functionality__.
+
+- How does undo help the user bridge them?
+
+--
+.right-column50[
+<br>
+<Br>
+**Gulf of Execution** is the user's believe in the functions the system _doesn't have_
+  - This is the users 'error' region
+
+**Gulf of Evaluation** is where the user _doesn't realize the system HAS a functionality_.
+]
+
+---
+# Model of Mental Models
+
+
+.left-column50[
+![:img A box showing the design (white) and actual function (blue missing
+a little bit of the white) with a grey circle added in the center
+labeled "Frequently Used (Well understood) Part of System
+Functionality" a cloud further out with errors (regions outside the blue system
+box) and an arrow pointing from the part they really understand to the part outside
+of the application,100%](img/undo/mental7.png)
+]
+.right-column50[
+What happens when the user does something they think is core but is really not supported?
+]
+
+???
+
+(Undo is needed)
+--
+.right-column50[
+Undo helps with this
+]
+
+---
+class: center, middle, inverse
+
+# How do we support Undo?
+
+---
+layout:false
+
+.left-column-half[
+## Remember this?
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface, 100%](img/undo/callbacks.png)]
+.right-column-half[
+Dispatch Strategies
+- Bottom-first and top-down positional
+- Focus-based
+
+State Machine describes *within-view* response to events
+]
+---
+.left-column-half[
+## Event Dispatch
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface and a do_action() call
+happening below the line in response to a button_pressed(), 100%](img/undo/callbacks2.png)]
+.right-column-half[
+Callbacks handle *application* response to events
+- Update Application Model
+
+]
+
+---
+.left-column-half[
+## Event Dispatch
+
+![:img Picture of interactor hierarchy connected to an interface and a
+dotted line indicating application interface with do_action() replaced
+with an actionListener, 100%](img/undo/callbacks3.png)]
+.right-column-half[
+Callbacks handle *application* response to events
+- Update Application Model
+- Best implemented using custom listeners
+
+]
+---
+# What is `ActionPerformed`?
+`Higher level` input event (`Command` or `Action` object)
+ - Puts some  separation between UI and translation objects
+ - Application (or UI) can ‘listen’ for these events:
+
+Key advantage: interactors don’t need to know who/what got notification
+
+Same basic flow as simple callbacks
+---
+# What should an Action object do?
+`doAction()`
+
+???
+seems like a lot of work when we could just directly do the
+action. Major reason for action objects
+--
+`undoAction()`
+
+???
+What additional information do we need to undo an action?
+
+---
+.left-column[
+## Advantages of an action object
+- can be stored on an undo stack
+- can create a consistent abstraction for reversing an action
+]
+.right-column[
+<div class="mermaid">
+classDiagram
+
+AbstractAction <|.. AbstractReversibleAction
+AbstractReversibleAction <|.. ChangeColorAction
+AbstractReversibleAction <|.. ChangeThicknessAction
+AbstractReversibleAction <|.. AbstractReversibleViewAction
+AbstractReversibleViewAction <|.. StrokeAction
+
+class AbstractAction {
+  doAction()
+}
+
+class AbstractReversibleAction {
+  +boolean done
+  +undoAction
+}
+
+class AbstractReversibleViewAction  {
+  +invalidate
+}
+
+
+</div>
+]
+---
+# Where do we store actions? A stack
+
+.left-column50[
+<div class="mermaid">
+classDiagram
+
+AbstractStackHistory <|.. StackHistory
+class AbstractStackHistory {
+  addAction(AbstractReversibleAction action)
+  undo()
+  redo()
+  canUndo()
+  canRedo()
+}
+
+class StackHistory {
+   +capacity: "Max stack size"
+}
+
+
+</div>
+]
+.right-column50[
+Why a stack?
+]
+
+???
+Consider having some volunteers be actions and have them act it out?
+---
+.left-column[
+## Undo and Redo]
+.right-column[
+1) new action object created and `doAction()` called
+
+2) Undo stack updated
+
+3) new action object created and `doAction()` called
+
+4) Undo stack updated
+
+5) `undo()` invoked
+
+6) Undo stack reduced and Redo stack increased
+
+7) `undo()` invoked
+
+8) Undo stack reduced and Redo stack increased
+]
+???
+draw sequence
+---
+.left-column[
+## Undo and Redo]
+.right-column[
+9) `redo()` invoked
+
+10) Redo stack decreased and Undo stack increased
+
+11) new action object created and `doAction()` called
+
+12) Redo stack cleared and Undo stack stack increased
+]
+---
+.left-column[
+## What if an action can't be undone?]
+.right-column[
+Actions that put system into a totally different context
+
+Clear both `undo` *and* `redo` stacks! Users may hate you]
+???
+example? Saving a file
+---
+.left-column[
+## Implementing `undo()`
+]
+.right-column[
+
+System pops action off undo stack
+
+Calls `undoAction()` method on it
+
+Pushes it on redo stack
+]
+---
+.left-column[
+## Why is `undoAction()` hard?
+]
+.right-column[
+Two ways to implement:
+
+- *Direct Code* (each action object has custom code)
+ - Need parameters of original action
+ - Better store in `doAction()` for later
+ - This is what we will implement
+]
+---
+.left-column[
+## Why is `undoAction()` hard?
+]
+.right-column[
+Two ways to implement:
+
+- *Direct Code* (each action object has custom code)
+- *Change Records* (Keep a record of the “old value” for everything
+changed by the application, then put all those values back to undo)
+ - Like some version control systems
+ - More general
+ - Takes more space
+ - `Action` object records `ChangeRecord` (changes which are abstracted into a
+ common data format)
+ - Application has to provide code to restore from change records
+]
+---
+
+.left-column[
+## Implementing `redo()`
+]
+.right-column[
+
+System pops action off redo stack
+
+Calls `doAction()` method
+
+Pushes it on undo stack
+]
+---
+.left-column[
+## More sophisticated forms of Undo
+]
+.right-column[
+Explicit visualization of steps
+
+Manipulation of action list
+
+Delete actions from the middle, reorder, etc.
+by undoing back to point of change then redoing forward
+
+But note: doAction() must be able to work in new context
+]
+
+---
+.left-column[
+## Flatland: Semantic Undo
+
+![:img Picture of a map with multiple edits including deleting and adding roads,100%](img/undo/flatland-roads.png)
+]
+.right-column[
+![:img Picture of an undo history with a transaction stack that
+represents causality in a timeline, 80%](img/undo/flatland.png)
+]
+.footnote[
+Edwards, W. K. ; Igarashi, T. ; LaMarca, A .; Mynatt, E. D. A temporal model for multi-level undo and redo. UIST 2000, Proceedings of 13th Annual ACM Symposium on User Interface Software and Technology; 2000 November 5-8; San Diego, CA. NY: ACM; 2000; 31-40.
+]
+---
+
+# Discussion of assignment
+
+Android Goals:
+- Be able to understand and modify an existing user interface
+  - Learn about floating action buttons
+  - Implement core data structure for Undo
+
+HCI Goals
+  - Modify and existing app in a consistent fashion
+  - Make your modifications accessible
+  - Make your modifications usable
+  - Use heuristic evaluation to assess an app
+
+---
+# Discussion of assignment
+
+.left-column-half[
+![:youtube Video of assignment, F5FyW3YJ0x4]
+]
+.right-column-half[
+![:youtube Video of assignment, NhUE7GgH-vc]
+]
+---
+
+# Discussion of assignment
+
+.left-column[
+First time you are modifying a fully working program
+
+Lots to explore/understand e.g. FAB buttons)
+]
+--
+.right-column[
+<div class="mermaid">
+graph TD
+M[ReversibleDrawingActivity] --> D[DrawingView]
+M --> FUndo[FAB:Undo]
+M --> FRedo[FAB:Redo]
+M --> FColor[FAB:Color]
+M --> FThick[FAB:Thickness]
+FColor --> Red[Red]
+FColor --> Green[Green]
+FColor --> Blue[Blue]
+FThick --> Thin[Thin]
+FThick --> Med[Med]
+FThick --> Thick[Thick]
+
+
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+
+class M,D,FColor,FThick,Vis start
+class Red,Green,Blue,Thin,Med,Thick,Hid normal
+
+</div>
+]
+
+---
+
+# Discussion of assignment
+
+.left-column[
+DrawingView: Holds strokes
+
+FABs:
+- Green ones are always visible
+- Purple ones are only visible when active
+]
+.right-column[
+<div class="mermaid">
+graph TD
+M[ReversibleDrawingActivity] --> D[DrawingView]
+M --> FUndo[FAB:Undo]
+M --> FRedo[FAB:Redo]
+M --> FColor[FAB:Color]
+M --> FThick[FAB:Thickness]
+FColor --> Red[Red]
+FColor --> Green[Green]
+FColor --> Blue[Blue]
+FThick --> Thin[Thin]
+FThick --> Med[Med]
+FThick --> Thick[Thick]
+
+
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+
+class M,D,FColor,FThick,Vis start
+class Red,Green,Blue,Thin,Med,Thick,Hid normal
+
+</div>
+]
+
+---
+# Code deliverables
+
+There are five parts for the coding part of this assignment:
+- Part 1: Implement `ChangeThicknessAction`
+- Part 2: Implement history
+- Part 3: Add a thickness 0 FAB to the thickness menu
+- Part 4: Integrate colorpicker
+- Part 5: Add a new feature to your app. Make sure it is accessible
+
+Later we will learn how to do a Heuristic Evaluation of the application!
+---
diff --git a/slides/wk09/cse340-guestlecture-6mar20.pdf b/slides/wk09/cse340-guestlecture-6mar20.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..39501853fe68c732f784a87d25cbdac6eb0305de
Binary files /dev/null and b/slides/wk09/cse340-guestlecture-6mar20.pdf differ
diff --git a/slides/wk09/cse340-guestlecture-june5.pdf b/slides/wk09/cse340-guestlecture-june5.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..c9fec37970d9b5a6628e2ac6f1f25f9051d1c6f8
Binary files /dev/null and b/slides/wk09/cse340-guestlecture-june5.pdf differ
diff --git a/slides/wk09/cse340-guestlecture-june5.pptx b/slides/wk09/cse340-guestlecture-june5.pptx
new file mode 100644
index 0000000000000000000000000000000000000000..5aa95362a0a3a4368955c03c44be87556be67560
Binary files /dev/null and b/slides/wk09/cse340-guestlecture-june5.pptx differ
diff --git a/slides/wk09/cse340-guestlecture-mar20.pptx b/slides/wk09/cse340-guestlecture-mar20.pptx
new file mode 100644
index 0000000000000000000000000000000000000000..fbc9c5897ac891f951fe38abb89751e8adee3435
Binary files /dev/null and b/slides/wk09/cse340-guestlecture-mar20.pptx differ
diff --git a/slides/wk09/img/ml/Carat.jpg b/slides/wk09/img/ml/Carat.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..2d065755d3b2be286049076e52bab07548de114c
Binary files /dev/null and b/slides/wk09/img/ml/Carat.jpg differ
diff --git a/slides/wk09/img/ml/aipoly.jpg b/slides/wk09/img/ml/aipoly.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..9dcd75d04cd8002753683644bf253bf79fe62270
Binary files /dev/null and b/slides/wk09/img/ml/aipoly.jpg differ
diff --git a/slides/wk09/img/ml/bias.png b/slides/wk09/img/ml/bias.png
new file mode 100644
index 0000000000000000000000000000000000000000..531eaaacd795fb9587d2d21e8cc58dfff031dbdd
Binary files /dev/null and b/slides/wk09/img/ml/bias.png differ
diff --git a/slides/wk09/img/ml/captioning.png b/slides/wk09/img/ml/captioning.png
new file mode 100644
index 0000000000000000000000000000000000000000..2397234b76fe9605470d62ff287a2de4eb11d945
Binary files /dev/null and b/slides/wk09/img/ml/captioning.png differ
diff --git a/slides/wk09/img/ml/cross-validation.png b/slides/wk09/img/ml/cross-validation.png
new file mode 100644
index 0000000000000000000000000000000000000000..8aaa3c2816b91dc8af0605c35eafd004639ea150
Binary files /dev/null and b/slides/wk09/img/ml/cross-validation.png differ
diff --git a/slides/wk09/img/ml/decisiontree.png b/slides/wk09/img/ml/decisiontree.png
new file mode 100644
index 0000000000000000000000000000000000000000..d70048fd94c67ba4dee4947494266980e412b2d8
Binary files /dev/null and b/slides/wk09/img/ml/decisiontree.png differ
diff --git a/slides/wk09/img/ml/gma.png b/slides/wk09/img/ml/gma.png
new file mode 100644
index 0000000000000000000000000000000000000000..23af5ef8b20de432e227898a9ab4a1009be9ef7e
Binary files /dev/null and b/slides/wk09/img/ml/gma.png differ
diff --git a/slides/wk09/img/ml/google.jpg b/slides/wk09/img/ml/google.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..9ca6ebdcd0269a225d5f26b29cd3172cab0bc0ec
Binary files /dev/null and b/slides/wk09/img/ml/google.jpg differ
diff --git a/slides/wk09/img/ml/imprompdo.jpg b/slides/wk09/img/ml/imprompdo.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f13f4a3d85c7c38638cc6dc19db26a873f91b56a
Binary files /dev/null and b/slides/wk09/img/ml/imprompdo.jpg differ
diff --git a/slides/wk09/img/ml/leafsnap.jpg b/slides/wk09/img/ml/leafsnap.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a2149f1b9c60dd72c85e3444a4a2ede49cadc16e
Binary files /dev/null and b/slides/wk09/img/ml/leafsnap.jpg differ
diff --git a/slides/wk09/img/ml/mixed-initiative.png b/slides/wk09/img/ml/mixed-initiative.png
new file mode 100644
index 0000000000000000000000000000000000000000..10c04f554bac0b6a8878ef0a7542df53f957a7fe
Binary files /dev/null and b/slides/wk09/img/ml/mixed-initiative.png differ
diff --git a/slides/wk09/img/ml/mixed2.png b/slides/wk09/img/ml/mixed2.png
new file mode 100644
index 0000000000000000000000000000000000000000..871799ee6f4b116a68e7c0497555ec085f1d3b0e
Binary files /dev/null and b/slides/wk09/img/ml/mixed2.png differ
diff --git a/slides/wk09/img/ml/mixed3.png b/slides/wk09/img/ml/mixed3.png
new file mode 100644
index 0000000000000000000000000000000000000000..c1eca8c22e65eb1b9dd1ee66dd1a21e958147527
Binary files /dev/null and b/slides/wk09/img/ml/mixed3.png differ
diff --git a/slides/wk09/img/ml/overfitting.png b/slides/wk09/img/ml/overfitting.png
new file mode 100644
index 0000000000000000000000000000000000000000..f2ea67e6880780c274e3412b7f55502e93addeb8
Binary files /dev/null and b/slides/wk09/img/ml/overfitting.png differ
diff --git a/slides/wk09/img/ml/personal.png b/slides/wk09/img/ml/personal.png
new file mode 100644
index 0000000000000000000000000000000000000000..82aa0ec0763dd8ad334e7be7ef83f71320a09d7a
Binary files /dev/null and b/slides/wk09/img/ml/personal.png differ
diff --git a/slides/wk09/img/ml/phone-bed.jpg b/slides/wk09/img/ml/phone-bed.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a423153082a753ab1aa2339bf9a812425e61b313
Binary files /dev/null and b/slides/wk09/img/ml/phone-bed.jpg differ
diff --git a/slides/wk09/img/ml/regression.png b/slides/wk09/img/ml/regression.png
new file mode 100644
index 0000000000000000000000000000000000000000..0eae144ec64759e55fd8b06746ec19badc0a6e94
Binary files /dev/null and b/slides/wk09/img/ml/regression.png differ
diff --git a/slides/wk09/img/ml/sleep.png b/slides/wk09/img/ml/sleep.png
new file mode 100644
index 0000000000000000000000000000000000000000..07a49fdb1c7fc4aefcd1ba7b724119b676406a2b
Binary files /dev/null and b/slides/wk09/img/ml/sleep.png differ
diff --git a/slides/wk09/img/ml/training.png b/slides/wk09/img/ml/training.png
new file mode 100644
index 0000000000000000000000000000000000000000..14ec13e5b4f92746066ac21d64dd9b1b7546abec
Binary files /dev/null and b/slides/wk09/img/ml/training.png differ
diff --git a/slides/wk09/img/ml/wrong.png b/slides/wk09/img/ml/wrong.png
new file mode 100644
index 0000000000000000000000000000000000000000..93a3549c8ba3f42058bdb1a81406047116eede35
Binary files /dev/null and b/slides/wk09/img/ml/wrong.png differ
diff --git a/slides/wk09/img/web/animated-skeleton.gif b/slides/wk09/img/web/animated-skeleton.gif
new file mode 100644
index 0000000000000000000000000000000000000000..366149f29f99f2b3e1d4d54e06c924a311541e9d
Binary files /dev/null and b/slides/wk09/img/web/animated-skeleton.gif differ
diff --git a/slides/wk09/img/web/bones.png b/slides/wk09/img/web/bones.png
new file mode 100644
index 0000000000000000000000000000000000000000..cc36a5c3f74cd446cf3d07c1161312142397b96e
Binary files /dev/null and b/slides/wk09/img/web/bones.png differ
diff --git a/slides/wk09/img/web/chrome-inspector.png b/slides/wk09/img/web/chrome-inspector.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a9aba34636e7d5284d4661e78f990174eaf3e26
Binary files /dev/null and b/slides/wk09/img/web/chrome-inspector.png differ
diff --git a/slides/wk09/img/web/dom.png b/slides/wk09/img/web/dom.png
new file mode 100644
index 0000000000000000000000000000000000000000..3dacc41a64334e458ac2f0ada02bc389d5a51718
Binary files /dev/null and b/slides/wk09/img/web/dom.png differ
diff --git a/slides/wk09/img/web/dressed-skeleton.png b/slides/wk09/img/web/dressed-skeleton.png
new file mode 100644
index 0000000000000000000000000000000000000000..2b18695ab67f05bf90ea1c599dc776a8f5efd726
Binary files /dev/null and b/slides/wk09/img/web/dressed-skeleton.png differ
diff --git a/slides/wk09/img/web/flexbox.png b/slides/wk09/img/web/flexbox.png
new file mode 100644
index 0000000000000000000000000000000000000000..40282210afae036fca7ee7d1fded5d6110b30650
Binary files /dev/null and b/slides/wk09/img/web/flexbox.png differ
diff --git a/slides/wk09/img/web/full-skeleton.png b/slides/wk09/img/web/full-skeleton.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa79f9691d037b698ac6193350f511b9645b9600
Binary files /dev/null and b/slides/wk09/img/web/full-skeleton.png differ
diff --git a/slides/wk09/img/web/spottheheron-android.gif b/slides/wk09/img/web/spottheheron-android.gif
new file mode 100644
index 0000000000000000000000000000000000000000..8cd77214db5c25fd769b05592c908e9040d836f4
Binary files /dev/null and b/slides/wk09/img/web/spottheheron-android.gif differ
diff --git a/slides/wk09/img/web/spottheheron-web.gif b/slides/wk09/img/web/spottheheron-web.gif
new file mode 100644
index 0000000000000000000000000000000000000000..e47b7cc3794bb9c70009e8f46bbb31a43b893330
Binary files /dev/null and b/slides/wk09/img/web/spottheheron-web.gif differ
diff --git a/slides/wk09/img/web/spottheheronscreen.png b/slides/wk09/img/web/spottheheronscreen.png
new file mode 100644
index 0000000000000000000000000000000000000000..95458745f69650794ec867b65ab98cf1eb0747b9
Binary files /dev/null and b/slides/wk09/img/web/spottheheronscreen.png differ
diff --git a/slides/wk09/img/web/viewpagesource.png b/slides/wk09/img/web/viewpagesource.png
new file mode 100644
index 0000000000000000000000000000000000000000..bf7a54811f5104150016f0773e6d07c7b2170880
Binary files /dev/null and b/slides/wk09/img/web/viewpagesource.png differ
diff --git a/slides/wk09/ml.html b/slides/wk09/ml.html
new file mode 100644
index 0000000000000000000000000000000000000000..772a7fbddbb5985f3721fcd2605b3e9d3b196d47
--- /dev/null
+++ b/slides/wk09/ml.html
@@ -0,0 +1,671 @@
+---
+layout: presentation
+title: Using Mobile Phones for Machine Learning
+description: Using Mobile Phones for Machine Learning
+class: middle, center, inve
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Google maps
+
+![![:img google maps,100%](img/ml/google.jpg)](img/ml/google.jpg)
+
+
+.footnote[Picture from [Machine Learning on your Phone](https://www.appypie.com/top-machine-learning-mobile-apps)]
+
+???
+fame/shame
+neighborhood traffic...
+shorter commutes...
+---
+# Machine Learning and your Phone
+
+Jennifer Mankoff
+
+CSE 340 {{site.quarter}}
+
+.footnote[Slides credit: Jason Hong, Carnegie Mellon University
+ [Are my Devices Spying on Me? Living in a World of
+Ubiquitous
+Computing](https://www.slideshare.net/jas0nh0ng/are-my-devices-spying-on-me-living-in-a-world-of-ubiquitous-computing);
+]
+
+---
+layout: false
+
+.left-column[
+## Smartphones are Intimate Fun Facts about Millennials
+
+![:fa thumbs-down] 83% sleep with phones
+]
+.right-column[
+![:img Millenial with phone in bed, 100%](img/ml/phone-bed.jpg)
+]
+---
+.left-column[
+## Smartphones are Intimate Fun Facts about Millennials
+
+![:fa thumbs-down] 83% sleep with phones
+
+![:fa thumbs-down]  90% check first thing in morning
+]
+.right-column[
+![:img Millenial with phone in bed, 100%](img/ml/phone-bed.jpg)
+]
+---
+.left-column[
+## Smartphones are Intimate Fun Facts about Millennials
+
+![:fa thumbs-down] 83% sleep with phones
+
+![:fa thumbs-down] 90% check first thing in morning
+
+![:fa thumbs-down]  1 in 3 use in bathroom
+
+]
+.right-column[
+![:img Millenial with phone in bed, 100%](img/ml/phone-bed.jpg)
+
+]
+---
+# Smartphone Data is Intimate
+
+![:img Picture of smart phone screens with phone numbers; map; and sensor data, 60%](img/ml/personal.png)
+
+| Who we know           | Sensors               | Where we go   |
+|-----------------------|-----------------------|---------------|
+| (contacts + call log) | (accel, sound, light) | (gps, photos) |
+
+---
+# Some useful applications of this data
+
+![:img Picture of LeafSnap app, 60%](img/ml/leafsnap.jpg)
+
+.footnote[[LeafSnap](http://leafsnap.com/) uses computer vision to
+identify trees by their leaves]
+
+---
+# Some useful applications of this data
+
+![:img Picture of Aipoly app, 60%](img/ml/aipoly.jpg)
+
+.footnote[[Vision AI](https://www.aipoly.com/) uses computer vision to
+identify images for the Blind and Visually Impaired]
+
+---
+# Some useful applications of this data
+
+![:img Picture of Carat app, 60%](img/ml/Carat.jpg)
+
+.footnote[[Carat: Collaborative Energy
+Diagnosis](http://carat.cs.helsinki.fi/) uses machine learning to save
+battery life]
+---
+# Some useful applications of this data
+
+![:img Picture of Imprompdo app, 50%](img/ml/imprompdo.jpg)
+
+.footnote[[Imprompdo](http://imprompdo.webflow.io/
+) uses machine learning to recommend activities to do, both fund and todos]
+---
+# How do these systems work?
+
+
+Machine Learning is used to make these kinds of predictions 
+- Machine learning is one area of Artificial Intelligence 
+- This is the kind that’s been getting lots of press 
+
+The goal of machine learning is to develop systems that can improve
+performance with more experience 
+- Can use "example data" as "experience"
+- Uses these examples to discern patterns 
+- And to make predictions
+---
+# Two main approaches
+
+![:fa eye] *Supervised learning* (we have lots of examples of what should be
+ predicted)
+ 
+![:fa eye-slash] *Unsupervised learning* (e.g. clustering into groups and inferring what
+they are about)
+
+![:fa low-vision] Can combine these (semi-supervised)
+
+![:fa history]  Can learn over time or train up front
+
+---
+.left-column[
+## In class exercise
+
+![:fa bed, fa-7x] 
+]
+.right-column[
+How might you recognize sleep?
+
+- What recognition question
+- What sensors
+]
+???
+
+(sleep quality? length?...)
+
+How to interpret sensors?
+
+---
+.left-column[
+## In class exercise
+
+- What recognition question (sleep quality? length?...)
+- What sensors
+- How to interpret sensors?
+]
+.right-column[
+![:img Sleep trace for accelerometer and sound, 80%](img/ml/sleep.png)
+]
+
+---
+# How do we program this?
+
+Write down some rules
+
+Implement them
+
+---
+# ML is a major shift in thinking
+
+Old Approach: Create software by hand
+- Use libraries (like JQuery) and frameworks
+- Create content, do layout, code up functionality
+- Deterministic (code does what you tell it to)
+
+New Approach: Collect data and train algorithms
+- Will still do the above, but will also have some functionality based
+on ML 
+- *Collect lots of examples and train a ML algorithm*
+- *Statistical way of thinking*
+
+---
+# How Machine Learning is Typically Used
+
+Step 1: Gather lots of data (easy on a phone!)
+--
+
+Step 2: Figure out useful features
+- Convert data to information (not knowledge!)
+- (typically) Collect labels
+
+---
+# How Machine Learning is Typically Used
+
+Step 1: Gather lots of data (easy on a phone!)
+
+Step 2: Figure out useful features
+
+Step 3: Select and train the ML algorithm to make a prediction
+- Lots of toolkits for this
+- Lots of algorithms to choose from
+- Mostly treat as a "black box" 
+
+---
+# Example: Decision tree for predicting premature birth
+
+![:img decision tree, 50%](img/ml/decisiontree.png)
+
+
+---
+# Examwple: Deep Learning for Image Captioning
+
+![:img Captioning Images. Note the errors,
+40%](img/ml/captioning.png)
+
+.footnote[[Captioning images. Note the
+errors.](http://cs.stanford.edu/people/karpathy/deepimagesent/) Deep
+learning now
+[available on your phone!](https://www.tensorflow.org/lite)]
+
+???
+Note differences between these: one label vs many
+---
+# Training process
+
+![:img ML Training Process, 60%](img/ml/training.png)
+
+---
+# How Machine Learning is Typically Used
+
+Step 1: Gather lots of data (easy on a phone!)
+
+Step 2: Figure out useful features
+
+Step 3: Select and train the ML algorithm
+
+Step 4: Evaluate metrics (and iterate)
+
+???
+See how well algorithm does using several metrics
+Error analysis: what went wrong and why
+Iterate: get new data, make new features
+---
+# Evaluation Concerns
+
+Accuracy: Might be too error-prone
+
+---
+.left-column[
+## Assessing Accuracy]
+.right-column[
+
+Prior probabilities
+- Probability before any observations (ie just guessing)
+- Ex. ML classifier to guess if a person is male or female based on name
+ - Just assume all names are female (50% will be right)
+- Your trained model needs to do better than prior
+
+Other baseline approaches
+- Cheap and dumb algorithms
+- Ex. Names that end in vowel are female
+- Your model needs to do better than these too
+]
+
+???
+We did this to study gender's impact on academic authorship; doctors reviews
+
+---
+.left-column[
+## Assessing Accuracy]
+
+.right-column[
+Don't just measure accuracy (percent right)
+
+Sometimes we care about *False positives* vs *False negatives*
+]
+---
+.left-column[
+## Assessing Accuracy
+
+## Confusion matrix helps show this]
+
+.right-column[
+
+|             |              | .red[Prediction]     |                      |
+|-------------|--------------|----------------------|----------------------|
+|             |              | **Positive**         | **Negative**         |
+| .red[Label] | **Positive** | True Positive (good) | False Negative (bad) |
+|             | **Negative** | False Positive (bad) | True Negative (good) |
+
+Accuracy is (TP + TN) / (TP + FP + TN + FN)
+
+]
+---
+.left-column[
+## Assessing Accuracy
+
+## Precision
+]
+
+.right-column[
+
+|             |              | .red[Prediction]           |                      |
+|-------------|--------------|----------------------------|----------------------|
+|             |              | **Positive**               | **Negative**         |
+| .red[Label] | **Positive** | .red[True Positive (good)] | False Negative (bad) |
+|             | **Negative** | .ref[False Positive (bad)] | True Negative (good) |
+
+Precision = TP / (TP+FP)
+
+Intuition: Of the positive items, how many right?
+
+]
+
+---
+.left-column[
+## Assessing Accuracy
+
+## Recall
+]
+.right-column[
+
+|        |              | Prediction                 |                            |
+|--------|--------------|----------------------------|----------------------------|
+| Actual |              | **Positive**               | **Negative**               |
+|        | **Positive** | .red[True Positive (good)] | .red[False Negative (bad)] |
+|        | **Negative** | False Positive (bad)       | True Negative (good)       |
+
+Recall = TP / (TP+FN)
+
+Intuition: Of all things that should have been positive, how many actually labeled correctly?
+]
+
+---
+# Evaluation Concerns
+
+Accuracy: Might be too error-prone
+
+Overfitting: Your ML model is too specific for data you have
+- Might not generalize well
+
+![:img overfitting, 40%](img/ml/overfitting.png)
+
+---
+# Avoiding Overfitting
+
+
+To avoid overfitting, typically split data into training set and test set
+
+Train model on training set, and test on test set
+
+Often do this through cross validation
+
+![:img cross validation, 40%](img/ml/cross-validation.png)
+
+
+
+
+---
+# How Machine Learning is Typically Used
+
+Step 1: Gather lots of data (easy on a phone!)
+
+Step 2: Figure out useful features
+
+Step 3: Select and train the ML algorithm
+
+Step 4: Evaluate metrics (and iterate)
+
+Step 5: Deploy
+---
+# What makes this work well?
+
+Typically more data is better
+
+Accurate labels important
+
+Quality of features determines quality of results
+
+.red[*NOT* as sophisticated as the media makes out]
+--
+
+.red[*BUT* can infer all sorts of things]
+---
+# AI / Machine Learning Not As Sophisticated as in Media
+
+
+A lot of people outside of computer science often ascribe human
+behaviors to AI systems 
+- Especially desires and intentions 
+- Works well for sci-fi, but not for today or near future 
+
+These systems only do: 
+- What we program them to do 
+- What they are trained to do (based on the (possibly biased) data) 
+---
+# Concerns
+
+Significant Societal Challenges for Privacy
+---
+.left-column[
+## Wide Range of Privacy Risks]
+.right-column[
+
+| Everyday Risks     | Medium Risk         | Extreme Risks     |
+|--------------------|---------------------|-------------------|
+| Friends, Family    | Employer/Government | Stalkers, Hackers |
+| Over-protection    | Over-monitoring     | Well-being        |
+| Social obligations | Discrimination      | Personal safety   |
+| Embarrassment      | Reputation          | Blackmail         |
+|                    | Civil Liberties     |                   |
+
+- It's not just Big Brother 
+- It-s not just corporations 
+- Privacy is about our relationships with every other individual and
+  organization out there
+  
+]
+---
+# Five Reasons Why Privacy is Hard
+
+### 1 Strong Incentives to for Companies to Collect Data 
+### 2 Low Knowledge, Awareness, Motivation by Devs 
+### 3 Companies Get Little Pushback on Privacy 
+### 4 Unclear What the Right Thing To Do Is 
+### 5 Burden on End-Users is Too High 
+
+???
+- Barriers to collecting data are also really low 
+- More data means better predictive models 
+- Many developers don’t realize how much data their app is collecting (Or that it was collecting data at all)
+ - In one study, over 40% of apps collect data only because of these  libraries
+- Lack of info means privacy does not influence customer purchases. Less than 0.1% of reviews on Google Play mention privacy concerns 
+- Individuals also   have to make too many decisions 
+---
+# Concerns
+
+Significant Societal Challenges for Privacy
+
+Who should have the initiative?
+
+---
+# Mixed-initiative interfaces
+
+Basically, who is in charge?
+- Does person initiate things? Or computer?
+- How much does computer system do on your behalf?
+
+Example: Autonomous vehicles
+- Some people think Tesla autopilot is full autonomous, leads to risky actions
+
+Why initiative matters
+- Potential major shift: instead of direct manipulation, some smarts (intelligent agent) for automation
+---
+.left-column50[
+## Mixed-initiative best practices
+- Significant value-added automation
+- Considering uncertainty
+- Socially appropriate interaction w/ agent
+- Consider cost, benefit, uncertainty
+- Use dialog to resolve uncertainty
+- Support direct invocation and termination
+- Remember recent interactions
+]
+.right-column50[
+
+![:img mixed initiative figure, 100%](img/ml/mixed-initiative.png)
+]
+---
+.left-column50[
+## Mixed-initiative best practices
+- Significant value-added automation
+- Considering uncertainty
+- Socially appropriate interaction w/ agent
+- Consider cost, benefit, uncertainty
+- Use dialog to resolve uncertainty
+- Support direct invocation and termination
+- Remember recent interactions
+]
+.right-column50[
+
+![:img mixed initiative figure, 100%](img/ml/mixed2.png)
+]
+???
+Can see what agent is suggesting, in terms of scheduling a meeting
+
+---
+.left-column50[
+## Mixed-initiative best practices
+- Significant value-added automation
+- Considering uncertainty
+- Socially appropriate interaction w/ agent
+- Consider cost, benefit, uncertainty
+- Use dialog to resolve uncertainty
+- Support direct invocation and termination
+- Remember recent interactions
+]
+.right-column50[
+
+![:img mixed initiative figure, 100%](img/ml/mixed3.png)
+]
+???
+Uses anthropomorphized aganet
+Uses speech for input
+Uses mediation to help resolve conflict
+---
+.left-column[
+## Mixed-initiative best practices
+]
+
+.right-column[
+Built-in cost-benefit model in system
+- If perceived benefit >> cost, then do the action
+- Otherwise wait
+
+Note that this is just one point in design space (1999), and still lots of open questions
+- Ex. Should “intelligence” be anthropomorphized?
+- Ex. How to learn what system can and can’t do?
+- Ex. What kinds of tasks should be automated / not?
+- Ex. What are strategies for showing state of system?
+- Ex. What are strategies for preventing errors?
+]
+---
+
+# Concerns
+
+Significant Societal Challenges for Privacy
+
+Who should have the initiative?
+
+Bias in Machine Learning
+---
+background-image: url(img/ml/gma.png)
+
+
+.quote[Johnson says his jaw dropped when he read one of the reasons American
+Express gave for lowering his credit limit:  
+
+![:fa quote-left] Other customers who have used their card at establishments
+where you recently shopped have a poor repayment history with American
+Express.
+]
+---
+.right-column[
+
+![:img bias figure, 60%](img/ml/bias.png)
+]
+---
+
+# Concerns
+
+Significant Societal Challenges for Privacy
+
+Who should have the initiative?
+
+Bias in Machine Learning
+
+Understanding ML
+---
+# Understanding what is going on: Forming Mental Models
+
+How does a system know I am addressing it?
+
+How do I know a system is attending to me?
+
+When I issue a command/action, how does the system know what it relates to?
+
+How do I know that the system correctly understands my command and correctly executes my intended action?
+
+.footnote[
+Belloti et al., CHI 2002 ‘Making Sense of Sensing’
+]
+---
+# Wrong location-based rec
+
+
+![:img wrong, 60%](img/ml/wrong.png)
+???
+Why did it not tell me about the Museum? How does it determine my location? 
+Providing explana7ons to these ques7ons can make Intelligent systems Intelligible 
+
+other examples: caregiving hours by insurance company, etc
+
+---
+# Types of feedback
+
+Feedback: crucial to user’s understanding of how a system works and helping guide future action 
+- What did the system do?
+- What if I do W, what will the system do? 
+- Why did the system do X?
+- Why did the system not do Y
+- How do I get the system to do Z? 
+---
+# Summary ML and ethics
+
+ML is powerful (but not perfect), often better than heuristics
+
+Basic approach is collect data, train, test, deploy
+
+Hard to understand what algorithms are doing (transparency)
+- ML algorithms just try to optimize, but might end up finding a proxy for race, gender, computer, etc
+- But hard to inspect these algorithms
+- Still a huge open question
+
+Privacy
+- How much data should be collected about people?
+- How to communicate this to people?
+- What kinds of inferences are ok?
+
+---
+# End of deck
+
+---
+.left-column[
+## Regression
+
+![:img Example of regression, 100%](img/ml/regression.png)
+]
+.right-column[
+Predicting a *continuous value* based on inputs
+- Ex. House price based on #rooms, #bathrooms, etc
+- Ex. #views based on page content
+
+Simple example: linear regression
+- Same as in statistics
+- Seeks to minimize errorin predictions
+
+Lots of algorithms
+- See Wikipedia
+]
+
+---
+
+.left-column[
+## Example classification algorithms]
+.right-column[
+Naïve Bayes (probabilities)
+
+Neural Networks / Deep Learning (human brain)
+
+**Decision Tree (workflow)**
+
+Support Vector Machine (analogy / similarity)
+
+]
+
+---
+.left-column[
+## Classification
+]
+.right-column[
+Predicting from a *set of categories*
+- Ex. {Spam, Ham}?
+- Ex. {Chalupa, Taco, Burrito}?
+
+Lots of variants
+- Multi-class (the examples above)
+- One-class (identifies all objects in that class)
+- Multi-label (it’s both a Chalupa and a Burrito)
+
+Also lots of algorithms
+- See Wikipedia
+]
+
diff --git a/slides/wk09/web.html b/slides/wk09/web.html
new file mode 100644
index 0000000000000000000000000000000000000000..f1b9ad651bf758d2e98857cc036b0c847a506743
--- /dev/null
+++ b/slides/wk09/web.html
@@ -0,0 +1,337 @@
+---
+layout: presentation
+title: Web Programming
+description: Interaction Programming in Web Development
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Interaction Programming in Web Development
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout: false
+
+[//]: # (Outline Slide)
+# Today's goals
+
+- Interaction Programming in Web Development
+  - Crash course on Web Programming
+  - Spot The Heron: web version
+
+---
+# Spot The Heron review
+
+Code for the [Spot The Heron](https://gitlab.cs.washington.edu/cse340-20sp-students/cse340-spottheheron) case study.
+- Layout was achieved with high level tool which generated XML
+- Images were stored in the "drawable" directory
+- When app started the `AppCompatActivity#onCreate(Bundle savedInstanceState)` was called. This method:
+  - Set the app to use the XML defined layout
+  - Initialized some variables
+  - Registered callbacks for the three buttons - previous, slideshow, and next
+  - Used the `loadImage(int image)` to load the first image (0th index) in the list of file names
+- The `loadImage(int image)` method
+  - Got a handle on the image view interactor using an id `findViewById(R.id.heronView)`
+  - Set the image view's source to be the new image.
+  - Set the content description of the image view to be in line with the new image.
+- If the previous or next button was pressed, the `switchImage(boolean forward)` method is called.
+- If the slideshow button was pressed, a timer would start that changes the image every 1500 ms
+
+---
+# Spot The Heron Comparison
+
+|Android Version | Web Version |
+| :--: | :--: |
+|![:img Spot The Heron Android Version, 32%](img/web/spottheheron-android.gif)|![:img Spot the Heron Web Version, 35%](img/web/spottheheron-web.gif)|
+
+---
+# Interlude: What is a web page really?
+
+| Content | Structure | Style | Behavior |
+| :--: | :--: | :--: | :--: |
+|![:img bones, 20%](img/web/bones.png)|
+| Words and Images | HTML | CSS | JavaScript |
+
+---
+# Interlude: What is a web page really?
+
+| Content | Structure | Style | Behavior |
+| :--: | :--: | :--: | :--: |
+|![:img bones, 40%](img/web/bones.png)|![:img Skeleton, 40%](img/web/full-skeleton.png)|
+| Words and Images | HTML | CSS | JavaScript |
+
+---
+# Interlude: What is a web page really?
+
+| Content | Structure | Style | Behavior |
+| :--: | :--: | :--: | :--: |
+|![:img bones, 50%](img/web/bones.png)|![:img Skeleton, 50%](img/web/full-skeleton.png)|![:img Boundless Skeleton, 50%](img/web/dressed-skeleton.png)|
+| Words and Images | HTML | CSS | JavaScript |
+
+
+---
+# Interlude: What is a web page really?
+
+| Content | Structure | Style | Behavior |
+| :--: | :--: | :--: | :--: |
+|![:img bones, 60%](img/web/bones.png)|![:img Skeleton, 60%](img/web/full-skeleton.png)|![:img Boundless Skeleton, 60%](img/web/dressed-skeleton.png)|![:img Animated Boundless Skeleton, 60%](img/web/animated-skeleton.gif)|
+| Words and Images | HTML | CSS | JavaScript |
+
+---
+# Vocabulary
+
+- **Internet** - Hardware infrastructure of connected computers and wires
+- **World Wide Web (WWW) (http)** - The information on the Internet made up of files and folders stored on computers
+- **Hyper Text Markup Language (HTML), Cascading Style Sheets (CSS), & JavaScript (JS)** - The languages that we use to program our webpages
+- **Web Browser** An application (Chrome, Netscape, Safari) that interprets our web languages and renders it visually
+
+---
+# Languages
+
+Java != JavaScript
+
+| Java | JavaScript | HTML/CSS |
+| -- | -- | -- |  |
+| Compiled &nbsp;&nbsp;  | Interpreted  | Rendered Data |
+| Type safe | Not type safe &nbsp;&nbsp;  | N/A |
+
+---
+# Lifecycle of a browser* loading a page
+
+1. Fetch the page
+2. Parse the page
+3. Build up an internal representation of the web page
+4. Display the page
+
+.footnote[*: As seen by Chrome]
+
+---
+# Fetch the Page
+
+1. Connect to the **Internet** and ask for the URL
+2. As a **DNS** (Domain name service) to find the machine with the appropriate resources
+3. Ask the machine with the resources for the web page with a **GET request**
+4. Transfer file(s) the internet using the **TCP/IP** protocol back to your machine.
+
+---
+.left-column[# View Page Source
+
+[Spot The Heron Solution](webpages/spottheheron-solution.html)
+]
+
+.right-column[
+![:img Viewing the page source for the spot the heron app, 90%](img/web/viewpagesource.png)
+]
+
+
+---
+# Parse and Display the Page
+
+.left-column[
+![:img Initial screen for the spot the heron app, 90%](img/web/spottheheronscreen.png)
+
+]
+
+.right-column[
+1. First line: <!DOCTYPE html>
+   -  Ok: need to build an internal representation of the page
+2. Line-by-line, go through the HTML
+   - If one of the tags links to a cascading style sheet (CSS) file, load and parse it
+   - If one of the tags links to Javascript (JS) for behavior, load and parse it
+3. FINALLY display the page…
+]
+
+---
+# Hypertext Markup Language (HTML)
+
+- A subset of XML
+- Keywords that are surrounded by the ‘<‘ and ‘>’ (“alligators”) are Tags
+- Tags label the structure of parts of your web page
+  - You put the associated content within the tags
+- There are two types of tags
+  - Open and closing pairs
+    - Ex: <body>This is some text for my body</body>
+    - Most content tags will be of this type
+  - Self-closing tags
+    - `<img />`, `<hr />`, `<br />`, `<link />`
+- Every tag must be a pair or self-closing!
+- Tags can be nested!
+
+
+---
+# Basic HTML Skeleton
+
+```html
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title></title>
+  </head>
+  <body>
+
+  </body>
+</html>
+```
+
+
+---
+# Adding content
+
+- There are 100s of tags! See [Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/HTML/Element)!
+- Some simple tags include
+  - Title `<title></title>` (which nests inside your `<head></head>`)
+  - Headings `<h1></h1>` .. `<h6></h6>`
+  - Paragraphs `<p>`
+  - Ordered or unordered lists: `<ol></ol>`, `<ul></ul>`, with list elements `<li></li>`
+  - Horizontal rules `<hr />`
+  - Strong `<strong></strong>` which defaults to a bold style and emphasis `<em></em>` which defaults to italicized in most browsers.
+- Some tags add semantic context
+  - `<header></header>`: The header or banner that displays the title of the page
+  - `<main></main>`: The bulk of the content of the page
+  - `<footer></footer>`: The footer is optional but you can put contact info and copyright date in there.
+- Some tags need additional information, added to a tag with attributes
+  - Links to other pages `&lt;a href="filename"&gt;&lt;/a&gt;`
+  - Links to other pages `<img src="img.jpg" alt="Description!"/>`
+- Some tags (comments) are important for documentation `<!-- -->`
+
+
+
+---
+# Document Object Model (DOM)
+
+.left-column[
+![:img DOM Example](img/web/dom.png)
+
+]
+
+.right-column[
+- This builds a hierarchy of document elements in what we call the **Document Object Model**
+- Looks very much like the Android Interactor Hierarchy
+
+
+]
+
+---
+# Cascading Style Sheets (CSS)
+
+- Allows us to change the look and feel of the content on the page
+- Style is separated into a .css file
+  - Makes styling multiple pages easier
+  - Allows changing multiple pages easier
+- Style sheets must be linked to an html page in the <head> for the styles to work
+     `&lt;link href=“style.css” rel=“stylesheet” /&gt;`
+- Great example is [CSS Zen Garden](http://www.csszengarden.com/)
+
+---
+# CSS
+
+.left-column[
+- Files consist of one or more rule sets
+- Each rule set has a selector which chooses which HTML elements you want to style
+- Style properties are set with rules which are  property/value pairs
+- Syntax is important
+- More on [CSS](https://developer.mozilla.org/en-US/docs/Web/CSS)
+
+]
+
+.right-column[
+![:img CSS rules description](https://code.makery.ch/library/html-css/part3/css-rule.png)
+
+From [W3Schools](https://code.makery.ch/library/html-css/part3/)
+]
+
+---
+# Layout in CSS
+
+Layout can be [complicated](https://www.amazon.com/CSS-Awesome-Mug-Programmer-Developer/dp/B06Y13QC8N),
+fortunately there is CSS [Flexbox](https://courses.cs.washington.edu/courses/cse154/flexboxducky/) or Grid!!
+
+![:img Sample screen from flexbox ducky game, 50%](img/web/flexbox.png)
+
+
+---
+# Spot The Heron Conversion
+.left-column[
+Mind blowing demo time!
+]
+
+.right-column[
+![:img Goole chrome with the pet gallery loaded on the left and the element view on the right, 80%](img/web/chrome-inspector.png)
+]
+
+---
+# Some Comparisons
+
+| Android | Web |
+| --- | --- |
+| Java | HTML/CSS/JS |
+| Layouts | CSS Flexbox or Grid |
+| Interactor Hierarchy   | Document Object Model (DOM) |
+| Content Description | alt text |
+| Paint objects on a canvas | CSS |
+| `onCreate`   | `window.addEventListener("load", init);` |
+| `View.OnClickListener#onClick`   | `domElement.addEventListener("click", callback);` |
+
+---
+# The Application Stack for Devices - Review
+.left-column[.font-smaller[
+<div class="mermaid">
+  graph LR
+  ap[Application Program]
+  hlt[High Level Tools]
+  t[Toolkit]
+  w[Window System]
+  o[OS]
+  h[Hardware]
+
+class ap,w,o,h yellow
+class hlt,t green
+
+</div>
+]]
+
+.right-column[
+- **Application Program** - An application designed for an end user to perform specific tasks.
+- **High Level Tools** - Graphical interfaces that that let you specify parts of your interface (such as layout). Subject to Worfian Effects
+- **Toolkit** - A set of libraries and tools you use to develop applications.
+- **Window System** - Manages window size and visibility across applications
+- **OS** - The operating system that is running on the device, providing system services such as acceess to displays, input devices, file I/O
+- **Hardware** - The device that is running software, such as an Android Phone
+
+High level tools and the the Toolkit are generally packaged as part of a toolkit but really should be thought of as separate things. (You can program the toolkit without the tools. )
+]
+---
+# The Application Stack for Web Programming
+.left-column[.font-smaller[
+<div class="mermaid">
+  graph LR
+  ap[Application Program]
+  hlt[High Level Tools]
+  t[Toolkit]
+  w[Window System]
+  o[OS]
+  h[Hardware]
+
+class ap,w,o,h yellow
+class hlt,t green
+
+</div>
+]]
+
+.right-column[
+- **Application Program** - A web page
+- **High Level Tools** - Dream Weaver, Adobe XD, Google Web Designer, etc
+- **Toolkit** - HTML/CSS/JavaScript, jQuery, React, etc. Browser tools.
+- **Window System** - Browser running in a Windowing system.
+- **OS** - The web browser itself? Or the browser and the OS combined?
+- **Hardware** - The device that is running OS and browser, such as a Mac, PC or Phone.
+
+You can do web programming with a notepad editor and a browser, nothing more.
+]
+---
+# End of Deck
diff --git a/slides/wk09/webpages/img/after.svg b/slides/wk09/webpages/img/after.svg
new file mode 100644
index 0000000000000000000000000000000000000000..ec2fa420965037676613a51722eeb6d321a0c630
--- /dev/null
+++ b/slides/wk09/webpages/img/after.svg
@@ -0,0 +1,13 @@
+<svg
+    xmlns="http://www.w3.org/2000/svg"
+    viewBox="0 0 24 24"
+    id="vector">
+    <path
+        id="path"
+        d="M 10 6 L 8.59 7.41 L 13.17 12 L 8.59 16.59 L 10 18 L 16 12 Z"
+        fill="#000000"/>
+    <path
+        id="path_1"
+        d="M 0 0 L 24 0 L 24 24 L 0 24 Z"
+        fill="none"/>
+</svg>
diff --git a/slides/wk09/webpages/img/before.svg b/slides/wk09/webpages/img/before.svg
new file mode 100644
index 0000000000000000000000000000000000000000..fb07fa0cf6f2d3392cdb144a64311b7c87e0e5cc
--- /dev/null
+++ b/slides/wk09/webpages/img/before.svg
@@ -0,0 +1,13 @@
+<svg
+    xmlns="http://www.w3.org/2000/svg"
+    viewBox="0 0 24 24"
+    id="vector">
+    <path
+        id="path"
+        d="M 15.41 7.41 L 14 6 L 8 12 L 14 18 L 15.41 16.59 L 10.83 12 Z"
+        fill="#000000"/>
+    <path
+        id="path_1"
+        d="M 0 0 L 24 0 L 24 24 L 0 24 Z"
+        fill="none"/>
+</svg>
diff --git a/slides/wk09/webpages/img/cold.jpg b/slides/wk09/webpages/img/cold.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..9b13846a9d5450f4b1cae09f1282440dfcac9b71
Binary files /dev/null and b/slides/wk09/webpages/img/cold.jpg differ
diff --git a/slides/wk09/webpages/img/dontcare.jpg b/slides/wk09/webpages/img/dontcare.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7a0cdf895ad662528c4aafe1019e4dfd3659a982
Binary files /dev/null and b/slides/wk09/webpages/img/dontcare.jpg differ
diff --git a/slides/wk09/webpages/img/fishing.jpg b/slides/wk09/webpages/img/fishing.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a7dfe9604be5f6275fba6782f1c3b5e8476e9615
Binary files /dev/null and b/slides/wk09/webpages/img/fishing.jpg differ
diff --git a/slides/wk09/webpages/img/flying.jpg b/slides/wk09/webpages/img/flying.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..e92fe38845efa6affa4ade9b96479488e3fc12c3
Binary files /dev/null and b/slides/wk09/webpages/img/flying.jpg differ
diff --git a/slides/wk09/webpages/img/gru.jpg b/slides/wk09/webpages/img/gru.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..0d1372fe6cdebfea639355a7d57158372cff3b31
Binary files /dev/null and b/slides/wk09/webpages/img/gru.jpg differ
diff --git a/slides/wk09/webpages/img/hidden.jpg b/slides/wk09/webpages/img/hidden.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..0fd03f0b2224951780af489ae16e8d25a54895ac
Binary files /dev/null and b/slides/wk09/webpages/img/hidden.jpg differ
diff --git a/slides/wk09/webpages/img/ic_navigate_next.xml b/slides/wk09/webpages/img/ic_navigate_next.xml
new file mode 100644
index 0000000000000000000000000000000000000000..932261b4e108eaa248b3a65ab554e36c3aa640ef
--- /dev/null
+++ b/slides/wk09/webpages/img/ic_navigate_next.xml
@@ -0,0 +1,13 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+   <path
+        android:fillColor="#000000"
+        android:pathData="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/>
+    <path
+        android:pathData="M0 0h24v24H0z"
+        />
+</vector>
\ No newline at end of file
diff --git a/slides/wk09/webpages/img/ic_slideshow.xml b/slides/wk09/webpages/img/ic_slideshow.xml
new file mode 100644
index 0000000000000000000000000000000000000000..47e37eb4105558fd5cc0b1226853fd7cd2be44f4
--- /dev/null
+++ b/slides/wk09/webpages/img/ic_slideshow.xml
@@ -0,0 +1,13 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:aapt="http://schemas.android.com/aapt"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:fillColor="#000000"
+        d="M0 0h24v24H0z" />
+    <path
+        android:fillColor="#000000"
+        android:pathData="M10 8v8l5-4-5-4zm9-5H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V5h14v14z"/>
+</vector>
\ No newline at end of file
diff --git a/slides/wk09/webpages/img/log.jpg b/slides/wk09/webpages/img/log.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f68258248cd9496190a27722af1b4ec1efae5b8a
Binary files /dev/null and b/slides/wk09/webpages/img/log.jpg differ
diff --git a/slides/wk09/webpages/img/lonely.jpg b/slides/wk09/webpages/img/lonely.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7b0c82a3d832979bfda248b5563f5bf1eb78d24c
Binary files /dev/null and b/slides/wk09/webpages/img/lonely.jpg differ
diff --git a/slides/wk09/webpages/img/reeds.jpg b/slides/wk09/webpages/img/reeds.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..6b11581e06ddddebda2dcc506bc141bcca2a55e3
Binary files /dev/null and b/slides/wk09/webpages/img/reeds.jpg differ
diff --git a/slides/wk09/webpages/img/reflection.jpg b/slides/wk09/webpages/img/reflection.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..18ded76e174597bf106d016612373a34e919c9c1
Binary files /dev/null and b/slides/wk09/webpages/img/reflection.jpg differ
diff --git a/slides/wk09/webpages/img/slideshow.svg b/slides/wk09/webpages/img/slideshow.svg
new file mode 100644
index 0000000000000000000000000000000000000000..d187b03ac8f66c779b8fed1f892f4955ffdd0cab
--- /dev/null
+++ b/slides/wk09/webpages/img/slideshow.svg
@@ -0,0 +1,9 @@
+<svg
+    xmlns="http://www.w3.org/2000/svg"
+    viewBox="0 0 24 24"
+    id="vector">
+    <path
+        id="path_1"
+        d="M 10 8 L 10 16 L 15 12 L 10 8 Z M 19 3 L 5 3 C 3.9 3 3 3.9 3 5 L 3 19 C 3 20.1 3.9 21 5 21 L 19 21 C 20.1 21 21 20.1 21 19 L 21 5 C 21 3.9 20.1 3 19 3 Z M 19 19 L 5 19 L 5 5 L 19 5 L 19 19 Z"
+        fill="#000000"/>
+</svg>
diff --git a/slides/wk09/webpages/img/sunrise.jpg b/slides/wk09/webpages/img/sunrise.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d1b3e5f482a4e88c9de234695fe7eef91c0f73f6
Binary files /dev/null and b/slides/wk09/webpages/img/sunrise.jpg differ
diff --git a/slides/wk09/webpages/img/treebird.jpg b/slides/wk09/webpages/img/treebird.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..582e5d677d4da1b9b5846f7d8be2b7b5bc03fa3f
Binary files /dev/null and b/slides/wk09/webpages/img/treebird.jpg differ
diff --git a/slides/wk09/webpages/img/wading.jpg b/slides/wk09/webpages/img/wading.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..38198c303fe104efa44a10059419b43129e7c54a
Binary files /dev/null and b/slides/wk09/webpages/img/wading.jpg differ
diff --git a/slides/wk09/webpages/spottheheron-solution.html b/slides/wk09/webpages/spottheheron-solution.html
new file mode 100644
index 0000000000000000000000000000000000000000..7206ed583167fa1319d332d16419892f665c3e7f
--- /dev/null
+++ b/slides/wk09/webpages/spottheheron-solution.html
@@ -0,0 +1,25 @@
+<!--
+  Lauren Bricker
+   Interaction Programming in Web Programming Lecture
+  Spot the Heron as a web page
+-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Spot the Heron</title>
+    <link rel="stylesheet" href="spottheheron.css">
+    <!-- <script src="spottheheron.js"></script> -->
+    <script src="spottheheron-solution.js"></script>
+  </head>
+  <body>
+    <section>
+      <h1>Spot The Heron</h1>
+      <img id="heron-pic" src="img/cold.jpg" alt="A very cold heron">
+      <div>
+        <button id="prev-btn"><img src="img/before.svg" alt="Go to previous pet"></button>
+        <button id="play-btn"><img src="img/slideshow.svg" alt="Run slideshow"></button>
+        <button id="next-btn"><img src="img/after.svg" alt="Go to next pet"></button>
+      </div>
+    </section>
+  </body>
+</html>
diff --git a/slides/wk09/webpages/spottheheron-solution.js b/slides/wk09/webpages/spottheheron-solution.js
new file mode 100644
index 0000000000000000000000000000000000000000..607fab3619e6c456267d3e01155025ae22eb6c41
--- /dev/null
+++ b/slides/wk09/webpages/spottheheron-solution.js
@@ -0,0 +1,107 @@
+/*
+  Lauren Bricker
+  Interaction Programming in Web Programming Lecture
+  Spot the Heron as a web page
+  Javascript to add the behavior to the static web page.
+*/
+
+"use strict";
+(function() {
+
+  /** List of images in the img directory */
+  let images = ["cold", "dontcare", "fishing", "flying",
+            "gru", "hidden", "log", "lonely", "reeds", "reflection", "sunrise",
+            "treebird", "wading"];
+
+  /** Index of currently selected Image */
+  let whichImage;
+
+
+  /** Whether we're in the slideshow or not */
+  let inSlideshow = false;
+
+  /** How many seconds between flipping images in the image view */
+  const SLIDESHOW_TIME = 1500;
+
+  let timer = null;
+
+  window.addEventListener("load", init);
+
+  // Note: This function is called as soon as the window is loaded (and the browser
+  // has created the HTML DOM for the page)
+  function init() {
+    // Add event listeners for clicking the #prev-btn, #next-btn, and #play-btn.
+    id("prev-btn").addEventListener("click", function() {switchImage(false);} );
+    id("next-btn").addEventListener("click", function() {switchImage(true);} );
+    id("play-btn").addEventListener("click", doSlideshow);
+    inSlideshow = false;
+    whichImage = 0;
+    loadImage(whichImage);
+  }
+
+  // Callback to handle the slideshow button
+  function doSlideshow () {
+      if (!inSlideshow) {
+          //sets image to flip in SLIDESHOW_TIME ms.
+          timer = setInterval(intervalImage, SLIDESHOW_TIME);
+      }
+      else {
+          //turns off auto flipping
+          clearInterval(timer);
+          timer = null;
+      }
+      inSlideshow = !inSlideshow;
+  }
+
+
+  // Add the rest of the functions here!
+  /** Method to load an image from the images array into the heronView ImageView interactor
+   *
+   * @param img the number of the image to load, assumes 0 <= img < images.length
+   */
+  function loadImage(img) {
+      let heronView = id("heron-pic");
+      heronView.src = "img/" + images[img] + ".jpg";
+      heronView.alt = images[img];
+  }
+
+  /** Method to move onto the next or previous image, depending on the flag passed in
+   *
+   * @param forward true if you are to go to the next image, false if not.
+   */
+  function switchImage(forward) {
+      if (forward) {
+          if (whichImage == images.length - 1)
+              whichImage = 0;
+          else
+              whichImage++;
+      }
+      else {
+          if (whichImage == 0)
+              whichImage = images.length - 1;
+          else
+              whichImage--;
+      }
+      loadImage(whichImage);
+  }
+
+  /** Method to keep flipping the images.
+    *
+    */
+  function intervalImage() {
+    // Switches image
+    switchImage(true);
+
+  }
+
+  /** -------------------------- Helper functions -------------------------- */
+  /**
+   * Returns the element that has the ID attribute with the specified value.
+   * @param {string} idName - element ID
+   * @returns {object} DOM object associated with id.
+   */
+  function id(idName) {
+    return document.getElementById(idName);
+  }
+
+})();
diff --git a/slides/wk09/webpages/spottheheron.css b/slides/wk09/webpages/spottheheron.css
new file mode 100644
index 0000000000000000000000000000000000000000..5f83d96865f934651ac9933e9283917ddd970148
--- /dev/null
+++ b/slides/wk09/webpages/spottheheron.css
@@ -0,0 +1,56 @@
+/*
+  Lauren Bricker
+   Interaction Programming in Web Programming Lecture
+  Spot the Heron as a web page
+  Styles to make the Spot the Heron app look purty.
+*/
+
+body {
+  /* simulating the screen size */
+  width: 540px;
+  height: 960px;
+  border-radius: 10px;
+  border: 2px solid black;
+  margin: 1em auto 0 auto;
+}
+
+
+section {
+  margin: 1.5em;
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-start;
+  height: 95%;
+}
+
+h1 {
+  background-color: #c0FFEE;
+  font-size: 2em;
+  color: #303F9F;
+  text-align: center;
+  font-weight: bold;
+  font-family: roboto, sans-serif;
+  margin: 0;
+  padding: .1em;
+  margin-bottom: .8em;
+}
+
+img {
+  margin: 0;
+}
+
+div {
+  display: flex;
+  justify-content: space-between;
+  margin-top: auto;
+  margin-bottom:
+}
+
+button {
+  height: 100px;
+  width: 100px;
+  text-align: center;
+  vertical-align: center;
+  border: 0;
+  padding: 0;
+}
diff --git a/slides/wk09/webpages/spottheheron.html b/slides/wk09/webpages/spottheheron.html
new file mode 100644
index 0000000000000000000000000000000000000000..1dd9ba0d63f24b04eae09ed79b958c4e22b95e33
--- /dev/null
+++ b/slides/wk09/webpages/spottheheron.html
@@ -0,0 +1,22 @@
+<!--
+  Lauren Bricker
+   Interaction Programming in Web Programming Lecture
+  Spot the Heron as a web page
+-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Spot the Heron</title>
+  </head>
+  <body>
+    <section>
+      <h1>Spot The Heron</h1>
+      <img id="heron-pic" src="img/cold.jpg" alt="A very cold heron">
+      <div>
+        <button id="prev-btn"><img src="img/before.svg" alt="Go to previous pet"></button>
+        <button id="play-btn"><img src="img/slideshow.svg" alt="Run slideshow"></button>
+        <button id="next-btn"><img src="img/after.svg" alt="Go to next pet"></button>
+      </div>
+    </section>
+  </body>
+</html>
diff --git a/slides/wk09/webpages/spottheheron.js b/slides/wk09/webpages/spottheheron.js
new file mode 100644
index 0000000000000000000000000000000000000000..fe18db8747228e56ce1a333372956dc967e3a968
--- /dev/null
+++ b/slides/wk09/webpages/spottheheron.js
@@ -0,0 +1,33 @@
+/*
+  Lauren Bricker
+  Interaction Programming in Web Programming Lecture
+  Spot the Heron as a web page
+  Javascript to add the behavior to the static web page.
+*/
+
+"use strict";
+(function() {
+
+  window.addEventListener("load", init);
+
+  // Note: This function is called as soon as the window is loaded (and the browser
+  // has created the HTML DOM for the page)
+  function init() {
+    // Add event listeners for clicking the #prev-btn, #next-btn, and $play-btn.
+  }
+
+  // Add the rest of the functions here!
+
+
+
+  /** -------------------------- Helper functions -------------------------- */
+  /**
+   * Returns the element that has the ID attribute with the specified value.
+   * @param {string} idName - element ID
+   * @returns {object} DOM object associated with id.
+   */
+  function id(idName) {
+    return document.getElementById(idName);
+  }
+
+})();
diff --git a/slides/wk10/final.html b/slides/wk10/final.html
new file mode 100644
index 0000000000000000000000000000000000000000..9d263d283d741332158ac48bac06ce280de83920
--- /dev/null
+++ b/slides/wk10/final.html
@@ -0,0 +1,446 @@
+---
+layout: presentation
+title: Final Exam Review
+description: Final Exam Review
+class: middle, center, inverse
+---
+name: inverse
+layout: true
+class: center, middle, inverse
+---
+# Final Exam Review
+
+Jennifer Mankoff
+
+CSE 340 Spring 2019 
+
+---
+layout: false
+
+.title[Plan for Final (Monday 8:30-10)]
+.body[
+Will cover material from whole course
+
+Emphasis on second half
+
+Same basic structure, more questions
+- Long answer questions
+- Short answer questions
+- Coding questions
+- 'Cheat Sheet' allowed (2 sided, hand written)
+
+Nothing on sustainability; augmented reality
+
+
+]
+---
+.title[Subjective exam question advice]
+.body[
+Study by synthesizing and summarizing material
+
+An adequate answer can get you around 85%
+Ex:
+Human eyes have cones that can see red green and blue. Yellow is just
+a mix of these. 
+
+A complete, deeper answer can get you an A 
+Ex:
+Our eyes can only detect red, green and blue wavelengths of light
+(with cones) and greyscale (with rods). They see color as a
+combination of these wavelengths. Thus, displaying “true” yellow
+pixels won’t make a difference since our eyes will see them as a
+combination of red and green anyway. 
+
+
+When writing: Aim to stay within 10% of suggested length, make a point
+and then provide support for it. A verbose answer may get you back to
+B (if redundant or wrong)  
+
+
+Show your work extra important 
+]
+
+---
+.title[Core concepts from first half]
+.body[
+
+Input
+- Input models (events)
+- Event dispatch
+- Event handling (PPS) likely coding problem
+- Callbacks to application likely coding problem
+
+Output
+- Interactor Hierarchy design & use
+- Drawing models (`onDraw()`) likely coding problem
+- Layout (`onLayout()` or `XML`) likely coding problem
+- Damage and redraw process
+]
+---
+.title[And Introduced Model View Controller]
+.body[
+Model
+- Model of a single interactor: Typically a field
+- Application model
+ - Separate from view model
+- Typically more persistent (e.g., saved with bundler)
+
+View
+- `onDraw()` in a single interactor
+- Interactor hierarchy in an application
+
+Controller
+- PPS in a single interactor
+- callbacks (e.g., custom listeners) in an application
+]
+---
+.left-column50[
+## 2D Drawing -> 3D modeling
+
+Same core concepts
+
+Now in OpenSCAD
+
+Key ideas:
+- 3D
+ - `cube (size)`
+ - `cylinder (h, r|d, center)`
+ - `polyhedron (points, triangles, convexity)`
+ - `sphere (radius | d=diameter)`
+ ]
+ 
+.right-column50[
+## Similar Transformations
+
+- Transformations
+ - `translate ([x, y, z])`
+ - `rotate ([x, y, z])`
+ - `scale ([x, y, z])`
+ - `resize ([x, y, z], auto)`
+- Boolean operations
+ - `union()`
+ - `difference()` (subtract second from first)
+ - `intersection()`
+]
+
+???
+Limitations of 3D printing?
+
+cost for large scale manufacturing
+
+
+---
+.title[Studies]
+
+.body[
+
+<div class="mermaid">
+graph LR
+S((.)) --> Hypothesis((Hypothesis:<br>Decreased seek <br>time and errors))
+Hypothesis -- "Study Design" --> Method((2 menu x <br> 3 task conditions ))
+Method -- "Run Study" --> Data((Consent<br>Consistency))
+Data -- "Clean and Prep" --> Analysis((Clean<br>Compute))
+Analysis --> Conclusions((Conclusions))
+
+classDef finish outline-style:double,fill:#d1e0e0,stroke:#333,stroke-width:2px;
+classDef normal fill:#e6f3ff,stroke:#333,stroke-width:2px;
+classDef start fill:#d1e0e0,stroke:#333,stroke-width:4px;
+classDef invisible fill:#FFFFFF,stroke:#FFFFFF,color:#FFFFFF
+
+linkStyle 0 stroke-width:4px;
+linkStyle 1 stroke-width:4px;
+linkStyle 2 stroke-width:4px;
+linkStyle 3 stroke-width:4px;
+linkStyle 4 stroke-width:4px;
+
+
+class S invisible
+class Hypothesis,Conclusions start
+class Method,Data,Analysis normal
+</div>
+
+method:
+conditions | sessions | trials
+
+ethics:
+beneficence | respect for persons | justice
+
+- Which is violated by a coercive statement in a consent form?
+- Which is violated by an inequitable selection of participants?
+- Which is violated by risky, pointless research?
+
+analysis:
+How do we determine causality?
+   - correlation
+   - intervention
+]
+
+---
+.title[Accessibility]
+.body[
+**Disability** is a
+mismatched interaction
+between someone and
+their context
+]
+---
+.title[Example Q1: Which is true about disability?]
+.body[
+A personal attribute
+Context dependent
+Permanent
+]
+---
+.title[Example Q2: Is using a phone while holding a dog leash]
+.body[
+Temporary impairment
+Permanent impairment
+Situational impairment?
+]
+---
+.title[Example Q3: List three examples of Assistive technologies]
+
+???
+Screen reader
+Zooming
+Speech input
+Sticky keys
+Xbox adaptive controller
+High contrast interaction
+
+---
+.title[Accessibility Testing]
+.body[
+
+| Error                | Description                                                                                                                   |
+|----------------------|-------------------------------------------------------------------------------------------------------------------------------|
+| Clickable Items      | Overlapping clickable items                                                                                                   |
+| Editable Image Label | TextView has a content description. This might interfere with a screen reader’s ability to read the content of the text field |
+| Image Contrast       | Low contrast in image or icon                                                                                                 |
+| Item Descriptions    | Items with identical speakable text                                                                                           |
+| Item Label           | Missing element label                                                                                                         |
+| Item Type Label      | Item label ends with type, e.g., “Play Button.” TalkBack automatically announces item type, so information is redundant       |
+| Link                 | URL in link may be invalid                                                                                                    |
+| Text Contrast        | Low text contrast between foreground and background                                                                           |
+| Touch Target         | Item is too small|
+
+]
+???
+minimum to fix each problem (legal accessibility)
+
+true accessibility
+
+---
+.title[Affordances & Feedback
+]
+.body[
+Good Affordance| Bad Affordance
+----|----
+![:img Picture of a round doorknob, 40%](img/final/round-doorknob.png) | ![:img Picture of a flat doorknob, 40%](img/final/flat-doorknob.png) 
+
+Well-designed objects have affordances
+- Clues to their operation that are readily apparent
+- Often visual, but not always (e.g., speech)
+- Allows and promotes certain actions
+]
+???
+Opportunities to act which are readily apparent to the user ... and
+appropriate to the user’s abilities 
+
+relationship of affordence and feedback
+
+Form “affords” certain actions and makes that apparent
+
+---
+.title[# Model of Mental Models]
+.body[
+![:img A box showing the design (white) and actual function (blue missing
+a little bit of the white) with a grey circle added in the center
+labeled "Frequently Used (Well understood) Part of System
+Functionality" a dark blue cloud labeled "Occasionally Used Part of
+System Functionality" around the user's well understood region and
+another cloud further out with errors (regions outside the blue system
+box) labeled "Users full model of what the system does",100%](img/final/mental6.png)
+]
+
+???
+- Where are the gulf of evaluation and gulf of execution in this
+  image?  Gulf of execution is the user 'error' region (user requests
+  function the __system DOESNT HAVE__), gulf of
+  evaluation is when the user __doesn't realize the system HAS a
+  functionality__. 
+  
+- How does undo help the user bridge them? 
+
+---
+
+.title[Undo Sample Q]
+.body[
+Something other than drawing! Let's try text
+
+What should be the "action"? Characters or words?
+]
+--
+.body[
+
+- type "helo"
+- type "world"
+- undo
+- undo
+- type "hello"
+- redo
+- type "world"
+]
+
+---
+.left-column[
+### Heuristic Evaluation
+- H1: Visibility of system status
+- H2: Match between system and the real world
+- H3: User control and freedom
+- H4: Consistency and standards
+- H5: Error prevention
+- H6: Recognition vs. recall
+- H7: Flexibility and efficiency of use
+- H8: Aesthetic and minimalist design
+- H9: Error recovery
+- H10: Help and Documentation
+]
+.right-column[
+## UAR
+- Which heuristic
+- Explanation
+- Severity
+ - Frequency
+ - Impact
+ - Persistence
+- Scale: 
+ - 0 - Not a problem at all
+ - 1 - Cosmetic problem only
+ - 2 - Minor usability problem (fix with low priority)
+ - 3 - Major usability problem (fix with high priority)
+ - 4 - Usability catastrophe (imperative to fix before release)
+
+]
+.upper_right[![:img Four dialogue boxes with different locations for
+ok; cancel and help (inconsistent), 80%](img/final/consistency.png)]
+---
+.title[HE pros and cons?]
+---
+.left-column50[
+## Pros
+
+Discount usability engineering
+
+Intimidation low
+
+Don't need to identify tasks, activities
+
+Can identify some fairly obvious fixes
+
+Can expose problems user testing doesn’t expose
+
+Provides a language for justifying usability recommendations
+]
+.right-column50[
+## Cons
+
+Un-validated
+
+Unreliable
+
+Should use usability experts
+
+Problems unconnected with tasks
+
+Heuristics may be hard to apply to new technology
+
+Coordination costs]
+---
+.title[Sensing and context-awareness]
+.body[
+What makes an app context-aware?
+
+]
+???
+*use of implicit input*
+---
+.title[Sensing and context-awareness]
+.body[
+What makes an app context-aware?
+
+
+*use of implicit input*
+]
+---
+.title[Types of context-aware apps]
+--
+.body[
+Capture and Access
+
+Adaptive Services (changing operation or timing)
+
+Novel Interaction
+
+Behavioral Imaging
+
+General Solutions for Data Collection and Response
+
+Challenges?
+]
+???
+- Battery
+- Raw sensors not behavior data
+- Not the sensors we always want
+- Computational complexity
+- Latency in communication
+- Basic software framework to support apps that can adapt to user behavior
+- Apps that drive innovation
+- How people use phones
+
+---
+.title[Fences and snapshots]
+.body[
+When to use each?]
+
+---
+.left-column[
+## Behavior Change
+
+![:img five part model of personal informatics with stages
+preparation; collection; integration; reflection; action ,
+150%](img/final/personal-informatics-model.png)
+]
+.right-column[
+- Example Q: What stage does the leader board engage with?
+- Example Q: What stage do the icons support 
+- Example Q: What aspect of this interface supports action?
+
+![:img cscw, 70%](img/final/android.png)
+
+]
+---
+.left-column[
+## Machine Learning
+
+![:img decision tree, 80%](img/ml/decisiontree.png)
+]
+
+.right-column[
+
+<div class="mermaid">
+graph TD
+  T[Time] -- "10pm-8am" -->  N[Noise]
+  T[Time] -- "8am-10pm" --> Aw2[Awake y=35,n=2]
+  N -- "Low" --> As[Asleep y=20,n=5]
+  N -- "High" --> Aw3[Awake y=10,n=2]
+  
+</div>
+
+- Q1: What is this recognizing
+- Q2: What features are being used?
+- Q3: What are the labels?
+- Q4: What will be predicted if there is noise between 10am and noon?
+- Q5: What is the accuracy of this decision tree?
+]
+---
diff --git a/slides/wk10/heuristic.html b/slides/wk10/heuristic.html
new file mode 100644
index 0000000000000000000000000000000000000000..e480672b76a9eba90217d235a195d3b0e295dce6
--- /dev/null
+++ b/slides/wk10/heuristic.html
@@ -0,0 +1,695 @@
+---
+layout: presentation
+title: Heuristic Evaluation --Week 7, Friday--
+description: Heuristic Evaluation for Analyzing Interfaces
+class: middle, center, inverse
+---
+
+layout: false
+
+# Hall of Shame?
+
+What do you think happened here?
+.left-column50[
+![:img Funimation web page with a large image and an interface to add items to a queue and remove items from a queue, 100%](img/heuristic/funimation1.png)
+]
+.right-column40[
+![:img Large red remove from queue button, 50%](img/heuristic/funimation2.png)
+![:img Large red add to queue button, 80%](img/heuristic/funimation3.png)
+
+]
+
+???
+Thanks to Jeremy Zhang for the find.
+
+
+---
+
+name: inverse
+layout: true
+class: center, middle, inverse
+
+# Heuristic Evaluation for Analyzing Interfaces
+
+{{site.author.name}}
+
+CSE 340 {{site.quarter}}
+---
+layout: false
+
+[//]: # (Outline Slide)
+# Today's goals
+
+- [Combined data from Menus](https://docs.google.com/spreadsheets/d/1neu_22-YTI3TsP5uHKMsiEs4yxxz4xtghk69bYIgoJo/edit?usp=sharing)
+- Introduce Heuristic Evaluation
+- Describe UARs
+- Time at the end to fill out the [course eval](https://uw.iasystem.org/survey/227053)
+
+---
+.left-column[
+## Introducing Heuristic Evaluation]
+.right-column[
+.quote[Discount usability engineering methods]
+
+-- Jakob Nielsen
+
+Involves a small team of evaluators to evaluate an interface based on recognized usability principles
+
+Heuristics–”rules of thumb”
+
+]
+???
+"serving to discover or find out," 1821, irregular formation from Gk. heuretikos "inventive," related to heuriskein "to find" (cognate with O.Ir. fuar "I have found"). Heuristics "study of heuristic methods," first recorded 1959.
+
+---
+.left-column[
+## Introducing Heuristic Evaluation]
+.right-column[
+
+First introduced in 1990 by Nielsen & Molich
+
+Quick, inexpensive, popular technique
+
+~5 experts find 70-80% of problems
+n
+Based on 10 heuristics
+
+Does not require working interface
+]
+---
+<div class="mermaid">
+gantt
+	title Typical Heuristic Evaluation Process
+	section Evaluation
+	dateFormat DD
+	Designer Provides Setting (Description of Interface and List of Tasks) :list, 22, 5d
+	5ish evaluators Try tasks and record problems     :evals, after list, 5d
+	Designer conducts synthesis and analysis :synthesis, 28, 5d
+	Designer writes report :30, 5d
+</div>
+
+---
+.left-column[
+## So what are the heuristics?]
+--
+.right-column[
+- H1: Visibility of system status
+- H2: Match between system and the real world
+- H3: User control and freedom
+- H4: Consistency and standards
+- H5: Error prevention
+- H6: Recognition vs. recall
+- H7: Flexibility and efficiency of use
+- H8: Aesthetic and minimalist design
+- H9: Error recovery
+- H10: Help and documentation
+]
+???
+These should not be hugely surprising after everything we've talked about...
+---
+.left-column[
+## H1: Visibility of System Status
+
+Keep users informed about what is going on
+
+]
+.right-column[
+
+What does this interface tell you?
+
+![:img feedback being shown about how much time is left until a
+database search returns, 80%](img/heuristic/visibility.png)
+
+]
+--
+.right-column[
+- What input has been received--Does the interface above say what the search input was?
+- What processing it is currently doing--Does it say what it is currently doing?
+- What the results of processing are--Does it give the results of processing?
+
+Feedback allows user to monitor progress towards solution of their
+task, allows the closure of tasks and reduces user anxiety (Lavery et
+al)
+]
+
+---
+.left-column[
+## H2: Match between system and real world
+
+Speak the users’ language
+
+Follow real world conventions
+]
+.right-column[
+![:img two error messages returned by a bank machine-- one in terms the
+user can understand relating to dollars available and the other
+uninterpretable, 80%](img/heuristic/match.png)
+
+- Use concepts, language and real-world conventions that are familiar to the user.
+- Developers will need to understand the task from the point of view of users.
+- Cultural issues relevant for the design of systems that are expected to be used globally.
+
+A good match minimizes the extra knowledge required to use the system,
+simplying all task action mappings (re-expression of users’ intuitions
+into system concepts)
+]
+
+
+---
+.left-column[
+## H2: Match between system and real world
+
+Example of a huge violation of this H2
+
+]
+.right-column[
+
+| | |
+|--|--|
+| ![:img Picture of macintosh desktop with old style floppy disk to be dragged over trash to be ejected, 100%](img/heuristic/mactrash.png) |Possibly the biggest usability in problem in the Macintosh. Heuristic violation--people want to get their disk out of the machine--not discard it.|
+
+]
+---
+.left-column[
+## H2: Match between system and real world
+
+Example of a mismatch depends on knowledge about users
+]
+.right-column[
+
+Would an icon with a red flag for new mail be appropriate in all cultures?
+
+![:img Picture of a mailbox with red flag raised, 50%](img/heuristic/mailbox.png)
+]
+---
+.left-column[
+## H3: User Control and Freedom
+“Exits” for mistaken choices, undo, redo
+
+Don’t force down fixed paths
+
+]
+.right-column[
+![:img Dialog box with lots of exits for mistaken choices--
+undo;redo;Don’t force down fixed paths, 60%](img/heuristic/control.png)
+
+Users choose actions by mistake
+
+]
+
+
+---
+.left-column[
+## H4: Consistency and Standards
+]
+
+.right-column[
+![:img Four dialogue boxes with different locations for ok; cancel and help (inconsistent), 50%](img/heuristic/consistency.png)
+
+Same words, situations, actions, should mean the same thing in similar
+situations; same things look the same, be located in the same place.
+
+Different things should be different
+]
+---
+.left-column[
+## H4: Consistency and Standards
+]
+
+.right-column[
+- Both H2 (Match between system and the real world) and H4 related to user’s prior knowledge. The difference is
+  - H2 is knowledge of world
+  - H4 of knowledge others parts of application and other applications on the same platform.
+- Consistency within an application and within a platform. Developers need to know platform conventions.
+- Consistency with old interface
+
+Consistency maximizes the user knowledge required to use the systems
+by letting users generalize from existing experience of the system to
+other systems
+]
+---
+.left-column[
+## H4: Consistency and Standards
+]
+.right-column[
+
+Evidence: Should include at least
+- two inconsistent elements in the same interface, or
+- an element that is inconsisten with a platform guideline
+
+Explanation: What inconsistent element is and what it is inconsistent with
+
+![:img Four dialogue boxes with different locations for ok; cancel and help (inconsistent), 50%](img/heuristic/consistency.png)
+]
+---
+.left-column[
+## H5: Error Prevention
+
+Careful design which prevents a problem from occurring in the first place
+]
+
+.right-column[
+![:img Picture of a calendar entry interface with text entry (error
+prone) vs data selection (less error prone), 65%](img/heuristic/error.png)
+
+- Help users select among legal actions (e.g., greying out inappropirate
+buttons) rather than letting them select and then telling them that
+they have made an error (gotcha!).
+- Subset of H1 (Visibility of system status) but so important it gets a separate heuristic.
+
+Motivation: Errors are a main source of frustration, inefficiency and
+ineffectiveness during system usage (Lavery et al)
+
+Explanation in terms of tasks and system details such as adjacency of
+function keys and menu options, discriminability of icons and labels.
+]
+---
+.left-column[
+## H6: Recognition Rather than Recall
+
+Make objects, actions and options visible or easily retrievable
+
+]
+.right-column[
+
+![:img Compuserve connect old school interface, 30%](img/heuristic/recognition.png)
+
+- Classic examples:
+  - command line interfaces  (`rm *`)
+  - Arrows on keys that people can’t map to functions
+- Much easier for people to remember what to do if there are cues in the environment
+
+Goes into working memory through perceptions
+]
+---
+.left-column[
+## H7: Flexibility and Efficiency of Use
+
+Accelerators for experts (e.g., gestures, keyboard shortcuts)
+
+Allow users to tailor frequent actions (e.g., macros)
+
+]
+.right-column[
+![:img ,40%](img/heuristic/flexibility.png)
+
+- Typing single keys is typically faster than continually switching the
+hand between the keyboard and the mouse and point to things on the
+screen.
+- Skilled users develop plans of action, which they will want
+to execute frequently, so tailoring can capture these plans in the
+interface.
+]
+---
+.left-column[
+## H8: Aesthetic and Minimalist design
+
+Dialogs should not contain irrelevant or rarely needed information
+
+]
+.right-column[
+
+![:img ,80%](img/heuristic/minimalist.png)
+
+- Visual search--eyes must search through more. More (irrelevant info) interferes with Long Term Memory (LTM)
+retrieval of information that is relevant to task.
+- Cluttered displays have the effect of increasing search times for commands or users missing features on the screen (Lavery et al)
+
+_Chartjunk_ (Tufte): "The interior decoration of graphics generates a lot of ink that does not tell
+the viewer anything new."
+
+]
+---
+.left-column[
+## H9: Help users recognize, diagnose, and recover from errors
+
+]
+.right-column[
+
+![:img ,40%](img/heuristic/error2.png)
+
+- Error messages in language user will understand
+- Precisely indicate the problem
+- Constructively suggest a solution
+
+]
+
+---
+.left-column[
+## H10: Help and Documentation
+
+Easy to search
+
+Focused on the user’s task
+
+List concrete steps to carry out
+
+Always available
+]
+
+.right-column[
+![:img ,40%](img/heuristic/help.png)
+
+Allow search by gist--people do not remember exact system terms
+
+]
+
+???
+If user ever even knew system terms.
+
+
+---
+<div class="mermaid">
+gantt
+	title Typical Heuristic Evaluation Process
+	section Evaluation
+	dateFormat DD
+	Designer Provides Setting (Description of Interface and List of Tasks) :list, 22, 5d
+	5ish evaluators Try tasks and record problems     :evals, after list, 5d
+</div>
+
+Why 5 or more people?
+
+-4 or 5 are recommended by Nielsen (this is a point of contention. I
+aim for *saturation*).
+- A single person will not be able to find all usability problems
+- Different people find different usability problems
+- Successful evaluators may find both easy and hard problems
+
+
+???
+You can estimate how many you need (see NM book, pp 32-35).
+
+4 or 5 are recommended by Nielsen
+
+---
+<div class="mermaid">
+gantt
+	title Typical Heuristic Evaluation Process
+	section Evaluation
+	dateFormat DD
+	Designer Provides Setting (Description of Interface and List of Tasks) :list, 22, 5d
+	5ish evaluators Try tasks and record problems     :evals, after list, 5d
+</div>
+
+How should the Designer "provide a setting"? How should the evaluator evaluate?
+
+---
+<div class="mermaid">
+gantt
+	title Typical Heuristic Evaluation Process
+	section Evaluation
+	dateFormat DD
+	Designer Provides Setting (Description of Interface and List of Tasks) :list, 22, 5d
+	5ish evaluators Try tasks and record problems     :evals, after list, 5d
+</div>
+.left-column[
+## What does the evaluator do?]
+.right-column[
+
+Designer: Briefing (HE method, Domain, Scenario)
+
+Evaluator:
+- Two passes through interface (video in our case)
+- Inspect flow
+- Inspect each screen, one at a time against heuristics
+- Fill out a *Usability Action Report* (we'll keep this simple in peer review)
+]
+???
+
+NOT a single-user empirical test that is, do not say “I tried it and
+it didn’t work therefore I’ll search for a heuristic this violates”
+
+---
+<div class="mermaid">
+gantt
+	title Typical Heuristic Evaluation Process
+	section Evaluation
+	dateFormat DD
+	Designer Provides Setting (Description of Interface and List of Tasks) :list, 22, 5d
+	5ish evaluators Try tasks and record problems     :evals, after list, 5d
+</div>
+
+.left-column[
+## Usability Action Report
+]
+.right-column[
+UAR rather than “Problem report” because you report good aspects as
+well as problems -- you want to preserve them in the next iteration of
+the system!
+
+- **UAR Identifier** (Type-Number) Problem or Good Aspect
+- *Describe:* Succinct description of the usability aspect
+- *Heuristics:* What heuristics are violated
+- **Evidence:** support material for the aspect
+- **Explanation:** your own interpretation
+- *Severity:* your reasoning about importance
+- **Solution:** if the aspect is a problem, include a possible solution and potential trade-offs
+- **Relationships:** to other usability aspects (if any)
+]
+???
+
+We'll ask you to do the things in italics in peer grading
+---
+<div class="mermaid">
+gantt
+	title Typical Heuristic Evaluation Process
+	section Evaluation
+	dateFormat DD
+	Designer Provides Setting (Description of Interface and List of Tasks) :list, 22, 5d
+	5ish evaluators Try tasks and record problems     :evals, after list, 5d
+</div>
+.left-column[
+## Writing a description]
+.right-column[
+Should be *A PROBLEM*, not a solution
+
+Don't be misleading (e.g., “User couldn’t find state in the list” when
+the state wasn’t in the list)
+
+Don't be overly narrow (e.g., “PA not listed” when there is nothing
+special about PA and other states are not listed)
+
+Don't be too broad, not distinctive (e.g., “User can’t find item”)
+]
+---
+<div class="mermaid">
+gantt
+	title Typical Heuristic Evaluation Process
+	section Evaluation
+	dateFormat DD
+	Designer Provides Setting (Description of Interface and List of Tasks) :list, 22, 5d
+	5ish evaluators Try tasks and record problems     :evals, after list, 5d
+</div>
+.left-column[
+## Picking a Heuristic]
+.right-column[
+Ok to list more than one
+
+This is subjective. Use your best judgement
+]
+---
+<div class="mermaid">
+gantt
+	title Typical Heuristic Evaluation Process
+	section Evaluation
+	dateFormat DD
+	Designer Provides Setting (Description of Interface and List of Tasks) :list, 22, 5d
+	5ish evaluators Try tasks and record problems     :evals, after list, 5d
+</div>
+.left-column[
+## Deciding on a severity]
+.right-column[
+- Make a claim about factors and support it with reasons
+- Consider *Frequency* (e.g., All
+users would probably experience this problem because…)
+- Consider *Impact*  Will it be easy or hard to overcome. NOT is the task the user
+is doing important (put importance of task in explanation and in
+justification of weighting, if relevant).
+- Consider *Persistence* Once the problem is known, is it a one-time problem or
+will the user be continually bothered? NOT low persistence because the
+user abandons goal (that is impact--can’t overcome it.  If can’t
+detect and can’t overcome, problem persists).
+
+]
+???
+Why? Make claim (All users would PROBABLY experience this problem BECAUSE…) and IMMEDIATELY
+---
+<div class="mermaid">
+gantt
+	title Typical Heuristic Evaluation Process
+	section Evaluation
+	dateFormat DD
+	Designer Provides Setting (Description of Interface and List of Tasks) :list, 22, 5d
+	5ish evaluators Try tasks and record problems     :evals, after list, 5d
+</div>
+.left-column[
+## Rating Severity
+
+5-point scale
+
+]
+.right-column[
+
+0 - Not a problem at all (or a good feature)
+
+1 - Cosmetic problem only
+
+2 - Minor usability problem (fix with low priority)
+
+3 - Major usability problem (fix with high priority)
+
+4 - Usability catastrophe (imperative to fix before release)
+
+]
+
+---
+<div class="mermaid">
+gantt
+	title Heuristic Evaluation Process
+	section Evaluation
+	dateFormat MM-DD
+	Designer Provides Setting (>Description of Interface and List of Tasks) :list, 03-02, 9d
+	Videos distributed  :vids, after list, 1d
+	Tasks--5 evaluators     :evals, after vids, 2d
+	Section Problems
+	E1--Problem1...        :after vids, 2d
+    E1--Problem2...        :after vids, 2d
+    E2--Problem3...        :after vids, 2d
+		...                :after vids, 2d
+	Section Synthesis and Analysis
+    Group like problems :analysis, 03-14, 2d
+	Summarize problems :summarize, after analysis, 2d
+	Write report :after summarize, 1d
+</div>
+
+Group like problems
+- Important thing is whether they have similar description
+- This is for you to decide
+- Similarity may be conceptual (e.g. the same problem may show up in multiple parts of your interface)
+
+---
+<div class="mermaid">
+gantt
+	title Heuristic Evaluation Process
+	section Evaluation
+	dateFormat MM-DD
+	Designer Provides Setting (>Description of Interface and List of Tasks) :list, 03-02, 9d
+	Videos distributed  :vids, after list, 1d
+	Tasks--5 evaluators     :evals, after vids, 2d
+	Section Problems
+	E1--Problem1...        :after vids, 2d
+    E1--Problem2...        :after vids, 2d
+    E2--Problem3...        :after vids, 2d
+		...                :after vids, 2d
+	Section Synthesis and Analysis
+    Group like problems :analysis, 03-14, 2d
+	Summarize problems :summarize, after analysis, 2d
+	Write report :after summarize, 1d
+</div>
+
+Summarize problems
+- Average severities
+- List all relevant heuristics
+- List all areas of website affected
+- Also prioritize at this point
+
+---
+<div class="mermaid">
+gantt
+	title Heuristic Evaluation Process
+	section Evaluation
+	dateFormat MM-DD
+	Designer Provides Setting (>Description of Interface and List of Tasks) :list, 03-02, 9d
+	Videos distributed  :vids, after list, 1d
+	Tasks--5 evaluators     :evals, after vids, 2d
+	Section Problems
+	E1--Problem1...        :after vids, 2d
+    E1--Problem2...        :after vids, 2d
+    E2--Problem3...        :after vids, 2d
+		...                :after vids, 2d
+	Section Synthesis and Analysis
+    Group like problems :analysis, 03-14, 2d
+	Summarize problems :summarize, after analysis, 2d
+	Write report :after summarize, 1d
+</div>
+
+Write report
+
+We've provided a [template](../../assignments/undo-report)
+
+---
+.left-column[
+## Advantages of HE]
+.right-column[
+
+“Discount usability engineering”
+
+Intimidation low
+
+Don’t need to identify tasks, activities
+
+Can identify some fairly obvious fixes
+
+Can expose problems user testing doesn’t expose
+
+Provides a language for justifying usability recommendations
+
+]
+---
+.left-column[
+## Disadvantages of HE]
+.right-column[
+Un-validated
+
+Unreliable
+
+Should use usability experts
+
+Problems unconnected with tasks
+
+Heuristics may be hard to apply to new technology
+
+Coordination costs
+]
+
+---
+.left-column[
+## Summary]
+.right-column[
+Heuristic Evaluation can be used to evaluate & improve user interfaces
+
+10 heuristics
+
+Heuristic Evaluation process
+
+Individual: Flow & screens
+
+Group: Consensus report, severity
+
+Usability Aspect Reports
+
+Structured way to record good & bad
+]
+---
+
+# Hall of Shame?
+
+Cycling back: What would you say in your HE of this interface?
+
+![:youtube Video of funimation problems, 1zDMh3NHDjw]
+
+
+---
+# Hall of Shame?
+
+Cycling back: What would you say in your HE of this interface?
+
+.left-column50[
+![:img Funimation web page with a large image and an interface to add items to a queue and remove items from a queue, 100%](img/heuristic/funimation1.png)
+]
+.right-column40[
+![:img Large red remove from queue button, 50%](img/heuristic/funimation2.png)
+![:img Large red add to queue button, 80%](img/heuristic/funimation3.png)
+
+]
diff --git a/slides/wk10/img/final/android.png b/slides/wk10/img/final/android.png
new file mode 100644
index 0000000000000000000000000000000000000000..c05abc897a6ba254f4bf90cfa088dfb9de0d2569
Binary files /dev/null and b/slides/wk10/img/final/android.png differ
diff --git a/slides/wk10/img/final/consistency.png b/slides/wk10/img/final/consistency.png
new file mode 100644
index 0000000000000000000000000000000000000000..0ff8ff37943bd763d0afc16950d27425276161fd
Binary files /dev/null and b/slides/wk10/img/final/consistency.png differ
diff --git a/slides/wk10/img/final/decisiontree.png b/slides/wk10/img/final/decisiontree.png
new file mode 100644
index 0000000000000000000000000000000000000000..d70048fd94c67ba4dee4947494266980e412b2d8
Binary files /dev/null and b/slides/wk10/img/final/decisiontree.png differ
diff --git a/slides/wk10/img/final/flat-doorknob.png b/slides/wk10/img/final/flat-doorknob.png
new file mode 100644
index 0000000000000000000000000000000000000000..b7fa0fcc0b4a0daed1e12d9f5fdb49318a4aed07
Binary files /dev/null and b/slides/wk10/img/final/flat-doorknob.png differ
diff --git a/slides/wk10/img/final/mental6.png b/slides/wk10/img/final/mental6.png
new file mode 100644
index 0000000000000000000000000000000000000000..5baea3ac170bd237ee0c35101160347918f32c04
Binary files /dev/null and b/slides/wk10/img/final/mental6.png differ
diff --git a/slides/wk10/img/final/personal-informatics-model.png b/slides/wk10/img/final/personal-informatics-model.png
new file mode 100644
index 0000000000000000000000000000000000000000..b7ec7714d914b333ceda3cb2146c805e38cd7107
Binary files /dev/null and b/slides/wk10/img/final/personal-informatics-model.png differ
diff --git a/slides/wk10/img/final/round-doorknob.png b/slides/wk10/img/final/round-doorknob.png
new file mode 100644
index 0000000000000000000000000000000000000000..8413e79008f7f0537894d637cd1810b0b460239e
Binary files /dev/null and b/slides/wk10/img/final/round-doorknob.png differ
diff --git a/slides/wk10/img/heuristic/consistency.png b/slides/wk10/img/heuristic/consistency.png
new file mode 100644
index 0000000000000000000000000000000000000000..0ff8ff37943bd763d0afc16950d27425276161fd
Binary files /dev/null and b/slides/wk10/img/heuristic/consistency.png differ
diff --git a/slides/wk10/img/heuristic/control.png b/slides/wk10/img/heuristic/control.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f0ffd0ff7430cfeb48ee48dfb8fecb497e97aba
Binary files /dev/null and b/slides/wk10/img/heuristic/control.png differ
diff --git a/slides/wk10/img/heuristic/error.png b/slides/wk10/img/heuristic/error.png
new file mode 100644
index 0000000000000000000000000000000000000000..ad009d6088f7c37219f73da52c210ecb0e76eb0a
Binary files /dev/null and b/slides/wk10/img/heuristic/error.png differ
diff --git a/slides/wk10/img/heuristic/error2.png b/slides/wk10/img/heuristic/error2.png
new file mode 100644
index 0000000000000000000000000000000000000000..5cdddd5a43b172eaa38e99e774110ef02a171278
Binary files /dev/null and b/slides/wk10/img/heuristic/error2.png differ
diff --git a/slides/wk10/img/heuristic/flexibility.png b/slides/wk10/img/heuristic/flexibility.png
new file mode 100644
index 0000000000000000000000000000000000000000..0c21d4ffc1261db1092157291bbee76d9437bbdc
Binary files /dev/null and b/slides/wk10/img/heuristic/flexibility.png differ
diff --git a/slides/wk10/img/heuristic/funimation1.png b/slides/wk10/img/heuristic/funimation1.png
new file mode 100644
index 0000000000000000000000000000000000000000..046f837cf7661e7f3fb1c6d19fe1284570068981
Binary files /dev/null and b/slides/wk10/img/heuristic/funimation1.png differ
diff --git a/slides/wk10/img/heuristic/funimation2.png b/slides/wk10/img/heuristic/funimation2.png
new file mode 100644
index 0000000000000000000000000000000000000000..3440a441f71940bb3ca4dc03a433fb734c1a6f1a
Binary files /dev/null and b/slides/wk10/img/heuristic/funimation2.png differ
diff --git a/slides/wk10/img/heuristic/funimation3.png b/slides/wk10/img/heuristic/funimation3.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ace94a18212ae587673e3426735fa04f4c80fde
Binary files /dev/null and b/slides/wk10/img/heuristic/funimation3.png differ
diff --git a/slides/wk10/img/heuristic/help.png b/slides/wk10/img/heuristic/help.png
new file mode 100644
index 0000000000000000000000000000000000000000..26ee35f713c90875590da8eb098cfc590dc9eaae
Binary files /dev/null and b/slides/wk10/img/heuristic/help.png differ
diff --git a/slides/wk10/img/heuristic/mactrash.png b/slides/wk10/img/heuristic/mactrash.png
new file mode 100644
index 0000000000000000000000000000000000000000..c08482003ca9e3c4bf641b7bf5d6918471ab5759
Binary files /dev/null and b/slides/wk10/img/heuristic/mactrash.png differ
diff --git a/slides/wk10/img/heuristic/mailbox.png b/slides/wk10/img/heuristic/mailbox.png
new file mode 100644
index 0000000000000000000000000000000000000000..0c75a10406b3976cce65d0262d6833905814305b
Binary files /dev/null and b/slides/wk10/img/heuristic/mailbox.png differ
diff --git a/slides/wk10/img/heuristic/match.png b/slides/wk10/img/heuristic/match.png
new file mode 100644
index 0000000000000000000000000000000000000000..6b84fb7c1706daca865c35504c624abd62d9308a
Binary files /dev/null and b/slides/wk10/img/heuristic/match.png differ
diff --git a/slides/wk10/img/heuristic/minimalist.png b/slides/wk10/img/heuristic/minimalist.png
new file mode 100644
index 0000000000000000000000000000000000000000..c32b6646c92c7761fdc83b830cb9e095fa2d0f8b
Binary files /dev/null and b/slides/wk10/img/heuristic/minimalist.png differ
diff --git a/slides/wk10/img/heuristic/recognition.png b/slides/wk10/img/heuristic/recognition.png
new file mode 100644
index 0000000000000000000000000000000000000000..d1fb5cd5ddf8b92fe1acd7f9a0b82c9115bd9213
Binary files /dev/null and b/slides/wk10/img/heuristic/recognition.png differ
diff --git a/slides/wk10/img/heuristic/visibility.png b/slides/wk10/img/heuristic/visibility.png
new file mode 100644
index 0000000000000000000000000000000000000000..21dae906da003a422d64c43fb8fc1fe538d989d6
Binary files /dev/null and b/slides/wk10/img/heuristic/visibility.png differ
diff --git a/slides/wk10/pui2016-slides-23-usable-privacy-and-security.pptx b/slides/wk10/pui2016-slides-23-usable-privacy-and-security.pptx
new file mode 100644
index 0000000000000000000000000000000000000000..f3995476ae662f9c8779ae5de169ca642d0bf336
Binary files /dev/null and b/slides/wk10/pui2016-slides-23-usable-privacy-and-security.pptx differ