diff --git a/assets/csvkit.js b/assets/csvkit.js
new file mode 100644
index 0000000..fd43939
--- /dev/null
+++ b/assets/csvkit.js
@@ -0,0 +1,250 @@
+(function() {
+ this.CSVKit = {};
+
+ /* Utils */
+
+ var ctor = function() {};
+ var inherits = function(child, parent){
+ ctor.prototype = parent.prototype;
+ child.prototype = new ctor();
+ child.prototype.constructor = child;
+ };
+
+ /* CSVKit.Reader */
+
+ CSVKit.Reader = function(options) {
+ options = options || {};
+
+ this.separator = options.separator || ',';
+ this.quote_char = options.quote_char || '"';
+ this.escape_char = options.escape_char || '"';
+ this.column_names = options.column_names || [];
+ this.columns_from_header = 'columns_from_header' in options ? options.columns_from_header : true;
+ this.nested_quotes = 'nested_quotes' in options ? options.nested_quotes : false;
+ this.rows = [];
+
+ this.state = {
+ rows: 0,
+ open_record: [],
+ open_field: '',
+ last_char: '',
+ in_quoted_field: false
+ };
+ };
+
+ CSVKit.Reader.prototype.parse = function(data) {
+ if (this.state.open_record.length === 0) {
+ if (data.charCodeAt(0) === 0xFEFF) {
+ data = data.slice(1);
+ }
+ }
+
+ for (var i = 0; i < data.length; i++) {
+ var c = data.charAt(i), next_char;
+ switch (c) {
+ // escape and separator may be the same char, typically '"'
+ case this.escape_char:
+ case this.quote_char:
+ var is_escape = false;
+
+ if (c === this.escape_char) {
+ next_char = data.charAt(i + 1);
+
+ if (this._is_escapable(next_char)) {
+ this._add_character(next_char);
+ i++;
+ is_escape = true;
+ }
+ }
+ if (!is_escape && (c === this.quote_char)) {
+ if (this.state.open_field && !this.state.in_quoted_field) {
+ this.state.in_quoted_field = true;
+ break;
+ }
+
+ if (this.state.in_quoted_field) {
+ // closing quote should be followed by separator unless the nested quotes option is set
+ next_char = data.charAt(i + 1);
+
+ if (next_char && next_char !== '\r' && next_char != '\n' && next_char !== this.separator && this.nested_quotes !== true) {
+ throw new Error("separator expected after a closing quote; found " + next_char);
+ } else {
+ this.state.in_quoted_field = false;
+ }
+ } else if (this.state.open_field === '') {
+ this.state.in_quoted_field = true;
+ }
+ }
+
+ break;
+ case this.separator:
+ if (this.state.in_quoted_field) {
+ this._add_character(c);
+ } else {
+ this._add_field();
+ }
+ break;
+ case '\n':
+ // handle CRLF sequence
+ if (!this.state.in_quoted_field && (this.state.last_char === '\r')) {
+ break;
+ }
+ case '\r':
+ if (this.state.in_quoted_field) {
+ this._add_character(c);
+ } else {
+ this._add_field();
+ this._add_record();
+ }
+ break;
+ default:
+ this._add_character(c);
+ }
+
+ this.state.last_char = c;
+ }
+
+ if (this.state.in_quoted_field) {
+ throw new Error("Input stream ended but closing quotes expected");
+ } else {
+ if (this.state.open_field) {
+ this._add_field();
+ }
+
+ if (this.state.open_record.length > 0) {
+ this._add_record();
+ }
+ }
+ };
+
+ CSVKit.Reader.prototype._is_escapable = function(c) {
+ if ((c === this.escape_char) || (c === this.quote_char)) {
+ return true;
+ }
+ return false;
+ };
+
+ CSVKit.Reader.prototype._add_character = function(c) {
+ this.state.open_field += c;
+ };
+
+ CSVKit.Reader.prototype._add_field = function() {
+ this.state.open_record.push(this.state.open_field);
+ this.state.open_field = '';
+ this.state.in_quoted_field = false;
+ };
+
+ CSVKit.Reader.prototype._add_record = function() {
+ if (this.columns_from_header && this.state.rows === 0) {
+ this.column_names = this.state.open_record;
+ } else {
+ this.rows.push(this._serialize_record(this.state.open_record));
+ }
+
+ this.state.rows++;
+ this.state.open_record = [];
+ this.state.open_field = '';
+ this.state.in_quoted_field = false;
+ };
+
+ CSVKit.Reader.prototype._serialize_record = function(record) {
+ return record;
+ };
+
+ /* CSVKit.ObjectReader */
+
+ CSVKit.ObjectReader = function(options) {
+ CSVKit.Reader.call(this, options);
+ };
+ inherits(CSVKit.ObjectReader, CSVKit.Reader);
+
+ CSVKit.ObjectReader.prototype._serialize_record = function(record) {
+ var obj = {};
+
+ for (var i = 0; i < this.column_names.length; i++) {
+ obj[this.column_names[i]] = record[i];
+ }
+
+ return obj;
+ };
+
+ /* CSVKit.Writer */
+
+ CSVKit.Writer = function(options) {
+ options = options || {};
+
+ this.separator = options.separator || ',';
+ this.quote_char = options.quote_char || '"';
+ this.escape_char = options.escape_char || '"';
+ this.quote_all = options.quote_all || false;
+ this.newline = '\n';
+
+ CSVKit.Writer.prototype.write = function(rows) {
+ var formatted_rows = [];
+
+ for (var i = 0; i < rows.length; i++) {
+ formatted_rows.push(this._serialize_row(rows[i]));
+ }
+
+ return formatted_rows.join(this.newline);
+ };
+
+ CSVKit.Writer.prototype._serialize_row = function(row) {
+ var formatted_cells = [];
+
+ for (var i = 0; i < row.length; i++) {
+ formatted_cells.push(this._serialize_cell(row[i]));
+ }
+
+ return formatted_cells.join(this.separator);
+ };
+
+ CSVKit.Writer.prototype._serialize_cell = function(cell) {
+ if (cell.indexOf(this.quote_char) >= 0) {
+ cell = cell.replace(new RegExp(this.quote_char, 'g'), this.escape_char + this.quote_char);
+ }
+
+ if (this.quote_all || cell.indexOf(this.separator) >= 0 || cell.indexOf(this.newline) >= 0) {
+ return this.quote_char + cell + this.quote_char;
+ }
+
+ return cell;
+ };
+ }
+
+ /* CSVKit.ObjectWriter */
+
+ CSVKit.ObjectWriter = function(options) {
+ CSVKit.Writer.call(this, options);
+
+ if (!('column_names' in options)) {
+ throw "The column_names option is required.";
+ }
+
+ this.column_names = options.column_names;
+ };
+ inherits(CSVKit.ObjectWriter, CSVKit.Writer);
+
+ CSVKit.ObjectWriter.prototype.write = function(rows) {
+ var header = {};
+
+ for (var i = 0; i < this.column_names.length; i++) {
+ header[this.column_names[i]] = this.column_names[i];
+ }
+
+ rows.splice(0, 0, header);
+
+ return CSVKit.Writer.prototype.write.call(this, rows);
+ }
+
+ CSVKit.ObjectWriter.prototype._serialize_row = function(row) {
+ var cells = [];
+
+ for (var i = 0; i < this.column_names.length; i++) {
+ cells.push(row[this.column_names[i]]);
+ }
+
+ return CSVKit.Writer.prototype._serialize_row.call(this, cells);
+ };
+
+}).call(this);
diff --git a/assets/leaderboard.js b/assets/leaderboard.js
new file mode 100644
index 0000000..69ee40b
--- /dev/null
+++ b/assets/leaderboard.js
@@ -0,0 +1,94 @@
+// Sourced from ryanparag on CodePen
+
+console.clear();
+
+const tableRow = document.querySelectorAll(".list__row");
+const overlay = document.querySelector(".overlay");
+const sidebar = document.querySelector(".sidebar");
+const closeOverlayBtn = document.querySelector(".button--close");
+
+const sidebarClose = () => {
+ sidebar.classList.remove("is-open");
+ overlay.style.opacity = 0;
+ setTimeout(() => {
+ overlay.classList.remove("is-open");
+ overlay.style.opacity = 1;
+ }, 300);
+};
+
+tableRow.forEach(tableRow => {
+ tableRow.addEventListener("click", function () {
+ overlay.style.opacity = 0;
+ overlay.classList.add("is-open");
+ sidebar.classList.add("is-open");
+ setTimeout(() => {
+ overlay.style.opacity = 1;
+ }, 100);
+
+ // Sidebar content
+ const sidebarBody = document.querySelector(".sidebar__body");
+ sidebarBody.innerHTML = '';
+
+ const driverPlace = this.querySelector(".list__cell:nth-of-type(1) .list__value").innerHTML;
+ const driverName = this.querySelector(".list__cell:nth-of-type(2) .list__value").innerHTML;
+ const driverTeam = this.querySelector(".list__cell:nth-of-type(3) .list__value").innerHTML;
+ const driverPoints = this.querySelector(".list__cell:nth-of-type(4) .list__value").innerHTML;
+ const driverImage = this.dataset.image;
+ const driverNationality = this.dataset.nationality;
+ const driverDOB = this.dataset.dob;
+ const driverCountry = this.dataset.country;
+
+ const newDriver = document.createElement('div');
+ newDriver.classList = 'driver';
+
+ const driverContent = document.createElement('div');
+ driverContent.classList = 'driver__content';
+
+ const profile = document.createElement('div');
+ profile.classList = 'driver__image';
+ profile.style.backgroundImage = `url('${driverImage}')`;
+ newDriver.appendChild(profile);
+
+ const driverTitle = document.createElement('div');
+ driverTitle.classList = 'driver__title';
+ driverTitle.innerHTML = driverName;
+ driverContent.appendChild(driverTitle);
+
+ const driverInfo = document.createElement('div');
+ driverInfo.innerHTML = `
+
+
+
+ Belt |
+ ${driverTeam} |
+
+
+ Level |
+ ${driverPoints} |
+
+
+ Activity |
+ ${driverNationality} |
+
+
+ Place |
+ ${driverPlace} |
+
+
+
+
`;
+ driverContent.appendChild(driverInfo);
+
+ newDriver.appendChild(driverContent);
+ sidebarBody.appendChild(newDriver);
+
+ });
+});
+
+closeOverlayBtn.addEventListener("click", function () {
+ sidebarClose();
+});
+
+overlay.addEventListener("click", function () {
+ sidebarClose();
+});
\ No newline at end of file
diff --git a/assets/style.css b/assets/style.css
new file mode 100644
index 0000000..6b0b92e
--- /dev/null
+++ b/assets/style.css
@@ -0,0 +1,261 @@
+html {
+ --black: #21252a;
+ --grey-1: #343A40;
+ --grey-2: #495057;
+ --grey-3: #868E96;
+ --grey-4: #ADB5BD;
+ --grey-5: #CED4DA;
+ --grey-6: #DEE2E6;
+ --grey-7: #E9ECEF;
+ --grey-8: #F1F3F5;
+ --grey-9: #F8F9FA;
+ --trans-black: rgba(33, 37, 42, .9);
+ --red: #e10600;
+ --gold: #ffda65;
+ --gold-dark: #a3862c;
+ --bronze: #c99355;
+ --bronze-dark: #80582c;
+ }
+
+ html {
+ box-sizing: border-box;
+ }
+
+ *, *:before, *:after {
+ box-sizing: inherit;
+ }
+
+ html, body {
+ width: 99%;
+ height: 100%;
+ }
+
+ body {
+ font-family: "Inter UI", system-ui;
+ color: var(--black);
+ background: var(--black);
+ }
+
+ .list {
+ width: 100%;
+ max-width: 600px;
+ margin: 3rem auto 3rem;
+ border-radius: 0.4rem;
+ box-shadow: 0px 12px 25px rgba(0, 0, 0, 0.1), 0px 5px 12px rgba(0, 0, 0, 0.07);
+ }
+ @media screen and (max-width: 800px) {
+ .list {
+ margin: 0 auto;
+ }
+ }
+ .list__table {
+ width: 100%;
+ border-spacing: 0;
+ color: var(--grey-3);
+ }
+ .list__header {
+ padding: 2rem 2rem;
+ background: white;
+ border-top-left-radius: 0.4rem;
+ border-top-right-radius: 0.4rem;
+ }
+ .list__header h1, .list__header h5 {
+ margin: 0;
+ padding: 0;
+ }
+ .list__header h5 {
+ margin-bottom: 0.5rem;
+ text-transform: uppercase;
+ color: var(--red);
+ }
+ .list__value {
+ display: block;
+ font-size: 17px;
+ }
+ .list__label {
+ font-size: 10px;
+ opacity: 0.6;
+ }
+ .list__row {
+ background: var(--grey-7);
+ cursor: pointer;
+ transition: all 300ms ease;
+ }
+ .list__row:hover, .list__row:focus {
+ transform: scale(1.05);
+ box-shadow: 0px 15px 28px rgba(0, 0, 0, 0.1), 0px 5px 12px rgba(0, 0, 0, 0.08);
+ transition: all 300ms ease;
+ }
+ .list__row:not(:last-of-type) .list__cell {
+ box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.08);
+ }
+ .list__row:first-of-type {
+ color: var(--gold-dark);
+ background: var(--grey-9);
+ }
+ .list__row:first-of-type .list__cell:first-of-type {
+ background: var(--gold);
+ color: var(--gold-dark);
+ }
+ .list__row:nth-of-type(2) {
+ color: var(--grey-2);
+ background: var(--grey-9);
+ }
+ .list__row:nth-of-type(2) .list__cell:first-of-type {
+ background: var(--grey-4);
+ color: var(--grey-2);
+ }
+ .list__row:nth-of-type(3) {
+ color: var(--bronze-dark);
+ background: var(--grey-9);
+ }
+ .list__row:nth-of-type(3) .list__cell:first-of-type {
+ background: var(--bronze);
+ color: var(--bronze-dark);
+ }
+ .list__cell {
+ padding: 1rem;
+ }
+ .list__cell:first-of-type {
+ text-align: center;
+ padding: 1rem 0.2rem;
+ background: var(--grey-5);
+ }
+
+ .overlay {
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background: var(--trans-black);
+ display: none;
+ cursor: pointer;
+ transition: all 300ms ease;
+ }
+ .overlay.is-open {
+ display: block;
+ }
+
+ .sidebar {
+ position: fixed;
+ background: white;
+ width: 100%;
+ max-width: 500px;
+ top: 0;
+ bottom: 0;
+ box-shadow: none;
+ right: -500px;
+ display: flex;
+ flex-direction: column;
+ justify-content: flex-start;
+ /*@media screen and (max-width: 650px) {
+ flex-direction: column-reverse;
+ justify-content: space-between;
+ }*/
+ transition: all 300ms ease;
+ }
+ .sidebar.is-open {
+ right: 0;
+ transition: all 300ms ease;
+ box-shadow: 0px 0px 100px var(--black);
+ }
+ .sidebar__header {
+ display: flex;
+ justify-content: space-between;
+ background: var(--grey-9);
+ align-items: center;
+ }
+ .sidebar__header, .sidebar__body {
+ padding: 2rem;
+ }
+ .sidebar__title {
+ font-size: 1.5rem;
+ font-weight: 700;
+ color: var(--grey-4);
+ }
+
+ .button {
+ font-family: inherit;
+ border: 0;
+ background: transparent;
+ cursor: pointer;
+ }
+ .button:focus, .button:active {
+ outline: 0;
+ }
+ .button--close {
+ padding: 0;
+ margin: 0;
+ height: auto;
+ line-height: 1;
+ color: var(--grey-5);
+ }
+ .button--close:hover {
+ color: var(--grey--4);
+ }
+
+ .driver {
+ display: flex;
+ align-items: flex-start;
+ opacity: 0;
+ position: relative;
+ left: 100px;
+ -webkit-animation: fade 500ms ease 150ms forwards;
+ animation: fade 500ms ease 150ms forwards;
+ }
+ .driver__image {
+ width: 100px;
+ height: 100px;
+ border-radius: 50%;
+ background-size: 220px;
+ background-repeat: no-repeat;
+ background-position: top center;
+ border: 3px solid white;
+ box-shadow: 0px 5px 12px rgba(0, 0, 0, 0.12);
+ margin-right: 1.5rem;
+ }
+ .driver__content {
+ width: auto;
+ }
+ .driver__title {
+ font-weight: 700;
+ font-size: 1.6rem;
+ margin: 0.5rem 0;
+ }
+ .driver__table {
+ width: 100%;
+ color: var(--grey-2);
+ }
+ .driver__table small {
+ color: var(--grey-4);
+ }
+ .driver__table td {
+ padding: 0.3rem 0.6rem 0.3rem 0;
+ height: 2rem;
+ }
+ .driver__table td img {
+ position: relative;
+ top: 5px;
+ margin-right: 6px;
+ }
+
+ @-webkit-keyframes fade {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ left: 0;
+ }
+ }
+
+ @keyframes fade {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ left: 0;
+ }
+ }
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..444b339
--- /dev/null
+++ b/index.html
@@ -0,0 +1,160 @@
+
+
+
+
+
+ Document
+
+
+
+
+
+
+
+
+
+
+ 1 |
+ Lewis HamiltonNinja |
+ WhiteBelt |
+ 8Level |
+
+
+ 2 |
+ Sebastian VettelDriver |
+ FerrariConstructor |
+ 78Points |
+
+
+ 3 |
+ Valtteri BottasDriver |
+ MercedesConstructor |
+ 58Points |
+
+
+ 4 |
+ Kimi RäikkönenDriver |
+ FerrariConstructor |
+ 48Points |
+
+
+ 5 |
+ Daniel RicciardoDriver |
+ Red BullConstructor |
+ 47Points |
+
+
+ 6 |
+ Max VerstappenDriver |
+ Red BullConstructor |
+ 33Points |
+
+
+ 7 |
+ Fernando AlonsoDriver |
+ McLarenConstructor |
+ 32Points |
+
+
+ 8 |
+ Nico HülkenbergDriver |
+ RenaultConstructor |
+ 22Points |
+
+
+ 9 |
+ Kevin MagnussenDriver |
+ Haas F1 TeamConstructor |
+ 19Points |
+
+
+ 10 |
+ Carlos SainzDriver |
+ RenaultConstructor |
+ 19Points |
+
+
+ 11 |
+ Sergio PérezDriver |
+ Force IndiaConstructor |
+ 17Points |
+
+
+ 12 |
+ Pierre GaslyDriver |
+ Toro RossoConstructor |
+ 12Points |
+
+
+ 13 |
+ Charles LeclercDriver |
+ SauberConstructor |
+ 9Points |
+
+
+ 14 |
+ Stoffel VandoorneDriver |
+ McLarenConstructor |
+ 8Points |
+
+
+ 15 |
+ Lance StrollDriver |
+ WilliamsConstructor |
+ 4Points |
+
+
+ 16 |
+ Marcus EricssonDriver |
+ SauberConstructor |
+ 2Points |
+
+
+ 17 |
+ Esteban OconDriver |
+ Force IndiaConstructor |
+ 1Points |
+
+
+ 18 |
+ Brendon HartleyDriver |
+ Toro RossoConstructor |
+ 1Points |
+
+
+ 19 |
+ Romain GrosjeanDriver |
+ Haas F1 TeamConstructor |
+ 0Points |
+
+
+ 20 |
+ Sergey SirotkinDriver |
+ WilliamsConstructor |
+ 0Points |
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file