Repository: Modernizr/Modernizr
Pull request #2547 (2020-04-27 17:43:13)

Add metadata documentation
I found out that there was no documentation for the metadata of the files, so I created a little Markdown file explaining what every piece of metadata represents + putting all of them together, as all the detects don't have the same amount of metadata.

I didn't know where to put this information, so I created a new file, feel free to suggest any other location.

There is also some of them that I don't know their functionality, I'll comment them on line comments.



Patch:
diff --git a/.gitignore b/.gitignore
index e8cdbc1c..3214a109 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@ metadata.json
 .project
 *.log
 tmp
+/.nyc_output
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 7c5482fe..370282ce 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,31 +1,21 @@
-sudo: false
+os: linux
+dist: xenial
 language: node_js
 node_js:
   - 10
   - 12
+  - 14
 before_install:
   - npm install -g npm@latest
 before_script:
+  - |
+      if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(.md)'
+      then
+        echo "Only doc files were updated, not running the CI."
+        exit
+      fi
   - npm install -g gulp-cli
-  - export CI_BUILD_NUMBER=$(git rev-parse HEAD)
-  - if [ "${TRAVIS_NODE_VERSION}" = "0.12" ] && [ "${TRAVIS_REPO_SLUG}" = "modernizr-savage/Modernizr" ]; then export BROWSER_COVERAGE=true; fi
 after_success:
-  - |
-      # Automatically update the content from the `gh-pages` branch
-      $(npm bin)/update-branch --commands "gulp copy:gh-pages" \
-                               --commit-message "Hey server, this content is for you! [skip ci]" \
-                               --directory "gh-pages" \
-                               --distribution-branch "gh-pages" \
-                               --source-branch "master"
+  - ./node_modules/.bin/nyc report --reporter=text-lcov | ./node_modules/.bin/codecov --pipe
 script:
   - npm test
