diff --git a/.gitignore b/.gitignore
index 229b5d7..67dfbeb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
/node_modules
/static/bundle.js
/static/bundle.js.map
+.env
\ No newline at end of file
diff --git a/README.md b/README.md
index 49361db..3584ad7 100644
--- a/README.md
+++ b/README.md
@@ -1,32 +1,51 @@
-# Your own project
-
-Build an app of your choice.
-
-- You are free to use any technologies covered so far. You are welcome to try new technologies you find interesting.
-- Keep it simple. Aim to get the basic functionality working on day one. You can then extend it on days two and three.
-- Feel free to use an external API to provide additional functionality to your app. Avoid APIs that use complex authentication mechanisms.
-- Use pen and paper to draw a diagram of the webpage layout before starting to code. Have a think about what components you will need in advance.
-- Think about how to organise your data in advance
-- Make sure your app is responsive
-- Commit frequently
-- Create pull request at the end
-- Keep it simple
-
-## Technical notes
-
-* Run `npm install` after cloning to download all dependencies
-* Use `npm run dev -- --watch` to build React
-* Use `node server.js` to run the Node server in another tab
-* You can view the site at [http://localhost:8080](http://localhost:8080)
-* If you would like to user `nodemon` to automatically rebuild your server, run `npm run server`
-* The node server file is `/server.js`
-* The index home page is in `/views/index.hbs`
-* Place all static files such as images and CSS in the `static` folder.
-
-## README
-
-* Produce a README.md which explains
- * what the project does
- * what technologies it uses
- * how to build it and run it
- * any unresolved issues the user should be aware of
+# Spotify Dashboard
+
+Welcome to Spotify Dashboard. This project aims to provide a useful companion to Spotify by displaying interesting and useful information about the artist that you are currently listening to.
+
+## Prerequistes
+
+This application is built using Node.js and React.
+
+## Installing Dependencies
+
+- Use `npm run dev` or `npm run dev -- --watch` to build React
+- Use `node server.js` to run the Node server
+- View the site at [http://localhost:8080](http://localhost:8080)
+- The node server file can be found at /server.js
+- The index home page can be found in /views/index.hbs
+
+## How To Use
+
+First of all, the Spotify SDK used by this application requires an SDK token to be generated using a Spotify Premium Account [here](https://developer.spotify.com/documentation/web-playback-sdk/quick-start/#). These tokens last for an hour before needing updating.
+
+Once you have input a usable SDK token, you will be instructed by Spotify Dashboard to go to your Spotify Device, open "Connect to a device" and connect to Spotify Dashboard. Once this happens, the songs that you are listening to will be represented on the app with the album cover, artist, song name and album name.
+
+When you change through the songs on your device, or load up a playlist and leave it to run, this is represented on screen. Information about the music/podcast you are listening to will change dynamically.
+
+Alongside this, the app uses the information about the artist and executes a fetch to Ticketmaster's Discover API to find information about upcoming events, including links to buy tickets. This information can be scrolled through on the page without affecting the view of your artist information.
+
+This device also works responsively at different views, allowing the user to read through upcoming events without spoiling the view of the song information.
+
+## Notable Features
+
+- This app has good responsivity for various devices, allowing for a minimalist sleek view while keeping the ability to navigate through a wide range of information.
+- I feel that this project has demonstrated my ability to create and maintain clean and human-friendly React components and data structure.
+- Information presented in the app changes based on whether the user has a device connected or not. This is implemented in `App.js` on lines 24-44.
+- Anyone with a Spotify Premium account can request an SDK token and input it to use the app.
+
+## Unresolved Issues/Un-implemented Features
+
+While I am very proud of the work I have done on this app, there are a number of issues that need resolving and should be kept in mind when using Spotify Dashboard. There were also a number of features that I was unable to implement which are listed below:
+
+- The Spotify SDK token only works for an hour. As a result, the project can stop working without warning. This is a nuisance in terms of usability and it would be nice to give some kind of indication as to how long you have left on the token/an alert when your time is about to expire.
+- The Ticketmaster API provides amazing information about an artist's upcoming events. Unfortunately, it often returns 429 response status codes for too many requests. Sadly, there is no `Retry-After` header attached indicating how often this would happen. This can provide some annoying user experiences as the Spotify SDK re-triggers a fetch about 1 minute into a song. It also re-triggers a fetch when the song is paused and then played again. This can happen quite a few times during a play through, which can provide some undesirable results from the API. It can also provide issues if, for example, you skip through a couple of songs and the app will tell the user that there are no upcoming events regardless of if this is true or not!
+- I would like to refactor the way the dates are presented as they are not very readable. For instance, instead of the format YYYY-MM-DD I would prefer something along the lines of "Tuesday 1st November 2018". I would also like to add a countdown feature that shows how far away we are from the show.
+- The Ticketmaster API results only say whether the tickets are onsale or offsale. This works when redirecting people to buy tickets to available events, but it would be preferable to have more information that the user could find useful. For instance, are the tickets unavailable because they have sold out or because they haven't been released yet?
+
+## Acknowledgements
+
+This application utilises [Spotify's Web Playback SDK](https://developer.spotify.com/documentation/web-playback-sdk/).
+
+This application utilises [Ticketmaster's Discovery API](https://developer.ticketmaster.com/products-and-docs/apis/discovery-api/v2/) to fetch upcoming event information.
+
+Inspiration for the layout came from [Music UI](https://dribbble.com/shots/4242093-Music-UI) by Giga Tamarashvili for Adjara Design on Feb 19, 2018 @ dribbble.
diff --git a/coverage/clover.xml b/coverage/clover.xml
new file mode 100644
index 0000000..e787561
--- /dev/null
+++ b/coverage/clover.xml
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json
new file mode 100644
index 0000000..8010fe9
--- /dev/null
+++ b/coverage/coverage-final.json
@@ -0,0 +1,9 @@
+{"/Users/olliecrook/workspace/own-project/src/spotify.js": {"path":"/Users/olliecrook/workspace/own-project/src/spotify.js","statementMap":{"0":{"start":{"line":1,"column":15},"end":{"line":5,"column":1}},"1":{"start":{"line":9,"column":2},"end":{"line":9,"column":32}},"2":{"start":{"line":12,"column":0},"end":{"line":59,"column":2}},"3":{"start":{"line":13,"column":16},"end":{"line":13,"column":28}},"4":{"start":{"line":14,"column":17},"end":{"line":19,"column":4}},"5":{"start":{"line":17,"column":6},"end":{"line":17,"column":16}},"6":{"start":{"line":22,"column":2},"end":{"line":24,"column":5}},"7":{"start":{"line":23,"column":4},"end":{"line":23,"column":27}},"8":{"start":{"line":25,"column":2},"end":{"line":27,"column":5}},"9":{"start":{"line":26,"column":4},"end":{"line":26,"column":27}},"10":{"start":{"line":28,"column":2},"end":{"line":30,"column":5}},"11":{"start":{"line":29,"column":4},"end":{"line":29,"column":27}},"12":{"start":{"line":31,"column":2},"end":{"line":33,"column":5}},"13":{"start":{"line":32,"column":4},"end":{"line":32,"column":27}},"14":{"start":{"line":36,"column":2},"end":{"line":38,"column":5}},"15":{"start":{"line":37,"column":4},"end":{"line":37,"column":26}},"16":{"start":{"line":40,"column":2},"end":{"line":45,"column":5}},"17":{"start":{"line":41,"column":4},"end":{"line":44,"column":5}},"18":{"start":{"line":42,"column":6},"end":{"line":42,"column":43}},"19":{"start":{"line":43,"column":6},"end":{"line":43,"column":13}},"20":{"start":{"line":48,"column":2},"end":{"line":50,"column":5}},"21":{"start":{"line":49,"column":4},"end":{"line":49,"column":51}},"22":{"start":{"line":53,"column":2},"end":{"line":55,"column":5}},"23":{"start":{"line":54,"column":4},"end":{"line":54,"column":57}},"24":{"start":{"line":58,"column":2},"end":{"line":58,"column":19}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":8,"column":15},"end":{"line":8,"column":16}},"loc":{"start":{"line":8,"column":38},"end":{"line":10,"column":1}},"line":8},"1":{"name":"(anonymous_1)","decl":{"start":{"line":12,"column":38},"end":{"line":12,"column":39}},"loc":{"start":{"line":12,"column":44},"end":{"line":59,"column":1}},"line":12},"2":{"name":"(anonymous_2)","decl":{"start":{"line":16,"column":19},"end":{"line":16,"column":20}},"loc":{"start":{"line":16,"column":25},"end":{"line":18,"column":5}},"line":16},"3":{"name":"(anonymous_3)","decl":{"start":{"line":22,"column":45},"end":{"line":22,"column":46}},"loc":{"start":{"line":22,"column":62},"end":{"line":24,"column":3}},"line":22},"4":{"name":"(anonymous_4)","decl":{"start":{"line":25,"column":45},"end":{"line":25,"column":46}},"loc":{"start":{"line":25,"column":62},"end":{"line":27,"column":3}},"line":25},"5":{"name":"(anonymous_5)","decl":{"start":{"line":28,"column":38},"end":{"line":28,"column":39}},"loc":{"start":{"line":28,"column":55},"end":{"line":30,"column":3}},"line":28},"6":{"name":"(anonymous_6)","decl":{"start":{"line":31,"column":39},"end":{"line":31,"column":40}},"loc":{"start":{"line":31,"column":56},"end":{"line":33,"column":3}},"line":31},"7":{"name":"(anonymous_7)","decl":{"start":{"line":36,"column":45},"end":{"line":36,"column":46}},"loc":{"start":{"line":36,"column":54},"end":{"line":38,"column":3}},"line":36},"8":{"name":"(anonymous_8)","decl":{"start":{"line":40,"column":32},"end":{"line":40,"column":33}},"loc":{"start":{"line":40,"column":41},"end":{"line":45,"column":3}},"line":40},"9":{"name":"(anonymous_9)","decl":{"start":{"line":48,"column":30},"end":{"line":48,"column":31}},"loc":{"start":{"line":48,"column":49},"end":{"line":50,"column":3}},"line":48},"10":{"name":"(anonymous_10)","decl":{"start":{"line":53,"column":34},"end":{"line":53,"column":35}},"loc":{"start":{"line":53,"column":53},"end":{"line":55,"column":3}},"line":53}},"branchMap":{"0":{"loc":{"start":{"line":41,"column":4},"end":{"line":44,"column":5}},"type":"if","locations":[{"start":{"line":41,"column":4},"end":{"line":44,"column":5}},{"start":{"line":41,"column":4},"end":{"line":44,"column":5}}],"line":41}},"s":{"0":2,"1":2,"2":2,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0},"f":{"0":2,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0},"b":{"0":[0,0]},"_coverageSchema":"332fd63041d2c1bcb487cc26dd0d5f7d97098a6c","hash":"96b2df683194f4fbb55f36cd78ce04ee16a506c5"}
+,"/Users/olliecrook/workspace/own-project/src/components/App.js": {"path":"/Users/olliecrook/workspace/own-project/src/components/App.js","statementMap":{"0":{"start":{"line":9,"column":4},"end":{"line":9,"column":12}},"1":{"start":{"line":11,"column":4},"end":{"line":18,"column":6}},"2":{"start":{"line":20,"column":4},"end":{"line":20,"column":67}},"3":{"start":{"line":21,"column":4},"end":{"line":21,"column":49}},"4":{"start":{"line":25,"column":4},"end":{"line":43,"column":5}},"5":{"start":{"line":26,"column":6},"end":{"line":33,"column":9}},"6":{"start":{"line":35,"column":6},"end":{"line":41,"column":9}},"7":{"start":{"line":42,"column":6},"end":{"line":42,"column":24}},"8":{"start":{"line":47,"column":4},"end":{"line":47,"column":38}},"9":{"start":{"line":51,"column":4},"end":{"line":58,"column":53}},"10":{"start":{"line":56,"column":24},"end":{"line":56,"column":39}},"11":{"start":{"line":57,"column":20},"end":{"line":57,"column":68}},"12":{"start":{"line":58,"column":22},"end":{"line":58,"column":51}},"13":{"start":{"line":62,"column":4},"end":{"line":89,"column":6}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":8,"column":2},"end":{"line":8,"column":3}},"loc":{"start":{"line":8,"column":16},"end":{"line":22,"column":3}},"line":8},"1":{"name":"(anonymous_1)","decl":{"start":{"line":24,"column":2},"end":{"line":24,"column":3}},"loc":{"start":{"line":24,"column":29},"end":{"line":44,"column":3}},"line":24},"2":{"name":"(anonymous_2)","decl":{"start":{"line":46,"column":2},"end":{"line":46,"column":3}},"loc":{"start":{"line":46,"column":22},"end":{"line":48,"column":3}},"line":46},"3":{"name":"(anonymous_3)","decl":{"start":{"line":50,"column":2},"end":{"line":50,"column":3}},"loc":{"start":{"line":50,"column":15},"end":{"line":59,"column":3}},"line":50},"4":{"name":"(anonymous_4)","decl":{"start":{"line":56,"column":12},"end":{"line":56,"column":13}},"loc":{"start":{"line":56,"column":24},"end":{"line":56,"column":39}},"line":56},"5":{"name":"(anonymous_5)","decl":{"start":{"line":57,"column":12},"end":{"line":57,"column":13}},"loc":{"start":{"line":57,"column":20},"end":{"line":57,"column":68}},"line":57},"6":{"name":"(anonymous_6)","decl":{"start":{"line":58,"column":13},"end":{"line":58,"column":14}},"loc":{"start":{"line":58,"column":22},"end":{"line":58,"column":51}},"line":58},"7":{"name":"(anonymous_7)","decl":{"start":{"line":61,"column":2},"end":{"line":61,"column":3}},"loc":{"start":{"line":61,"column":11},"end":{"line":90,"column":3}},"line":61}},"branchMap":{"0":{"loc":{"start":{"line":25,"column":4},"end":{"line":43,"column":5}},"type":"if","locations":[{"start":{"line":25,"column":4},"end":{"line":43,"column":5}},{"start":{"line":25,"column":4},"end":{"line":43,"column":5}}],"line":25},"1":{"loc":{"start":{"line":66,"column":11},"end":{"line":78,"column":11}},"type":"cond-expr","locations":[{"start":{"line":67,"column":12},"end":{"line":72,"column":14}},{"start":{"line":74,"column":12},"end":{"line":77,"column":14}}],"line":66},"2":{"loc":{"start":{"line":80,"column":11},"end":{"line":86,"column":18}},"type":"cond-expr","locations":[{"start":{"line":81,"column":12},"end":{"line":81,"column":52}},{"start":{"line":82,"column":14},"end":{"line":86,"column":18}}],"line":80},"3":{"loc":{"start":{"line":80,"column":11},"end":{"line":80,"column":68}},"type":"binary-expr","locations":[{"start":{"line":80,"column":11},"end":{"line":80,"column":35}},{"start":{"line":80,"column":39},"end":{"line":80,"column":68}}],"line":80},"4":{"loc":{"start":{"line":82,"column":14},"end":{"line":86,"column":18}},"type":"cond-expr","locations":[{"start":{"line":83,"column":12},"end":{"line":85,"column":18}},{"start":{"line":86,"column":14},"end":{"line":86,"column":18}}],"line":82},"5":{"loc":{"start":{"line":82,"column":14},"end":{"line":82,"column":63}},"type":"binary-expr","locations":[{"start":{"line":82,"column":14},"end":{"line":82,"column":39}},{"start":{"line":82,"column":43},"end":{"line":82,"column":63}}],"line":82}},"s":{"0":2,"1":2,"2":2,"3":2,"4":0,"5":0,"6":0,"7":0,"8":2,"9":0,"10":0,"11":0,"12":0,"13":2},"f":{"0":2,"1":0,"2":2,"3":0,"4":0,"5":0,"6":0,"7":2},"b":{"0":[0,0],"1":[0,2],"2":[0,2],"3":[2,0],"4":[0,2],"5":[2,2]},"_coverageSchema":"332fd63041d2c1bcb487cc26dd0d5f7d97098a6c","hash":"d861973669f391fb7b40beb1da4287ade6bc10de"}
+,"/Users/olliecrook/workspace/own-project/src/components/Event.js": {"path":"/Users/olliecrook/workspace/own-project/src/components/Event.js","statementMap":{"0":{"start":{"line":4,"column":2},"end":{"line":22,"column":4}}},"fnMap":{"0":{"name":"Event","decl":{"start":{"line":3,"column":9},"end":{"line":3,"column":14}},"loc":{"start":{"line":3,"column":26},"end":{"line":23,"column":1}},"line":3}},"branchMap":{"0":{"loc":{"start":{"line":12,"column":7},"end":{"line":20,"column":7}},"type":"cond-expr","locations":[{"start":{"line":13,"column":8},"end":{"line":17,"column":12}},{"start":{"line":19,"column":8},"end":{"line":19,"column":49}}],"line":12}},"s":{"0":2},"f":{"0":2},"b":{"0":[2,0]},"_coverageSchema":"332fd63041d2c1bcb487cc26dd0d5f7d97098a6c","hash":"67080099be4db4681260a2af30702fccce37c8cd"}
+,"/Users/olliecrook/workspace/own-project/src/components/Events.js": {"path":"/Users/olliecrook/workspace/own-project/src/components/Events.js","statementMap":{"0":{"start":{"line":5,"column":2},"end":{"line":11,"column":4}},"1":{"start":{"line":8,"column":8},"end":{"line":8,"column":54}}},"fnMap":{"0":{"name":"Events","decl":{"start":{"line":4,"column":9},"end":{"line":4,"column":15}},"loc":{"start":{"line":4,"column":31},"end":{"line":12,"column":1}},"line":4},"1":{"name":"(anonymous_1)","decl":{"start":{"line":7,"column":21},"end":{"line":7,"column":22}},"loc":{"start":{"line":7,"column":37},"end":{"line":9,"column":7}},"line":7}},"branchMap":{},"s":{"0":2,"1":2},"f":{"0":2,"1":2},"b":{},"_coverageSchema":"332fd63041d2c1bcb487cc26dd0d5f7d97098a6c","hash":"28dbb7b4b8934fbc9a232e4966d0031f507c59b8"}
+,"/Users/olliecrook/workspace/own-project/src/components/Header.js": {"path":"/Users/olliecrook/workspace/own-project/src/components/Header.js","statementMap":{"0":{"start":{"line":4,"column":2},"end":{"line":18,"column":4}}},"fnMap":{"0":{"name":"Header","decl":{"start":{"line":3,"column":9},"end":{"line":3,"column":15}},"loc":{"start":{"line":3,"column":31},"end":{"line":19,"column":1}},"line":3}},"branchMap":{"0":{"loc":{"start":{"line":8,"column":7},"end":{"line":16,"column":14}},"type":"cond-expr","locations":[{"start":{"line":9,"column":8},"end":{"line":15,"column":14}},{"start":{"line":16,"column":10},"end":{"line":16,"column":14}}],"line":8}},"s":{"0":2},"f":{"0":2},"b":{"0":[2,0]},"_coverageSchema":"332fd63041d2c1bcb487cc26dd0d5f7d97098a6c","hash":"c3ba70c2ef2c565369746accc7535723d7fdfb69"}
+,"/Users/olliecrook/workspace/own-project/src/components/PlayWindow.js": {"path":"/Users/olliecrook/workspace/own-project/src/components/PlayWindow.js","statementMap":{"0":{"start":{"line":4,"column":2},"end":{"line":13,"column":4}}},"fnMap":{"0":{"name":"PlayWindow","decl":{"start":{"line":3,"column":9},"end":{"line":3,"column":19}},"loc":{"start":{"line":3,"column":63},"end":{"line":14,"column":1}},"line":3}},"branchMap":{},"s":{"0":1},"f":{"0":1},"b":{},"_coverageSchema":"332fd63041d2c1bcb487cc26dd0d5f7d97098a6c","hash":"23cb0871500dc32f791a6b6284bf621b195b0dfc"}
+,"/Users/olliecrook/workspace/own-project/tests/mockEventsResults.js": {"path":"/Users/olliecrook/workspace/own-project/tests/mockEventsResults.js","statementMap":{"0":{"start":{"line":1,"column":22},"end":{"line":2260,"column":1}}},"fnMap":{},"branchMap":{},"s":{"0":1},"f":{},"b":{},"_coverageSchema":"332fd63041d2c1bcb487cc26dd0d5f7d97098a6c","hash":"a3091c7b168af6a82b287dd3dac09b307fd2f5d0"}
+,"/Users/olliecrook/workspace/own-project/tests/setup.js": {"path":"/Users/olliecrook/workspace/own-project/tests/setup.js","statementMap":{"0":{"start":{"line":4,"column":0},"end":{"line":4,"column":45}}},"fnMap":{},"branchMap":{},"s":{"0":5},"f":{},"b":{},"_coverageSchema":"332fd63041d2c1bcb487cc26dd0d5f7d97098a6c","hash":"0915a4a56782f4184672b1248037a857b456dc7d"}
+}
diff --git a/coverage/lcov-report/base.css b/coverage/lcov-report/base.css
new file mode 100644
index 0000000..7090209
--- /dev/null
+++ b/coverage/lcov-report/base.css
@@ -0,0 +1,223 @@
+body, html {
+ margin:0; padding: 0;
+ height: 100%;
+}
+body {
+ font-family: Helvetica Neue, Helvetica, Arial;
+ font-size: 14px;
+ color:#333;
+}
+.small { font-size: 12px; }
+*, *:after, *:before {
+ -webkit-box-sizing:border-box;
+ -moz-box-sizing:border-box;
+ box-sizing:border-box;
+ }
+h1 { font-size: 20px; margin: 0;}
+h2 { font-size: 14px; }
+pre {
+ font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
+ margin: 0;
+ padding: 0;
+ -moz-tab-size: 2;
+ -o-tab-size: 2;
+ tab-size: 2;
+}
+a { color:#0074D9; text-decoration:none; }
+a:hover { text-decoration:underline; }
+.strong { font-weight: bold; }
+.space-top1 { padding: 10px 0 0 0; }
+.pad2y { padding: 20px 0; }
+.pad1y { padding: 10px 0; }
+.pad2x { padding: 0 20px; }
+.pad2 { padding: 20px; }
+.pad1 { padding: 10px; }
+.space-left2 { padding-left:55px; }
+.space-right2 { padding-right:20px; }
+.center { text-align:center; }
+.clearfix { display:block; }
+.clearfix:after {
+ content:'';
+ display:block;
+ height:0;
+ clear:both;
+ visibility:hidden;
+ }
+.fl { float: left; }
+@media only screen and (max-width:640px) {
+ .col3 { width:100%; max-width:100%; }
+ .hide-mobile { display:none!important; }
+}
+
+.quiet {
+ color: #7f7f7f;
+ color: rgba(0,0,0,0.5);
+}
+.quiet a { opacity: 0.7; }
+
+.fraction {
+ font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
+ font-size: 10px;
+ color: #555;
+ background: #E8E8E8;
+ padding: 4px 5px;
+ border-radius: 3px;
+ vertical-align: middle;
+}
+
+div.path a:link, div.path a:visited { color: #333; }
+table.coverage {
+ border-collapse: collapse;
+ margin: 10px 0 0 0;
+ padding: 0;
+}
+
+table.coverage td {
+ margin: 0;
+ padding: 0;
+ vertical-align: top;
+}
+table.coverage td.line-count {
+ text-align: right;
+ padding: 0 5px 0 20px;
+}
+table.coverage td.line-coverage {
+ text-align: right;
+ padding-right: 10px;
+ min-width:20px;
+}
+
+table.coverage td span.cline-any {
+ display: inline-block;
+ padding: 0 5px;
+ width: 100%;
+}
+.missing-if-branch {
+ display: inline-block;
+ margin-right: 5px;
+ border-radius: 3px;
+ position: relative;
+ padding: 0 4px;
+ background: #333;
+ color: yellow;
+}
+
+.skip-if-branch {
+ display: none;
+ margin-right: 10px;
+ position: relative;
+ padding: 0 4px;
+ background: #ccc;
+ color: white;
+}
+.missing-if-branch .typ, .skip-if-branch .typ {
+ color: inherit !important;
+}
+.coverage-summary {
+ border-collapse: collapse;
+ width: 100%;
+}
+.coverage-summary tr { border-bottom: 1px solid #bbb; }
+.keyline-all { border: 1px solid #ddd; }
+.coverage-summary td, .coverage-summary th { padding: 10px; }
+.coverage-summary tbody { border: 1px solid #bbb; }
+.coverage-summary td { border-right: 1px solid #bbb; }
+.coverage-summary td:last-child { border-right: none; }
+.coverage-summary th {
+ text-align: left;
+ font-weight: normal;
+ white-space: nowrap;
+}
+.coverage-summary th.file { border-right: none !important; }
+.coverage-summary th.pct { }
+.coverage-summary th.pic,
+.coverage-summary th.abs,
+.coverage-summary td.pct,
+.coverage-summary td.abs { text-align: right; }
+.coverage-summary td.file { white-space: nowrap; }
+.coverage-summary td.pic { min-width: 120px !important; }
+.coverage-summary tfoot td { }
+
+.coverage-summary .sorter {
+ height: 10px;
+ width: 7px;
+ display: inline-block;
+ margin-left: 0.5em;
+ background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
+}
+.coverage-summary .sorted .sorter {
+ background-position: 0 -20px;
+}
+.coverage-summary .sorted-desc .sorter {
+ background-position: 0 -10px;
+}
+.status-line { height: 10px; }
+/* yellow */
+.cbranch-no { background: yellow !important; color: #111; }
+/* dark red */
+.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
+.low .chart { border:1px solid #C21F39 }
+.highlighted,
+.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
+ background: #C21F39 !important;
+}
+/* medium red */
+.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
+/* light red */
+.low, .cline-no { background:#FCE1E5 }
+/* light green */
+.high, .cline-yes { background:rgb(230,245,208) }
+/* medium green */
+.cstat-yes { background:rgb(161,215,106) }
+/* dark green */
+.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
+.high .chart { border:1px solid rgb(77,146,33) }
+
+.medium .chart { border:1px solid #666; }
+.medium .cover-fill { background: #666; }
+
+.cstat-skip { background: #ddd; color: #111; }
+.fstat-skip { background: #ddd; color: #111 !important; }
+.cbranch-skip { background: #ddd !important; color: #111; }
+
+span.cline-neutral { background: #eaeaea; }
+.medium { background: #eaeaea; }
+
+.coverage-summary td.empty {
+ opacity: .5;
+ padding-top: 4px;
+ padding-bottom: 4px;
+ line-height: 1;
+ color: #888;
+}
+
+.cover-fill, .cover-empty {
+ display:inline-block;
+ height: 12px;
+}
+.chart {
+ line-height: 0;
+}
+.cover-empty {
+ background: white;
+}
+.cover-full {
+ border-right: none !important;
+}
+pre.prettyprint {
+ border: none !important;
+ padding: 0 !important;
+ margin: 0 !important;
+}
+.com { color: #999 !important; }
+.ignore-none { color: #999; font-weight: normal; }
+
+.wrapper {
+ min-height: 100%;
+ height: auto !important;
+ height: 100%;
+ margin: 0 auto -48px;
+}
+.footer, .push {
+ height: 48px;
+}
diff --git a/coverage/lcov-report/block-navigation.js b/coverage/lcov-report/block-navigation.js
new file mode 100644
index 0000000..0c71903
--- /dev/null
+++ b/coverage/lcov-report/block-navigation.js
@@ -0,0 +1,63 @@
+var jumpToCode = (function init () {
+ // Classes of code we would like to highlight
+ var missingCoverageClasses = [ '.cbranch-no', '.cstat-no', '.fstat-no' ];
+
+ // We don't want to select elements that are direct descendants of another match
+ var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > `
+
+ // Selecter that finds elements on the page to which we can jump
+ var selector = notSelector + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b`
+
+ // The NodeList of matching elements
+ var missingCoverageElements = document.querySelectorAll(selector);
+
+ var currentIndex;
+
+ function toggleClass(index) {
+ missingCoverageElements.item(currentIndex).classList.remove('highlighted');
+ missingCoverageElements.item(index).classList.add('highlighted');
+ }
+
+ function makeCurrent(index) {
+ toggleClass(index);
+ currentIndex = index;
+ missingCoverageElements.item(index)
+ .scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'center' });
+ }
+
+ function goToPrevious() {
+ var nextIndex = 0;
+ if (typeof currentIndex !== 'number' || currentIndex === 0) {
+ nextIndex = missingCoverageElements.length - 1;
+ } else if (missingCoverageElements.length > 1) {
+ nextIndex = currentIndex - 1;
+ }
+
+ makeCurrent(nextIndex);
+ }
+
+ function goToNext() {
+ var nextIndex = 0;
+
+ if (typeof currentIndex === 'number' && currentIndex < (missingCoverageElements.length - 1)) {
+ nextIndex = currentIndex + 1;
+ }
+
+ makeCurrent(nextIndex);
+ }
+
+ return function jump(event) {
+ switch (event.which) {
+ case 78: // n
+ case 74: // j
+ goToNext();
+ break;
+ case 66: // b
+ case 75: // k
+ case 80: // p
+ goToPrevious();
+ break;
+ }
+ };
+}());
+window.addEventListener('keydown', jumpToCode);
diff --git a/coverage/lcov-report/index.html b/coverage/lcov-report/index.html
new file mode 100644
index 0000000..0a96942
--- /dev/null
+++ b/coverage/lcov-report/index.html
@@ -0,0 +1,123 @@
+
+
+
+ Code coverage report for All files
+
+
+
+
+
+
+
+
+
+
+ All files
+
+
+
+ 34.78%
+ Statements
+ 16/46
+
+
+ 44.44%
+ Branches
+ 8/18
+
+
+ 37.5%
+ Functions
+ 9/24
+
+
+ 34.78%
+ Lines
+ 16/46
+
+
+
+ Press n or j to go to the next uncovered block, b, p or k for the previous block.
+