Index: frontend/node_modules/jest-each/README.md
===================================================================
--- frontend/node_modules/jest-each/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
+++ frontend/node_modules/jest-each/README.md	(revision 9af201e94b5a79beb92a30858fc54de4bc3b9449)
@@ -0,0 +1,548 @@
+<div align="center">
+  <h1>jest-each</h1>
+  Jest Parameterised Testing
+</div>
+
+<hr />
+
+[![version](https://img.shields.io/npm/v/jest-each.svg?style=flat-square)](https://www.npmjs.com/package/jest-each) [![downloads](https://img.shields.io/npm/dm/jest-each.svg?style=flat-square)](http://npm-stat.com/charts.html?package=jest-each&from=2017-03-21) [![MIT License](https://img.shields.io/npm/l/jest-each.svg?style=flat-square)](https://github.com/facebook/jest/blob/main/LICENSE)
+
+A parameterised testing library for [Jest](https://jestjs.io/) inspired by [mocha-each](https://github.com/ryym/mocha-each).
+
+jest-each allows you to provide multiple arguments to your `test`/`describe` which results in the test/suite being run once per row of parameters.
+
+## Features
+
+- `.test` to runs multiple tests with parameterised data
+  - Also under the alias: `.it`
+- `.test.only` to only run the parameterised tests
+  - Also under the aliases: `.it.only` or `.fit`
+- `.test.skip` to skip the parameterised tests
+  - Also under the aliases: `.it.skip` or `.xit` or `.xtest`
+- `.test.concurrent`
+  - Also under the alias: `.it.concurrent`
+- `.test.concurrent.only`
+  - Also under the alias: `.it.concurrent.only`
+- `.test.concurrent.skip`
+  - Also under the alias: `.it.concurrent.skip`
+- `.describe` to runs test suites with parameterised data
+- `.describe.only` to only run the parameterised suite of tests
+  - Also under the aliases: `.fdescribe`
+- `.describe.skip` to skip the parameterised suite of tests
+  - Also under the aliases: `.xdescribe`
+- Asynchronous tests with `done`
+- Unique test titles with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args):
+  - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format).
+  - `%s`- String.
+  - `%d`- Number.
+  - `%i` - Integer.
+  - `%f` - Floating point value.
+  - `%j` - JSON.
+  - `%o` - Object.
+  - `%#` - Index of the test case.
+  - `%%` - single percent sign ('%'). This does not consume an argument.
+- Unique test titles by injecting properties of test case object
+- 🖖 Spock like data tables with [Tagged Template Literals](#tagged-template-literal-of-rows)
+
+---
+
+- [Demo](#demo)
+- [Installation](#installation)
+- [Importing](#importing)
+- APIs
+  - [Array of Rows](#array-of-rows)
+    - [Usage](#usage)
+  - [Tagged Template Literal of rows](#tagged-template-literal-of-rows)
+    - [Usage](#usage-1)
+
+## Demo
+
+#### Tests without jest-each
+
+![Current jest tests](assets/default-demo.gif)
+
+#### Tests can be re-written with jest-each to:
+
+**`.test`**
+
+![Current jest tests](assets/test-demo.gif)
+
+**`.test` with Tagged Template Literals**
+
+![Current jest tests](assets/tagged-template-literal.gif)
+
+**`.describe`**
+
+![Current jest tests](assets/describe-demo.gif)
+
+## Installation
+
+`npm i --save-dev jest-each`
+
+`yarn add -D jest-each`
+
+## Importing
+
+jest-each is a default export so it can be imported with whatever name you like.
+
+```js
+// es6
+import each from 'jest-each';
+```
+
+```js
+// es5
+const each = require('jest-each').default;
+```
+
+## Array of rows
+
+### API
+
+#### `each([parameters]).test(name, testFn)`
+
+##### `each`:
+
+- parameters: `Array` of Arrays with the arguments that are passed into the `testFn` for each row
+  - _Note_ If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]`
+
+##### `.test`:
+
+- name: `String` the title of the `test`.
+  - Generate unique test titles by positionally injecting parameters with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args):
+    - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format).
+    - `%s`- String.
+    - `%d`- Number.
+    - `%i` - Integer.
+    - `%f` - Floating point value.
+    - `%j` - JSON.
+    - `%o` - Object.
+    - `%#` - Index of the test case.
+    - `%%` - single percent sign ('%'). This does not consume an argument.
+  - Or generate unique test titles by injecting properties of test case object with `$variable`
+    - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value`
+    - You can use `$#` to inject the index of the test case
+    - You cannot use `$variable` with the `printf` formatting except for `%%`
+- testFn: `Function` the test logic, this is the function that will receive the parameters of each row as function arguments
+
+#### `each([parameters]).describe(name, suiteFn)`
+
+##### `each`:
+
+- parameters: `Array` of Arrays with the arguments that are passed into the `suiteFn` for each row
+  - _Note_ If you pass in a 1D array of primitives, internally it will be mapped to a table i.e. `[1, 2, 3] -> [[1], [2], [3]]`
+
+##### `.describe`:
+
+- name: `String` the title of the `describe`
+  - Generate unique test titles by positionally injecting parameters with [`printf` formatting](https://nodejs.org/api/util.html#util_util_format_format_args):
+    - `%p` - [pretty-format](https://www.npmjs.com/package/pretty-format).
+    - `%s`- String.
+    - `%d`- Number.
+    - `%i` - Integer.
+    - `%f` - Floating point value.
+    - `%j` - JSON.
+    - `%o` - Object.
+    - `%#` - Index of the test case.
+    - `%%` - single percent sign ('%'). This does not consume an argument.
+  - Or generate unique test titles by injecting properties of test case object with `$variable`
+    - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value`
+    - You can use `$#` to inject the index of the test case
+    - You cannot use `$variable` with the `printf` formatting except for `%%`
+- suiteFn: `Function` the suite of `test`/`it`s to be ran, this is the function that will receive the parameters in each row as function arguments
+
+### Usage
+
+#### `.test(name, fn)`
+
+Alias: `.it(name, fn)`
+
+```js
+each([
+  [1, 1, 2],
+  [1, 2, 3],
+  [2, 1, 3],
+]).test('returns the result of adding %d to %d', (a, b, expected) => {
+  expect(a + b).toBe(expected);
+});
+```
+
+```js
+each([
+  {a: 1, b: 1, expected: 2},
+  {a: 1, b: 2, expected: 3},
+  {a: 2, b: 1, expected: 3},
+]).test('returns the result of adding $a to $b', ({a, b, expected}) => {
+  expect(a + b).toBe(expected);
+});
+```
+
+#### `.test.only(name, fn)`
+
+Aliases: `.it.only(name, fn)` or `.fit(name, fn)`
+
+```js
+each([
+  [1, 1, 2],
+  [1, 2, 3],
+  [2, 1, 3],
+]).test.only('returns the result of adding %d to %d', (a, b, expected) => {
+  expect(a + b).toBe(expected);
+});
+```
+
+#### `.test.skip(name, fn)`
+
+Aliases: `.it.skip(name, fn)` or `.xit(name, fn)` or `.xtest(name, fn)`
+
+```js
+each([
+  [1, 1, 2],
+  [1, 2, 3],
+  [2, 1, 3],
+]).test.skip('returns the result of adding %d to %d', (a, b, expected) => {
+  expect(a + b).toBe(expected);
+});
+```
+
+#### `.test.concurrent(name, fn)`
+
+Aliases: `.it.concurrent(name, fn)`
+
+```js
+each([
+  [1, 1, 2],
+  [1, 2, 3],
+  [2, 1, 3],
+]).test.concurrent(
+  'returns the result of adding %d to %d',
+  (a, b, expected) => {
+    expect(a + b).toBe(expected);
+  },
+);
+```
+
+#### `.test.concurrent.only(name, fn)`
+
+Aliases: `.it.concurrent.only(name, fn)`
+
+```js
+each([
+  [1, 1, 2],
+  [1, 2, 3],
+  [2, 1, 3],
+]).test.concurrent.only(
+  'returns the result of adding %d to %d',
+  (a, b, expected) => {
+    expect(a + b).toBe(expected);
+  },
+);
+```
+
+#### `.test.concurrent.skip(name, fn)`
+
+Aliases: `.it.concurrent.skip(name, fn)`
+
+```js
+each([
+  [1, 1, 2],
+  [1, 2, 3],
+  [2, 1, 3],
+]).test.concurrent.skip(
+  'returns the result of adding %d to %d',
+  (a, b, expected) => {
+    expect(a + b).toBe(expected);
+  },
+);
+```
+
+#### Asynchronous `.test(name, fn(done))`
+
+Alias: `.it(name, fn(done))`
+
+```js
+each([['hello'], ['mr'], ['spy']]).test(
+  'gives 007 secret message: %s',
+  (str, done) => {
+    const asynchronousSpy = message => {
+      expect(message).toBe(str);
+      done();
+    };
+    callSomeAsynchronousFunction(asynchronousSpy)(str);
+  },
+);
+```
+
+#### `.describe(name, fn)`
+
+```js
+each([
+  [1, 1, 2],
+  [1, 2, 3],
+  [2, 1, 3],
+]).describe('.add(%d, %d)', (a, b, expected) => {
+  test(`returns ${expected}`, () => {
+    expect(a + b).toBe(expected);
+  });
+
+  test('does not mutate first arg', () => {
+    a + b;
+    expect(a).toBe(a);
+  });
+
+  test('does not mutate second arg', () => {
+    a + b;
+    expect(b).toBe(b);
+  });
+});
+```
+
+```js
+each([
+  {a: 1, b: 1, expected: 2},
+  {a: 1, b: 2, expected: 3},
+  {a: 2, b: 1, expected: 3},
+]).describe('.add($a, $b)', ({a, b, expected}) => {
+  test(`returns ${expected}`, () => {
+    expect(a + b).toBe(expected);
+  });
+
+  test('does not mutate first arg', () => {
+    a + b;
+    expect(a).toBe(a);
+  });
+
+  test('does not mutate second arg', () => {
+    a + b;
+    expect(b).toBe(b);
+  });
+});
+```
+
+#### `.describe.only(name, fn)`
+
+Aliases: `.fdescribe(name, fn)`
+
+```js
+each([
+  [1, 1, 2],
+  [1, 2, 3],
+  [2, 1, 3],
+]).describe.only('.add(%d, %d)', (a, b, expected) => {
+  test(`returns ${expected}`, () => {
+    expect(a + b).toBe(expected);
+  });
+});
+```
+
+#### `.describe.skip(name, fn)`
+
+Aliases: `.xdescribe(name, fn)`
+
+```js
+each([
+  [1, 1, 2],
+  [1, 2, 3],
+  [2, 1, 3],
+]).describe.skip('.add(%d, %d)', (a, b, expected) => {
+  test(`returns ${expected}`, () => {
+    expect(a + b).toBe(expected);
+  });
+});
+```
+
+---
+
+## Tagged Template Literal of rows
+
+### API
+
+#### `each[tagged template].test(name, suiteFn)`
+
+```js
+each`
+  a    | b    | expected
+  ${1} | ${1} | ${2}
+  ${1} | ${2} | ${3}
+  ${2} | ${1} | ${3}
+`.test('returns $expected when adding $a to $b', ({a, b, expected}) => {
+  expect(a + b).toBe(expected);
+});
+```
+
+##### `each` takes a tagged template string with:
+
+- First row of variable name column headings separated with `|`
+- One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
+
+##### `.test`:
+
+- name: `String` the title of the `test`, use `$variable` in the name string to inject test values into the test title from the tagged template expressions
+  - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value`
+  - You can use `$#` to inject the index of the table row.
+- testFn: `Function` the test logic, this is the function that will receive the parameters of each row as function arguments
+
+#### `each[tagged template].describe(name, suiteFn)`
+
+```js
+each`
+  a    | b    | expected
+  ${1} | ${1} | ${2}
+  ${1} | ${2} | ${3}
+  ${2} | ${1} | ${3}
+`.describe('$a + $b', ({a, b, expected}) => {
+  test(`returns ${expected}`, () => {
+    expect(a + b).toBe(expected);
+  });
+
+  test('does not mutate first arg', () => {
+    a + b;
+    expect(a).toBe(a);
+  });
+
+  test('does not mutate second arg', () => {
+    a + b;
+    expect(b).toBe(b);
+  });
+});
+```
+
+##### `each` takes a tagged template string with:
+
+- First row of variable name column headings separated with `|`
+- One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
+
+##### `.describe`:
+
+- name: `String` the title of the `test`, use `$variable` in the name string to inject test values into the test title from the tagged template expressions
+  - To inject nested object values use you can supply a keyPath i.e. `$variable.path.to.value`
+- suiteFn: `Function` the suite of `test`/`it`s to be ran, this is the function that will receive the parameters in each row as function arguments
+
+### Usage
+
+#### `.test(name, fn)`
+
+Alias: `.it(name, fn)`
+
+```js
+each`
+  a    | b    | expected
+  ${1} | ${1} | ${2}
+  ${1} | ${2} | ${3}
+  ${2} | ${1} | ${3}
+`.test('returns $expected when adding $a to $b', ({a, b, expected}) => {
+  expect(a + b).toBe(expected);
+});
+```
+
+#### `.test.only(name, fn)`
+
+Aliases: `.it.only(name, fn)` or `.fit(name, fn)`
+
+```js
+each`
+  a    | b    | expected
+  ${1} | ${1} | ${2}
+  ${1} | ${2} | ${3}
+  ${2} | ${1} | ${3}
+`.test.only('returns $expected when adding $a to $b', ({a, b, expected}) => {
+  expect(a + b).toBe(expected);
+});
+```
+
+#### `.test.skip(name, fn)`
+
+Aliases: `.it.skip(name, fn)` or `.xit(name, fn)` or `.xtest(name, fn)`
+
+```js
+each`
+  a    | b    | expected
+  ${1} | ${1} | ${2}
+  ${1} | ${2} | ${3}
+  ${2} | ${1} | ${3}
+`.test.skip('returns $expected when adding $a to $b', ({a, b, expected}) => {
+  expect(a + b).toBe(expected);
+});
+```
+
+#### Asynchronous `.test(name, fn(done))`
+
+Alias: `.it(name, fn(done))`
+
+```js
+each`
+  str
+  ${'hello'}
+  ${'mr'}
+  ${'spy'}
+`.test('gives 007 secret message: $str', ({str}, done) => {
+  const asynchronousSpy = message => {
+    expect(message).toBe(str);
+    done();
+  };
+  callSomeAsynchronousFunction(asynchronousSpy)(str);
+});
+```
+
+#### `.describe(name, fn)`
+
+```js
+each`
+  a    | b    | expected
+  ${1} | ${1} | ${2}
+  ${1} | ${2} | ${3}
+  ${2} | ${1} | ${3}
+`.describe('$a + $b', ({a, b, expected}) => {
+  test(`returns ${expected}`, () => {
+    expect(a + b).toBe(expected);
+  });
+
+  test('does not mutate first arg', () => {
+    a + b;
+    expect(a).toBe(a);
+  });
+
+  test('does not mutate second arg', () => {
+    a + b;
+    expect(b).toBe(b);
+  });
+});
+```
+
+#### `.describe.only(name, fn)`
+
+Aliases: `.fdescribe(name, fn)`
+
+```js
+each`
+  a    | b    | expected
+  ${1} | ${1} | ${2}
+  ${1} | ${2} | ${3}
+  ${2} | ${1} | ${3}
+`.describe.only('$a + $b', ({a, b, expected}) => {
+  test(`returns ${expected}`, () => {
+    expect(a + b).toBe(expected);
+  });
+});
+```
+
+#### `.describe.skip(name, fn)`
+
+Aliases: `.xdescribe(name, fn)`
+
+```js
+each`
+  a    | b    | expected
+  ${1} | ${1} | ${2}
+  ${1} | ${2} | ${3}
+  ${2} | ${1} | ${3}
+`.describe.skip('$a + $b', ({a, b, expected}) => {
+  test(`returns ${expected}`, () => {
+    expect(a + b).toBe(expected);
+  });
+});
+```
+
+## License
+
+MIT