-notifications:
-  webhooks:
-    - http://patrickkettner.com:8080/savage/travis
-env:
-  global:
-  - secure: F5Xmkr+31YIXvtS1sqt2PDCI1CEQN/zpoJBKzqYXIUZVLvyH/4zVxRRa2LYleLRSIc+YZfzE3YZjfwWUC9vMcEREk380gRwSot9mhVbCOmNd1qhrFocSAzpI0fnwPUMfQknhE/mLuXnFQ0OAJBFzVCFOHHhKTlL8q+I7dNUhErc=
-  - secure: bSjU9XMTm3bmROc4rNERCPDgoa30dAJTJg16o3yYGjCyLhl6JdXSgh53rFu4IKg8hT4wvZB9/X7wiAk8s5Md+U1q746meTvNe0D6SCmgjtvaqJOY0Gina+MvRgYtqfYZByapotIO6+zy9bURixIQbo1ZIxeuux/0glGYG8yPr6k=
-  - secure: mBLGOwhFac+42FrM5FMNxsEgHIBnhVzBywuusyIOl3HDF6AU6pMb1KObVdmWzvUWnloQsh8d0xJ36YSq0upJ1kAs/PyAC1mJJgWvTjojBdkqeEndLbupmB1UT4Zh61Gzaln8dueWqVTRM9em0aHzPSKs+sSB7PpOeWzWL+19cOc=
-  - secure: GijLoFIOjQ0elKMTLa58uS1Cgti+VzBOYXOPKKLikD8IAyNq2LRoochlYopAI2wAEMmX5UZAUpPiziyVGDCNmaDxCk4hmaG/WEFAHByu4PIcQaRGdqYT/kiGsn5vvKadHv34R2Fs3A0q1Fzx5mpAOJwKpANNvOHcHIESlvWzPvM=
-  - secure: HAztDqXTzRcsZ8StX4rDZiY2116SBQFWF9faf5/pl5UByj55lk6jYuC+DCB5ZHeRvmndMNjGqHLS3AvQZ5wMRVOlHfFMZdXGu+oONjFEWbZ9SHU5YNE8oRWIHB7XsFafvQpyAshReV1ogUj08cKFPC60EG8K3drxH2ybXcSpVi0=
diff --git a/HOW_TO_WRITE_FEATURE_DETECTS.md b/HOW_TO_WRITE_FEATURE_DETECTS.md
new file mode 100644
index 00000000..b81c4a9a
--- /dev/null
+++ b/HOW_TO_WRITE_FEATURE_DETECTS.md
@@ -0,0 +1,55 @@
+# How to Write Feature Detects
+The scope of this file is to help you to create new feature detects or edit existing ones. Here you will find details and guidelines that will help you understand how
+Modernizr works.
+
+#### Table of contents
+[Metadata](#metadata)
+
+## Metadata
+A JSON fragment at the top of every feature detect in Modernizr represents the metadata of the test. This data is used, for example, to build the webpage.
+### Schema
+The following code represents an example of the schema (it does not represent a real test):
+```json
+/*!
+{
+  "name": "JPEG 2000",
+  "property": "jpeg2000",
+  "tags": ["media", "image"],
+  "caniuse": "jpeg2000",
+  "authors": ["Markel Ferro (@MarkelFe)", "@rejas", "Brandom Aaron"],
+  "builderAliases": ["jpeg2"],
+  "polyfills": ["jpeg2000js"],
+  "aliases": ["jpeg-2000", "jpg2"],
+  "async": true,
+  "warnings": ["These tests currently require document.body to be present"],
+  "knownBugs": ["This will false positive in IE6"],
+  "notes": [{
+    "name": "Specification",
+    "href": "https://www.w3.org/"
+  }, {
+    "name": "Github issue",
+    "href": "https://github.com/Modernizr/"
+  }]
+}
+!*/
+/* DOC
+Here it would go a description of the feature test. You can use **markdown** here :)
+*/
+```
+> Metadata does no need to appear in a set order, however, it is common to see `name` and `property` at the top while `notes` at the bottom.
+
+### Item description
+|                  | Necessity |                      Description                     |                                       Notes                                      |
+|------------------|:---------:|:----------------------------------------------------:|:--------------------------------------------------------------------------------:|
+| `name`           |  required |             Name of the feature detection            |                                                                                  |
+| `property`       |  required | The property name established in `Modernizr.addTest` |                   It must be lowercase, without any punctuation                  |
+| `tags`           |  optional |    A group that encapsulates many feature detects    |                                                                                  |
+| `caniuse`        |  optional |      A conversion table of caniuse and Modernizr     |      Consider adding it to [caniuse.js](test/browser/integration/caniuse.js)     |
+| `authors`        |  optional |          List of contributors of the script          |                                                                                  |
+| `builderAliases` |  optional |     Used by CI and the web when tests are renamed    |                         Should not be needed in new tests                        |
+| `polyfills`      |  optional |     Available polyfills for not working versions     | Any polyfill listed needs to be included in [polyfills.json](lib/polyfills.json) |
+| `aliases`        |  optional |   Used if a feature has more than a canonical name   |                             Legacy only - do not use                             |
+| `async`          |  optional |       If the test supports async functionality       |                                 Defaults to false                                |
+| `warnings`       |  optional |        Notes to the developer using the script       |                          Don't mistake it for knownBugs                          |
+| `knownBugs`      |  optional |  Bugs known of the test (e.g.: doesn't work in IE6)  |                                                                                  |
+| `notes`          |  optional |                  Links to resources                  |                                                                                  |
diff --git a/README.md b/README.md
index afd60412..467ac1d9 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,8 @@
 # Modernizr 
 [![npm version](https://badge.fury.io/js/modernizr.svg)](https://badge.fury.io/js/modernizr)
 [![Build Status](https://api.travis-ci.org/Modernizr/Modernizr.svg?branch=master)](https://travis-ci.org/Modernizr/Modernizr) 
+[![Build Status](https://ci.appveyor.com/api/projects/status/github/Modernizr/modernizr?branch=master&svg=true)](https://ci.appveyor.com/project/rejas/modernizr) 
+[![codecov](https://codecov.io/gh/Modernizr/Modernizr/branch/master/graph/badge.svg)](https://codecov.io/gh/Modernizr/Modernizr)
 [![Inline docs](https://inch-ci.org/github/Modernizr/Modernizr.svg?branch=master)](https://inch-ci.org/github/Modernizr/Modernizr)
 
 ##### Modernizr is a JavaScript library that detects HTML5 and CSS3 features in the user’s browser.
@@ -16,6 +18,12 @@ Modernizr tests which native CSS3 and HTML5 features are available in the curren
 
 - Dropped Node 8 Support, please upgrade to Node v10
 
+- These tests got removed:
+
+    - `touchevents`: [discussion](https://github.com/Modernizr/Modernizr/pull/2432) 
+    - `unicode`: [discussion](https://github.com/Modernizr/Modernizr/issues/2468) 
+    - `templatestrings`: duplicate of the es6 detect `stringtemplate`
+    
 ## New Asynchronous Event Listeners
 
 Often times people want to know when an asynchronous test is done so they can allow their application to react to it.
@@ -105,16 +113,6 @@ and navigating to these two URLs:
 http://localhost:8080/test/unit.html
 http://localhost:8080/test/integration.html
 ```
- 
- 
-## Deprecation
-
-These tests are considered deprecated. They are not included anymore in the default build
-and will be removed in the next major version:
-
-- `touchevents` (in 4.0)
-- `unicode` (in 4.0) 
-
 
 ## Code of Conduct
 
diff --git a/appveyor.yml b/appveyor.yml
index f1cac827..94282258 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -2,6 +2,7 @@ environment:
   matrix:
     - nodejs_version: 10
     - nodejs_version: 12
+    - nodejs_version: 14
 
 install:
   - ps: Install-Product node $env:nodejs_version
@@ -12,6 +13,11 @@ build: off
 before_test:
   - npm install -g gulp-cli
 
+# Skipping specific commit files: https://www.appveyor.com/docs/appveyor-yml and https://www.appveyor.com/docs/how-to/filtering-commits
+skip_commits:
+  files:
+    - '**/*.md'
+
 test_script:
   - node --version
   - npm --version
diff --git a/feature-detects/css/cubicbezierrange.js b/feature-detects/css/cubicbezierrange.js
index 39677c7a..8f94508e 100644
--- a/feature-detects/css/cubicbezierrange.js
+++ b/feature-detects/css/cubicbezierrange.js
@@ -5,7 +5,7 @@
   "tags": ["css"],
   "builderAliases": ["css_cubicbezierrange"],
   "authors": ["@calvein"],
-  "warnings": ["cubic-bezier values can't be > 1 for Webkit until [bug #45761](https://bugs.webkit.org/show_bug.cgi?id=45761) is fixed"],
+  "warnings": ["In old versions (pre-2013) cubic-bezier values can't be > 1 due to Webkit [bug #45761](https://bugs.webkit.org/show_bug.cgi?id=45761)"],
   "notes": [{
     "name": "Comprehensive Compat Chart",
     "href": "https://muddledramblings.com/table-of-css3-border-radius-compliance/"
diff --git a/feature-detects/css/generatedcontent.js b/feature-detects/css/generatedcontent.js
index 3a3949d8..4ed09120 100644
--- a/feature-detects/css/generatedcontent.js
+++ b/feature-detects/css/generatedcontent.js
@@ -3,7 +3,7 @@
   "name": "CSS Generated Content",
   "property": "generatedcontent",
   "tags": ["css"],
-  "warnings": ["Android won't return correct height for anything below 7px #738"],
+  "warnings": ["Android may not return correct height for anything below 7px in old versions #738"],
   "notes": [{
     "name": "W3C Spec",
     "href": "https://www.w3.org/TR/css3-selectors/#gen-content"
diff --git a/feature-detects/css/nthchild.js b/feature-detects/css/nthchild.js
index 888f1e21..1e2cc812 100644
--- a/feature-detects/css/nthchild.js
+++ b/feature-detects/css/nthchild.js
@@ -12,7 +12,7 @@
     "href": "https://www.sitepoint.com/atoz-css-screencast-nth-child/"
   }],
   "authors": ["@emilchristensen"],
-  "warnings": ["Known false negative in Safari 3.1 and Safari 3.2.2"]
+  "knownBugs": ["Known false negative in Safari 3.1 and Safari 3.2.2"]
 }
 !*/
 /* DOC
diff --git a/feature-detects/css/overflow-scrolling.js b/feature-detects/css/overflow-scrolling.js
index 2de8aed8..5e3668db 100644
--- a/feature-detects/css/overflow-scrolling.js
+++ b/feature-detects/css/overflow-scrolling.js
@@ -4,10 +4,12 @@
   "property": "overflowscrolling",
   "tags": ["css"],
   "builderAliases": ["css_overflow_scrolling"],
-  "warnings": ["Introduced in iOS5b2. API is subject to change."],
   "notes": [{
     "name": "Article on iOS overflow scrolling",
     "href": "https://css-tricks.com/snippets/css/momentum-scrolling-on-ios-overflow-elements/"
+  }, {
+    "name": "MDN Docs",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-overflow-scrolling"
   }]
 }
 !*/
diff --git a/feature-detects/css/positionsticky.js b/feature-detects/css/positionsticky.js
index 0cdb643e..5e67c0e7 100644
--- a/feature-detects/css/positionsticky.js
+++ b/feature-detects/css/positionsticky.js
@@ -6,7 +6,7 @@
   "builderAliases": ["css_positionsticky"],
   "notes": [{
     "name": "Chrome bug report",
-    "href":"https://bugs.chromium.org/p/chromium/issues/detail?id=322972"
+    "href": "https://bugs.chromium.org/p/chromium/issues/detail?id=322972"
   }],
   "warnings": ["using position:sticky on anything but top aligned elements is buggy in Chrome < 37 and iOS <=7+"]
 }
diff --git a/feature-detects/css/textalignlast.js b/feature-detects/css/textalignlast.js
index 72b98b10..f15798e5 100644
--- a/feature-detects/css/textalignlast.js
+++ b/feature-detects/css/textalignlast.js
@@ -4,7 +4,7 @@
   "property": "textalignlast",
   "caniuse": "css-text-align-last",
   "tags": ["css"],
-  "knownBugs": ["IE does not support the 'start' or 'end' values."],
+  "warnings": ["IE does not support the 'start' or 'end' values."],
   "notes": [{
     "name": "Quirksmode",
     "href": "https://www.quirksmode.org/css/text/textalignlast.html"
diff --git a/feature-detects/css/transforms3d.js b/feature-detects/css/transforms3d.js
index 90aad7df..ef87237e 100644
--- a/feature-detects/css/transforms3d.js
+++ b/feature-detects/css/transforms3d.js
@@ -4,8 +4,8 @@
   "property": "csstransforms3d",
   "caniuse": "transforms3d",
   "tags": ["css"],
-  "warnings": [
-    "Chrome may occasionally fail this test on some systems; more info: https://bugs.chromium.org/p/chromium/issues/detail?id=129004"
+  "knownBugs": [
+    "Chrome may occasionally fail this test on some systems; more info: https://bugs.chromium.org/p/chromium/issues/detail?id=129004, however, the issue has since been closed (marked as fixed)."
   ]
 }
 !*/
diff --git a/feature-detects/es6/array.js b/feature-detects/es6/array.js
index ca0af02e..2e160186 100644
--- a/feature-detects/es6/array.js
+++ b/feature-detects/es6/array.js
@@ -3,12 +3,14 @@
   "name": "ES6 Array",
   "property": "es6array",
   "notes": [{
-    "name": "unofficial ECMAScript 6 draft specification",
-    "href": "https://web.archive.org/web/20180825202128/https://tc39.github.io/ecma262/"
+    "name": "ECMAScript 6 specification",
+    "href": "https://www.ecma-international.org/ecma-262/6.0/index.html"
+  }, {
+    "name": "Last ECMAScript specification",
+    "href": "https://www.ecma-international.org/ecma-262/index.html"
   }],
   "polyfills": ["es6shim"],
   "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."],
   "tags": ["es6"]
 }
 !*/
diff --git a/feature-detects/es6/collections.js b/feature-detects/es6/collections.js
index 61a09a3a..8f178192 100644
--- a/feature-detects/es6/collections.js
+++ b/feature-detects/es6/collections.js
@@ -3,12 +3,14 @@
   "name": "ES6 Collections",
   "property": "es6collections",
   "notes": [{
-    "name": "unofficial ECMAScript 6 draft specification",
-    "href": "https://web.archive.org/web/20180825202128/https://tc39.github.io/ecma262/"
+    "name": "ECMAScript 6 specification",
+    "href": "https://www.ecma-international.org/ecma-262/6.0/index.html"
+  }, {
+    "name": "Last ECMAScript specification",
+    "href": "https://www.ecma-international.org/ecma-262/index.html"
   }],
   "polyfills": ["es6shim", "weakmap"],
   "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."],
   "tags": ["es6"]
 }
 !*/
diff --git a/feature-detects/es6/math.js b/feature-detects/es6/math.js
index a76450ea..3b5c13a4 100644
--- a/feature-detects/es6/math.js
+++ b/feature-detects/es6/math.js
@@ -3,12 +3,14 @@
   "name": "ES6 Math",
   "property": "es6math",
   "notes": [{
-    "name": "unofficial ECMAScript 6 draft specification",
-    "href": "https://web.archive.org/web/20180825202128/https://tc39.github.io/ecma262/"
+    "name": "ECMAScript 6 specification",
+    "href": "https://www.ecma-international.org/ecma-262/6.0/index.html"
+  }, {
+    "name": "Last ECMAScript specification",
+    "href": "https://www.ecma-international.org/ecma-262/index.html"
   }],
   "polyfills": ["es6shim"],
   "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."],
   "tags": ["es6"]
 }
 !*/
diff --git a/feature-detects/es6/number.js b/feature-detects/es6/number.js
index 687c646f..132ebf5c 100644
--- a/feature-detects/es6/number.js
+++ b/feature-detects/es6/number.js
@@ -3,12 +3,14 @@
   "name": "ES6 Number",
   "property": "es6number",
   "notes": [{
-    "name": "unofficial ECMAScript 6 draft specification",
-    "href": "https://web.archive.org/web/20180825202128/https://tc39.github.io/ecma262/"
+    "name": "ECMAScript 6 specification",
+    "href": "https://www.ecma-international.org/ecma-262/6.0/index.html"
+  }, {
+    "name": "Last ECMAScript specification",
+    "href": "https://www.ecma-international.org/ecma-262/index.html"
   }],
   "polyfills": ["es6shim"],
   "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."],
   "tags": ["es6"]
 }
 !*/
diff --git a/feature-detects/es6/object.js b/feature-detects/es6/object.js
index 1afee449..66c75f0f 100644
--- a/feature-detects/es6/object.js
+++ b/feature-detects/es6/object.js
@@ -3,12 +3,14 @@
   "name": "ES6 Object",
   "property": "es6object",
   "notes": [{
-    "name": "unofficial ECMAScript 6 draft specification",
-    "href": "https://web.archive.org/web/20180825202128/https://tc39.github.io/ecma262/"
+    "name": "ECMAScript 6 specification",
+    "href": "https://www.ecma-international.org/ecma-262/6.0/index.html"
+  }, {
+    "name": "Last ECMAScript specification",
+    "href": "https://www.ecma-international.org/ecma-262/index.html"
   }],
   "polyfills": ["es6shim"],
   "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."],
   "tags": ["es6"]
 }
 !*/
diff --git a/feature-detects/es6/spread-array.js b/feature-detects/es6/spread-array.js
index 9f8fb9d9..49c1f9b6 100644
--- a/feature-detects/es6/spread-array.js
+++ b/feature-detects/es6/spread-array.js
@@ -3,7 +3,7 @@
   "name": "ES6 Spread array",
   "property": "spreadarray",
   "notes": [{
-    "name": "ECMAScript 6 language specification",
+    "name": "ECMAScript Specification",
     "href": "https://tc39.es/ecma262/#sec-array-initializer"
   },
   {
diff --git a/feature-detects/es6/string-template.js b/feature-detects/es6/string-template.js
index b672a093..afaa72f4 100644
--- a/feature-detects/es6/string-template.js
+++ b/feature-detects/es6/string-template.js
@@ -3,6 +3,7 @@
   "name": "ES6 Template Strings",
   "property": "stringtemplate",
   "caniuse": "template-literals",
+  "builderAliases": ["templatestrings"],
   "notes": [{
     "name": "ECMAScript 6 draft specification",
     "href": "https://tc39wiki.calculist.org/es6/template-strings/"
diff --git a/feature-detects/es6/string.js b/feature-detects/es6/string.js
index 877c9fb3..1f7e0979 100644
--- a/feature-detects/es6/string.js
+++ b/feature-detects/es6/string.js
@@ -3,12 +3,14 @@
   "name": "ES6 String",
   "property": "es6string",
   "notes": [{
-    "name": "unofficial ECMAScript 6 draft specification",
-    "href": "https://web.archive.org/web/20180825202128/https://tc39.github.io/ecma262/"
+    "name": "ECMAScript 6 Specification",
+    "href": "https://www.ecma-international.org/ecma-262/6.0/index.html"
+  }, {
+    "name": "Last ECMAScript Specification",
+    "href": "https://www.ecma-international.org/ecma-262/index.html"
   }],
   "polyfills": ["es6shim"],
   "authors": ["Ron Waldon (@jokeyrhyme)"],
-  "warnings": ["ECMAScript 6 is still a only a draft, so this detect may not match the final specification or implementations."],
   "tags": ["es6"]
 }
 !*/
diff --git a/feature-detects/es7/array.js b/feature-detects/es7/array.js
index 0d1dda3a..56d85a23 100644
--- a/feature-detects/es7/array.js
+++ b/feature-detects/es7/array.js
@@ -3,11 +3,10 @@
   "name": "ES7 Array",
   "property": "es7array",
   "notes": [{
-    "name": "official ECMAScript 7 array draft specification",
+    "name": "ECMAScript array Specification",
     "href": "https://tc39.es/ecma262/#sec-array.prototype.includes"
   }],
   "authors": ["dabretin"],
-  "warnings": ["ECMAScript 7 is still a only a draft, so this detect may not match the final specification or implementations."],
   "tags": ["es7"]
 }
 !*/
diff --git a/feature-detects/es7/rest-destructuring.js b/feature-detects/es7/rest-destructuring.js
index ced542e5..2ccb1cd4 100644
--- a/feature-detects/es7/rest-destructuring.js
+++ b/feature-detects/es7/rest-destructuring.js
@@ -4,11 +4,10 @@
   "property": ["restdestructuringarray", "restdestructuringobject"],
   "caniuse" : "destructuring%20assignment",
   "notes": [{
-    "name": "official ECMAScript 7 Destructuring Assignment draft specification",
+    "name": "ECMAScript Destructuring Assignment Specification",
     "href": "https://tc39.es/ecma262/#sec-destructuring-assignment"
   }],
   "authors": ["dabretin"],
-  "warnings": ["ECMAScript 7 is still a only a draft, so this detect may not match the final specification or implementations."],
   "tags": ["es7"]
 }
 !*/
diff --git a/feature-detects/es7/spread-object.js b/feature-detects/es7/spread-object.js
index 35b1c178..25d6bb83 100644
--- a/feature-detects/es7/spread-object.js
+++ b/feature-detects/es7/spread-object.js
@@ -3,11 +3,10 @@
   "name": "ES7 Spread object",
   "property": "spreadobject",
   "notes": [{
-    "name": "official ECMAScript 7 array draft specification",
-    "href": "http://www.ecma-international.org/ecma-262/9.0/#sec-object-initializer"
+    "name": "ECMAScript array Specification",
+    "href": "http://www.ecma-international.org/ecma-262/#sec-object-initializer"
   }],
   "authors": ["dabretin"],
-  "warnings": ["ECMAScript 7 is still a only a draft, so this detect may not match the final specification or implementations."],
   "tags": ["es7"]
 }
 !*/
diff --git a/feature-detects/es8/object.js b/feature-detects/es8/object.js
index b4a82721..fa54f6be 100644
--- a/feature-detects/es8/object.js
+++ b/feature-detects/es8/object.js
@@ -3,15 +3,14 @@
   "name": "ES8 Object",
   "property": "es8object",
   "notes": [{
-    "name": "ECMAScript 8 draft specification: Object.entries",
-    "href": "https://www.ecma-international.org/ecma-262/8.0/#sec-object.entries"
+    "name": "ECMAScript specification: Object.entries",
+    "href": "https://www.ecma-international.org/ecma-262/#sec-object.entries"
   }, {
-    "name": "ECMAScript 8 draft specification: Object.values",
-    "href": "https://www.ecma-international.org/ecma-262/8.0/#sec-object.values"
+    "name": "ECMAScript specification: Object.values",
+    "href": "https://www.ecma-international.org/ecma-262/#sec-object.values"
   }],
   "caniuse": "object-entries,object-values",
   "authors": ["dabretin"],
-  "warnings": ["ECMAScript 8 is still a only a draft, so this detect may not match the final specification or implementations."],
   "tags": ["es8"]
 }
 !*/
diff --git a/feature-detects/img/avif.js b/feature-detects/img/avif.js
new file mode 100644
index 00000000..9c14a9ec
--- /dev/null
+++ b/feature-detects/img/avif.js
@@ -0,0 +1,30 @@
+/*!
+{
+  "name": "AVIF",
+  "async": true,
+  "property": "avif",
+  "caniuse": "avif",
+  "tags": ["image"],
+  "authors": ["Markel Ferro (@MarkelFe)"],
+  "polyfills": ["avifjs"],
+  "notes": [{
+    "name": "Avif Spec",
+    "href": "https://aomediacodec.github.io/av1-avif/"
+  }]
+}
+!*/
+/* DOC
+Test for AVIF support
+*/
+define(['Modernizr', 'addTest'], function(Modernizr, addTest) {
+
+    Modernizr.addAsyncTest(function() {
+      var image = new Image();
+  
+      image.onload = image.onerror = function() {
+        addTest('avif', image.width === 1);
+      };
+  
+      image.src = 'data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAAEcbWV0YQAAAAAAAABIaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGNhdmlmIC0gaHR0cHM6Ly9naXRodWIuY29tL2xpbmstdS9jYXZpZgAAAAAeaWxvYwAAAAAEQAABAAEAAAAAAUQAAQAAABcAAAAqaWluZgEAAAAAAAABAAAAGmluZmUCAAAAAAEAAGF2MDFJbWFnZQAAAAAOcGl0bQAAAAAAAQAAAHJpcHJwAAAAUmlwY28AAAAQcGFzcAAAAAEAAAABAAAAFGlzcGUAAAAAAAAAAQAAAAEAAAAQcGl4aQAAAAADCAgIAAAAFmF2MUOBAAwACggYAAYICGgIIAAAABhpcG1hAAAAAAAAAAEAAQUBAoMDhAAAAB9tZGF0CggYAAYICGgIIBoFHiAAAEQiBACwDoA=';
+    });
+  });
\ No newline at end of file
diff --git a/feature-detects/postmessage.js b/feature-detects/postmessage.js
index c23941e8..c1d13792 100644
--- a/feature-detects/postmessage.js
+++ b/feature-detects/postmessage.js
@@ -8,8 +8,11 @@
     "href": "https://www.w3.org/TR/webmessaging/#crossDocumentMessages"
   }],
   "polyfills": ["easyxdm", "postmessage-jquery"],
-  "knownBugs": ["structuredclones - Android 2&3 can not send a structured clone of dates, filelists or regexps"],
-  "warnings": ["Some old WebKit versions have bugs. Stick with object, array, number and pixeldata to be safe."]
+  "knownBugs": [
+    "structuredclones - Android 2&3 can not send a structured clone of dates, filelists or regexps.",
+    "Some old WebKit versions have bugs."
+  ],
+  "warnings": ["To be safe you should stick with object, array, number and pixeldata."]
 }
 !*/
 /* DOC
diff --git a/feature-detects/touchevents.js b/feature-detects/touchevents.js
deleted file mode 100644
index 829043a6..00000000
--- a/feature-detects/touchevents.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/*!
-{
-  "name": "Touch Events",
-  "property": "touchevents",
-  "caniuse": "touch",
-  "tags": ["media", "attribute"],
-  "notes": [{
-    "name": "Touch Events spec",
-    "href": "https://www.w3.org/TR/2013/WD-touch-events-20130124/"
-  }],
-  "warnings": [
-    "** DEPRECATED see https://github.com/Modernizr/Modernizr/pull/2432 **",
-    "Indicates if the browser supports the Touch Events spec, and does not necessarily reflect a touchscreen device"
-  ],
-  "knownBugs": [
-    "False-positive on some configurations of Nokia N900",
-    "False-positive on some BlackBerry 6.0 builds – https://github.com/Modernizr/Modernizr/issues/372#issuecomment-3112695"
-  ]
-}
-!*/
-/* DOC
-Indicates if the browser supports the W3C Touch Events API.
-
-This *does not* necessarily reflect a touchscreen device:
-
-* Older touchscreen devices only emulate mouse events
-* Modern IE touch devices implement the Pointer Events API instead: use `Modernizr.pointerevents` to detect support for that
-* Some browsers & OS setups may enable touch APIs when no touchscreen is connected
-* Future browsers may implement other event models for touch interactions
-
-See this article: [You Can't Detect A Touchscreen](http://www.stucox.com/blog/you-cant-detect-a-touchscreen/).
-
-It's recommended to bind both mouse and touch/pointer events simultaneously – see [this HTML5 Rocks tutorial](https://www.html5rocks.com/en/mobile/touchandmouse/).
-
-This test will also return `true` for Firefox 4 Multitouch support.
-*/
-define(['Modernizr', 'prefixes', 'mq'], function(Modernizr, prefixes, mq) {
-  // Chrome (desktop) used to lie about its support on this, but that has since been rectified: https://bugs.chromium.org/p/chromium/issues/detail?id=36415
-  // Chrome also changed its behaviour since v70 and recommends the TouchEvent object for detection: https://www.chromestatus.com/feature/4764225348042752
-  Modernizr.addTest('touchevents', function() {
-    if (('ontouchstart' in window) || window.TouchEvent || window.DocumentTouch && document instanceof DocumentTouch) {
-      return true;
-    }
-
-    // include the 'heartz' as a way to have a non matching MQ to help terminate the join
-    // https://github.com/Modernizr/Modernizr/issues/1814
-    var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
-    return mq(query);
-  });
-});
diff --git a/feature-detects/unicode.js b/feature-detects/unicode.js
deleted file mode 100644
index 38b5d9f2..00000000
--- a/feature-detects/unicode.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/*!
-{
-  "name": "Unicode characters",
-  "property": "unicode",
-  "tags": ["encoding"],
-  "warnings": [
-    "** DEPRECATED see https://github.com/Modernizr/Modernizr/issues/2468 **",
-    "positive Unicode support doesn't mean you can use it inside <title>, this seems more related to OS & Language packs"
-  ]
-}
-!*/
-/* DOC
-Detects if unicode characters are supported in the current document.
-*/
-define(['Modernizr', 'createElement', 'testStyles', 'isSVG'], function(Modernizr, createElement, testStyles, isSVG) {
-  /**
-   * Unicode special character support
-   *
-   * Detection is made by testing missing glyph box rendering against star character
-   * If widths are the same, this "probably" means the browser didn't support the star character and rendered a glyph box instead
-   * Just need to ensure the font characters have different widths
-   */
-  Modernizr.addTest('unicode', function() {
-    var bool;
-    var missingGlyph = createElement('span');
-    var star = createElement('span');
-
-    testStyles('#modernizr{font-family:Arial,sans;font-size:300em;}', function(node) {
-
-      missingGlyph.innerHTML = isSVG ? '\u5987' : '&#5987;';
-      star.innerHTML = isSVG ? '\u2606' : '&#9734;';
-
-      node.appendChild(missingGlyph);
-      node.appendChild(star);
-
-      bool = 'offsetWidth' in missingGlyph && missingGlyph.offsetWidth !== star.offsetWidth;
-    });
-
-    return bool;
-  });
-});
diff --git a/feature-detects/websockets.js b/feature-detects/websockets.js
index 61342cd1..cb21f7f9 100644
--- a/feature-detects/websockets.js
+++ b/feature-detects/websockets.js
@@ -5,9 +5,7 @@
   "authors": ["Phread (@fearphage)", "Mike Sherov (@mikesherov)", "Burak Yigit Kaya (@BYK)"],
   "caniuse": "websockets",
   "tags": ["html5"],
-  "warnings": [
-    "This test will reject any old version of WebSockets even if it is not prefixed such as in Safari 5.1"
-  ],
+  "knownBugs": ["This test will reject any old version of WebSockets even if it is not prefixed such as in Safari 5.1"],
   "notes": [{
     "name": "CLOSING State and Spec",
     "href": "https://www.w3.org/TR/websockets/#the-websocket-interface"
diff --git a/feature-detects/workers/blobworkers.js b/feature-detects/workers/blobworkers.js
index a79467c2..560a8d6d 100644
--- a/feature-detects/workers/blobworkers.js
+++ b/feature-detects/workers/blobworkers.js
@@ -8,7 +8,7 @@
     "name": "W3C Spec",
     "href": "https://www.w3.org/TR/workers/"
   }],
-  "knownBugs": ["This test may output garbage to console."],
+  "warnings": ["This test may output garbage to console."],
   "authors": ["Jussi Kalliokoski"],
   "async": true
 }
diff --git a/feature-detects/workers/dataworkers.js b/feature-detects/workers/dataworkers.js
index dc6f91ca..c4fe7c3c 100644
--- a/feature-detects/workers/dataworkers.js
+++ b/feature-detects/workers/dataworkers.js
@@ -8,7 +8,7 @@
     "name": "W3C Spec",
     "href": "https://www.w3.org/TR/workers/"
   }],
-  "knownBugs": ["This test may output garbage to console."],
+  "warnings": ["This test may output garbage to console."],
   "authors": ["Jussi Kalliokoski"],
   "async": true
 }
diff --git a/lib/config-all.json b/lib/config-all.json
index 50deadfb..99163b3c 100644
--- a/lib/config-all.json
+++ b/lib/config-all.json
@@ -213,6 +213,7 @@
     "iframe/seamless",
     "iframe/srcdoc",
     "img/apng",
+    "img/avif",
     "img/crossorigin",
     "img/jpeg2000",
     "img/jpegxr",
@@ -281,7 +282,6 @@
     "svg/foreignobject",
     "svg/inline",
     "svg/smil",
-    "templatestrings",
     "textarea/maxlength",
     "textencoding",
     "typed-arrays",
diff --git a/lib/metadata.js b/lib/metadata.js
index ea9c0278..6ff5474b 100644
--- a/lib/metadata.js
+++ b/lib/metadata.js
@@ -66,8 +66,10 @@ function metadata(cb) {
       metadata.path = './' + (start + '/' + file).replace(baseDir, '').replace(/\\/g, '/');
       metadata.amdPath = metadata.path.replace(/^\.\/feature\-detects/, 'test').replace(/\.js$/i, '');
 
-      if (!metadata.name) {
-        metadata.name = metadata.amdPath;
+      // Force minimal metadata #2551
+      // Consider adding new tests in test/node/lib/metadata.js if you add new minimal requirements
+      if (!metadata.name || !metadata.property) {
+        throw new Error('Minimal metadata not found in `' + file + '`')
       }
 
       var pfs = [];
diff --git a/lib/polyfills.json b/lib/polyfills.json
index cd8ba944..1b367e88 100644
--- a/lib/polyfills.json
+++ b/lib/polyfills.json
@@ -780,5 +780,11 @@
     "authors": ["Tom Van Cutsem"],
     "href": "https://github.com/tvcutsem/harmony-reflect",
     "licenses": ["Apache2"]
+  },
+  "avifjs": {
+    "name": "Avif.js",
+    "authors": ["Kagami"],
+    "href": "https://github.com/Kagami/avif.js",
+    "licenses": ["CC0"]
   }
 }
diff --git a/package-lock.json b/package-lock.json
index d39b83c4..a1381823 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,30 +20,30 @@
       }
     },
     "@babel/compat-data": {
-      "version": "7.9.0",
-      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.0.tgz",
-      "integrity": "sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g==",
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.9.6.tgz",
+      "integrity": "sha512-5QPTrNen2bm7RBc7dsOmcA5hbrS4O2Vhmk5XOL4zWW/zD/hV0iinpefDlkm+tBBy8kDtFaaeEvmAqt+nURAV2g==",
       "dev": true,
       "requires": {
-        "browserslist": "^4.9.1",
+        "browserslist": "^4.11.1",
         "invariant": "^2.2.4",
         "semver": "^5.5.0"
       }
     },
     "@babel/core": {
-      "version": "7.9.0",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz",
-      "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==",
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz",
+      "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==",
       "dev": true,
       "requires": {
         "@babel/code-frame": "^7.8.3",
-        "@babel/generator": "^7.9.0",
+        "@babel/generator": "^7.9.6",
         "@babel/helper-module-transforms": "^7.9.0",
-        "@babel/helpers": "^7.9.0",
-        "@babel/parser": "^7.9.0",
+        "@babel/helpers": "^7.9.6",
+        "@babel/parser": "^7.9.6",
         "@babel/template": "^7.8.6",
-        "@babel/traverse": "^7.9.0",
-        "@babel/types": "^7.9.0",
+        "@babel/traverse": "^7.9.6",
+        "@babel/types": "^7.9.6",
         "convert-source-map": "^1.7.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.1",
@@ -63,6 +63,29 @@
             "@babel/highlight": "^7.8.3"
           }
         },
+        "@babel/generator": {
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz",
+          "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "^7.9.6",
+            "jsesc": "^2.5.1",
+            "lodash": "^4.17.13",
+            "source-map": "^0.5.0"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.9.5",
+          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz",
+          "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "^7.8.3",
+            "@babel/template": "^7.8.3",
+            "@babel/types": "^7.9.5"
+          }
+        },
         "@babel/highlight": {
           "version": "7.9.0",
           "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
@@ -74,6 +97,48 @@
             "js-tokens": "^4.0.0"
           }
         },
+        "@babel/parser": {
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
+          "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==",
+          "dev": true
+        },
+        "@babel/traverse": {
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz",
+          "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.8.3",
+            "@babel/generator": "^7.9.6",
+            "@babel/helper-function-name": "^7.9.5",
+            "@babel/helper-split-export-declaration": "^7.8.3",
+            "@babel/parser": "^7.9.6",
+            "@babel/types": "^7.9.6",
+            "debug": "^4.1.0",
+            "globals": "^11.1.0",
+            "lodash": "^4.17.13"
+          }
+        },
+        "@babel/types": {
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
+          "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-validator-identifier": "^7.9.5",
+            "lodash": "^4.17.13",
+            "to-fast-properties": "^2.0.0"
+          },
+          "dependencies": {
+            "@babel/helper-validator-identifier": {
+              "version": "7.9.5",
+              "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
+              "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==",
+              "dev": true
+            }
+          }
+        },
         "convert-source-map": {
           "version": "1.7.0",
           "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
@@ -117,13 +182,13 @@
       }
     },
     "@babel/helper-compilation-targets": {
-      "version": "7.8.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz",
-      "integrity": "sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw==",
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.9.6.tgz",
+      "integrity": "sha512-x2Nvu0igO0ejXzx09B/1fGBxY9NXQlBW2kZsSxCJft+KHN8t9XWzIvFxtPHnBOAXpVsdxZKZFbRUC8TsNKajMw==",
       "dev": true,
       "requires": {
-        "@babel/compat-data": "^7.8.6",
-        "browserslist": "^4.9.1",
+        "@babel/compat-data": "^7.9.6",
+        "browserslist": "^4.11.1",
         "invariant": "^2.2.4",
         "levenary": "^1.1.1",
         "semver": "^5.5.0"
@@ -261,15 +326,102 @@
       }
     },
     "@babel/helper-replace-supers": {
-      "version": "7.8.6",
-      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz",
-      "integrity": "sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==",
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz",
+      "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==",
       "dev": true,
       "requires": {
         "@babel/helper-member-expression-to-functions": "^7.8.3",
         "@babel/helper-optimise-call-expression": "^7.8.3",
-        "@babel/traverse": "^7.8.6",
-        "@babel/types": "^7.8.6"
+        "@babel/traverse": "^7.9.6",
+        "@babel/types": "^7.9.6"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.8.3",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
+          "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.8.3"
+          }
+        },
+        "@babel/generator": {
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz",
+          "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "^7.9.6",
+            "jsesc": "^2.5.1",
+            "lodash": "^4.17.13",
+            "source-map": "^0.5.0"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.9.5",
+          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz",
+          "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "^7.8.3",
+            "@babel/template": "^7.8.3",
+            "@babel/types": "^7.9.5"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.9.0",
+          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
+          "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-validator-identifier": "^7.9.0",
+            "chalk": "^2.0.0",
+            "js-tokens": "^4.0.0"
+          }
+        },
+        "@babel/parser": {
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
+          "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==",
+          "dev": true
+        },
+        "@babel/traverse": {
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz",
+          "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.8.3",
+            "@babel/generator": "^7.9.6",
+            "@babel/helper-function-name": "^7.9.5",
+            "@babel/helper-split-export-declaration": "^7.8.3",
+            "@babel/parser": "^7.9.6",
+            "@babel/types": "^7.9.6",
+            "debug": "^4.1.0",
+            "globals": "^11.1.0",
+            "lodash": "^4.17.13"
+          }
+        },
+        "@babel/types": {
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
+          "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-validator-identifier": "^7.9.5",
+            "lodash": "^4.17.13",
+            "to-fast-properties": "^2.0.0"
+          },
+          "dependencies": {
+            "@babel/helper-validator-identifier": {
+              "version": "7.9.5",
+              "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
+              "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==",
+              "dev": true
+            }
+          }
+        }
       }
     },
     "@babel/helper-simple-access": {
@@ -310,14 +462,101 @@
       }
     },
     "@babel/helpers": {
-      "version": "7.9.2",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz",
-      "integrity": "sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==",
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz",
+      "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==",
       "dev": true,
       "requires": {
         "@babel/template": "^7.8.3",
-        "@babel/traverse": "^7.9.0",
-        "@babel/types": "^7.9.0"
+        "@babel/traverse": "^7.9.6",
+        "@babel/types": "^7.9.6"
+      },
+      "dependencies": {
+        "@babel/code-frame": {
+          "version": "7.8.3",
+          "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
+          "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
+          "dev": true,
+          "requires": {
+            "@babel/highlight": "^7.8.3"
+          }
+        },
+        "@babel/generator": {
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz",
+          "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "^7.9.6",
+            "jsesc": "^2.5.1",
+            "lodash": "^4.17.13",
+            "source-map": "^0.5.0"
+          }
+        },
+        "@babel/helper-function-name": {
+          "version": "7.9.5",
+          "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz",
+          "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-get-function-arity": "^7.8.3",
+            "@babel/template": "^7.8.3",
+            "@babel/types": "^7.9.5"
+          }
+        },
+        "@babel/highlight": {
+          "version": "7.9.0",
+          "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
+          "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-validator-identifier": "^7.9.0",
+            "chalk": "^2.0.0",
+            "js-tokens": "^4.0.0"
+          }
+        },
+        "@babel/parser": {
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
+          "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==",
+          "dev": true
+        },
+        "@babel/traverse": {
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz",
+          "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.8.3",
+            "@babel/generator": "^7.9.6",
+            "@babel/helper-function-name": "^7.9.5",
+            "@babel/helper-split-export-declaration": "^7.8.3",
+            "@babel/parser": "^7.9.6",
+            "@babel/types": "^7.9.6",
+            "debug": "^4.1.0",
+            "globals": "^11.1.0",
+            "lodash": "^4.17.13"
+          }
+        },
+        "@babel/types": {
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
+          "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
+          "dev": true,
+          "requires": {
+            "@babel/helper-validator-identifier": "^7.9.5",
+            "lodash": "^4.17.13",
+            "to-fast-properties": "^2.0.0"
+          },
+          "dependencies": {
+            "@babel/helper-validator-identifier": {
+              "version": "7.9.5",
+              "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
+              "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==",
+              "dev": true
+            }
+          }
+        }
       }
     },
     "@babel/highlight": {
@@ -389,9 +628,9 @@
       }
     },
     "@babel/plugin-proposal-object-rest-spread": {
-      "version": "7.9.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.5.tgz",
-      "integrity": "sha512-VP2oXvAf7KCYTthbUHwBlewbl1Iq059f6seJGsxMizaCdgHIeczOr7FBqELhSqfkIl04Fi8okzWzl63UKbQmmg==",
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.6.tgz",
+      "integrity": "sha512-Ga6/fhGqA9Hj+y6whNpPv8psyaK5xzrQwSPsGPloVkvmH+PqW1ixdnfJ9uIO06OjQNYol3PMnfmJ8vfZtkzF+A==",
       "dev": true,
       "requires": {
         "@babel/helper-plugin-utils": "^7.8.3",
@@ -583,9 +822,9 @@
           "dev": true
         },
         "@babel/types": {
-          "version": "7.9.5",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz",
-          "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==",
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
+          "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
           "dev": true,
           "requires": {
             "@babel/helper-validator-identifier": "^7.9.5",
@@ -680,38 +919,38 @@
       }
     },
     "@babel/plugin-transform-modules-amd": {
-      "version": "7.9.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz",
-      "integrity": "sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q==",
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.6.tgz",
+      "integrity": "sha512-zoT0kgC3EixAyIAU+9vfaUVKTv9IxBDSabgHoUCBP6FqEJ+iNiN7ip7NBKcYqbfUDfuC2mFCbM7vbu4qJgOnDw==",
       "dev": true,
       "requires": {
         "@babel/helper-module-transforms": "^7.9.0",
         "@babel/helper-plugin-utils": "^7.8.3",
-        "babel-plugin-dynamic-import-node": "^2.3.0"
+        "babel-plugin-dynamic-import-node": "^2.3.3"
       }
     },
     "@babel/plugin-transform-modules-commonjs": {
-      "version": "7.9.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz",
-      "integrity": "sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g==",
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.6.tgz",
+      "integrity": "sha512-7H25fSlLcn+iYimmsNe3uK1at79IE6SKW9q0/QeEHTMC9MdOZ+4bA+T1VFB5fgOqBWoqlifXRzYD0JPdmIrgSQ==",
       "dev": true,
       "requires": {
         "@babel/helper-module-transforms": "^7.9.0",
         "@babel/helper-plugin-utils": "^7.8.3",
         "@babel/helper-simple-access": "^7.8.3",
-        "babel-plugin-dynamic-import-node": "^2.3.0"
+        "babel-plugin-dynamic-import-node": "^2.3.3"
       }
     },
     "@babel/plugin-transform-modules-systemjs": {
-      "version": "7.9.0",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz",
-      "integrity": "sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ==",
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.6.tgz",
+      "integrity": "sha512-NW5XQuW3N2tTHim8e1b7qGy7s0kZ2OH3m5octc49K1SdAKGxYxeIx7hiIz05kS1R2R+hOWcsr1eYwcGhrdHsrg==",
       "dev": true,
       "requires": {
         "@babel/helper-hoist-variables": "^7.8.3",
         "@babel/helper-module-transforms": "^7.9.0",
         "@babel/helper-plugin-utils": "^7.8.3",
-        "babel-plugin-dynamic-import-node": "^2.3.0"
+        "babel-plugin-dynamic-import-node": "^2.3.3"
       }
     },
     "@babel/plugin-transform-modules-umd": {
@@ -847,13 +1086,13 @@
       }
     },
     "@babel/preset-env": {
-      "version": "7.9.5",
-      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.5.tgz",
-      "integrity": "sha512-eWGYeADTlPJH+wq1F0wNfPbVS1w1wtmMJiYk55Td5Yu28AsdR9AsC97sZ0Qq8fHqQuslVSIYSGJMcblr345GfQ==",
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.6.tgz",
+      "integrity": "sha512-0gQJ9RTzO0heXOhzftog+a/WyOuqMrAIugVYxMYf83gh1CQaQDjMtsOpqOwXyDL/5JcWsrCm8l4ju8QC97O7EQ==",
       "dev": true,
       "requires": {
-        "@babel/compat-data": "^7.9.0",
-        "@babel/helper-compilation-targets": "^7.8.7",
+        "@babel/compat-data": "^7.9.6",
+        "@babel/helper-compilation-targets": "^7.9.6",
         "@babel/helper-module-imports": "^7.8.3",
         "@babel/helper-plugin-utils": "^7.8.3",
         "@babel/plugin-proposal-async-generator-functions": "^7.8.3",
@@ -861,7 +1100,7 @@
         "@babel/plugin-proposal-json-strings": "^7.8.3",
         "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
         "@babel/plugin-proposal-numeric-separator": "^7.8.3",
-        "@babel/plugin-proposal-object-rest-spread": "^7.9.5",
+        "@babel/plugin-proposal-object-rest-spread": "^7.9.6",
         "@babel/plugin-proposal-optional-catch-binding": "^7.8.3",
         "@babel/plugin-proposal-optional-chaining": "^7.9.0",
         "@babel/plugin-proposal-unicode-property-regex": "^7.8.3",
@@ -888,9 +1127,9 @@
         "@babel/plugin-transform-function-name": "^7.8.3",
         "@babel/plugin-transform-literals": "^7.8.3",
         "@babel/plugin-transform-member-expression-literals": "^7.8.3",
-        "@babel/plugin-transform-modules-amd": "^7.9.0",
-        "@babel/plugin-transform-modules-commonjs": "^7.9.0",
-        "@babel/plugin-transform-modules-systemjs": "^7.9.0",
+        "@babel/plugin-transform-modules-amd": "^7.9.6",
+        "@babel/plugin-transform-modules-commonjs": "^7.9.6",
+        "@babel/plugin-transform-modules-systemjs": "^7.9.6",
         "@babel/plugin-transform-modules-umd": "^7.9.0",
         "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3",
         "@babel/plugin-transform-new-target": "^7.8.3",
@@ -906,8 +1145,8 @@
         "@babel/plugin-transform-typeof-symbol": "^7.8.4",
         "@babel/plugin-transform-unicode-regex": "^7.8.3",
         "@babel/preset-modules": "^0.1.3",
-        "@babel/types": "^7.9.5",
-        "browserslist": "^4.9.1",
+        "@babel/types": "^7.9.6",
+        "browserslist": "^4.11.1",
         "core-js-compat": "^3.6.2",
         "invariant": "^2.2.2",
         "levenary": "^1.1.1",
@@ -921,9 +1160,9 @@
           "dev": true
         },
         "@babel/types": {
-          "version": "7.9.5",
-          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz",
-          "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==",
+          "version": "7.9.6",
+          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
+          "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
           "dev": true,
           "requires": {
             "@babel/helper-validator-identifier": "^7.9.5",
@@ -960,9 +1199,9 @@
       }
     },
     "@babel/runtime": {
-      "version": "7.9.2",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz",
-      "integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==",
+      "version": "7.9.6",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz",
+      "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==",
       "dev": true,
       "requires": {
         "regenerator-runtime": "^0.13.4"
@@ -1051,6 +1290,66 @@
         "to-fast-properties": "^2.0.0"
       }
     },
+    "@istanbuljs/load-nyc-config": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz",
+      "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==",
+      "dev": true,
+      "requires": {
+        "camelcase": "^5.3.1",
+        "find-up": "^4.1.0",
+        "js-yaml": "^3.13.1",
+        "resolve-from": "^5.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+          "dev": true
+        },
+        "resolve-from": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+          "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+          "dev": true
+        }
+      }
+    },
+    "@istanbuljs/schema": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
+      "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==",
+      "dev": true
+    },
     "@nodelib/fs.scandir": {
       "version": "2.1.3",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
@@ -1122,6 +1421,12 @@
       "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
       "dev": true
     },
+    "@tootallnate/once": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+      "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+      "dev": true
+    },
     "@types/babel-types": {
       "version": "7.0.6",
       "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.6.tgz",
@@ -1344,6 +1649,15 @@
         "buffer-equal": "^1.0.0"
       }
     },
+    "append-transform": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz",
+      "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==",
+      "dev": true,
+      "requires": {
+        "default-require-extensions": "^3.0.0"
+      }
+    },
     "archy": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
@@ -1378,6 +1692,12 @@
         }
       }
     },
+    "argv": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
+      "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=",
+      "dev": true
+    },
     "arr-diff": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
@@ -1844,6 +2164,35 @@
         "unset-value": "^1.0.0"
       }
     },
+    "caching-transform": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
+      "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==",
+      "dev": true,
+      "requires": {
+        "hasha": "^5.0.0",
+        "make-dir": "^3.0.0",
+        "package-hash": "^4.0.0",
+        "write-file-atomic": "^3.0.0"
+      },
+      "dependencies": {
+        "make-dir": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+          "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+          "dev": true,
+          "requires": {
+            "semver": "^6.0.0"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
     "callsites": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -2080,6 +2429,19 @@
       "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
       "dev": true
     },
+    "codecov": {
+      "version": "3.6.5",
+      "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.6.5.tgz",
+      "integrity": "sha512-v48WuDMUug6JXwmmfsMzhCHRnhUf8O3duqXvltaYJKrO1OekZWpB/eH6iIoaxMl8Qli0+u3OxptdsBOYiD7VAQ==",
+      "dev": true,
+      "requires": {
+        "argv": "0.0.2",
+        "ignore-walk": "3.0.3",
+        "js-yaml": "3.13.1",
+        "teeny-request": "6.0.1",
+        "urlgrey": "0.4.4"
+      }
+    },
     "collection-map": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz",
@@ -2346,6 +2708,23 @@
         }
       }
     },
+    "default-require-extensions": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz",
+      "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==",
+      "dev": true,
+      "requires": {
+        "strip-bom": "^4.0.0"
+      },
+      "dependencies": {
+        "strip-bom": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+          "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+          "dev": true
+        }
+      }
+    },
     "default-resolution": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz",
@@ -2542,9 +2921,9 @@
       "dev": true
     },
     "electron-to-chromium": {
-      "version": "1.3.418",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.418.tgz",
-      "integrity": "sha512-i2QrQtHes5fK/F9QGG5XacM5WKEuR322fxTYF9e8O9Gu0mc0WmjjwGpV8c7Htso6Zf2Di18lc3SIPxmMeRFBug==",
+      "version": "1.3.427",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.427.tgz",
+      "integrity": "sha512-/rG5G7Opcw68/Yrb4qYkz07h3bESVRJjUl4X/FrKLXzoUJleKm6D7K7rTTz8V5LUWnd+BbTOyxJX2XprRqHD8A==",
       "dev": true
     },
     "emoji-regex": {
@@ -2650,6 +3029,12 @@
         "next-tick": "^1.0.0"
       }
     },
+    "es6-error": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
+      "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+      "dev": true
+    },
     "es6-iterator": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
@@ -3017,9 +3402,9 @@
       }
     },
     "eslint-plugin-jsdoc": {
-      "version": "24.0.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-24.0.0.tgz",
-      "integrity": "sha512-AGAc9PYpramsJGVmqtxnXBYlq+AMh+hIZdbJ52OLvyJS3f+PaT/PzuckRFOLnth2uhCDv4IjgsB3r5jUFWqUnw==",
+      "version": "24.0.1",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-24.0.1.tgz",
+      "integrity": "sha512-lVTBsiufOO55Vo924WLa6UyxzQRB5qDifaCBafPzzO6NsTv44Y79Y9a6fkLiYeLg/77yiKAMJoyeYR7xddxgEw==",
       "dev": true,
       "requires": {
         "comment-parser": "^0.7.2",
@@ -3623,6 +4008,59 @@
         "for-in": "^1.0.1"
       }
     },
+    "foreground-child": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
+      "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "^7.0.0",
+        "signal-exit": "^3.0.2"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "7.0.2",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz",
+          "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.1.0",
+            "shebang-command": "^2.0.0",
+            "which": "^2.0.1"
+          }
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+          "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+          "dev": true,
+          "requires": {
+            "shebang-regex": "^3.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+          "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+          "dev": true
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
+      }
+    },
     "fragment-cache": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
@@ -3638,6 +4076,12 @@
       "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
       "dev": true
     },
+    "fromentries": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.0.tgz",
+      "integrity": "sha512-33X7H/wdfO99GdRLLgkjUrD4geAFdq/Uv0kl3HD4da6HDixd2GUg8Mw7dahLCV9r/EARkmtYBB6Tch4EEokFTQ==",
+      "dev": true
+    },
     "fs-extra": {
       "version": "9.0.0",
       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.0.tgz",
@@ -5070,6 +5514,16 @@
         }
       }
     },
+    "hasha": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.0.tgz",
+      "integrity": "sha512-2W+jKdQbAdSIrggA8Q35Br8qKadTrqCTC8+XZvBWepKDK6m9XkX6Iz1a2yh2KP01kzAR/dpuMeUnocoLYDcskw==",
+      "dev": true,
+      "requires": {
+        "is-stream": "^2.0.0",
+        "type-fest": "^0.8.0"
+      }
+    },
     "he": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
@@ -5097,6 +5551,12 @@
       "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
       "dev": true
     },
+    "html-escaper": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+      "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+      "dev": true
+    },
     "http-errors": {
       "version": "1.7.2",
       "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
@@ -5116,6 +5576,28 @@
       "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=",
       "dev": true
     },
+    "http-proxy-agent": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+      "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+      "dev": true,
+      "requires": {
+        "@tootallnate/once": "1",
+        "agent-base": "6",
+        "debug": "4"
+      },
+      "dependencies": {
+        "agent-base": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz",
+          "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==",
+          "dev": true,
+          "requires": {
+            "debug": "4"
+          }
+        }
+      }
+    },
     "https-proxy-agent": {
       "version": "2.2.4",
       "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
@@ -5152,6 +5634,15 @@
       "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
       "dev": true
     },
+    "ignore-walk": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz",
+      "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
+      "dev": true,
+      "requires": {
+        "minimatch": "^3.0.4"
+      }
+    },
     "import-fresh": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz",
@@ -5435,6 +5926,12 @@
         "is-unc-path": "^1.0.0"
       }
     },
+    "is-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+      "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+      "dev": true
+    },
     "is-symbol": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
@@ -5452,6 +5949,12 @@
         }
       }
     },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
     "is-unc-path": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
@@ -5506,6 +6009,198 @@
       "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
       "dev": true
     },
+    "istanbul-lib-coverage": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
+      "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
+      "dev": true
+    },
+    "istanbul-lib-hook": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz",
+      "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==",
+      "dev": true,
+      "requires": {
+        "append-transform": "^2.0.0"
+      }
+    },
+    "istanbul-lib-instrument": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz",
+      "integrity": "sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.7.5",
+        "@babel/parser": "^7.7.5",
+        "@babel/template": "^7.7.4",
+        "@babel/traverse": "^7.7.4",
+        "@istanbuljs/schema": "^0.1.2",
+        "istanbul-lib-coverage": "^3.0.0",
+        "semver": "^6.3.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
+    "istanbul-lib-processinfo": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz",
+      "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==",
+      "dev": true,
+      "requires": {
+        "archy": "^1.0.0",
+        "cross-spawn": "^7.0.0",
+        "istanbul-lib-coverage": "^3.0.0-alpha.1",
+        "make-dir": "^3.0.0",
+        "p-map": "^3.0.0",
+        "rimraf": "^3.0.0",
+        "uuid": "^3.3.3"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "7.0.2",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz",
+          "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.1.0",
+            "shebang-command": "^2.0.0",
+            "which": "^2.0.1"
+          }
+        },
+        "make-dir": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+          "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+          "dev": true,
+          "requires": {
+            "semver": "^6.0.0"
+          }
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+          "dev": true
+        },
+        "rimraf": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+          "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+          "dev": true,
+          "requires": {
+            "shebang-regex": "^3.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+          "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+          "dev": true
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
+      }
+    },
+    "istanbul-lib-report": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+      "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+      "dev": true,
+      "requires": {
+        "istanbul-lib-coverage": "^3.0.0",
+        "make-dir": "^3.0.0",
+        "supports-color": "^7.1.0"
+      },
+      "dependencies": {
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true
+        },
+        "make-dir": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+          "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+          "dev": true,
+          "requires": {
+            "semver": "^6.0.0"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
+          "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
+    "istanbul-lib-source-maps": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
+      "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.1",
+        "istanbul-lib-coverage": "^3.0.0",
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "istanbul-reports": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
+      "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==",
+      "dev": true,
+      "requires": {
+        "html-escaper": "^2.0.0",
+        "istanbul-lib-report": "^3.0.0"
+      }
+    },
     "joi": {
       "version": "14.3.1",
       "resolved": "https://registry.npmjs.org/joi/-/joi-14.3.1.tgz",
@@ -5576,20 +6271,12 @@
       "dev": true
     },
     "json5": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz",
-      "integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==",
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
+      "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
       "dev": true,
       "requires": {
         "minimist": "^1.2.5"
-      },
-      "dependencies": {
-        "minimist": {
-          "version": "1.2.5",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-          "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
-          "dev": true
-        }
       }
     },
     "jsonfile": {
@@ -5763,6 +6450,12 @@
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
       "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
     },
+    "lodash.flattendeep": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
+      "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
+      "dev": true
+    },
     "lodash.get": {
       "version": "4.4.2",
       "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
@@ -6343,6 +7036,15 @@
       "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=",
       "dev": true
     },
+    "node-preload": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz",
+      "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==",
+      "dev": true,
+      "requires": {
+        "process-on-spawn": "^1.0.0"
+      }
+    },
     "node-releases": {
       "version": "1.1.53",
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.53.tgz",
@@ -6385,6 +7087,149 @@
       "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
       "dev": true
     },
+    "nyc": {
+      "version": "15.0.1",
+      "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.0.1.tgz",
+      "integrity": "sha512-n0MBXYBYRqa67IVt62qW1r/d9UH/Qtr7SF1w/nQLJ9KxvWF6b2xCHImRAixHN9tnMMYHC2P14uo6KddNGwMgGg==",
+      "dev": true,
+      "requires": {
+        "@istanbuljs/load-nyc-config": "^1.0.0",
+        "@istanbuljs/schema": "^0.1.2",
+        "caching-transform": "^4.0.0",
+        "convert-source-map": "^1.7.0",
+        "decamelize": "^1.2.0",
+        "find-cache-dir": "^3.2.0",
+        "find-up": "^4.1.0",
+        "foreground-child": "^2.0.0",
+        "glob": "^7.1.6",
+        "istanbul-lib-coverage": "^3.0.0",
+        "istanbul-lib-hook": "^3.0.0",
+        "istanbul-lib-instrument": "^4.0.0",
+        "istanbul-lib-processinfo": "^2.0.2",
+        "istanbul-lib-report": "^3.0.0",
+        "istanbul-lib-source-maps": "^4.0.0",
+        "istanbul-reports": "^3.0.2",
+        "make-dir": "^3.0.0",
+        "node-preload": "^0.2.1",
+        "p-map": "^3.0.0",
+        "process-on-spawn": "^1.0.0",
+        "resolve-from": "^5.0.0",
+        "rimraf": "^3.0.0",
+        "signal-exit": "^3.0.2",
+        "spawn-wrap": "^2.0.0",
+        "test-exclude": "^6.0.0",
+        "yargs": "^15.0.2"
+      },
+      "dependencies": {
+        "convert-source-map": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+          "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+          "dev": true,
+          "requires": {
+            "safe-buffer": "~5.1.1"
+          }
+        },
+        "find-cache-dir": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
+          "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
+          "dev": true,
+          "requires": {
+            "commondir": "^1.0.1",
+            "make-dir": "^3.0.2",
+            "pkg-dir": "^4.1.0"
+          }
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "glob": {
+          "version": "7.1.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+          "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "make-dir": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+          "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+          "dev": true,
+          "requires": {
+            "semver": "^6.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+          "dev": true
+        },
+        "pkg-dir": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+          "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+          "dev": true,
+          "requires": {
+            "find-up": "^4.0.0"
+          }
+        },
+        "resolve-from": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+          "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+          "dev": true
+        },
+        "rimraf": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        }
+      }
+    },
     "object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -6579,6 +7424,18 @@
       "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
       "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
     },
+    "package-hash": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz",
+      "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.15",
+        "hasha": "^5.0.0",
+        "lodash.flattendeep": "^4.4.0",
+        "release-zalgo": "^1.0.0"
+      }
+    },
     "parent-module": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -6859,6 +7716,15 @@
       "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
       "dev": true
     },
+    "process-on-spawn": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz",
+      "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==",
+      "dev": true,
+      "requires": {
+        "fromentries": "^1.2.0"
+      }
+    },
     "progress": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
@@ -7345,6 +8211,15 @@
         }
       }
     },
+    "release-zalgo": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
+      "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=",
+      "dev": true,
+      "requires": {
+        "es6-error": "^4.0.1"
+      }
+    },
     "remove-bom-buffer": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz",
@@ -7945,6 +8820,55 @@
       "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==",
       "dev": true
     },
+    "spawn-wrap": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz",
+      "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==",
+      "dev": true,
+      "requires": {
+        "foreground-child": "^2.0.0",
+        "is-windows": "^1.0.2",
+        "make-dir": "^3.0.0",
+        "rimraf": "^3.0.0",
+        "signal-exit": "^3.0.2",
+        "which": "^2.0.1"
+      },
+      "dependencies": {
+        "make-dir": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+          "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+          "dev": true,
+          "requires": {
+            "semver": "^6.0.0"
+          }
+        },
+        "rimraf": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+          "dev": true
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
+      }
+    },
     "spdx-correct": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
@@ -8024,6 +8948,15 @@
       "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
       "dev": true
     },
+    "stream-events": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz",
+      "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==",
+      "dev": true,
+      "requires": {
+        "stubs": "^3.0.0"
+      }
+    },
     "stream-exhaust": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
@@ -8145,6 +9078,12 @@
       "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
       "dev": true
     },
+    "stubs": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz",
+      "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=",
+      "dev": true
+    },
     "supports-color": {
       "version": "5.5.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@@ -8176,6 +9115,64 @@
         "string-width": "^3.0.0"
       }
     },
+    "teeny-request": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.1.tgz",
+      "integrity": "sha512-TAK0c9a00ELOqLrZ49cFxvPVogMUFaWY8dUsQc/0CuQPGF+BOxOQzXfE413BAk2kLomwNplvdtMpeaeGWmoc2g==",
+      "dev": true,
+      "requires": {
+        "http-proxy-agent": "^4.0.0",
+        "https-proxy-agent": "^4.0.0",
+        "node-fetch": "^2.2.0",
+        "stream-events": "^1.0.5",
+        "uuid": "^3.3.2"
+      },
+      "dependencies": {
+        "agent-base": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz",
+          "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==",
+          "dev": true
+        },
+        "https-proxy-agent": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz",
+          "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==",
+          "dev": true,
+          "requires": {
+            "agent-base": "5",
+            "debug": "4"
+          }
+        }
+      }
+    },
+    "test-exclude": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+      "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+      "dev": true,
+      "requires": {
+        "@istanbuljs/schema": "^0.1.2",
+        "glob": "^7.1.4",
+        "minimatch": "^3.0.4"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+          "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        }
+      }
+    },
     "text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -8369,6 +9366,15 @@
       "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
       "dev": true
     },
+    "typedarray-to-buffer": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+      "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+      "dev": true,
+      "requires": {
+        "is-typedarray": "^1.0.0"
+      }
+    },
     "ua-parser-js": {
       "version": "0.7.21",
       "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz",
@@ -8558,6 +9564,12 @@
       "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
       "dev": true
     },
+    "urlgrey": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz",
+      "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=",
+      "dev": true
+    },
     "use": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
@@ -8576,6 +9588,12 @@
       "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
       "dev": true
     },
+    "uuid": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+      "dev": true
+    },
     "v8-compile-cache": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
@@ -8836,6 +9854,18 @@
         }
       }
     },
+    "write-file-atomic": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+      "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+      "dev": true,
+      "requires": {
+        "imurmurhash": "^0.1.4",
+        "is-typedarray": "^1.0.0",
+        "signal-exit": "^3.0.2",
+        "typedarray-to-buffer": "^3.1.5"
+      }
+    },
     "ws": {
       "version": "6.2.1",
       "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
diff --git a/package.json b/package.json
index 768b3d0d..4eab069e 100644
--- a/package.json
+++ b/package.json
@@ -57,14 +57,15 @@
   },
   "devDependencies": {
     "@alrra/travis-scripts": "^3.0.1",
-    "@babel/core": "^7.9.0",
-    "@babel/preset-env": "^7.9.5",
+    "@babel/core": "^7.9.6",
+    "@babel/preset-env": "^7.9.6",
     "@babel/register": "^7.9.0",
     "auto-changelog": "^2.0.0",
     "chai": "^4.2.0",
+    "codecov": "^3.6.5",
     "del": "^5.1.0",
     "eslint": "^6.8.0",
-    "eslint-plugin-jsdoc": "^24.0.0",
+    "eslint-plugin-jsdoc": "^24.0.1",
     "find-parent-dir": "^0.3.0",
     "fs-extra": "^9.0.0",
     "globby": "^11.0.0",
@@ -77,6 +78,7 @@
     "json3": "^3.3.3",
     "mocha": "^7.1.2",
     "mocha-headless-chrome": "^2.0.3",
+    "nyc": "^15.0.1",
     "proxyquire": "^2.1.3",
     "serve-static": "^1.14.1",
     "sinon": "^9.0.2",
@@ -85,7 +87,7 @@
   "scripts": {
     "--- DEFAULT SCRIPTS ---": "",
     "start": "gulp default",
-    "test": "gulp test",
+    "test": "nyc gulp test",
     "--- GULP SCRIPTS ---": "",
     "clean": "gulp clean",
     "lint": "gulp eslint",


Test patch:
diff --git a/feature-detects/templatestrings.js b/feature-detects/templatestrings.js
deleted file mode 100644
index 481b77a7..00000000
--- a/feature-detects/templatestrings.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/*!
-{
-  "name": "Template strings",
-  "property": "templatestrings",
-  "notes": [{
-    "name": "MDN Docs",
-    "href": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Browser_compatibility"
-  }]
-}
-!*/
-/* DOC
-Template strings are string literals allowing embedded expressions.
-*/
-define(['Modernizr'], function(Modernizr) {
-  Modernizr.addTest('templatestrings', function() {
-    var supports;
-    try {
-      // A number of tools, including uglifyjs and require, break on a raw "`", so
-      // use an eval to get around that.
-      // eslint-disable-next-line
-      eval('``');
-      supports = true;
-    } catch (e) {}
-    return !!supports;
-  });
-});
diff --git a/test/browser/integration/caniuse.js b/test/browser/integration/caniuse.js
index 3f98442a..37138e35 100644
--- a/test/browser/integration/caniuse.js
+++ b/test/browser/integration/caniuse.js
@@ -24,8 +24,10 @@ window.caniusecb = function(caniuse) {
       applicationcache: 'offline-apps',
       atobbtoa: 'atob-btoa',
       audio: 'audio',
+      avif: 'avif',
       backdropfilter: 'css-backdrop-filter',
       backgroundblendmode: 'css-backgroundblendmode',
+      bgpositionshorthand: 'css-background-offsets',
       blobconstructor: 'blobbuilder',
       bloburls: 'bloburls',
       borderimage: 'border-image',
@@ -44,6 +46,7 @@ window.caniusecb = function(caniuse) {
       cryptography: 'cryptography',
       cssanimations: 'css-animation',
       csscalc: 'calc',
+      csschunit: 'ch-unit',
       csscolumns: 'multicolumn',
       cssfilters: 'css-filters',
       cssgradients: 'css-gradients',
@@ -54,13 +57,14 @@ window.caniusecb = function(caniuse) {
       cssreflections: 'css-reflections',
       cssremunit: 'rem',
       cssresize: 'css-resize',
-      csstransforms3d: 'transforms3d',
       csstransforms: 'transforms2d',
+      csstransforms3d: 'transforms3d',
       csstransitions: 'css-transitions',
       cssvhunit: 'viewport-units',
       cssvmaxunit: 'viewport-units',
       cssvminunit: 'viewport-units',
       cssvwunit: 'viewport-units',
+      customelements: 'custom-elementsv1',
       customproperties: 'css-variables',
       datalistelem: 'datalist',
       dataset: 'dataset',
@@ -69,6 +73,7 @@ window.caniusecb = function(caniuse) {
       deviceorientation: 'deviceorientation',
       displaytable: 'css-table',
       ellipsis: 'text-overflow',
+      eventlistener: 'addeventlistener',
       eventsource: 'eventsource',
       fetch: 'fetch',
       fileinput: 'forms',
@@ -95,8 +100,9 @@ window.caniusecb = function(caniuse) {
       inlinesvg: 'svg-html5',
       inputtypes: 'forms',
       intersectionobserver: 'intersectionobserver',
-      jpegxr: 'jpegxr',
+      intl: 'internationalization',
       jpeg2000: 'jpeg2000',
+      jpegxr: 'jpegxr',
       json: 'json',
       lastchild: 'css-sel3',
       ligatures: 'font-feature',
@@ -108,13 +114,16 @@ window.caniusecb = function(caniuse) {
       meter: 'progress',
       multiplebgs: 'multibackgrounds',
       mutationobserver: 'mutationobserver',
-      nthchild: 'css-sel3',
       notification: 'notifications',
+      nthchild: 'css-sel3',
       objectfit: 'object-fit',
       opacity: 'css-opacity',
       pagevisibility: 'pagevisibility',
+      passiveeventlisteners: 'passive-event-listener',
+      peerconnection: 'rtcpeerconnection',
       performance: 'nav-timing',
       picture: 'picture',
+      pointerevents: 'pointer',
       postmessage: 'x-doc-messaging',
       progressbar: 'progress',
       promises: 'promises',
@@ -127,11 +136,16 @@ window.caniusecb = function(caniuse) {
       sandbox: 'iframe-sandbox',
       scriptasync: 'script-async',
       scriptdefer: 'script-defer',
+      scrollsnappoints: 'css-snappoints',
       seamless: 'iframe-seamless',
+      serviceworker: 'serviceworkers',
       shapes: 'css-shapes',
       sharedworkers: 'sharedworkers',
       siblinggeneral: 'css-sel3',
       smil: 'svg-smil',
+      speechrecognition: 'speech-recognition',
+      speechsynthesis: 'speech-synthesis',
+      srcdoc: 'iframe-srcdoc',
       srcset: 'srcset',
       strictmode: 'use-strict',
       stylescoped: 'style-scoped',
@@ -147,6 +161,7 @@ window.caniusecb = function(caniuse) {
       touchevents: 'touch',
       typedarrays: 'typedarrays',
       unicoderange: 'font-unicode-range',
+      urlsearchparams: 'urlsearchparams',
       userselect: 'user-select-none',
       vibrate: 'vibration',
       video: 'video',
diff --git a/test/node/lib/metadata.js b/test/node/lib/metadata.js
index bc9081e1..e9041387 100644
--- a/test/node/lib/metadata.js
+++ b/test/node/lib/metadata.js
@@ -76,31 +76,38 @@ describe('cli/metadata', function() {
     expect(metadata).to.throw(/Couldn't find the define/);
   });
 
-  it('should use amdPath as a fallback for name', function() {
+  it('should throw if no name is defined', function() {
 
     var metadata = proxyquire(root + 'lib/metadata', {
-      'file': {
-        'walkSync': function(dir, cb) {
-          cb('/', [], ['fakeDetect.js']);
-        }
-      },
       'fs': {
         'readFileSync': function() {
           return '/*! { "property": "fake"}!*/ define([],';
         }
       }
     });
-    var result = metadata();
 
-    expect(result.name).to.be.equal(result.amdPath);
+    expect(metadata).to.throw(/Minimal metadata not found/);
   });
 
-  it('should throw if we can\'t find the define', function() {
+  it('should throw if no property is defined', function() {
 
     var metadata = proxyquire(root + 'lib/metadata', {
       'fs': {
         'readFileSync': function() {
-          return '/*! { "polyfills": ["fake"]}!*/ define([],';
+          return '/*! { "name": "fake"}!*/ define([],';
+        }
+      }
+    });
+
+    expect(metadata).to.throw(/Minimal metadata not found/);
+  });
+
+  it('should throw if polyfill is incorrectly configured', function() {
+
+    var metadata = proxyquire(root + 'lib/metadata', {
+      'fs': {
+        'readFileSync': function() {
+          return '/*! { "name": "fake", "property": "fake", "polyfills": ["fake"]}!*/ define([],';
         }
       }
     });
@@ -108,12 +115,12 @@ describe('cli/metadata', function() {
     expect(metadata).to.throw(/Polyfill not found/);
   });
 
-  it('should throw if we can\'t find the define', function() {
+  it('should return null if cssclass is incorrectly configured', function() {
 
     var metadata = proxyquire(root + 'lib/metadata', {
       'fs': {
         'readFileSync': function() {
-          return '/*! { "property": "fake", "cssclass": "realFake"}!*/ define([],';
+          return '/*! { "name": "fake", "property": "fake", "cssclass": "realFake"}!*/ define([],';
         }
       }
     });
@@ -128,7 +135,7 @@ describe('cli/metadata', function() {
     var metadata = proxyquire(root + 'lib/metadata', {
       'fs': {
         'readFileSync': function() {
-          return '/*! { "docs": "originally docs" }!*/ define([],';
+          return '/*! { "name": "fake", "property": "fake", "docs": "originally docs" }!*/ define([],';
         }
       }
     });