You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lo...@apache.org on 2022/08/03 07:36:04 UTC

[myfaces-tobago] branch main updated: build: updating several npm libs

This is an automated email from the ASF dual-hosted git repository.

lofwyr pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git


The following commit(s) were added to refs/heads/main by this push:
     new 4ac7805b52 build: updating several npm libs
     new 4b7776ca9f Merge pull request #3030 from lofwyr14/main-update-npm-libs
4ac7805b52 is described below

commit 4ac7805b521b8d34233a166a035bbfa72ebe3922
Author: Udo Schnurpfeil <ud...@irian.eu>
AuthorDate: Wed Aug 3 09:34:58 2022 +0200

    build: updating several npm libs
    
    * jasmine
    * bootstrap-icons
    * (others for build time)
---
 .../tobago-example-demo/package-lock.json          | 1272 ++++----
 tobago-example/tobago-example-demo/package.json    |   10 +-
 .../src/main/webapp/js/boot0.js                    |   10 +-
 .../src/main/webapp/js/boot1.js                    |   18 +-
 .../src/main/webapp/js/jasmine-html.js             |  175 +-
 .../src/main/webapp/js/jasmine.js                  | 3060 +++++++++++---------
 tobago-theme/package-lock.json                     |  668 +++--
 tobago-theme/package.json                          |   26 +-
 .../src/main/css/bootstrap-icons.css               |  177 +-
 .../src/main/css/fonts/bootstrap-icons.woff        |  Bin 137216 -> 150592 bytes
 .../src/main/css/fonts/bootstrap-icons.woff2       |  Bin 102380 -> 112440 bytes
 11 files changed, 3005 insertions(+), 2411 deletions(-)

diff --git a/tobago-example/tobago-example-demo/package-lock.json b/tobago-example/tobago-example-demo/package-lock.json
index 7cfa723bd0..a13a7332ea 100644
--- a/tobago-example/tobago-example-demo/package-lock.json
+++ b/tobago-example/tobago-example-demo/package-lock.json
@@ -10,54 +10,54 @@
       "license": "Apache-2.0",
       "dependencies": {
         "font-awesome": "4.7.0",
-        "jasmine-core": "^4.2.0",
+        "jasmine-core": "^4.3.0",
         "prismjs": "^1.28.0"
       },
       "devDependencies": {
         "@rollup/plugin-node-resolve": "^13.3.0",
         "@rollup/plugin-replace": "^4.0.0",
         "@types/prismjs": "^1.26.0",
-        "autoprefixer": "^10.4.7",
-        "clean-css-cli": "^5.6.0",
+        "autoprefixer": "^10.4.8",
+        "clean-css-cli": "^5.6.1",
         "lodash": "^4.17.21",
         "ncp": "^2.0.0",
         "npm-run-all": "^4.1.5",
         "postcss-cli": "^10.0.0",
-        "rollup": "^2.75.7",
-        "sass": "^1.53.0",
+        "rollup": "^2.77.2",
+        "sass": "^1.54.1",
         "tslint": "^6.1.3",
         "typescript": "^4.7.4",
         "y18n": "^5.0.8"
       }
     },
     "node_modules/@babel/code-frame": {
-      "version": "7.14.5",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
-      "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
       "dev": true,
       "dependencies": {
-        "@babel/highlight": "^7.14.5"
+        "@babel/highlight": "^7.18.6"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.15.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz",
-      "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
+      "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==",
       "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/highlight": {
-      "version": "7.14.5",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
-      "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.14.5",
+        "@babel/helper-validator-identifier": "^7.18.6",
         "chalk": "^2.0.0",
         "js-tokens": "^4.0.0"
       },
@@ -157,9 +157,9 @@
       "dev": true
     },
     "node_modules/@types/node": {
-      "version": "16.11.1",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz",
-      "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==",
+      "version": "18.6.3",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz",
+      "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==",
       "dev": true
     },
     "node_modules/@types/prismjs": {
@@ -221,9 +221,9 @@
       }
     },
     "node_modules/autoprefixer": {
-      "version": "10.4.7",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz",
-      "integrity": "sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA==",
+      "version": "10.4.8",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.8.tgz",
+      "integrity": "sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==",
       "dev": true,
       "funding": [
         {
@@ -236,8 +236,8 @@
         }
       ],
       "dependencies": {
-        "browserslist": "^4.20.3",
-        "caniuse-lite": "^1.0.30001335",
+        "browserslist": "^4.21.3",
+        "caniuse-lite": "^1.0.30001373",
         "fraction.js": "^4.2.0",
         "normalize-range": "^0.1.2",
         "picocolors": "^1.0.0",
@@ -291,9 +291,9 @@
       }
     },
     "node_modules/browserslist": {
-      "version": "4.20.3",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz",
-      "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==",
+      "version": "4.21.3",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz",
+      "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==",
       "dev": true,
       "funding": [
         {
@@ -306,11 +306,10 @@
         }
       ],
       "dependencies": {
-        "caniuse-lite": "^1.0.30001332",
-        "electron-to-chromium": "^1.4.118",
-        "escalade": "^3.1.1",
-        "node-releases": "^2.0.3",
-        "picocolors": "^1.0.0"
+        "caniuse-lite": "^1.0.30001370",
+        "electron-to-chromium": "^1.4.202",
+        "node-releases": "^2.0.6",
+        "update-browserslist-db": "^1.0.5"
       },
       "bin": {
         "browserslist": "cli.js"
@@ -320,9 +319,9 @@
       }
     },
     "node_modules/builtin-modules": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz",
-      "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==",
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
+      "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
       "dev": true,
       "engines": {
         "node": ">=6"
@@ -345,9 +344,9 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001335",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001335.tgz",
-      "integrity": "sha512-ddP1Tgm7z2iIxu6QTtbZUv6HJxSaV/PZeSrWFZtbY4JZ69tOeNhBCl3HyRQgeNZKE5AOn1kpV7fhljigy0Ty3w==",
+      "version": "1.0.30001373",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz",
+      "integrity": "sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ==",
       "dev": true,
       "funding": [
         {
@@ -375,14 +374,20 @@
       }
     },
     "node_modules/chokidar": {
-      "version": "3.5.2",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
-      "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
       "dev": true,
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://paulmillr.com/funding/"
+        }
+      ],
       "dependencies": {
         "anymatch": "~3.1.2",
         "braces": "~3.0.2",
-        "glob-parent": "~6.0.0",
+        "glob-parent": "~5.1.2",
         "is-binary-path": "~2.1.0",
         "is-glob": "~4.0.1",
         "normalize-path": "~3.0.0",
@@ -396,9 +401,9 @@
       }
     },
     "node_modules/clean-css": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz",
-      "integrity": "sha512-YYuuxv4H/iNb1Z/5IbMRoxgrzjWGhOEFfd+groZ5dMCVkpENiMZmwspdrzBo9286JjM1gZJPAyL7ZIdzuvu2AQ==",
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz",
+      "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==",
       "dev": true,
       "dependencies": {
         "source-map": "~0.6.0"
@@ -408,13 +413,13 @@
       }
     },
     "node_modules/clean-css-cli": {
-      "version": "5.6.0",
-      "resolved": "https://registry.npmjs.org/clean-css-cli/-/clean-css-cli-5.6.0.tgz",
-      "integrity": "sha512-68vorNEG808D1QzeerO9AlwQVTuaR8YSK4aqwIsjJq0wDSyPH11ApHY0O+EQrdEGUZcN+d72v+Nn/gpxjAFewQ==",
+      "version": "5.6.1",
+      "resolved": "https://registry.npmjs.org/clean-css-cli/-/clean-css-cli-5.6.1.tgz",
+      "integrity": "sha512-/StJu1YODZY6cOwkBx5FMhSoc9YmvEJXtwNN+udGg1GIKrr4PkdsCdUqC26GfdPdt5IuZnu+5y9/3mrdIJa40Q==",
       "dev": true,
       "dependencies": {
         "chokidar": "^3.5.2",
-        "clean-css": "^5.3.0",
+        "clean-css": "^5.3.1",
         "commander": "7.x",
         "glob": "^7.1.6"
       },
@@ -448,7 +453,7 @@
     "node_modules/color-name": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
       "dev": true
     },
     "node_modules/commander": {
@@ -463,7 +468,7 @@
     "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
       "dev": true
     },
     "node_modules/cross-spawn": {
@@ -492,15 +497,19 @@
       }
     },
     "node_modules/define-properties": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
-      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
+      "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
       "dev": true,
       "dependencies": {
-        "object-keys": "^1.0.12"
+        "has-property-descriptors": "^1.0.0",
+        "object-keys": "^1.1.1"
       },
       "engines": {
         "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/dependency-graph": {
@@ -533,19 +542,10 @@
         "node": ">=8"
       }
     },
-    "node_modules/dir-glob/node_modules/path-type": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
-      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-      "dev": true,
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/electron-to-chromium": {
-      "version": "1.4.131",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.131.tgz",
-      "integrity": "sha512-oi3YPmaP87hiHn0c4ePB67tXaF+ldGhxvZnT19tW9zX6/Ej+pLN0Afja5rQ6S+TND7I9EuwQTT8JYn1k7R7rrw==",
+      "version": "1.4.210",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.210.tgz",
+      "integrity": "sha512-kSiX4tuyZijV7Cz0MWVmGT8K2siqaOA4Z66K5dCttPPRh0HicOcOAEj1KlC8O8J1aOS/1M8rGofOzksLKaHWcQ==",
       "dev": true
     },
     "node_modules/emoji-regex": {
@@ -564,31 +564,34 @@
       }
     },
     "node_modules/es-abstract": {
-      "version": "1.19.1",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz",
-      "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==",
+      "version": "1.20.1",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz",
+      "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==",
       "dev": true,
       "dependencies": {
         "call-bind": "^1.0.2",
         "es-to-primitive": "^1.2.1",
         "function-bind": "^1.1.1",
+        "function.prototype.name": "^1.1.5",
         "get-intrinsic": "^1.1.1",
         "get-symbol-description": "^1.0.0",
         "has": "^1.0.3",
-        "has-symbols": "^1.0.2",
+        "has-property-descriptors": "^1.0.0",
+        "has-symbols": "^1.0.3",
         "internal-slot": "^1.0.3",
         "is-callable": "^1.2.4",
-        "is-negative-zero": "^2.0.1",
+        "is-negative-zero": "^2.0.2",
         "is-regex": "^1.1.4",
-        "is-shared-array-buffer": "^1.0.1",
+        "is-shared-array-buffer": "^1.0.2",
         "is-string": "^1.0.7",
-        "is-weakref": "^1.0.1",
-        "object-inspect": "^1.11.0",
+        "is-weakref": "^1.0.2",
+        "object-inspect": "^1.12.0",
         "object-keys": "^1.1.1",
         "object.assign": "^4.1.2",
-        "string.prototype.trimend": "^1.0.4",
-        "string.prototype.trimstart": "^1.0.4",
-        "unbox-primitive": "^1.0.1"
+        "regexp.prototype.flags": "^1.4.3",
+        "string.prototype.trimend": "^1.0.5",
+        "string.prototype.trimstart": "^1.0.5",
+        "unbox-primitive": "^1.0.2"
       },
       "engines": {
         "node": ">= 0.4"
@@ -626,7 +629,7 @@
     "node_modules/escape-string-regexp": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
       "dev": true,
       "engines": {
         "node": ">=0.8.0"
@@ -659,7 +662,7 @@
       "dependencies": {
         "@nodelib/fs.stat": "^2.0.2",
         "@nodelib/fs.walk": "^1.2.3",
-        "glob-parent": "^6.0.0",
+        "glob-parent": "^5.1.2",
         "merge2": "^1.3.0",
         "micromatch": "^4.0.4"
       },
@@ -691,7 +694,7 @@
     "node_modules/font-awesome": {
       "version": "4.7.0",
       "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
-      "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=",
+      "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==",
       "engines": {
         "node": ">=0.10.3"
       }
@@ -710,9 +713,9 @@
       }
     },
     "node_modules/fs-extra": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-      "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
       "dev": true,
       "dependencies": {
         "graceful-fs": "^4.2.0",
@@ -726,7 +729,7 @@
     "node_modules/fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
       "dev": true
     },
     "node_modules/fsevents": {
@@ -749,6 +752,33 @@
       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
       "dev": true
     },
+    "node_modules/function.prototype.name": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
+      "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.19.0",
+        "functions-have-names": "^1.2.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/functions-have-names": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+      "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/get-caller-file": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -759,14 +789,14 @@
       }
     },
     "node_modules/get-intrinsic": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
-      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+      "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
       "dev": true,
       "dependencies": {
         "function-bind": "^1.1.1",
         "has": "^1.0.3",
-        "has-symbols": "^1.0.1"
+        "has-symbols": "^1.0.3"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -801,15 +831,15 @@
       }
     },
     "node_modules/glob": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
-      "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
       "dev": true,
       "dependencies": {
         "fs.realpath": "^1.0.0",
         "inflight": "^1.0.4",
         "inherits": "2",
-        "minimatch": "^3.0.4",
+        "minimatch": "^3.1.1",
         "once": "^1.3.0",
         "path-is-absolute": "^1.0.0"
       },
@@ -821,15 +851,15 @@
       }
     },
     "node_modules/glob-parent": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
-      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
       "dev": true,
       "dependencies": {
-        "is-glob": "^4.0.3"
+        "is-glob": "^4.0.1"
       },
       "engines": {
-        "node": ">=10.13.0"
+        "node": ">= 6"
       }
     },
     "node_modules/globby": {
@@ -852,9 +882,9 @@
       }
     },
     "node_modules/graceful-fs": {
-      "version": "4.2.8",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
-      "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
+      "version": "4.2.10",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
     "node_modules/has": {
@@ -870,9 +900,9 @@
       }
     },
     "node_modules/has-bigints": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
-      "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+      "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
       "dev": true,
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -881,16 +911,28 @@
     "node_modules/has-flag": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
       "dev": true,
       "engines": {
         "node": ">=4"
       }
     },
+    "node_modules/has-property-descriptors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+      "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+      "dev": true,
+      "dependencies": {
+        "get-intrinsic": "^1.1.1"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/has-symbols": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
-      "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
       "dev": true,
       "engines": {
         "node": ">= 0.4"
@@ -930,15 +972,15 @@
       }
     },
     "node_modules/immutable": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
-      "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
+      "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
       "dev": true
     },
     "node_modules/inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
       "dev": true,
       "dependencies": {
         "once": "^1.3.0",
@@ -968,7 +1010,7 @@
     "node_modules/is-arrayish": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
       "dev": true
     },
     "node_modules/is-bigint": {
@@ -1012,15 +1054,18 @@
       }
     },
     "node_modules/is-builtin-module": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz",
-      "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz",
+      "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==",
       "dev": true,
       "dependencies": {
-        "builtin-modules": "^3.0.0"
+        "builtin-modules": "^3.3.0"
       },
       "engines": {
         "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/is-callable": {
@@ -1036,9 +1081,9 @@
       }
     },
     "node_modules/is-core-module": {
-      "version": "2.7.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz",
-      "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==",
+      "version": "2.9.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
+      "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
       "dev": true,
       "dependencies": {
         "has": "^1.0.3"
@@ -1065,7 +1110,7 @@
     "node_modules/is-extglob": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -1095,13 +1140,13 @@
     "node_modules/is-module": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
-      "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
+      "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
       "dev": true
     },
     "node_modules/is-negative-zero": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
-      "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+      "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
       "dev": true,
       "engines": {
         "node": ">= 0.4"
@@ -1120,9 +1165,9 @@
       }
     },
     "node_modules/is-number-object": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
-      "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==",
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+      "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
       "dev": true,
       "dependencies": {
         "has-tostringtag": "^1.0.0"
@@ -1151,10 +1196,13 @@
       }
     },
     "node_modules/is-shared-array-buffer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
-      "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+      "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
       "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2"
+      },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
@@ -1190,12 +1238,12 @@
       }
     },
     "node_modules/is-weakref": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz",
-      "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+      "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
       "dev": true,
       "dependencies": {
-        "call-bind": "^1.0.0"
+        "call-bind": "^1.0.2"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -1204,13 +1252,13 @@
     "node_modules/isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
       "dev": true
     },
     "node_modules/jasmine-core": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.2.0.tgz",
-      "integrity": "sha512-OcFpBrIhnbmb9wfI8cqPSJ50pv3Wg4/NSgoZIqHzIwO/2a9qivJWzv8hUvaREIMYYJBas6AvfXATFdVuzzCqVw=="
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.3.0.tgz",
+      "integrity": "sha512-qybtBUesniQdW6n+QIHMng2vDOHscIC/dEXjW+JzO9+LoAZMb03RCUC5xFOv/btSKPm1xL42fn+RjlU4oB42Lg=="
     },
     "node_modules/js-tokens": {
       "version": "4.0.0",
@@ -1250,9 +1298,9 @@
       }
     },
     "node_modules/lilconfig": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz",
-      "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==",
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz",
+      "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==",
       "dev": true,
       "engines": {
         "node": ">=10"
@@ -1261,7 +1309,7 @@
     "node_modules/load-json-file": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
-      "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+      "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
       "dev": true,
       "dependencies": {
         "graceful-fs": "^4.1.2",
@@ -1273,55 +1321,34 @@
         "node": ">=4"
       }
     },
+    "node_modules/load-json-file/node_modules/pify": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+      "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/lodash": {
       "version": "4.17.21",
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
       "dev": true
     },
-    "node_modules/lodash.difference": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
-      "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=",
-      "dev": true
-    },
-    "node_modules/lodash.forown": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-4.4.0.tgz",
-      "integrity": "sha1-hRFc8E9z75ZuztUlEdOJPMRmg68=",
-      "dev": true
-    },
-    "node_modules/lodash.get": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
-      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
-      "dev": true
-    },
-    "node_modules/lodash.groupby": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz",
-      "integrity": "sha1-Cwih3PaDl8OXhVwyOXg4Mt90A9E=",
-      "dev": true
-    },
-    "node_modules/lodash.sortby": {
-      "version": "4.7.0",
-      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
-      "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
-      "dev": true
-    },
     "node_modules/magic-string": {
-      "version": "0.25.7",
-      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
-      "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
+      "version": "0.25.9",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
+      "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
       "dev": true,
       "dependencies": {
-        "sourcemap-codec": "^1.4.4"
+        "sourcemap-codec": "^1.4.8"
       }
     },
     "node_modules/memorystream": {
       "version": "0.3.1",
       "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
-      "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
+      "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==",
       "dev": true,
       "engines": {
         "node": ">= 0.10.0"
@@ -1350,9 +1377,9 @@
       }
     },
     "node_modules/minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
       "dev": true,
       "dependencies": {
         "brace-expansion": "^1.1.7"
@@ -1368,21 +1395,21 @@
       "dev": true
     },
     "node_modules/mkdirp": {
-      "version": "0.5.5",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
-      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+      "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
       "dev": true,
       "dependencies": {
-        "minimist": "^1.2.5"
+        "minimist": "^1.2.6"
       },
       "bin": {
         "mkdirp": "bin/cmd.js"
       }
     },
     "node_modules/nanoid": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
-      "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
+      "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
       "dev": true,
       "peer": true,
       "bin": {
@@ -1395,7 +1422,7 @@
     "node_modules/ncp": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
-      "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=",
+      "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==",
       "dev": true,
       "bin": {
         "ncp": "bin/ncp"
@@ -1408,9 +1435,9 @@
       "dev": true
     },
     "node_modules/node-releases": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz",
-      "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==",
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
+      "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
       "dev": true
     },
     "node_modules/normalize-package-data": {
@@ -1437,7 +1464,7 @@
     "node_modules/normalize-range": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
-      "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
+      "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -1469,9 +1496,9 @@
       }
     },
     "node_modules/object-inspect": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
-      "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+      "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
       "dev": true,
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -1507,7 +1534,7 @@
     "node_modules/once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
       "dev": true,
       "dependencies": {
         "wrappy": "1"
@@ -1516,7 +1543,7 @@
     "node_modules/parse-json": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
-      "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+      "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
       "dev": true,
       "dependencies": {
         "error-ex": "^1.3.1",
@@ -1529,7 +1556,7 @@
     "node_modules/path-is-absolute": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -1538,7 +1565,7 @@
     "node_modules/path-key": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
-      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
       "dev": true,
       "engines": {
         "node": ">=4"
@@ -1551,15 +1578,12 @@
       "dev": true
     },
     "node_modules/path-type": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
-      "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
       "dev": true,
-      "dependencies": {
-        "pify": "^3.0.0"
-      },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/picocolors": {
@@ -1593,31 +1617,37 @@
       }
     },
     "node_modules/pify": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
       "dev": true,
       "engines": {
-        "node": ">=4"
+        "node": ">=0.10.0"
       }
     },
     "node_modules/postcss": {
-      "version": "8.4.5",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz",
-      "integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==",
+      "version": "8.4.14",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
+      "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
       "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        }
+      ],
       "peer": true,
       "dependencies": {
-        "nanoid": "^3.1.30",
+        "nanoid": "^3.3.4",
         "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.1"
+        "source-map-js": "^1.0.2"
       },
       "engines": {
         "node": "^10 || ^12 || >=14"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/postcss/"
       }
     },
     "node_modules/postcss-cli": {
@@ -1679,17 +1709,13 @@
       }
     },
     "node_modules/postcss-reporter": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.4.tgz",
-      "integrity": "sha512-jY/fnpGSin7kwJeunXbY35STp5O3VIxSFdjee5JkoPQ+FfGH5JW3N+Xe9oAPcL9UkjWjkK+JC72o8XH4XXKdhw==",
+      "version": "7.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.5.tgz",
+      "integrity": "sha512-glWg7VZBilooZGOFPhN9msJ3FQs19Hie7l5a/eE6WglzYqVeH3ong3ShFcp9kDWJT1g2Y/wd59cocf9XxBtkWA==",
       "dev": true,
       "dependencies": {
-        "lodash.difference": "^4.5.0",
-        "lodash.forown": "^4.4.0",
-        "lodash.get": "^4.4.2",
-        "lodash.groupby": "^4.6.0",
-        "lodash.sortby": "^4.7.0",
-        "picocolors": "^1.0.0"
+        "picocolors": "^1.0.0",
+        "thenby": "^1.3.4"
       },
       "engines": {
         "node": ">=10"
@@ -1711,7 +1737,7 @@
     "node_modules/pretty-hrtime": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
-      "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
+      "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==",
       "dev": true,
       "engines": {
         "node": ">= 0.8"
@@ -1748,25 +1774,16 @@
     "node_modules/read-cache": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
-      "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
+      "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
       "dev": true,
       "dependencies": {
         "pify": "^2.3.0"
       }
     },
-    "node_modules/read-cache/node_modules/pify": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/read-pkg": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
-      "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+      "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
       "dev": true,
       "dependencies": {
         "load-json-file": "^4.0.0",
@@ -1777,6 +1794,27 @@
         "node": ">=4"
       }
     },
+    "node_modules/read-pkg/node_modules/path-type": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+      "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+      "dev": true,
+      "dependencies": {
+        "pify": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/read-pkg/node_modules/pify": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+      "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
+    },
     "node_modules/readdirp": {
       "version": "3.6.0",
       "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -1789,23 +1827,44 @@
         "node": ">=8.10.0"
       }
     },
+    "node_modules/regexp.prototype.flags": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
+      "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
+      "dev": true,
+      "dependencies": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.3",
+        "functions-have-names": "^1.2.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
     },
     "node_modules/resolve": {
-      "version": "1.20.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
-      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+      "version": "1.22.1",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
       "dev": true,
       "dependencies": {
-        "is-core-module": "^2.2.0",
-        "path-parse": "^1.0.6"
+        "is-core-module": "^2.9.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
+      },
+      "bin": {
+        "resolve": "bin/resolve"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -1822,9 +1881,9 @@
       }
     },
     "node_modules/rollup": {
-      "version": "2.75.7",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.7.tgz",
-      "integrity": "sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ==",
+      "version": "2.77.2",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.2.tgz",
+      "integrity": "sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==",
       "dev": true,
       "bin": {
         "rollup": "dist/bin/rollup"
@@ -1860,9 +1919,9 @@
       }
     },
     "node_modules/sass": {
-      "version": "1.53.0",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.53.0.tgz",
-      "integrity": "sha512-zb/oMirbKhUgRQ0/GFz8TSAwRq2IlR29vOUJZOx0l8sV+CkHUfHa4u5nqrG+1VceZp7Jfj59SVW9ogdhTvJDcQ==",
+      "version": "1.54.1",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.1.tgz",
+      "integrity": "sha512-GHJJr31Me32RjjUBagyzx8tzjKBUcDwo5239XANIRBq0adDu5iIG0aFO0i/TBb/4I9oyxkEv44nq/kL1DxdDhA==",
       "dev": true,
       "dependencies": {
         "chokidar": ">=3.0.0 <4.0.0",
@@ -1888,7 +1947,7 @@
     "node_modules/shebang-command": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
-      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
       "dev": true,
       "dependencies": {
         "shebang-regex": "^1.0.0"
@@ -1900,7 +1959,7 @@
     "node_modules/shebang-regex": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
-      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -1948,9 +2007,9 @@
       }
     },
     "node_modules/source-map-js": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
-      "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -1989,15 +2048,15 @@
       }
     },
     "node_modules/spdx-license-ids": {
-      "version": "3.0.10",
-      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz",
-      "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==",
+      "version": "3.0.11",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz",
+      "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==",
       "dev": true
     },
     "node_modules/sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
       "dev": true
     },
     "node_modules/string-width": {
@@ -2032,26 +2091,28 @@
       }
     },
     "node_modules/string.prototype.trimend": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
-      "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz",
+      "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==",
       "dev": true,
       "dependencies": {
         "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3"
+        "define-properties": "^1.1.4",
+        "es-abstract": "^1.19.5"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
       }
     },
     "node_modules/string.prototype.trimstart": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
-      "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz",
+      "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==",
       "dev": true,
       "dependencies": {
         "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3"
+        "define-properties": "^1.1.4",
+        "es-abstract": "^1.19.5"
       },
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -2072,7 +2133,7 @@
     "node_modules/strip-bom": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
-      "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+      "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
       "dev": true,
       "engines": {
         "node": ">=4"
@@ -2090,6 +2151,24 @@
         "node": ">=4"
       }
     },
+    "node_modules/supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true,
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/thenby": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/thenby/-/thenby-1.3.4.tgz",
+      "integrity": "sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ==",
+      "dev": true
+    },
     "node_modules/to-regex-range": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -2142,7 +2221,7 @@
     "node_modules/tslint/node_modules/builtin-modules": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
-      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+      "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==",
       "dev": true,
       "engines": {
         "node": ">=0.10.0"
@@ -2180,14 +2259,14 @@
       }
     },
     "node_modules/unbox-primitive": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
-      "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+      "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
       "dev": true,
       "dependencies": {
-        "function-bind": "^1.1.1",
-        "has-bigints": "^1.0.1",
-        "has-symbols": "^1.0.2",
+        "call-bind": "^1.0.2",
+        "has-bigints": "^1.0.2",
+        "has-symbols": "^1.0.3",
         "which-boxed-primitive": "^1.0.2"
       },
       "funding": {
@@ -2203,6 +2282,32 @@
         "node": ">= 10.0.0"
       }
     },
+    "node_modules/update-browserslist-db": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz",
+      "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        }
+      ],
+      "dependencies": {
+        "escalade": "^3.1.1",
+        "picocolors": "^1.0.0"
+      },
+      "bin": {
+        "browserslist-lint": "cli.js"
+      },
+      "peerDependencies": {
+        "browserslist": ">= 4.21.0"
+      }
+    },
     "node_modules/validate-npm-package-license": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -2294,7 +2399,7 @@
     "node_modules/wrappy": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
       "dev": true
     },
     "node_modules/y18n": {
@@ -2316,56 +2421,56 @@
       }
     },
     "node_modules/yargs": {
-      "version": "17.2.1",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz",
-      "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==",
+      "version": "17.5.1",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
+      "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
       "dev": true,
       "dependencies": {
         "cliui": "^7.0.2",
         "escalade": "^3.1.1",
         "get-caller-file": "^2.0.5",
         "require-directory": "^2.1.1",
-        "string-width": "^4.2.0",
+        "string-width": "^4.2.3",
         "y18n": "^5.0.5",
-        "yargs-parser": "^20.2.2"
+        "yargs-parser": "^21.0.0"
       },
       "engines": {
         "node": ">=12"
       }
     },
     "node_modules/yargs-parser": {
-      "version": "20.2.9",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
-      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+      "version": "21.0.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
+      "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
       "dev": true,
       "engines": {
-        "node": ">=10"
+        "node": ">=12"
       }
     }
   },
   "dependencies": {
     "@babel/code-frame": {
-      "version": "7.14.5",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
-      "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+      "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
       "dev": true,
       "requires": {
-        "@babel/highlight": "^7.14.5"
+        "@babel/highlight": "^7.18.6"
       }
     },
     "@babel/helper-validator-identifier": {
-      "version": "7.15.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz",
-      "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
+      "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==",
       "dev": true
     },
     "@babel/highlight": {
-      "version": "7.14.5",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
-      "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+      "version": "7.18.6",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
       "dev": true,
       "requires": {
-        "@babel/helper-validator-identifier": "^7.14.5",
+        "@babel/helper-validator-identifier": "^7.18.6",
         "chalk": "^2.0.0",
         "js-tokens": "^4.0.0"
       }
@@ -2438,9 +2543,9 @@
       "dev": true
     },
     "@types/node": {
-      "version": "16.11.1",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz",
-      "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==",
+      "version": "18.6.3",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz",
+      "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==",
       "dev": true
     },
     "@types/prismjs": {
@@ -2493,13 +2598,13 @@
       }
     },
     "autoprefixer": {
-      "version": "10.4.7",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz",
-      "integrity": "sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA==",
+      "version": "10.4.8",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.8.tgz",
+      "integrity": "sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==",
       "dev": true,
       "requires": {
-        "browserslist": "^4.20.3",
-        "caniuse-lite": "^1.0.30001335",
+        "browserslist": "^4.21.3",
+        "caniuse-lite": "^1.0.30001373",
         "fraction.js": "^4.2.0",
         "normalize-range": "^0.1.2",
         "picocolors": "^1.0.0",
@@ -2538,22 +2643,21 @@
       }
     },
     "browserslist": {
-      "version": "4.20.3",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz",
-      "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==",
+      "version": "4.21.3",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz",
+      "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==",
       "dev": true,
       "requires": {
-        "caniuse-lite": "^1.0.30001332",
-        "electron-to-chromium": "^1.4.118",
-        "escalade": "^3.1.1",
-        "node-releases": "^2.0.3",
-        "picocolors": "^1.0.0"
+        "caniuse-lite": "^1.0.30001370",
+        "electron-to-chromium": "^1.4.202",
+        "node-releases": "^2.0.6",
+        "update-browserslist-db": "^1.0.5"
       }
     },
     "builtin-modules": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz",
-      "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==",
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
+      "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
       "dev": true
     },
     "call-bind": {
@@ -2567,9 +2671,9 @@
       }
     },
     "caniuse-lite": {
-      "version": "1.0.30001335",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001335.tgz",
-      "integrity": "sha512-ddP1Tgm7z2iIxu6QTtbZUv6HJxSaV/PZeSrWFZtbY4JZ69tOeNhBCl3HyRQgeNZKE5AOn1kpV7fhljigy0Ty3w==",
+      "version": "1.0.30001373",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz",
+      "integrity": "sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ==",
       "dev": true
     },
     "chalk": {
@@ -2584,15 +2688,15 @@
       }
     },
     "chokidar": {
-      "version": "3.5.2",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
-      "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
       "dev": true,
       "requires": {
         "anymatch": "~3.1.2",
         "braces": "~3.0.2",
         "fsevents": "~2.3.2",
-        "glob-parent": "~6.0.0",
+        "glob-parent": "~5.1.2",
         "is-binary-path": "~2.1.0",
         "is-glob": "~4.0.1",
         "normalize-path": "~3.0.0",
@@ -2600,22 +2704,22 @@
       }
     },
     "clean-css": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz",
-      "integrity": "sha512-YYuuxv4H/iNb1Z/5IbMRoxgrzjWGhOEFfd+groZ5dMCVkpENiMZmwspdrzBo9286JjM1gZJPAyL7ZIdzuvu2AQ==",
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz",
+      "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==",
       "dev": true,
       "requires": {
         "source-map": "~0.6.0"
       }
     },
     "clean-css-cli": {
-      "version": "5.6.0",
-      "resolved": "https://registry.npmjs.org/clean-css-cli/-/clean-css-cli-5.6.0.tgz",
-      "integrity": "sha512-68vorNEG808D1QzeerO9AlwQVTuaR8YSK4aqwIsjJq0wDSyPH11ApHY0O+EQrdEGUZcN+d72v+Nn/gpxjAFewQ==",
+      "version": "5.6.1",
+      "resolved": "https://registry.npmjs.org/clean-css-cli/-/clean-css-cli-5.6.1.tgz",
+      "integrity": "sha512-/StJu1YODZY6cOwkBx5FMhSoc9YmvEJXtwNN+udGg1GIKrr4PkdsCdUqC26GfdPdt5IuZnu+5y9/3mrdIJa40Q==",
       "dev": true,
       "requires": {
         "chokidar": "^3.5.2",
-        "clean-css": "^5.3.0",
+        "clean-css": "^5.3.1",
         "commander": "7.x",
         "glob": "^7.1.6"
       }
@@ -2643,7 +2747,7 @@
     "color-name": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
       "dev": true
     },
     "commander": {
@@ -2655,7 +2759,7 @@
     "concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
       "dev": true
     },
     "cross-spawn": {
@@ -2678,12 +2782,13 @@
       "dev": true
     },
     "define-properties": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
-      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
+      "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
       "dev": true,
       "requires": {
-        "object-keys": "^1.0.12"
+        "has-property-descriptors": "^1.0.0",
+        "object-keys": "^1.1.1"
       }
     },
     "dependency-graph": {
@@ -2705,20 +2810,12 @@
       "dev": true,
       "requires": {
         "path-type": "^4.0.0"
-      },
-      "dependencies": {
-        "path-type": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
-          "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-          "dev": true
-        }
       }
     },
     "electron-to-chromium": {
-      "version": "1.4.131",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.131.tgz",
-      "integrity": "sha512-oi3YPmaP87hiHn0c4ePB67tXaF+ldGhxvZnT19tW9zX6/Ej+pLN0Afja5rQ6S+TND7I9EuwQTT8JYn1k7R7rrw==",
+      "version": "1.4.210",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.210.tgz",
+      "integrity": "sha512-kSiX4tuyZijV7Cz0MWVmGT8K2siqaOA4Z66K5dCttPPRh0HicOcOAEj1KlC8O8J1aOS/1M8rGofOzksLKaHWcQ==",
       "dev": true
     },
     "emoji-regex": {
@@ -2737,31 +2834,34 @@
       }
     },
     "es-abstract": {
-      "version": "1.19.1",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz",
-      "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==",
+      "version": "1.20.1",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz",
+      "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==",
       "dev": true,
       "requires": {
         "call-bind": "^1.0.2",
         "es-to-primitive": "^1.2.1",
         "function-bind": "^1.1.1",
+        "function.prototype.name": "^1.1.5",
         "get-intrinsic": "^1.1.1",
         "get-symbol-description": "^1.0.0",
         "has": "^1.0.3",
-        "has-symbols": "^1.0.2",
+        "has-property-descriptors": "^1.0.0",
+        "has-symbols": "^1.0.3",
         "internal-slot": "^1.0.3",
         "is-callable": "^1.2.4",
-        "is-negative-zero": "^2.0.1",
+        "is-negative-zero": "^2.0.2",
         "is-regex": "^1.1.4",
-        "is-shared-array-buffer": "^1.0.1",
+        "is-shared-array-buffer": "^1.0.2",
         "is-string": "^1.0.7",
-        "is-weakref": "^1.0.1",
-        "object-inspect": "^1.11.0",
+        "is-weakref": "^1.0.2",
+        "object-inspect": "^1.12.0",
         "object-keys": "^1.1.1",
         "object.assign": "^4.1.2",
-        "string.prototype.trimend": "^1.0.4",
-        "string.prototype.trimstart": "^1.0.4",
-        "unbox-primitive": "^1.0.1"
+        "regexp.prototype.flags": "^1.4.3",
+        "string.prototype.trimend": "^1.0.5",
+        "string.prototype.trimstart": "^1.0.5",
+        "unbox-primitive": "^1.0.2"
       }
     },
     "es-to-primitive": {
@@ -2784,7 +2884,7 @@
     "escape-string-regexp": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
       "dev": true
     },
     "esprima": {
@@ -2807,7 +2907,7 @@
       "requires": {
         "@nodelib/fs.stat": "^2.0.2",
         "@nodelib/fs.walk": "^1.2.3",
-        "glob-parent": "^6.0.0",
+        "glob-parent": "^5.1.2",
         "merge2": "^1.3.0",
         "micromatch": "^4.0.4"
       }
@@ -2833,7 +2933,7 @@
     "font-awesome": {
       "version": "4.7.0",
       "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
-      "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM="
+      "integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg=="
     },
     "fraction.js": {
       "version": "4.2.0",
@@ -2842,9 +2942,9 @@
       "dev": true
     },
     "fs-extra": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
-      "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+      "version": "10.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+      "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
       "dev": true,
       "requires": {
         "graceful-fs": "^4.2.0",
@@ -2855,7 +2955,7 @@
     "fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
       "dev": true
     },
     "fsevents": {
@@ -2871,6 +2971,24 @@
       "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
       "dev": true
     },
+    "function.prototype.name": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
+      "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.3",
+        "es-abstract": "^1.19.0",
+        "functions-have-names": "^1.2.2"
+      }
+    },
+    "functions-have-names": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+      "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+      "dev": true
+    },
     "get-caller-file": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -2878,14 +2996,14 @@
       "dev": true
     },
     "get-intrinsic": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
-      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+      "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
       "dev": true,
       "requires": {
         "function-bind": "^1.1.1",
         "has": "^1.0.3",
-        "has-symbols": "^1.0.1"
+        "has-symbols": "^1.0.3"
       }
     },
     "get-stdin": {
@@ -2905,26 +3023,26 @@
       }
     },
     "glob": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
-      "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
       "dev": true,
       "requires": {
         "fs.realpath": "^1.0.0",
         "inflight": "^1.0.4",
         "inherits": "2",
-        "minimatch": "^3.0.4",
+        "minimatch": "^3.1.1",
         "once": "^1.3.0",
         "path-is-absolute": "^1.0.0"
       }
     },
     "glob-parent": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
-      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
       "dev": true,
       "requires": {
-        "is-glob": "^4.0.3"
+        "is-glob": "^4.0.1"
       }
     },
     "globby": {
@@ -2941,9 +3059,9 @@
       }
     },
     "graceful-fs": {
-      "version": "4.2.8",
-      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
-      "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
+      "version": "4.2.10",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+      "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
     "has": {
@@ -2956,21 +3074,30 @@
       }
     },
     "has-bigints": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
-      "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+      "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
       "dev": true
     },
     "has-flag": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
       "dev": true
     },
+    "has-property-descriptors": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+      "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+      "dev": true,
+      "requires": {
+        "get-intrinsic": "^1.1.1"
+      }
+    },
     "has-symbols": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
-      "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
       "dev": true
     },
     "has-tostringtag": {
@@ -2995,15 +3122,15 @@
       "dev": true
     },
     "immutable": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz",
-      "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==",
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz",
+      "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==",
       "dev": true
     },
     "inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
       "dev": true,
       "requires": {
         "once": "^1.3.0",
@@ -3030,7 +3157,7 @@
     "is-arrayish": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
       "dev": true
     },
     "is-bigint": {
@@ -3062,12 +3189,12 @@
       }
     },
     "is-builtin-module": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz",
-      "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz",
+      "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==",
       "dev": true,
       "requires": {
-        "builtin-modules": "^3.0.0"
+        "builtin-modules": "^3.3.0"
       }
     },
     "is-callable": {
@@ -3077,9 +3204,9 @@
       "dev": true
     },
     "is-core-module": {
-      "version": "2.7.0",
-      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz",
-      "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==",
+      "version": "2.9.0",
+      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
+      "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
       "dev": true,
       "requires": {
         "has": "^1.0.3"
@@ -3097,7 +3224,7 @@
     "is-extglob": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
       "dev": true
     },
     "is-fullwidth-code-point": {
@@ -3118,13 +3245,13 @@
     "is-module": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
-      "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=",
+      "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
       "dev": true
     },
     "is-negative-zero": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
-      "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
+      "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
       "dev": true
     },
     "is-number": {
@@ -3134,9 +3261,9 @@
       "dev": true
     },
     "is-number-object": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
-      "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==",
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+      "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
       "dev": true,
       "requires": {
         "has-tostringtag": "^1.0.0"
@@ -3153,10 +3280,13 @@
       }
     },
     "is-shared-array-buffer": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
-      "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==",
-      "dev": true
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
+      "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.2"
+      }
     },
     "is-string": {
       "version": "1.0.7",
@@ -3177,24 +3307,24 @@
       }
     },
     "is-weakref": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz",
-      "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+      "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
       "dev": true,
       "requires": {
-        "call-bind": "^1.0.0"
+        "call-bind": "^1.0.2"
       }
     },
     "isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
       "dev": true
     },
     "jasmine-core": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.2.0.tgz",
-      "integrity": "sha512-OcFpBrIhnbmb9wfI8cqPSJ50pv3Wg4/NSgoZIqHzIwO/2a9qivJWzv8hUvaREIMYYJBas6AvfXATFdVuzzCqVw=="
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.3.0.tgz",
+      "integrity": "sha512-qybtBUesniQdW6n+QIHMng2vDOHscIC/dEXjW+JzO9+LoAZMb03RCUC5xFOv/btSKPm1xL42fn+RjlU4oB42Lg=="
     },
     "js-tokens": {
       "version": "4.0.0",
@@ -3229,21 +3359,29 @@
       }
     },
     "lilconfig": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz",
-      "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==",
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz",
+      "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==",
       "dev": true
     },
     "load-json-file": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
-      "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+      "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
       "dev": true,
       "requires": {
         "graceful-fs": "^4.1.2",
         "parse-json": "^4.0.0",
         "pify": "^3.0.0",
         "strip-bom": "^3.0.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+          "dev": true
+        }
       }
     },
     "lodash": {
@@ -3252,49 +3390,19 @@
       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
       "dev": true
     },
-    "lodash.difference": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
-      "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=",
-      "dev": true
-    },
-    "lodash.forown": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-4.4.0.tgz",
-      "integrity": "sha1-hRFc8E9z75ZuztUlEdOJPMRmg68=",
-      "dev": true
-    },
-    "lodash.get": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
-      "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
-      "dev": true
-    },
-    "lodash.groupby": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/lodash.groupby/-/lodash.groupby-4.6.0.tgz",
-      "integrity": "sha1-Cwih3PaDl8OXhVwyOXg4Mt90A9E=",
-      "dev": true
-    },
-    "lodash.sortby": {
-      "version": "4.7.0",
-      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
-      "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
-      "dev": true
-    },
     "magic-string": {
-      "version": "0.25.7",
-      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
-      "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
+      "version": "0.25.9",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
+      "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
       "dev": true,
       "requires": {
-        "sourcemap-codec": "^1.4.4"
+        "sourcemap-codec": "^1.4.8"
       }
     },
     "memorystream": {
       "version": "0.3.1",
       "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
-      "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=",
+      "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==",
       "dev": true
     },
     "merge2": {
@@ -3314,9 +3422,9 @@
       }
     },
     "minimatch": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
       "dev": true,
       "requires": {
         "brace-expansion": "^1.1.7"
@@ -3329,25 +3437,25 @@
       "dev": true
     },
     "mkdirp": {
-      "version": "0.5.5",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
-      "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+      "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
       "dev": true,
       "requires": {
-        "minimist": "^1.2.5"
+        "minimist": "^1.2.6"
       }
     },
     "nanoid": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
-      "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
+      "version": "3.3.4",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
+      "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
       "dev": true,
       "peer": true
     },
     "ncp": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz",
-      "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=",
+      "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==",
       "dev": true
     },
     "nice-try": {
@@ -3357,9 +3465,9 @@
       "dev": true
     },
     "node-releases": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz",
-      "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==",
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
+      "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
       "dev": true
     },
     "normalize-package-data": {
@@ -3383,7 +3491,7 @@
     "normalize-range": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
-      "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
+      "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
       "dev": true
     },
     "npm-run-all": {
@@ -3404,9 +3512,9 @@
       }
     },
     "object-inspect": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
-      "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+      "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
       "dev": true
     },
     "object-keys": {
@@ -3430,7 +3538,7 @@
     "once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
       "dev": true,
       "requires": {
         "wrappy": "1"
@@ -3439,7 +3547,7 @@
     "parse-json": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
-      "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+      "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
       "dev": true,
       "requires": {
         "error-ex": "^1.3.1",
@@ -3449,13 +3557,13 @@
     "path-is-absolute": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
       "dev": true
     },
     "path-key": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
-      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
       "dev": true
     },
     "path-parse": {
@@ -3465,13 +3573,10 @@
       "dev": true
     },
     "path-type": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
-      "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
-      "dev": true,
-      "requires": {
-        "pify": "^3.0.0"
-      }
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+      "dev": true
     },
     "picocolors": {
       "version": "1.0.0",
@@ -3492,21 +3597,21 @@
       "dev": true
     },
     "pify": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
-      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
       "dev": true
     },
     "postcss": {
-      "version": "8.4.5",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz",
-      "integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==",
+      "version": "8.4.14",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
+      "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
       "dev": true,
       "peer": true,
       "requires": {
-        "nanoid": "^3.1.30",
+        "nanoid": "^3.3.4",
         "picocolors": "^1.0.0",
-        "source-map-js": "^1.0.1"
+        "source-map-js": "^1.0.2"
       }
     },
     "postcss-cli": {
@@ -3540,17 +3645,13 @@
       }
     },
     "postcss-reporter": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.4.tgz",
-      "integrity": "sha512-jY/fnpGSin7kwJeunXbY35STp5O3VIxSFdjee5JkoPQ+FfGH5JW3N+Xe9oAPcL9UkjWjkK+JC72o8XH4XXKdhw==",
+      "version": "7.0.5",
+      "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.0.5.tgz",
+      "integrity": "sha512-glWg7VZBilooZGOFPhN9msJ3FQs19Hie7l5a/eE6WglzYqVeH3ong3ShFcp9kDWJT1g2Y/wd59cocf9XxBtkWA==",
       "dev": true,
       "requires": {
-        "lodash.difference": "^4.5.0",
-        "lodash.forown": "^4.4.0",
-        "lodash.get": "^4.4.2",
-        "lodash.groupby": "^4.6.0",
-        "lodash.sortby": "^4.7.0",
-        "picocolors": "^1.0.0"
+        "picocolors": "^1.0.0",
+        "thenby": "^1.3.4"
       }
     },
     "postcss-value-parser": {
@@ -3562,7 +3663,7 @@
     "pretty-hrtime": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
-      "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
+      "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==",
       "dev": true
     },
     "prismjs": {
@@ -3579,29 +3680,38 @@
     "read-cache": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
-      "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
+      "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
       "dev": true,
       "requires": {
         "pify": "^2.3.0"
-      },
-      "dependencies": {
-        "pify": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-          "dev": true
-        }
       }
     },
     "read-pkg": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
-      "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+      "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
       "dev": true,
       "requires": {
         "load-json-file": "^4.0.0",
         "normalize-package-data": "^2.3.2",
         "path-type": "^3.0.0"
+      },
+      "dependencies": {
+        "path-type": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+          "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+          "dev": true,
+          "requires": {
+            "pify": "^3.0.0"
+          }
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+          "dev": true
+        }
       }
     },
     "readdirp": {
@@ -3613,20 +3723,32 @@
         "picomatch": "^2.2.1"
       }
     },
+    "regexp.prototype.flags": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
+      "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
+      "dev": true,
+      "requires": {
+        "call-bind": "^1.0.2",
+        "define-properties": "^1.1.3",
+        "functions-have-names": "^1.2.2"
+      }
+    },
     "require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
       "dev": true
     },
     "resolve": {
-      "version": "1.20.0",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
-      "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
+      "version": "1.22.1",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+      "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
       "dev": true,
       "requires": {
-        "is-core-module": "^2.2.0",
-        "path-parse": "^1.0.6"
+        "is-core-module": "^2.9.0",
+        "path-parse": "^1.0.7",
+        "supports-preserve-symlinks-flag": "^1.0.0"
       }
     },
     "reusify": {
@@ -3636,9 +3758,9 @@
       "dev": true
     },
     "rollup": {
-      "version": "2.75.7",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.7.tgz",
-      "integrity": "sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ==",
+      "version": "2.77.2",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.2.tgz",
+      "integrity": "sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==",
       "dev": true,
       "requires": {
         "fsevents": "~2.3.2"
@@ -3654,9 +3776,9 @@
       }
     },
     "sass": {
-      "version": "1.53.0",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.53.0.tgz",
-      "integrity": "sha512-zb/oMirbKhUgRQ0/GFz8TSAwRq2IlR29vOUJZOx0l8sV+CkHUfHa4u5nqrG+1VceZp7Jfj59SVW9ogdhTvJDcQ==",
+      "version": "1.54.1",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.1.tgz",
+      "integrity": "sha512-GHJJr31Me32RjjUBagyzx8tzjKBUcDwo5239XANIRBq0adDu5iIG0aFO0i/TBb/4I9oyxkEv44nq/kL1DxdDhA==",
       "dev": true,
       "requires": {
         "chokidar": ">=3.0.0 <4.0.0",
@@ -3673,7 +3795,7 @@
     "shebang-command": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
-      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
       "dev": true,
       "requires": {
         "shebang-regex": "^1.0.0"
@@ -3682,7 +3804,7 @@
     "shebang-regex": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
-      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
       "dev": true
     },
     "shell-quote": {
@@ -3715,9 +3837,9 @@
       "dev": true
     },
     "source-map-js": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
-      "integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+      "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
       "dev": true
     },
     "sourcemap-codec": {
@@ -3753,15 +3875,15 @@
       }
     },
     "spdx-license-ids": {
-      "version": "3.0.10",
-      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz",
-      "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==",
+      "version": "3.0.11",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz",
+      "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==",
       "dev": true
     },
     "sprintf-js": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
       "dev": true
     },
     "string-width": {
@@ -3787,23 +3909,25 @@
       }
     },
     "string.prototype.trimend": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
-      "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz",
+      "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==",
       "dev": true,
       "requires": {
         "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3"
+        "define-properties": "^1.1.4",
+        "es-abstract": "^1.19.5"
       }
     },
     "string.prototype.trimstart": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
-      "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz",
+      "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==",
       "dev": true,
       "requires": {
         "call-bind": "^1.0.2",
-        "define-properties": "^1.1.3"
+        "define-properties": "^1.1.4",
+        "es-abstract": "^1.19.5"
       }
     },
     "strip-ansi": {
@@ -3818,7 +3942,7 @@
     "strip-bom": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
-      "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+      "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
       "dev": true
     },
     "supports-color": {
@@ -3830,6 +3954,18 @@
         "has-flag": "^3.0.0"
       }
     },
+    "supports-preserve-symlinks-flag": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+      "dev": true
+    },
+    "thenby": {
+      "version": "1.3.4",
+      "resolved": "https://registry.npmjs.org/thenby/-/thenby-1.3.4.tgz",
+      "integrity": "sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ==",
+      "dev": true
+    },
     "to-regex-range": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -3869,7 +4005,7 @@
         "builtin-modules": {
           "version": "1.1.1",
           "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
-          "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+          "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==",
           "dev": true
         },
         "commander": {
@@ -3896,14 +4032,14 @@
       "dev": true
     },
     "unbox-primitive": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
-      "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+      "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
       "dev": true,
       "requires": {
-        "function-bind": "^1.1.1",
-        "has-bigints": "^1.0.1",
-        "has-symbols": "^1.0.2",
+        "call-bind": "^1.0.2",
+        "has-bigints": "^1.0.2",
+        "has-symbols": "^1.0.3",
         "which-boxed-primitive": "^1.0.2"
       }
     },
@@ -3913,6 +4049,16 @@
       "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
       "dev": true
     },
+    "update-browserslist-db": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz",
+      "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==",
+      "dev": true,
+      "requires": {
+        "escalade": "^3.1.1",
+        "picocolors": "^1.0.0"
+      }
+    },
     "validate-npm-package-license": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
@@ -3985,7 +4131,7 @@
     "wrappy": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
       "dev": true
     },
     "y18n": {
@@ -4001,24 +4147,24 @@
       "dev": true
     },
     "yargs": {
-      "version": "17.2.1",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz",
-      "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==",
+      "version": "17.5.1",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
+      "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
       "dev": true,
       "requires": {
         "cliui": "^7.0.2",
         "escalade": "^3.1.1",
         "get-caller-file": "^2.0.5",
         "require-directory": "^2.1.1",
-        "string-width": "^4.2.0",
+        "string-width": "^4.2.3",
         "y18n": "^5.0.5",
-        "yargs-parser": "^20.2.2"
+        "yargs-parser": "^21.0.0"
       }
     },
     "yargs-parser": {
-      "version": "20.2.9",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
-      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+      "version": "21.0.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
+      "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
       "dev": true
     }
   }
diff --git a/tobago-example/tobago-example-demo/package.json b/tobago-example/tobago-example-demo/package.json
index 02a6525ef1..52e8860fda 100644
--- a/tobago-example/tobago-example-demo/package.json
+++ b/tobago-example/tobago-example-demo/package.json
@@ -36,21 +36,21 @@
   },
   "dependencies": {
     "font-awesome": "4.7.0",
-    "jasmine-core": "^4.2.0",
+    "jasmine-core": "^4.3.0",
     "prismjs": "^1.28.0"
   },
   "devDependencies": {
     "@rollup/plugin-node-resolve": "^13.3.0",
     "@rollup/plugin-replace": "^4.0.0",
     "@types/prismjs": "^1.26.0",
-    "autoprefixer": "^10.4.7",
-    "clean-css-cli": "^5.6.0",
+    "autoprefixer": "^10.4.8",
+    "clean-css-cli": "^5.6.1",
     "lodash": "^4.17.21",
     "ncp": "^2.0.0",
     "npm-run-all": "^4.1.5",
     "postcss-cli": "^10.0.0",
-    "rollup": "^2.75.7",
-    "sass": "^1.53.0",
+    "rollup": "^2.77.2",
+    "sass": "^1.54.1",
     "tslint": "^6.1.3",
     "typescript": "^4.7.4",
     "y18n": "^5.0.8"
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/js/boot0.js b/tobago-example/tobago-example-demo/src/main/webapp/js/boot0.js
index 03186b008b..c773ba8eb7 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/js/boot0.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/js/boot0.js
@@ -27,14 +27,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  source files or spec files are loaded.
  */
 (function() {
-  var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
+  const jasmineRequire = window.jasmineRequire || require('./jasmine.js');
 
   /**
    * ## Require &amp; Instantiate
    *
    * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference.
    */
-  var jasmine = jasmineRequire.core(jasmineRequire),
+  const jasmine = jasmineRequire.core(jasmineRequire),
     global = jasmine.getGlobal();
   global.jasmine = jasmine;
 
@@ -46,19 +46,19 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   /**
    * Create the Jasmine environment. This is used to run all specs in a project.
    */
-  var env = jasmine.getEnv();
+  const env = jasmine.getEnv();
 
   /**
    * ## The Global Interface
    *
    * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
    */
-  var jasmineInterface = jasmineRequire.interface(jasmine, env);
+  const jasmineInterface = jasmineRequire.interface(jasmine, env);
 
   /**
    * Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
    */
-  for (var property in jasmineInterface) {
+  for (const property in jasmineInterface) {
     global[property] = jasmineInterface[property];
   }
 })();
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/js/boot1.js b/tobago-example/tobago-example-demo/src/main/webapp/js/boot1.js
index 7980a1bb93..5fe49e4189 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/js/boot1.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/js/boot1.js
@@ -34,7 +34,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
 (function() {
-  var env = jasmine.getEnv();
+  const env = jasmine.getEnv();
 
   /**
    * ## Runner Parameters
@@ -42,15 +42,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
    */
 
-  var queryString = new jasmine.QueryString({
+  const queryString = new jasmine.QueryString({
     getWindowLocation: function() {
       return window.location;
     }
   });
 
-  var filterSpecs = !!queryString.getParam('spec');
+  const filterSpecs = !!queryString.getParam('spec');
 
-  var config = {
+  const config = {
     stopOnSpecFailure: queryString.getParam('stopOnSpecFailure'),
     stopSpecOnExpectationFailure: queryString.getParam(
       'stopSpecOnExpectationFailure'
@@ -58,13 +58,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     hideDisabled: queryString.getParam('hideDisabled')
   };
 
-  var random = queryString.getParam('random');
+  const random = queryString.getParam('random');
 
   if (random !== undefined && random !== '') {
     config.random = random;
   }
 
-  var seed = queryString.getParam('seed');
+  const seed = queryString.getParam('seed');
   if (seed) {
     config.seed = seed;
   }
@@ -73,7 +73,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    * ## Reporters
    * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any).
    */
-  var htmlReporter = new jasmine.HtmlReporter({
+  const htmlReporter = new jasmine.HtmlReporter({
     env: env,
     navigateWithNewParam: function(key, value) {
       return queryString.navigateWithNewParam(key, value);
@@ -103,7 +103,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   /**
    * Filter which specs will be run by matching the start of the full name against the `spec` query param.
    */
-  var specFilter = new jasmine.HtmlSpecFilter({
+  const specFilter = new jasmine.HtmlSpecFilter({
     filterString: function() {
       return queryString.getParam('spec');
     }
@@ -120,7 +120,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    *
    * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
    */
-  var currentWindowOnload = window.onload;
+  const currentWindowOnload = window.onload;
 
   window.onload = function() {
     if (currentWindowOnload) {
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/js/jasmine-html.js b/tobago-example/tobago-example-demo/src/main/webapp/js/jasmine-html.js
index c4d7c8d2c0..2ebc6d0e5d 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/js/jasmine-html.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/js/jasmine-html.js
@@ -20,6 +20,7 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
+// eslint-disable-next-line no-var
 var jasmineRequire = window.jasmineRequire || require('./jasmine.js');
 
 jasmineRequire.html = function(j$) {
@@ -79,19 +80,21 @@ jasmineRequire.HtmlReporter = function(j$) {
   };
 
   function HtmlReporter(options) {
-    var config = function() {
-        return (options.env && options.env.configuration()) || {};
-      },
-      getContainer = options.getContainer,
-      createElement = options.createElement,
-      createTextNode = options.createTextNode,
-      navigateWithNewParam = options.navigateWithNewParam || function() {},
-      addToExistingQueryString =
-        options.addToExistingQueryString || defaultQueryString,
-      filterSpecs = options.filterSpecs,
-      htmlReporterMain,
-      symbols,
-      deprecationWarnings = [];
+    function config() {
+      return (options.env && options.env.configuration()) || {};
+    }
+
+    const getContainer = options.getContainer;
+    const createElement = options.createElement;
+    const createTextNode = options.createTextNode;
+    const navigateWithNewParam = options.navigateWithNewParam || function() {};
+    const addToExistingQueryString =
+      options.addToExistingQueryString || defaultQueryString;
+    const filterSpecs = options.filterSpecs;
+    let htmlReporterMain;
+    let symbols;
+    const deprecationWarnings = [];
+    const failures = [];
 
     this.initialize = function() {
       clearPrior();
@@ -119,14 +122,14 @@ jasmineRequire.HtmlReporter = function(j$) {
       getContainer().appendChild(htmlReporterMain);
     };
 
-    var totalSpecsDefined;
+    let totalSpecsDefined;
     this.jasmineStarted = function(options) {
       totalSpecsDefined = options.totalSpecsDefined || 0;
     };
 
-    var summary = createDom('div', { className: 'jasmine-summary' });
+    const summary = createDom('div', { className: 'jasmine-summary' });
 
-    var stateBuilder = new ResultsStateBuilder();
+    const stateBuilder = new ResultsStateBuilder();
 
     this.suiteStarted = function(result) {
       stateBuilder.suiteStarted(result);
@@ -145,12 +148,11 @@ jasmineRequire.HtmlReporter = function(j$) {
       stateBuilder.specStarted(result);
     };
 
-    var failures = [];
     this.specDone = function(result) {
       stateBuilder.specDone(result);
 
       if (noExpectations(result)) {
-        var noSpecMsg = "Spec '" + result.fullName + "' has no expectations.";
+        const noSpecMsg = "Spec '" + result.fullName + "' has no expectations.";
         if (result.status === 'failed') {
           console.error(noSpecMsg);
         } else {
@@ -194,10 +196,10 @@ jasmineRequire.HtmlReporter = function(j$) {
 
     this.jasmineDone = function(doneResult) {
       stateBuilder.jasmineDone(doneResult);
-      var banner = find('.jasmine-banner');
-      var alert = find('.jasmine-alert');
-      var order = doneResult && doneResult.order;
-      var i;
+      const banner = find('.jasmine-banner');
+      const alert = find('.jasmine-alert');
+      const order = doneResult && doneResult.order;
+
       alert.appendChild(
         createDom(
           'span',
@@ -209,14 +211,14 @@ jasmineRequire.HtmlReporter = function(j$) {
       banner.appendChild(optionsMenu(config()));
 
       if (stateBuilder.specsExecuted < totalSpecsDefined) {
-        var skippedMessage =
+        const skippedMessage =
           'Ran ' +
           stateBuilder.specsExecuted +
           ' of ' +
           totalSpecsDefined +
           ' specs - run all';
         // include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906
-        var skippedLink =
+        const skippedLink =
           (window.location.pathname || '') +
           addToExistingQueryString('spec', '');
         alert.appendChild(
@@ -231,10 +233,11 @@ jasmineRequire.HtmlReporter = function(j$) {
           )
         );
       }
-      var statusBarMessage = '';
-      var statusBarClassName = 'jasmine-overall-result jasmine-bar ';
-      var globalFailures = (doneResult && doneResult.failedExpectations) || [];
-      var failed = stateBuilder.failureCount + globalFailures.length > 0;
+      let statusBarMessage = '';
+      let statusBarClassName = 'jasmine-overall-result jasmine-bar ';
+      const globalFailures =
+        (doneResult && doneResult.failedExpectations) || [];
+      const failed = stateBuilder.failureCount + globalFailures.length > 0;
 
       if (totalSpecsDefined > 0 || failed) {
         statusBarMessage +=
@@ -260,7 +263,7 @@ jasmineRequire.HtmlReporter = function(j$) {
         statusBarClassName += ' jasmine-failed ';
       }
 
-      var seedBar;
+      let seedBar;
       if (order && order.random) {
         seedBar = createDom(
           'span',
@@ -286,10 +289,10 @@ jasmineRequire.HtmlReporter = function(j$) {
         )
       );
 
-      var errorBarClassName = 'jasmine-bar jasmine-errored';
-      var afterAllMessagePrefix = 'AfterAll ';
+      const errorBarClassName = 'jasmine-bar jasmine-errored';
+      const afterAllMessagePrefix = 'AfterAll ';
 
-      for (i = 0; i < globalFailures.length; i++) {
+      for (let i = 0; i < globalFailures.length; i++) {
         alert.appendChild(
           createDom(
             'span',
@@ -301,7 +304,7 @@ jasmineRequire.HtmlReporter = function(j$) {
 
       function globalFailureMessage(failure) {
         if (failure.globalErrorType === 'load') {
-          var prefix = 'Error during loading: ' + failure.message;
+          const prefix = 'Error during loading: ' + failure.message;
 
           if (failure.filename) {
             return (
@@ -319,9 +322,9 @@ jasmineRequire.HtmlReporter = function(j$) {
 
       addDeprecationWarnings(doneResult);
 
-      for (i = 0; i < deprecationWarnings.length; i++) {
-        var children = [],
-          context;
+      for (let i = 0; i < deprecationWarnings.length; i++) {
+        const children = [];
+        let context;
 
         switch (deprecationWarnings[i].runnableType) {
           case 'spec':
@@ -355,7 +358,7 @@ jasmineRequire.HtmlReporter = function(j$) {
         );
       }
 
-      var results = find('.jasmine-results');
+      const results = find('.jasmine-results');
       results.appendChild(summary);
 
       summaryList(stateBuilder.topResults, summary);
@@ -397,8 +400,8 @@ jasmineRequire.HtmlReporter = function(j$) {
 
         setMenuModeTo('jasmine-failure-list');
 
-        var failureNode = find('.jasmine-failures');
-        for (i = 0; i < failures.length; i++) {
+        const failureNode = find('.jasmine-failures');
+        for (let i = 0; i < failures.length; i++) {
           failureNode.appendChild(failures[i]);
         }
       }
@@ -407,16 +410,16 @@ jasmineRequire.HtmlReporter = function(j$) {
     return this;
 
     function failureDom(result) {
-      var failure = createDom(
+      const failure = createDom(
         'div',
         { className: 'jasmine-spec-detail jasmine-failed' },
         failureDescription(result, stateBuilder.currentParent),
         createDom('div', { className: 'jasmine-messages' })
       );
-      var messages = failure.childNodes[1];
+      const messages = failure.childNodes[1];
 
-      for (var i = 0; i < result.failedExpectations.length; i++) {
-        var expectation = result.failedExpectations[i];
+      for (let i = 0; i < result.failedExpectations.length; i++) {
+        const expectation = result.failedExpectations[i];
         messages.appendChild(
           createDom(
             'div',
@@ -451,7 +454,7 @@ jasmineRequire.HtmlReporter = function(j$) {
     }
 
     function debugLogTable(debugLogs) {
-      var tbody = createDom('tbody');
+      const tbody = createDom('tbody');
 
       debugLogs.forEach(function(entry) {
         tbody.appendChild(
@@ -491,14 +494,14 @@ jasmineRequire.HtmlReporter = function(j$) {
     }
 
     function summaryList(resultsTree, domParent) {
-      var specListNode;
-      for (var i = 0; i < resultsTree.children.length; i++) {
-        var resultNode = resultsTree.children[i];
+      let specListNode;
+      for (let i = 0; i < resultsTree.children.length; i++) {
+        const resultNode = resultsTree.children[i];
         if (filterSpecs && !hasActiveSpec(resultNode)) {
           continue;
         }
         if (resultNode.type === 'suite') {
-          var suiteListNode = createDom(
+          const suiteListNode = createDom(
             'ul',
             { className: 'jasmine-suite', id: 'suite-' + resultNode.result.id },
             createDom(
@@ -523,7 +526,7 @@ jasmineRequire.HtmlReporter = function(j$) {
             specListNode = createDom('ul', { className: 'jasmine-specs' });
             domParent.appendChild(specListNode);
           }
-          var specDescription = resultNode.result.description;
+          let specDescription = resultNode.result.description;
           if (noExpectations(resultNode.result)) {
             specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
           }
@@ -555,7 +558,7 @@ jasmineRequire.HtmlReporter = function(j$) {
     }
 
     function optionsMenu(config) {
-      var optionsMenuDom = createDom(
+      const optionsMenuDom = createDom(
         'div',
         { className: 'jasmine-run-options' },
         createDom('span', { className: 'jasmine-trigger' }, 'Options'),
@@ -621,13 +624,15 @@ jasmineRequire.HtmlReporter = function(j$) {
         )
       );
 
-      var failFastCheckbox = optionsMenuDom.querySelector('#jasmine-fail-fast');
+      const failFastCheckbox = optionsMenuDom.querySelector(
+        '#jasmine-fail-fast'
+      );
       failFastCheckbox.checked = config.stopOnSpecFailure;
       failFastCheckbox.onclick = function() {
         navigateWithNewParam('stopOnSpecFailure', !config.stopOnSpecFailure);
       };
 
-      var throwCheckbox = optionsMenuDom.querySelector(
+      const throwCheckbox = optionsMenuDom.querySelector(
         '#jasmine-throw-failures'
       );
       throwCheckbox.checked = config.stopSpecOnExpectationFailure;
@@ -638,7 +643,7 @@ jasmineRequire.HtmlReporter = function(j$) {
         );
       };
 
-      var randomCheckbox = optionsMenuDom.querySelector(
+      const randomCheckbox = optionsMenuDom.querySelector(
         '#jasmine-random-order'
       );
       randomCheckbox.checked = config.random;
@@ -646,13 +651,15 @@ jasmineRequire.HtmlReporter = function(j$) {
         navigateWithNewParam('random', !config.random);
       };
 
-      var hideDisabled = optionsMenuDom.querySelector('#jasmine-hide-disabled');
+      const hideDisabled = optionsMenuDom.querySelector(
+        '#jasmine-hide-disabled'
+      );
       hideDisabled.checked = config.hideDisabled;
       hideDisabled.onclick = function() {
         navigateWithNewParam('hideDisabled', !config.hideDisabled);
       };
 
-      var optionsTrigger = optionsMenuDom.querySelector('.jasmine-trigger'),
+      const optionsTrigger = optionsMenuDom.querySelector('.jasmine-trigger'),
         optionsPayload = optionsMenuDom.querySelector('.jasmine-payload'),
         isOpen = /\bjasmine-open\b/;
 
@@ -671,7 +678,7 @@ jasmineRequire.HtmlReporter = function(j$) {
     }
 
     function failureDescription(result, suite) {
-      var wrapper = createDom(
+      const wrapper = createDom(
         'div',
         { className: 'jasmine-description' },
         createDom(
@@ -680,7 +687,7 @@ jasmineRequire.HtmlReporter = function(j$) {
           result.description
         )
       );
-      var suiteLink;
+      let suiteLink;
 
       while (suite && suite.parent) {
         wrapper.insertBefore(createTextNode(' > '), wrapper.firstChild);
@@ -698,7 +705,7 @@ jasmineRequire.HtmlReporter = function(j$) {
     }
 
     function suiteHref(suite) {
-      var els = [];
+      const els = [];
 
       while (suite && suite.parent) {
         els.unshift(suite.result.description);
@@ -714,8 +721,8 @@ jasmineRequire.HtmlReporter = function(j$) {
 
     function addDeprecationWarnings(result, runnableType) {
       if (result && result.deprecationWarnings) {
-        for (var i = 0; i < result.deprecationWarnings.length; i++) {
-          var warning = result.deprecationWarnings[i].message;
+        for (let i = 0; i < result.deprecationWarnings.length; i++) {
+          const warning = result.deprecationWarnings[i].message;
           deprecationWarnings.push({
             message: warning,
             stack: result.deprecationWarnings[i].stack,
@@ -727,8 +734,8 @@ jasmineRequire.HtmlReporter = function(j$) {
     }
 
     function createExpander(stackTrace) {
-      var expandLink = createDom('a', { href: '#' }, 'Show stack trace');
-      var root = createDom(
+      const expandLink = createDom('a', { href: '#' }, 'Show stack trace');
+      const root = createDom(
         'div',
         { className: 'jasmine-expander' },
         expandLink,
@@ -759,8 +766,7 @@ jasmineRequire.HtmlReporter = function(j$) {
     }
 
     function clearPrior() {
-      // return the reporter
-      var oldReporter = find('');
+      const oldReporter = find('');
 
       if (oldReporter) {
         getContainer().removeChild(oldReporter);
@@ -768,22 +774,21 @@ jasmineRequire.HtmlReporter = function(j$) {
     }
 
     function createDom(type, attrs, childrenArrayOrVarArgs) {
-      var el = createElement(type),
-        children,
-        i;
+      const el = createElement(type);
+      let children;
 
       if (j$.isArray_(childrenArrayOrVarArgs)) {
         children = childrenArrayOrVarArgs;
       } else {
         children = [];
 
-        for (i = 2; i < arguments.length; i++) {
+        for (let i = 2; i < arguments.length; i++) {
           children.push(arguments[i]);
         }
       }
 
-      for (i = 0; i < children.length; i++) {
-        var child = children[i];
+      for (let i = 0; i < children.length; i++) {
+        const child = children[i];
 
         if (typeof child === 'string') {
           el.appendChild(createTextNode(child));
@@ -794,7 +799,7 @@ jasmineRequire.HtmlReporter = function(j$) {
         }
       }
 
-      for (var attr in attrs) {
+      for (const attr in attrs) {
         if (attr == 'className') {
           el[attr] = attrs[attr];
         } else {
@@ -806,7 +811,7 @@ jasmineRequire.HtmlReporter = function(j$) {
     }
 
     function pluralize(singular, count) {
-      var word = count == 1 ? singular : singular + 's';
+      const word = count == 1 ? singular : singular + 's';
 
       return '' + count + ' ' + word;
     }
@@ -836,7 +841,7 @@ jasmineRequire.HtmlReporter = function(j$) {
     }
 
     function noExpectations(result) {
-      var allExpectations =
+      const allExpectations =
         result.failedExpectations.length + result.passedExpectations.length;
 
       return (
@@ -851,7 +856,7 @@ jasmineRequire.HtmlReporter = function(j$) {
       }
 
       if (resultNode.type == 'suite') {
-        for (var i = 0, j = resultNode.children.length; i < j; i++) {
+        for (let i = 0, j = resultNode.children.length; i < j; i++) {
           if (hasActiveSpec(resultNode.children[i])) {
             return true;
           }
@@ -865,11 +870,11 @@ jasmineRequire.HtmlReporter = function(j$) {
 
 jasmineRequire.HtmlSpecFilter = function() {
   function HtmlSpecFilter(options) {
-    var filterString =
+    const filterString =
       options &&
       options.filterString() &&
       options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
-    var filterPattern = new RegExp(filterString);
+    const filterPattern = new RegExp(filterString);
 
     this.matches = function(specName) {
       return filterPattern.test(specName);
@@ -913,7 +918,7 @@ jasmineRequire.QueryString = function() {
     };
 
     this.fullStringWithNewParam = function(key, value) {
-      var paramMap = queryStringToParamMap();
+      const paramMap = queryStringToParamMap();
       paramMap[key] = value;
       return toQueryString(paramMap);
     };
@@ -925,8 +930,8 @@ jasmineRequire.QueryString = function() {
     return this;
 
     function toQueryString(paramMap) {
-      var qStrPairs = [];
-      for (var prop in paramMap) {
+      const qStrPairs = [];
+      for (const prop in paramMap) {
         qStrPairs.push(
           encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop])
         );
@@ -935,15 +940,15 @@ jasmineRequire.QueryString = function() {
     }
 
     function queryStringToParamMap() {
-      var paramStr = options.getWindowLocation().search.substring(1),
-        params = [],
-        paramMap = {};
+      const paramStr = options.getWindowLocation().search.substring(1);
+      let params = [];
+      const paramMap = {};
 
       if (paramStr.length > 0) {
         params = paramStr.split('&');
-        for (var i = 0; i < params.length; i++) {
-          var p = params[i].split('=');
-          var value = decodeURIComponent(p[1]);
+        for (let i = 0; i < params.length; i++) {
+          const p = params[i].split('=');
+          let value = decodeURIComponent(p[1]);
           if (value === 'true' || value === 'false') {
             value = JSON.parse(value);
           }
diff --git a/tobago-example/tobago-example-demo/src/main/webapp/js/jasmine.js b/tobago-example/tobago-example-demo/src/main/webapp/js/jasmine.js
index e65e0e0dbe..6a429e53c3 100644
--- a/tobago-example/tobago-example-demo/src/main/webapp/js/jasmine.js
+++ b/tobago-example/tobago-example-demo/src/main/webapp/js/jasmine.js
@@ -20,9 +20,9 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
-// eslint-disable-next-line no-unused-vars
+// eslint-disable-next-line no-unused-vars,no-var
 var getJasmineRequireObj = (function(jasmineGlobal) {
-  var jasmineRequire;
+  let jasmineRequire;
 
   if (
     typeof module !== 'undefined' &&
@@ -51,7 +51,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
   }
 
   getJasmineRequire().core = function(jRequire) {
-    var j$ = {};
+    const j$ = {};
 
     jRequire.base(j$, jasmineGlobal);
     j$.util = jRequire.util(j$);
@@ -90,6 +90,8 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
       j$
     );
     j$.ReportDispatcher = jRequire.ReportDispatcher(j$);
+    j$.RunableResources = jRequire.RunableResources(j$);
+    j$.Runner = jRequire.Runner(j$);
     j$.Spec = jRequire.Spec(j$);
     j$.Spy = jRequire.Spy(j$);
     j$.SpyFactory = jRequire.SpyFactory(j$);
@@ -99,6 +101,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
     j$.StringContaining = jRequire.StringContaining(j$);
     j$.UserContext = jRequire.UserContext(j$);
     j$.Suite = jRequire.Suite(j$);
+    j$.SuiteBuilder = jRequire.SuiteBuilder(j$);
     j$.Timer = jRequire.Timer();
     j$.TreeProcessor = jRequire.TreeProcessor();
     j$.version = jRequire.version();
@@ -125,7 +128,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
 })(this);
 
 getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
-  var availableMatchers = [
+  const availableMatchers = [
       'nothing',
       'toBe',
       'toBeCloseTo',
@@ -161,8 +164,7 @@ getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
     ],
     matchers = {};
 
-  for (var i = 0; i < availableMatchers.length; i++) {
-    var name = availableMatchers[i];
+  for (const name of availableMatchers) {
     matchers[name] = jRequire[name](j$);
   }
 
@@ -170,10 +172,6 @@ getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
 };
 
 getJasmineRequireObj().base = function(j$, jasmineGlobal) {
-  j$.unimplementedMethod_ = function() {
-    throw new Error('unimplemented method');
-  };
-
   /**
    * Maximum object depth the pretty printer will print to.
    * Set this to a lower value to speed up pretty printing if you have large objects.
@@ -214,7 +212,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
    * @default 5000
    * @since 1.3.0
    */
-  var DEFAULT_TIMEOUT_INTERVAL = 5000;
+  let DEFAULT_TIMEOUT_INTERVAL = 5000;
   Object.defineProperty(j$, 'DEFAULT_TIMEOUT_INTERVAL', {
     get: function() {
       return DEFAULT_TIMEOUT_INTERVAL;
@@ -238,7 +236,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
    * @return {Env}
    */
   j$.getEnv = function(options) {
-    var env = (j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options));
+    const env = (j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options));
     //jasmine. singletons in here (setTimeout blah blah).
     return env;
   };
@@ -379,7 +377,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
       return func.name;
     }
 
-    var matches =
+    const matches =
       func.toString().match(/^\s*function\s*(\w+)\s*\(/) ||
       func.toString().match(/^\s*\[object\s*(\w+)Constructor\]/);
 
@@ -387,7 +385,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
   };
 
   j$.isPending_ = function(promise) {
-    var sentinel = {};
+    const sentinel = {};
     return Promise.race([promise, Promise.resolve(sentinel)]).then(
       function(result) {
         return result === sentinel;
@@ -596,46 +594,65 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
   j$.debugLog = function(msg) {
     j$.getEnv().debugLog(msg);
   };
-};
-
-getJasmineRequireObj().util = function(j$) {
-  var util = {};
 
-  util.inherit = function(childClass, parentClass) {
-    var Subclass = function() {};
-    Subclass.prototype = parentClass.prototype;
-    childClass.prototype = new Subclass();
+  /**
+   * Replaces Jasmine's global error handling with a spy. This prevents Jasmine
+   * from treating uncaught exceptions and unhandled promise rejections
+   * as spec failures and allows them to be inspected using the spy's
+   * {@link Spy#calls|calls property} and related matchers such as
+   * {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}.
+   *
+   * After installing the spy, spyOnGlobalErrorsAsync immediately calls its
+   * argument, which must be an async or promise-returning function. The spy
+   * will be passed as the first argument to that callback. Normal error
+   * handling will be restored when the promise returned from the callback is
+   * settled.
+   *
+   * Note: The JavaScript runtime may deliver uncaught error events and unhandled
+   * rejection events asynchronously, especially in browsers. If the event
+   * occurs after the promise returned from the callback is settled, it won't
+   * be routed to the spy even if the underlying error occurred previously.
+   * It's up to you to ensure that the returned promise isn't resolved until
+   * all of the error/rejection events that you want to handle have occurred.
+   *
+   * You must await the return value of spyOnGlobalErrorsAsync.
+   * @name jasmine.spyOnGlobalErrorsAsync
+   * @function
+   * @async
+   * @param {AsyncFunction} fn - A function to run, during which the global error spy will be effective
+   * @example
+   * it('demonstrates global error spies', async function() {
+   *   await jasmine.spyOnGlobalErrorsAsync(async function(globalErrorSpy) {
+   *     setTimeout(function() {
+   *       throw new Error('the expected error');
+   *     });
+   *     await new Promise(function(resolve) {
+   *       setTimeout(resolve);
+   *     });
+   *     const expected = new Error('the expected error');
+   *     expect(globalErrorSpy).toHaveBeenCalledWith(expected);
+   *   });
+   * });
+   */
+  j$.spyOnGlobalErrorsAsync = async function(fn) {
+    await jasmine.getEnv().spyOnGlobalErrorsAsync(fn);
   };
+};
 
-  util.argsToArray = function(args) {
-    var arrayOfArgs = [];
-    for (var i = 0; i < args.length; i++) {
-      arrayOfArgs.push(args[i]);
-    }
-    return arrayOfArgs;
-  };
+getJasmineRequireObj().util = function(j$) {
+  const util = {};
 
   util.isUndefined = function(obj) {
     return obj === void 0;
   };
 
-  util.arrayContains = function(array, search) {
-    var i = array.length;
-    while (i--) {
-      if (array[i] === search) {
-        return true;
-      }
-    }
-    return false;
-  };
-
   util.clone = function(obj) {
     if (Object.prototype.toString.apply(obj) === '[object Array]') {
       return obj.slice();
     }
 
-    var cloned = {};
-    for (var prop in obj) {
+    const cloned = {};
+    for (const prop in obj) {
       if (obj.hasOwnProperty(prop)) {
         cloned[prop] = obj[prop];
       }
@@ -645,26 +662,23 @@ getJasmineRequireObj().util = function(j$) {
   };
 
   util.cloneArgs = function(args) {
-    var clonedArgs = [];
-    var argsAsArray = j$.util.argsToArray(args);
-    for (var i = 0; i < argsAsArray.length; i++) {
-      var str = Object.prototype.toString.apply(argsAsArray[i]),
+    return Array.from(args).map(function(arg) {
+      const str = Object.prototype.toString.apply(arg),
         primitives = /^\[object (Boolean|String|RegExp|Number)/;
 
       // All falsey values are either primitives, `null`, or `undefined.
-      if (!argsAsArray[i] || str.match(primitives)) {
-        clonedArgs.push(argsAsArray[i]);
+      if (!arg || str.match(primitives)) {
+        return arg;
       } else if (str === '[object Date]') {
-        clonedArgs.push(new Date(argsAsArray[i].valueOf()));
+        return new Date(arg.valueOf());
       } else {
-        clonedArgs.push(j$.util.clone(argsAsArray[i]));
+        return j$.util.clone(arg);
       }
-    }
-    return clonedArgs;
+    });
   };
 
   util.getPropertyDescriptor = function(obj, methodName) {
-    var descriptor,
+    let descriptor,
       proto = obj;
 
     do {
@@ -687,12 +701,12 @@ getJasmineRequireObj().util = function(j$) {
   };
 
   function callerFile() {
-    var trace = new j$.StackTrace(util.errorWithStack());
+    const trace = new j$.StackTrace(util.errorWithStack());
     return trace.frames[2].file;
   }
 
   util.jasmineFile = (function() {
-    var result;
+    let result;
 
     return function() {
       if (!result) {
@@ -703,17 +717,13 @@ getJasmineRequireObj().util = function(j$) {
     };
   })();
 
-  function StopIteration() {}
-  StopIteration.prototype = Object.create(Error.prototype);
-  StopIteration.prototype.constructor = StopIteration;
-
   util.validateTimeout = function(timeout, msgPrefix) {
     // Timeouts are implemented with setTimeout, which only supports a limited
     // range of values. The limit is unspecified, as is the behavior when it's
     // exceeded. But on all currently supported JS runtimes, setTimeout calls
     // the callback immediately when the timeout is greater than 2147483647
     // (the maximum value of a signed 32 bit integer).
-    var max = 2147483647;
+    const max = 2147483647;
 
     if (timeout > max) {
       throw new Error(
@@ -752,7 +762,6 @@ getJasmineRequireObj().Spec = function(j$) {
         return '';
       };
     this.onLateError = attrs.onLateError || function() {};
-    this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
     this.catchingExceptions =
       attrs.catchingExceptions ||
       function() {
@@ -798,6 +807,7 @@ getJasmineRequireObj().Spec = function(j$) {
 
   Spec.prototype.addExpectationResult = function(passed, data, isError) {
     const expectationResult = j$.buildExpectationResult(data);
+
     if (passed) {
       this.result.passedExpectations.push(expectationResult);
     } else {
@@ -805,6 +815,11 @@ getJasmineRequireObj().Spec = function(j$) {
         this.onLateError(expectationResult);
       } else {
         this.result.failedExpectations.push(expectationResult);
+
+        // TODO: refactor so that we don't need to override cached status
+        if (this.result.status) {
+          this.result.status = 'failed';
+        }
       }
 
       if (this.throwOnExpectationFailure && !isError) {
@@ -826,56 +841,57 @@ getJasmineRequireObj().Spec = function(j$) {
     return this.asyncExpectationFactory(actual, this);
   };
 
-  Spec.prototype.execute = function(onComplete, excluded, failSpecWithNoExp) {
-    var self = this;
-
-    var onStart = {
-      fn: function(done) {
-        self.timer.start();
-        self.onStart(self, done);
+  Spec.prototype.execute = function(
+    queueRunnerFactory,
+    onComplete,
+    excluded,
+    failSpecWithNoExp
+  ) {
+    const onStart = {
+      fn: done => {
+        this.timer.start();
+        this.onStart(this, done);
       }
     };
 
-    var complete = {
-      fn: function(done) {
-        if (self.autoCleanClosures) {
-          self.queueableFn.fn = null;
+    const complete = {
+      fn: done => {
+        if (this.autoCleanClosures) {
+          this.queueableFn.fn = null;
         }
-        self.result.status = self.status(excluded, failSpecWithNoExp);
-        self.result.duration = self.timer.elapsed();
+        this.result.status = this.status(excluded, failSpecWithNoExp);
+        this.result.duration = this.timer.elapsed();
 
-        if (self.result.status !== 'failed') {
-          self.result.debugLogs = null;
+        if (this.result.status !== 'failed') {
+          this.result.debugLogs = null;
         }
 
-        self.resultCallback(self.result, done);
+        this.resultCallback(this.result, done);
       },
       type: 'specCleanup'
     };
 
-    var fns = this.beforeAndAfterFns();
+    const fns = this.beforeAndAfterFns();
 
-    var runnerConfig = {
+    const runnerConfig = {
       isLeaf: true,
       queueableFns: [...fns.befores, this.queueableFn, ...fns.afters],
-      onException: function() {
-        self.handleException.apply(self, arguments);
-      },
-      onMultipleDone: function() {
+      onException: e => this.handleException(e),
+      onMultipleDone: () => {
         // Issue a deprecation. Include the context ourselves and pass
         // ignoreRunnable: true, since getting here always means that we've already
         // moved on and the current runnable isn't the one that caused the problem.
-        self.onLateError(
+        this.onLateError(
           new Error(
             'An asynchronous spec, beforeEach, or afterEach function called its ' +
               "'done' callback more than once.\n(in spec: " +
-              self.getFullName() +
+              this.getFullName() +
               ')'
           )
         );
       },
-      onComplete: function() {
-        if (self.result.status === 'failed') {
+      onComplete: () => {
+        if (this.result.status === 'failed') {
           onComplete(new j$.StopExecutionError('spec failed'));
         } else {
           onComplete();
@@ -892,7 +908,7 @@ getJasmineRequireObj().Spec = function(j$) {
     runnerConfig.queueableFns.unshift(onStart);
     runnerConfig.queueableFns.push(complete);
 
-    this.queueRunnerFactory(runnerConfig);
+    queueRunnerFactory(runnerConfig);
   };
 
   Spec.prototype.reset = function() {
@@ -1016,8 +1032,8 @@ getJasmineRequireObj().Spec = function(j$) {
     });
   };
 
-  var extractCustomPendingMessage = function(e) {
-    var fullMessage = e.toString(),
+  const extractCustomPendingMessage = function(e) {
+    const fullMessage = e.toString(),
       boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage),
       boilerplateEnd =
         boilerplateStart + Spec.pendingSpecExceptionMessage.length;
@@ -1083,7 +1099,7 @@ getJasmineRequireObj().Spec = function(j$) {
 getJasmineRequireObj().Order = function() {
   function Order(options) {
     this.random = 'random' in options ? options.random : true;
-    var seed = (this.seed = options.seed || generateSeed());
+    const seed = (this.seed = options.seed || generateSeed());
     this.sort = this.random ? randomOrder : naturalOrder;
 
     function naturalOrder(items) {
@@ -1091,7 +1107,7 @@ getJasmineRequireObj().Order = function() {
     }
 
     function randomOrder(items) {
-      var copy = items.slice();
+      const copy = items.slice();
       copy.sort(function(a, b) {
         return jenkinsHash(seed + a.id) - jenkinsHash(seed + b.id);
       });
@@ -1108,7 +1124,7 @@ getJasmineRequireObj().Order = function() {
     // used in conjunction with a seed
 
     function jenkinsHash(key) {
-      var hash, i;
+      let hash, i;
       for (hash = i = 0; i < key.length; ++i) {
         hash += key.charCodeAt(i);
         hash += hash << 10;
@@ -1136,14 +1152,12 @@ getJasmineRequireObj().Env = function(j$) {
   function Env(options) {
     options = options || {};
 
-    var self = this;
-    var global = options.global || j$.getGlobal();
-
-    var totalSpecsDefined = 0;
+    const self = this;
+    const global = options.global || j$.getGlobal();
 
-    var realSetTimeout = global.setTimeout;
-    var realClearTimeout = global.clearTimeout;
-    var clearStack = j$.getClearStack(global);
+    const realSetTimeout = global.setTimeout;
+    const realClearTimeout = global.clearTimeout;
+    const clearStack = j$.getClearStack(global);
     this.clock = new j$.Clock(
       global,
       function() {
@@ -1152,12 +1166,28 @@ getJasmineRequireObj().Env = function(j$) {
       new j$.MockDate(global)
     );
 
-    var runnableResources = {};
+    const globalErrors = new j$.GlobalErrors();
+    const installGlobalErrors = (function() {
+      let installed = false;
+      return function() {
+        if (!installed) {
+          globalErrors.install();
+          installed = true;
+        }
+      };
+    })();
+
+    const runableResources = new j$.RunableResources({
+      getCurrentRunableId: function() {
+        const r = runner.currentRunable();
+        return r ? r.id : null;
+      },
+      globalErrors
+    });
 
-    var currentSpec = null;
-    var currentlyExecutingSuites = [];
-    var currentDeclarationSuite = null;
-    var hasFailures = false;
+    let reporter;
+    let topSuite;
+    let runner;
 
     /**
      * This represents the available options to configure Jasmine.
@@ -1166,7 +1196,7 @@ getJasmineRequireObj().Env = function(j$) {
      * @interface Configuration
      * @since 3.3.0
      */
-    var config = {
+    const config = {
       /**
        * Whether to randomize spec execution order
        * @name Configuration#random
@@ -1259,28 +1289,9 @@ getJasmineRequireObj().Env = function(j$) {
       verboseDeprecations: false
     };
 
-    var currentSuite = function() {
-      return currentlyExecutingSuites[currentlyExecutingSuites.length - 1];
-    };
-
-    var currentRunnable = function() {
-      return currentSpec || currentSuite();
-    };
-
-    var globalErrors = null;
-
-    var installGlobalErrors = function() {
-      if (globalErrors) {
-        return;
-      }
-
-      globalErrors = new j$.GlobalErrors();
-      globalErrors.install();
-    };
-
     if (!options.suppressLoadErrors) {
       installGlobalErrors();
-      globalErrors.pushListener(function(
+      globalErrors.pushListener(function loadtimeErrorHandler(
         message,
         filename,
         lineno,
@@ -1306,7 +1317,7 @@ getJasmineRequireObj().Env = function(j$) {
      * @function
      */
     this.configure = function(configuration) {
-      var booleanProps = [
+      const booleanProps = [
         'random',
         'failSpecWithNoExpectations',
         'hideDisabled',
@@ -1343,122 +1354,44 @@ getJasmineRequireObj().Env = function(j$) {
      * @returns {Configuration}
      */
     this.configuration = function() {
-      var result = {};
-      for (var property in config) {
+      const result = {};
+      for (const property in config) {
         result[property] = config[property];
       }
       return result;
     };
 
     this.setDefaultSpyStrategy = function(defaultStrategyFn) {
-      if (!currentRunnable()) {
-        throw new Error(
-          'Default spy strategy must be set in a before function or a spec'
-        );
-      }
-      runnableResources[
-        currentRunnable().id
-      ].defaultStrategyFn = defaultStrategyFn;
+      runableResources.setDefaultSpyStrategy(defaultStrategyFn);
     };
 
     this.addSpyStrategy = function(name, fn) {
-      if (!currentRunnable()) {
-        throw new Error(
-          'Custom spy strategies must be added in a before function or a spec'
-        );
-      }
-      runnableResources[currentRunnable().id].customSpyStrategies[name] = fn;
+      runableResources.customSpyStrategies()[name] = fn;
     };
 
     this.addCustomEqualityTester = function(tester) {
-      if (!currentRunnable()) {
-        throw new Error(
-          'Custom Equalities must be added in a before function or a spec'
-        );
-      }
-      runnableResources[currentRunnable().id].customEqualityTesters.push(
-        tester
-      );
+      runableResources.customEqualityTesters().push(tester);
     };
 
     this.addMatchers = function(matchersToAdd) {
-      if (!currentRunnable()) {
-        throw new Error(
-          'Matchers must be added in a before function or a spec'
-        );
-      }
-      var customMatchers =
-        runnableResources[currentRunnable().id].customMatchers;
-
-      for (var matcherName in matchersToAdd) {
-        customMatchers[matcherName] = matchersToAdd[matcherName];
-      }
+      runableResources.addCustomMatchers(matchersToAdd);
     };
 
     this.addAsyncMatchers = function(matchersToAdd) {
-      if (!currentRunnable()) {
-        throw new Error(
-          'Async Matchers must be added in a before function or a spec'
-        );
-      }
-      var customAsyncMatchers =
-        runnableResources[currentRunnable().id].customAsyncMatchers;
-
-      for (var matcherName in matchersToAdd) {
-        customAsyncMatchers[matcherName] = matchersToAdd[matcherName];
-      }
+      runableResources.addCustomAsyncMatchers(matchersToAdd);
     };
 
     this.addCustomObjectFormatter = function(formatter) {
-      if (!currentRunnable()) {
-        throw new Error(
-          'Custom object formatters must be added in a before function or a spec'
-        );
-      }
-
-      runnableResources[currentRunnable().id].customObjectFormatters.push(
-        formatter
-      );
+      runableResources.customObjectFormatters().push(formatter);
     };
 
     j$.Expectation.addCoreMatchers(j$.matchers);
     j$.Expectation.addAsyncCoreMatchers(j$.asyncMatchers);
 
-    var nextSpecId = 0;
-    var getNextSpecId = function() {
-      return 'spec' + nextSpecId++;
-    };
-
-    var nextSuiteId = 0;
-    var getNextSuiteId = function() {
-      return 'suite' + nextSuiteId++;
-    };
-
-    var makePrettyPrinter = function() {
-      var customObjectFormatters =
-        runnableResources[currentRunnable().id].customObjectFormatters;
-      return j$.makePrettyPrinter(customObjectFormatters);
-    };
-
-    var makeMatchersUtil = function() {
-      const cr = currentRunnable();
-
-      if (cr) {
-        const customEqualityTesters =
-          runnableResources[cr.id].customEqualityTesters;
-        return new j$.MatchersUtil({
-          customTesters: customEqualityTesters,
-          pp: makePrettyPrinter()
-        });
-      } else {
-        return new j$.MatchersUtil({ pp: j$.basicPrettyPrinter_ });
-      }
-    };
-
     const expectationFactory = function(actual, spec) {
       return j$.Expectation.factory({
-        matchersUtil: makeMatchersUtil(),
-        customMatchers: runnableResources[spec.id].customMatchers,
+        matchersUtil: runableResources.makeMatchersUtil(),
+        customMatchers: runableResources.customMatchers(),
         actual: actual,
         addExpectationResult: addExpectationResult
       });
@@ -1486,7 +1419,7 @@ getJasmineRequireObj().Env = function(j$) {
     }
 
     function recordLateExpectation(runable, runableType, result) {
-      var delayedExpectationResult = {};
+      const delayedExpectationResult = {};
       Object.keys(result).forEach(function(k) {
         delayedExpectationResult[k] = result[k];
       });
@@ -1516,7 +1449,7 @@ getJasmineRequireObj().Env = function(j$) {
     function routeLateFailure(expectationResult) {
       // Report the result on the nearest ancestor suite that hasn't already
       // been reported done.
-      for (let r = currentRunnable(); r; r = r.parentSuite) {
+      for (let r = runner.currentRunable(); r; r = r.parentSuite) {
         if (!r.reportedDone) {
           if (r === topSuite) {
             expectationResult.globalErrorType = 'lateError';
@@ -1535,95 +1468,19 @@ getJasmineRequireObj().Env = function(j$) {
 
     const asyncExpectationFactory = function(actual, spec, runableType) {
       return j$.Expectation.asyncFactory({
-        matchersUtil: makeMatchersUtil(),
-        customAsyncMatchers: runnableResources[spec.id].customAsyncMatchers,
+        matchersUtil: runableResources.makeMatchersUtil(),
+        customAsyncMatchers: runableResources.customAsyncMatchers(),
         actual: actual,
         addExpectationResult: addExpectationResult
       });
 
       function addExpectationResult(passed, result) {
-        if (currentRunnable() !== spec) {
+        if (runner.currentRunable() !== spec) {
           recordLateExpectation(spec, runableType, result);
         }
         return spec.addExpectationResult(passed, result);
       }
     };
-    const suiteAsyncExpectationFactory = function(actual, suite) {
-      return asyncExpectationFactory(actual, suite, 'Suite');
-    };
-
-    const specAsyncExpectationFactory = function(actual, suite) {
-      return asyncExpectationFactory(actual, suite, 'Spec');
-    };
-
-    var defaultResourcesForRunnable = function(id, parentRunnableId) {
-      var resources = {
-        spies: [],
-        customEqualityTesters: [],
-        customMatchers: {},
-        customAsyncMatchers: {},
-        customSpyStrategies: {},
-        defaultStrategyFn: undefined,
-        customObjectFormatters: []
-      };
-
-      if (runnableResources[parentRunnableId]) {
-        resources.customEqualityTesters = j$.util.clone(
-          runnableResources[parentRunnableId].customEqualityTesters
-        );
-        resources.customMatchers = j$.util.clone(
-          runnableResources[parentRunnableId].customMatchers
-        );
-        resources.customAsyncMatchers = j$.util.clone(
-          runnableResources[parentRunnableId].customAsyncMatchers
-        );
-        resources.customObjectFormatters = j$.util.clone(
-          runnableResources[parentRunnableId].customObjectFormatters
-        );
-        resources.customSpyStrategies = j$.util.clone(
-          runnableResources[parentRunnableId].customSpyStrategies
-        );
-        resources.defaultStrategyFn =
-          runnableResources[parentRunnableId].defaultStrategyFn;
-      }
-
-      runnableResources[id] = resources;
-    };
-
-    var clearResourcesForRunnable = function(id) {
-      spyRegistry.clearSpies();
-      delete runnableResources[id];
-    };
-
-    var beforeAndAfterFns = function(targetSuite) {
-      return function() {
-        var befores = [],
-          afters = [],
-          suite = targetSuite;
-
-        while (suite) {
-          befores = befores.concat(suite.beforeFns);
-          afters = afters.concat(suite.afterFns);
-
-          suite = suite.parentSuite;
-        }
-
-        return {
-          befores: befores.reverse(),
-          afters: afters
-        };
-      };
-    };
-
-    var getSpecName = function(spec, suite) {
-      var fullName = [spec.description],
-        suiteFullName = suite.getFullName();
-
-      if (suiteFullName !== '') {
-        fullName.unshift(suiteFullName);
-      }
-      return fullName.join(' ');
-    };
 
     /**
      * Causes a deprecation warning to be logged to the console and reported to
@@ -1648,26 +1505,11 @@ getJasmineRequireObj().Env = function(j$) {
      * @param {Object} [options] Optional extra options, as described above
      */
     this.deprecated = function(deprecation, options) {
-      var runnable = currentRunnable() || topSuite;
-      deprecator.addDeprecationWarning(runnable, deprecation, options);
+      const runable = runner.currentRunable() || topSuite;
+      deprecator.addDeprecationWarning(runable, deprecation, options);
     };
 
-    var queueRunnerFactory = function(options, args) {
-      if (options.isLeaf) {
-        // A spec
-        options.SkipPolicy = j$.CompleteOnFirstErrorSkipPolicy;
-      } else if (options.isReporter) {
-        // A reporter queue
-        options.SkipPolicy = j$.NeverSkipPolicy;
-      } else {
-        // A suite
-        if (config.stopOnSpecFailure) {
-          options.SkipPolicy = j$.CompleteOnFirstErrorSkipPolicy;
-        } else {
-          options.SkipPolicy = j$.SkipAfterBeforeAllErrorPolicy;
-        }
-      }
-
+    function queueRunnerFactory(options) {
       options.clearStack = options.clearStack || clearStack;
       options.timeout = {
         setTimeout: realSetTimeout,
@@ -1678,23 +1520,24 @@ getJasmineRequireObj().Env = function(j$) {
       options.onException =
         options.onException ||
         function(e) {
-          (currentRunnable() || topSuite).handleException(e);
+          (runner.currentRunable() || topSuite).handleException(e);
         };
       options.deprecated = self.deprecated;
 
-      new j$.QueueRunner(options).execute(args);
-    };
+      new j$.QueueRunner(options).execute();
+    }
 
-    var topSuite = new j$.Suite({
-      id: getNextSuiteId(),
-      description: 'Jasmine__TopLevel__Suite',
-      expectationFactory: expectationFactory,
-      asyncExpectationFactory: suiteAsyncExpectationFactory,
-      autoCleanClosures: config.autoCleanClosures,
-      onLateError: recordLateError
+    const suiteBuilder = new j$.SuiteBuilder({
+      env: this,
+      expectationFactory,
+      asyncExpectationFactory,
+      onLateError: recordLateError,
+      specResultCallback,
+      specStarted,
+      queueRunnerFactory
     });
-    var deprecator = new j$.Deprecator(topSuite);
-    currentDeclarationSuite = topSuite;
+    topSuite = suiteBuilder.topSuite;
+    const deprecator = new j$.Deprecator(topSuite);
 
     /**
      * Provides the root suite, through which all suites and specs can be
@@ -1713,7 +1556,7 @@ getJasmineRequireObj().Env = function(j$) {
      * @interface Reporter
      * @see custom_reporter
      */
-    var reporter = new j$.ReportDispatcher(
+    reporter = new j$.ReportDispatcher(
       [
         /**
          * `jasmineStarted` is called after all of the specs have been loaded, but just before execution starts.
@@ -1780,10 +1623,24 @@ getJasmineRequireObj().Env = function(j$) {
          */
         'specDone'
       ],
-      queueRunnerFactory,
+      function(options) {
+        options.SkipPolicy = j$.NeverSkipPolicy;
+        return queueRunnerFactory(options);
+      },
       recordLateError
     );
 
+    runner = new j$.Runner({
+      topSuite,
+      totalSpecsDefined: () => suiteBuilder.totalSpecsDefined,
+      focusedRunables: () => suiteBuilder.focusedRunables,
+      runableResources,
+      reporter,
+      queueRunnerFactory,
+      getConfig: () => config,
+      reportSpecDone
+    });
+
     /**
      * Executes the specs.
      *
@@ -1811,200 +1668,20 @@ getJasmineRequireObj().Env = function(j$) {
      * @name Env#execute
      * @since 2.0.0
      * @function
-     * @param {(string[])=} runnablesToRun IDs of suites and/or specs to run
+     * @param {(string[])=} runablesToRun IDs of suites and/or specs to run
      * @param {Function=} onComplete Function that will be called after all specs have run
      * @return {Promise<JasmineDoneInfo>}
      */
-    this.execute = function(runnablesToRun, onComplete) {
-      if (this._executedBefore) {
-        topSuite.reset();
-      }
-      this._executedBefore = true;
-      defaultResourcesForRunnable(topSuite.id);
+    this.execute = function(runablesToRun, onComplete) {
       installGlobalErrors();
 
-      if (!runnablesToRun) {
-        if (focusedRunnables.length) {
-          runnablesToRun = focusedRunnables;
-        } else {
-          runnablesToRun = [topSuite.id];
-        }
-      }
-
-      var order = new j$.Order({
-        random: config.random,
-        seed: config.seed
-      });
-
-      var processor = new j$.TreeProcessor({
-        tree: topSuite,
-        runnableIds: runnablesToRun,
-        queueRunnerFactory: queueRunnerFactory,
-        failSpecWithNoExpectations: config.failSpecWithNoExpectations,
-        nodeStart: function(suite, next) {
-          currentlyExecutingSuites.push(suite);
-          defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
-          reporter.suiteStarted(suite.result, next);
-          suite.startTimer();
-        },
-        nodeComplete: function(suite, result, next) {
-          if (suite !== currentSuite()) {
-            throw new Error('Tried to complete the wrong suite');
-          }
-
-          clearResourcesForRunnable(suite.id);
-          currentlyExecutingSuites.pop();
-
-          if (result.status === 'failed') {
-            hasFailures = true;
-          }
-          suite.endTimer();
-
-          if (suite.hadBeforeAllFailure) {
-            reportChildrenOfBeforeAllFailure(suite).then(function() {
-              reportSuiteDone(suite, result, next);
-            });
-          } else {
-            reportSuiteDone(suite, result, next);
-          }
-        },
-        orderChildren: function(node) {
-          return order.sort(node.children);
-        },
-        excludeNode: function(spec) {
-          return !config.specFilter(spec);
+      return runner.execute(runablesToRun).then(function(jasmineDoneInfo) {
+        if (onComplete) {
+          onComplete();
         }
-      });
-
-      if (!processor.processTree().valid) {
-        throw new Error(
-          'Invalid order: would cause a beforeAll or afterAll to be run multiple times'
-        );
-      }
-
-      var jasmineTimer = new j$.Timer();
-      jasmineTimer.start();
-
-      return new Promise(function(resolve) {
-        runAll(function(jasmineDoneInfo) {
-          if (onComplete) {
-            onComplete();
-          }
 
-          resolve(jasmineDoneInfo);
-        });
+        return jasmineDoneInfo;
       });
-
-      function runAll(done) {
-        /**
-         * Information passed to the {@link Reporter#jasmineStarted} event.
-         * @typedef JasmineStartedInfo
-         * @property {Int} totalSpecsDefined - The total number of specs defined in this suite.
-         * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
-         * @since 2.0.0
-         */
-        reporter.jasmineStarted(
-          {
-            totalSpecsDefined: totalSpecsDefined,
-            order: order
-          },
-          function() {
-            currentlyExecutingSuites.push(topSuite);
-
-            processor.execute(function() {
-              (async function() {
-                if (topSuite.hadBeforeAllFailure) {
-                  await reportChildrenOfBeforeAllFailure(topSuite);
-                }
-
-                clearResourcesForRunnable(topSuite.id);
-                currentlyExecutingSuites.pop();
-                var overallStatus, incompleteReason;
-
-                if (
-                  hasFailures ||
-                  topSuite.result.failedExpectations.length > 0
-                ) {
-                  overallStatus = 'failed';
-                } else if (focusedRunnables.length > 0) {
-                  overallStatus = 'incomplete';
-                  incompleteReason = 'fit() or fdescribe() was found';
-                } else if (totalSpecsDefined === 0) {
-                  overallStatus = 'incomplete';
-                  incompleteReason = 'No specs found';
-                } else {
-                  overallStatus = 'passed';
-                }
-
-                /**
-                 * Information passed to the {@link Reporter#jasmineDone} event.
-                 * @typedef JasmineDoneInfo
-                 * @property {OverallStatus} overallStatus - The overall result of the suite: 'passed', 'failed', or 'incomplete'.
-                 * @property {Int} totalTime - The total time (in ms) that it took to execute the suite
-                 * @property {IncompleteReason} incompleteReason - Explanation of why the suite was incomplete.
-                 * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
-                 * @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level.
-                 * @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level.
-                 * @since 2.4.0
-                 */
-                const jasmineDoneInfo = {
-                  overallStatus: overallStatus,
-                  totalTime: jasmineTimer.elapsed(),
-                  incompleteReason: incompleteReason,
-                  order: order,
-                  failedExpectations: topSuite.result.failedExpectations,
-                  deprecationWarnings: topSuite.result.deprecationWarnings
-                };
-                topSuite.reportedDone = true;
-                reporter.jasmineDone(jasmineDoneInfo, function() {
-                  done(jasmineDoneInfo);
-                });
-              })();
-            });
-          }
-        );
-      }
-
-      async function reportChildrenOfBeforeAllFailure(suite) {
-        for (const child of suite.children) {
-          if (child instanceof j$.Suite) {
-            await new Promise(function(resolve) {
-              reporter.suiteStarted(child.result, resolve);
-            });
-            await reportChildrenOfBeforeAllFailure(child);
-
-            // Marking the suite passed is consistent with how suites that
-            // contain failed specs but no suite-level failures are reported.
-            child.result.status = 'passed';
-
-            await new Promise(function(resolve) {
-              reporter.suiteDone(child.result, resolve);
-            });
-          } else {
-            /* a spec */
-            await new Promise(function(resolve) {
-              reporter.specStarted(child.result, resolve);
-            });
-
-            child.addExpectationResult(
-              false,
-              {
-                passed: false,
-                message:
-                  'Not run because a beforeAll function failed. The ' +
-                  'beforeAll failure will be reported on the suite that ' +
-                  'caused it.'
-              },
-              true
-            );
-            child.result.status = 'failed';
-
-            await new Promise(function(resolve) {
-              reportSpecDone(child, child.result, resolve);
-            });
-          }
-        }
-      }
     };
 
     /**
@@ -2041,42 +1718,6 @@ getJasmineRequireObj().Env = function(j$) {
       reporter.clearReporters();
     };
 
-    var spyFactory = new j$.SpyFactory(
-      function getCustomStrategies() {
-        var runnable = currentRunnable();
-
-        if (runnable) {
-          return runnableResources[runnable.id].customSpyStrategies;
-        }
-
-        return {};
-      },
-      function getDefaultStrategyFn() {
-        var runnable = currentRunnable();
-
-        if (runnable) {
-          return runnableResources[runnable.id].defaultStrategyFn;
-        }
-
-        return undefined;
-      },
-      makeMatchersUtil
-    );
-
-    var spyRegistry = new j$.SpyRegistry({
-      currentSpies: function() {
-        if (!currentRunnable()) {
-          throw new Error(
-            'Spies must be created in a before function or a spec'
-          );
-        }
-        return runnableResources[currentRunnable().id].spies;
-      },
-      createSpy: function(name, originalFn) {
-        return self.createSpy(name, originalFn);
-      }
-    });
-
     /**
      * Configures whether Jasmine should allow the same function to be spied on
      * more than once during the execution of a spec. By default, spying on
@@ -2087,267 +1728,142 @@ getJasmineRequireObj().Env = function(j$) {
      * @param {boolean} allow Whether to allow respying
      */
     this.allowRespy = function(allow) {
-      spyRegistry.allowRespy(allow);
+      runableResources.spyRegistry.allowRespy(allow);
     };
 
     this.spyOn = function() {
-      return spyRegistry.spyOn.apply(spyRegistry, arguments);
+      return runableResources.spyRegistry.spyOn.apply(
+        runableResources.spyRegistry,
+        arguments
+      );
     };
 
     this.spyOnProperty = function() {
-      return spyRegistry.spyOnProperty.apply(spyRegistry, arguments);
+      return runableResources.spyRegistry.spyOnProperty.apply(
+        runableResources.spyRegistry,
+        arguments
+      );
     };
 
     this.spyOnAllFunctions = function() {
-      return spyRegistry.spyOnAllFunctions.apply(spyRegistry, arguments);
+      return runableResources.spyRegistry.spyOnAllFunctions.apply(
+        runableResources.spyRegistry,
+        arguments
+      );
     };
 
     this.createSpy = function(name, originalFn) {
-      if (arguments.length === 1 && j$.isFunction_(name)) {
-        originalFn = name;
-        name = originalFn.name;
-      }
-
-      return spyFactory.createSpy(name, originalFn);
+      return runableResources.spyFactory.createSpy(name, originalFn);
     };
 
     this.createSpyObj = function(baseName, methodNames, propertyNames) {
-      return spyFactory.createSpyObj(baseName, methodNames, propertyNames);
+      return runableResources.spyFactory.createSpyObj(
+        baseName,
+        methodNames,
+        propertyNames
+      );
     };
 
-    var ensureIsFunction = function(fn, caller) {
-      if (!j$.isFunction_(fn)) {
-        throw new Error(
-          caller + ' expects a function argument; received ' + j$.getType_(fn)
-        );
-      }
-    };
+    this.spyOnGlobalErrorsAsync = async function(fn) {
+      const spy = this.createSpy('global error handler');
+      const associatedRunable = runner.currentRunable();
+      let cleanedUp = false;
 
-    var ensureIsFunctionOrAsync = function(fn, caller) {
-      if (!j$.isFunction_(fn) && !j$.isAsyncFunction_(fn)) {
-        throw new Error(
-          caller + ' expects a function argument; received ' + j$.getType_(fn)
-        );
+      globalErrors.setOverrideListener(spy, () => {
+        if (!cleanedUp) {
+          const message =
+            'Global error spy was not uninstalled. (Did you ' +
+            'forget to await the return value of spyOnGlobalErrorsAsync?)';
+          associatedRunable.addExpectationResult(false, {
+            matcherName: '',
+            passed: false,
+            expected: '',
+            actual: '',
+            message,
+            error: null
+          });
+        }
+
+        cleanedUp = true;
+      });
+
+      try {
+        const maybePromise = fn(spy);
+
+        if (!j$.isPromiseLike(maybePromise)) {
+          throw new Error(
+            'The callback to spyOnGlobalErrorsAsync must be an async or promise-returning function'
+          );
+        }
+
+        await maybePromise;
+      } finally {
+        if (!cleanedUp) {
+          cleanedUp = true;
+          globalErrors.removeOverrideListener();
+        }
       }
     };
 
     function ensureIsNotNested(method) {
-      var runnable = currentRunnable();
-      if (runnable !== null && runnable !== undefined) {
+      const runable = runner.currentRunable();
+      if (runable !== null && runable !== undefined) {
         throw new Error(
           "'" + method + "' should only be used in 'describe' function"
         );
       }
     }
 
-    var suiteFactory = function(description) {
-      var suite = new j$.Suite({
-        id: getNextSuiteId(),
-        description: description,
-        parentSuite: currentDeclarationSuite,
-        timer: new j$.Timer(),
-        expectationFactory: expectationFactory,
-        asyncExpectationFactory: suiteAsyncExpectationFactory,
-        throwOnExpectationFailure: config.stopSpecOnExpectationFailure,
-        autoCleanClosures: config.autoCleanClosures,
-        onLateError: recordLateError
-      });
-
-      return suite;
-    };
-
-    this.describe = function(description, specDefinitions) {
+    this.describe = function(description, definitionFn) {
       ensureIsNotNested('describe');
-      ensureIsFunction(specDefinitions, 'describe');
-      var suite = suiteFactory(description);
-      if (specDefinitions.length > 0) {
-        throw new Error('describe does not expect any arguments');
-      }
-      if (currentDeclarationSuite.markedExcluding) {
-        suite.exclude();
-      }
-      addSpecsToSuite(suite, specDefinitions);
-      if (suite.parentSuite && !suite.children.length) {
-        throw new Error(
-          'describe with no children (describe() or it()): ' +
-            suite.getFullName()
-        );
-      }
-      return suite.metadata;
+      return suiteBuilder.describe(description, definitionFn).metadata;
     };
 
-    this.xdescribe = function(description, specDefinitions) {
+    this.xdescribe = function(description, definitionFn) {
       ensureIsNotNested('xdescribe');
-      ensureIsFunction(specDefinitions, 'xdescribe');
-      var suite = suiteFactory(description);
-      suite.exclude();
-      addSpecsToSuite(suite, specDefinitions);
-      return suite.metadata;
+      return suiteBuilder.xdescribe(description, definitionFn).metadata;
     };
 
-    var focusedRunnables = [];
-
-    this.fdescribe = function(description, specDefinitions) {
+    this.fdescribe = function(description, definitionFn) {
       ensureIsNotNested('fdescribe');
-      ensureIsFunction(specDefinitions, 'fdescribe');
-      var suite = suiteFactory(description);
-      suite.isFocused = true;
-
-      focusedRunnables.push(suite.id);
-      unfocusAncestor();
-      addSpecsToSuite(suite, specDefinitions);
-
-      return suite.metadata;
+      return suiteBuilder.fdescribe(description, definitionFn).metadata;
     };
 
-    function addSpecsToSuite(suite, specDefinitions) {
-      var parentSuite = currentDeclarationSuite;
-      parentSuite.addChild(suite);
-      currentDeclarationSuite = suite;
-
-      var declarationError = null;
-      try {
-        specDefinitions();
-      } catch (e) {
-        declarationError = e;
-      }
-
-      if (declarationError) {
-        suite.handleException(declarationError);
-      }
-
-      currentDeclarationSuite = parentSuite;
-    }
+    function specResultCallback(spec, result, next) {
+      runableResources.clearForRunable(spec.id);
+      runner.currentSpec = null;
 
-    function findFocusedAncestor(suite) {
-      while (suite) {
-        if (suite.isFocused) {
-          return suite.id;
-        }
-        suite = suite.parentSuite;
+      if (result.status === 'failed') {
+        runner.hasFailures = true;
       }
 
-      return null;
+      reportSpecDone(spec, result, next);
     }
 
-    function unfocusAncestor() {
-      var focusedAncestor = findFocusedAncestor(currentDeclarationSuite);
-      if (focusedAncestor) {
-        for (var i = 0; i < focusedRunnables.length; i++) {
-          if (focusedRunnables[i] === focusedAncestor) {
-            focusedRunnables.splice(i, 1);
-            break;
-          }
-        }
-      }
+    function specStarted(spec, suite, next) {
+      runner.currentSpec = spec;
+      runableResources.initForRunable(spec.id, suite.id);
+      reporter.specStarted(spec.result, next);
     }
 
-    var specFactory = function(description, fn, suite, timeout) {
-      totalSpecsDefined++;
-      var spec = new j$.Spec({
-        id: getNextSpecId(),
-        beforeAndAfterFns: beforeAndAfterFns(suite),
-        expectationFactory: expectationFactory,
-        asyncExpectationFactory: specAsyncExpectationFactory,
-        onLateError: recordLateError,
-        resultCallback: specResultCallback,
-        getSpecName: function(spec) {
-          return getSpecName(spec, suite);
-        },
-        onStart: specStarted,
-        description: description,
-        queueRunnerFactory: queueRunnerFactory,
-        userContext: function() {
-          return suite.clonedSharedUserContext();
-        },
-        queueableFn: {
-          fn: fn,
-          timeout: timeout || 0
-        },
-        throwOnExpectationFailure: config.stopSpecOnExpectationFailure,
-        autoCleanClosures: config.autoCleanClosures,
-        timer: new j$.Timer()
-      });
-      return spec;
-
-      function specResultCallback(result, next) {
-        clearResourcesForRunnable(spec.id);
-        currentSpec = null;
-
-        if (result.status === 'failed') {
-          hasFailures = true;
-        }
-
-        reportSpecDone(spec, result, next);
-      }
-
-      function specStarted(spec, next) {
-        currentSpec = spec;
-        defaultResourcesForRunnable(spec.id, suite.id);
-        reporter.specStarted(spec.result, next);
-      }
-    };
-
     function reportSpecDone(spec, result, next) {
       spec.reportedDone = true;
       reporter.specDone(result, next);
     }
 
-    function reportSuiteDone(suite, result, next) {
-      suite.reportedDone = true;
-      reporter.suiteDone(result, next);
-    }
-
-    this.it_ = function(description, fn, timeout) {
-      ensureIsNotNested('it');
-      // it() sometimes doesn't have a fn argument, so only check the type if
-      // it's given.
-      if (arguments.length > 1 && typeof fn !== 'undefined') {
-        ensureIsFunctionOrAsync(fn, 'it');
-      }
-
-      if (timeout) {
-        j$.util.validateTimeout(timeout);
-      }
-
-      var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
-      if (currentDeclarationSuite.markedExcluding) {
-        spec.exclude();
-      }
-      currentDeclarationSuite.addChild(spec);
-
-      return spec;
-    };
-
     this.it = function(description, fn, timeout) {
-      const spec = this.it_(description, fn, timeout);
-      return spec.metadata;
+      ensureIsNotNested('it');
+      return suiteBuilder.it(description, fn, timeout).metadata;
     };
 
     this.xit = function(description, fn, timeout) {
       ensureIsNotNested('xit');
-      // xit(), like it(), doesn't always have a fn argument, so only check the
-      // type when needed.
-      if (arguments.length > 1 && typeof fn !== 'undefined') {
-        ensureIsFunctionOrAsync(fn, 'xit');
-      }
-      var spec = this.it_.apply(this, arguments);
-      spec.exclude('Temporarily disabled with xit');
-      return spec.metadata;
+      return suiteBuilder.xit(description, fn, timeout).metadata;
     };
 
     this.fit = function(description, fn, timeout) {
       ensureIsNotNested('fit');
-      ensureIsFunctionOrAsync(fn, 'fit');
-
-      if (timeout) {
-        j$.util.validateTimeout(timeout);
-      }
-      var spec = specFactory(description, fn, currentDeclarationSuite, timeout);
-      currentDeclarationSuite.addChild(spec);
-      focusedRunnables.push(spec.id);
-      unfocusAncestor();
-      return spec.metadata;
+      return suiteBuilder.fit(description, fn, timeout).metadata;
     };
 
     /**
@@ -2359,12 +1875,15 @@ getJasmineRequireObj().Env = function(j$) {
      * @param {*} value The value of the property
      */
     this.setSpecProperty = function(key, value) {
-      if (!currentRunnable() || currentRunnable() == currentSuite()) {
+      if (
+        !runner.currentRunable() ||
+        runner.currentRunable() == runner.currentSuite()
+      ) {
         throw new Error(
           "'setSpecProperty' was used when there was no current spec"
         );
       }
-      currentRunnable().setSpecProperty(key, value);
+      runner.currentRunable().setSpecProperty(key, value);
     };
 
     /**
@@ -2376,16 +1895,16 @@ getJasmineRequireObj().Env = function(j$) {
      * @param {*} value The value of the property
      */
     this.setSuiteProperty = function(key, value) {
-      if (!currentSuite()) {
+      if (!runner.currentSuite()) {
         throw new Error(
           "'setSuiteProperty' was used when there was no current suite"
         );
       }
-      currentSuite().setSuiteProperty(key, value);
+      runner.currentSuite().setSuiteProperty(key, value);
     };
 
     this.debugLog = function(msg) {
-      var maybeSpec = currentRunnable();
+      const maybeSpec = runner.currentRunable();
 
       if (!maybeSpec || !maybeSpec.debugLog) {
         throw new Error("'debugLog' was called when there was no current spec");
@@ -2395,84 +1914,47 @@ getJasmineRequireObj().Env = function(j$) {
     };
 
     this.expect = function(actual) {
-      if (!currentRunnable()) {
+      if (!runner.currentRunable()) {
         throw new Error(
           "'expect' was used when there was no current spec, this could be because an asynchronous test timed out"
         );
       }
 
-      return currentRunnable().expect(actual);
+      return runner.currentRunable().expect(actual);
     };
 
     this.expectAsync = function(actual) {
-      if (!currentRunnable()) {
+      if (!runner.currentRunable()) {
         throw new Error(
           "'expectAsync' was used when there was no current spec, this could be because an asynchronous test timed out"
         );
       }
 
-      return currentRunnable().expectAsync(actual);
+      return runner.currentRunable().expectAsync(actual);
     };
 
     this.beforeEach = function(beforeEachFunction, timeout) {
       ensureIsNotNested('beforeEach');
-      ensureIsFunctionOrAsync(beforeEachFunction, 'beforeEach');
-
-      if (timeout) {
-        j$.util.validateTimeout(timeout);
-      }
-
-      currentDeclarationSuite.beforeEach({
-        fn: beforeEachFunction,
-        timeout: timeout || 0
-      });
+      suiteBuilder.beforeEach(beforeEachFunction, timeout);
     };
 
     this.beforeAll = function(beforeAllFunction, timeout) {
       ensureIsNotNested('beforeAll');
-      ensureIsFunctionOrAsync(beforeAllFunction, 'beforeAll');
-
-      if (timeout) {
-        j$.util.validateTimeout(timeout);
-      }
-
-      currentDeclarationSuite.beforeAll({
-        fn: beforeAllFunction,
-        timeout: timeout || 0
-      });
+      suiteBuilder.beforeAll(beforeAllFunction, timeout);
     };
 
     this.afterEach = function(afterEachFunction, timeout) {
       ensureIsNotNested('afterEach');
-      ensureIsFunctionOrAsync(afterEachFunction, 'afterEach');
-
-      if (timeout) {
-        j$.util.validateTimeout(timeout);
-      }
-
-      afterEachFunction.isCleanup = true;
-      currentDeclarationSuite.afterEach({
-        fn: afterEachFunction,
-        timeout: timeout || 0
-      });
+      suiteBuilder.afterEach(afterEachFunction, timeout);
     };
 
     this.afterAll = function(afterAllFunction, timeout) {
       ensureIsNotNested('afterAll');
-      ensureIsFunctionOrAsync(afterAllFunction, 'afterAll');
-
-      if (timeout) {
-        j$.util.validateTimeout(timeout);
-      }
-
-      currentDeclarationSuite.afterAll({
-        fn: afterAllFunction,
-        timeout: timeout || 0
-      });
+      suiteBuilder.afterAll(afterAllFunction, timeout);
     };
 
     this.pending = function(message) {
-      var fullMessage = j$.Spec.pendingSpecExceptionMessage;
+      let fullMessage = j$.Spec.pendingSpecExceptionMessage;
       if (message) {
         fullMessage += message;
       }
@@ -2480,13 +1962,13 @@ getJasmineRequireObj().Env = function(j$) {
     };
 
     this.fail = function(error) {
-      if (!currentRunnable()) {
+      if (!runner.currentRunable()) {
         throw new Error(
           "'fail' was used when there was no current spec, this could be because an asynchronous test timed out"
         );
       }
 
-      var message = 'Failed';
+      let message = 'Failed';
       if (error) {
         message += ': ';
         if (error.message) {
@@ -2495,11 +1977,12 @@ getJasmineRequireObj().Env = function(j$) {
           message += error;
         } else {
           // pretty print all kind of objects. This includes arrays.
-          message += makePrettyPrinter()(error);
+          const pp = runableResources.makePrettyPrinter();
+          message += pp(error);
         }
       }
 
-      currentRunnable().addExpectationResult(false, {
+      runner.currentRunable().addExpectationResult(false, {
         matcherName: '',
         passed: false,
         expected: '',
@@ -2531,8 +2014,8 @@ getJasmineRequireObj().JsApiReporter = function(j$) {
    * @hideconstructor
    */
   function JsApiReporter(options) {
-    var timer = options.timer || new j$.Timer(),
-      status = 'loaded';
+    const timer = options.timer || new j$.Timer();
+    let status = 'loaded';
 
     this.started = false;
     this.finished = false;
@@ -2544,7 +2027,7 @@ getJasmineRequireObj().JsApiReporter = function(j$) {
       timer.start();
     };
 
-    var executionTime;
+    let executionTime;
 
     this.jasmineDone = function(runDetails) {
       this.finished = true;
@@ -2564,7 +2047,7 @@ getJasmineRequireObj().JsApiReporter = function(j$) {
       return status;
     };
 
-    var suites = [],
+    const suites = [],
       suites_hash = {};
 
     this.suiteStarted = function(result) {
@@ -2606,7 +2089,7 @@ getJasmineRequireObj().JsApiReporter = function(j$) {
       return suites_hash;
     };
 
-    var specs = [];
+    const specs = [];
 
     this.specDone = function(result) {
       specs.push(result);
@@ -2734,8 +2217,7 @@ getJasmineRequireObj().ArrayContaining = function(j$) {
       return false;
     }
 
-    for (var i = 0; i < this.sample.length; i++) {
-      var item = this.sample[i];
+    for (const item of this.sample) {
       if (!matchersUtil.contains(other, item)) {
         return false;
       }
@@ -2772,8 +2254,7 @@ getJasmineRequireObj().ArrayWithExactContents = function(j$) {
       return false;
     }
 
-    for (var i = 0; i < this.sample.length; i++) {
-      var item = this.sample[i];
+    for (const item of this.sample) {
       if (!matchersUtil.contains(other, item)) {
         return false;
       }
@@ -2864,7 +2345,7 @@ getJasmineRequireObj().MapContaining = function(j$) {
     for (const [key, value] of this.sample) {
       // for each key/value pair in `sample`
       // there should be at least one pair in `other` whose key and value both match
-      var hasMatch = false;
+      let hasMatch = false;
       for (const [oKey, oValue] of other) {
         if (
           matchersUtil.equals(oKey, key) &&
@@ -2945,7 +2426,7 @@ getJasmineRequireObj().ObjectContaining = function(j$) {
       return false;
     }
 
-    for (var property in this.sample) {
+    for (const property in this.sample) {
       if (
         !hasProperty(other, property) ||
         !matchersUtil.equals(this.sample[property], other[property])
@@ -2965,7 +2446,7 @@ getJasmineRequireObj().ObjectContaining = function(j$) {
       };
     }
 
-    var filteredOther = {};
+    const filteredOther = {};
     Object.keys(this.sample).forEach(function(k) {
       // eq short-circuits comparison of objects that have different key sets,
       // so include all keys even if undefined.
@@ -3004,7 +2485,7 @@ getJasmineRequireObj().SetContaining = function(j$) {
       // for each item in `sample` there should be at least one matching item in `other`
       // (not using `matchersUtil.contains` because it compares set members by reference,
       // not by deep value equality)
-      var hasMatch = false;
+      let hasMatch = false;
       for (const oItem of other) {
         if (matchersUtil.equals(oItem, item)) {
           hasMatch = true;
@@ -3179,8 +2660,8 @@ getJasmineRequireObj().CallTracker = function(j$) {
    * @since 2.0.0
    */
   function CallTracker() {
-    var calls = [];
-    var opts = {};
+    let calls = [];
+    const opts = {};
 
     this.track = function(context) {
       if (opts.cloneArgs) {
@@ -3220,7 +2701,7 @@ getJasmineRequireObj().CallTracker = function(j$) {
      * @return {Array}
      */
     this.argsFor = function(index) {
-      var call = calls[index];
+      const call = calls[index];
       return call ? call.args : [];
     };
 
@@ -3233,7 +2714,7 @@ getJasmineRequireObj().CallTracker = function(j$) {
      * @return {Object?}
      */
     this.thisFor = function(index) {
-      var call = calls[index];
+      const call = calls[index];
       return call ? call.object : undefined;
     };
 
@@ -3256,12 +2737,7 @@ getJasmineRequireObj().CallTracker = function(j$) {
      * @return {Array}
      */
     this.allArgs = function() {
-      var callArgs = [];
-      for (var i = 0; i < calls.length; i++) {
-        callArgs.push(calls[i].args);
-      }
-
-      return callArgs;
+      return calls.map(c => c.args);
     };
 
     /**
@@ -3311,17 +2787,17 @@ getJasmineRequireObj().CallTracker = function(j$) {
 };
 
 getJasmineRequireObj().clearStack = function(j$) {
-  var maxInlineCallCount = 10;
+  const maxInlineCallCount = 10;
 
   function messageChannelImpl(global, setTimeout) {
-    var channel = new global.MessageChannel(),
-      head = {},
-      tail = head;
+    const channel = new global.MessageChannel();
+    let head = {};
+    let tail = head;
 
-    var taskRunning = false;
+    let taskRunning = false;
     channel.port1.onmessage = function() {
       head = head.next;
-      var task = head.task;
+      const task = head.task;
       delete head.task;
 
       if (taskRunning) {
@@ -3336,7 +2812,7 @@ getJasmineRequireObj().clearStack = function(j$) {
       }
     };
 
-    var currentCallCount = 0;
+    let currentCallCount = 0;
     return function clearStack(fn) {
       currentCallCount++;
 
@@ -3351,14 +2827,14 @@ getJasmineRequireObj().clearStack = function(j$) {
   }
 
   function getClearStack(global) {
-    var currentCallCount = 0;
-    var realSetTimeout = global.setTimeout;
-    var setTimeoutImpl = function clearStack(fn) {
+    let currentCallCount = 0;
+    const realSetTimeout = global.setTimeout;
+    const setTimeoutImpl = function clearStack(fn) {
       Function.prototype.apply.apply(realSetTimeout, [global, [fn, 0]]);
     };
 
     if (j$.isFunction_(global.setImmediate)) {
-      var realSetImmediate = global.setImmediate;
+      const realSetImmediate = global.setImmediate;
       return function(fn) {
         currentCallCount++;
 
@@ -3382,7 +2858,7 @@ getJasmineRequireObj().clearStack = function(j$) {
 
 getJasmineRequireObj().Clock = function() {
   /* global process */
-  var NODE_JS =
+  const NODE_JS =
     typeof process !== 'undefined' &&
     process.versions &&
     typeof process.versions.node === 'string';
@@ -3396,24 +2872,23 @@ getJasmineRequireObj().Clock = function() {
    * @hideconstructor
    */
   function Clock(global, delayedFunctionSchedulerFactory, mockDate) {
-    var self = this,
-      realTimingFunctions = {
-        setTimeout: global.setTimeout,
-        clearTimeout: global.clearTimeout,
-        setInterval: global.setInterval,
-        clearInterval: global.clearInterval
-      },
-      fakeTimingFunctions = {
-        setTimeout: setTimeout,
-        clearTimeout: clearTimeout,
-        setInterval: setInterval,
-        clearInterval: clearInterval
-      },
-      installed = false,
-      delayedFunctionScheduler,
-      timer;
+    const realTimingFunctions = {
+      setTimeout: global.setTimeout,
+      clearTimeout: global.clearTimeout,
+      setInterval: global.setInterval,
+      clearInterval: global.clearInterval
+    };
+    const fakeTimingFunctions = {
+      setTimeout: setTimeout,
+      clearTimeout: clearTimeout,
+      setInterval: setInterval,
+      clearInterval: clearInterval
+    };
+    let installed = false;
+    let delayedFunctionScheduler;
+    let timer;
 
-    self.FakeTimeout = FakeTimeout;
+    this.FakeTimeout = FakeTimeout;
 
     /**
      * Install the mock clock over the built-in methods.
@@ -3422,7 +2897,7 @@ getJasmineRequireObj().Clock = function() {
      * @function
      * @return {Clock}
      */
-    self.install = function() {
+    this.install = function() {
       if (!originalTimingFunctionsIntact()) {
         throw new Error(
           'Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?'
@@ -3433,7 +2908,7 @@ getJasmineRequireObj().Clock = function() {
       delayedFunctionScheduler = delayedFunctionSchedulerFactory();
       installed = true;
 
-      return self;
+      return this;
     };
 
     /**
@@ -3442,7 +2917,7 @@ getJasmineRequireObj().Clock = function() {
      * @since 2.0.0
      * @function
      */
-    self.uninstall = function() {
+    this.uninstall = function() {
       delayedFunctionScheduler = null;
       mockDate.uninstall();
       replace(global, realTimingFunctions);
@@ -3460,7 +2935,7 @@ getJasmineRequireObj().Clock = function() {
      * @function
      * @param {Function} closure The function to be called.
      */
-    self.withMock = function(closure) {
+    this.withMock = function(closure) {
       this.install();
       try {
         closure();
@@ -3476,29 +2951,29 @@ getJasmineRequireObj().Clock = function() {
      * @function
      * @param {Date} [initialDate=now] The `Date` to provide.
      */
-    self.mockDate = function(initialDate) {
+    this.mockDate = function(initialDate) {
       mockDate.install(initialDate);
     };
 
-    self.setTimeout = function(fn, delay, params) {
+    this.setTimeout = function(fn, delay, params) {
       return Function.prototype.apply.apply(timer.setTimeout, [
         global,
         arguments
       ]);
     };
 
-    self.setInterval = function(fn, delay, params) {
+    this.setInterval = function(fn, delay, params) {
       return Function.prototype.apply.apply(timer.setInterval, [
         global,
         arguments
       ]);
     };
 
-    self.clearTimeout = function(id) {
+    this.clearTimeout = function(id) {
       return Function.prototype.call.apply(timer.clearTimeout, [global, id]);
     };
 
-    self.clearInterval = function(id) {
+    this.clearInterval = function(id) {
       return Function.prototype.call.apply(timer.clearInterval, [global, id]);
     };
 
@@ -3509,7 +2984,7 @@ getJasmineRequireObj().Clock = function() {
      * @function
      * @param {int} millis The number of milliseconds to tick.
      */
-    self.tick = function(millis) {
+    this.tick = function(millis) {
       if (installed) {
         delayedFunctionScheduler.tick(millis, function(millis) {
           mockDate.tick(millis);
@@ -3521,7 +2996,7 @@ getJasmineRequireObj().Clock = function() {
       }
     };
 
-    return self;
+    return this;
 
     function originalTimingFunctionsIntact() {
       return (
@@ -3533,7 +3008,7 @@ getJasmineRequireObj().Clock = function() {
     }
 
     function replace(dest, source) {
-      for (var prop in source) {
+      for (const prop in source) {
         dest[prop] = source[prop];
       }
     }
@@ -3547,7 +3022,7 @@ getJasmineRequireObj().Clock = function() {
         );
       }
 
-      var timeout = new FakeTimeout();
+      const timeout = new FakeTimeout();
 
       delayedFunctionScheduler.scheduleFunction(
         fn,
@@ -3574,7 +3049,7 @@ getJasmineRequireObj().Clock = function() {
         );
       }
 
-      var timeout = new FakeTimeout();
+      const timeout = new FakeTimeout();
 
       delayedFunctionScheduler.scheduleFunction(
         fn,
@@ -3666,21 +3141,20 @@ getJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) {
 
 getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
   function DelayedFunctionScheduler() {
-    var self = this;
-    var scheduledLookup = [];
-    var scheduledFunctions = {};
-    var currentTime = 0;
-    var delayedFnCount = 0;
-    var deletedKeys = [];
-
-    self.tick = function(millis, tickDate) {
+    this.scheduledLookup_ = [];
+    this.scheduledFunctions_ = {};
+    this.currentTime_ = 0;
+    this.delayedFnCount_ = 0;
+    this.deletedKeys_ = [];
+
+    this.tick = function(millis, tickDate) {
       millis = millis || 0;
-      var endTime = currentTime + millis;
+      const endTime = this.currentTime_ + millis;
 
-      runScheduledFunctions(endTime, tickDate);
+      this.runScheduledFunctions_(endTime, tickDate);
     };
 
-    self.scheduleFunction = function(
+    this.scheduleFunction = function(
       funcToCall,
       millis,
       params,
@@ -3688,7 +3162,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
       timeoutKey,
       runAtMillis
     ) {
-      var f;
+      let f;
       if (typeof funcToCall === 'string') {
         f = function() {
           // eslint-disable-next-line no-eval
@@ -3699,10 +3173,10 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
       }
 
       millis = millis || 0;
-      timeoutKey = timeoutKey || ++delayedFnCount;
-      runAtMillis = runAtMillis || currentTime + millis;
+      timeoutKey = timeoutKey || ++this.delayedFnCount_;
+      runAtMillis = runAtMillis || this.currentTime_ + millis;
 
-      var funcToSchedule = {
+      const funcToSchedule = {
         runAtMillis: runAtMillis,
         funcToCall: f,
         recurring: recurring,
@@ -3711,12 +3185,12 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
         millis: millis
       };
 
-      if (runAtMillis in scheduledFunctions) {
-        scheduledFunctions[runAtMillis].push(funcToSchedule);
+      if (runAtMillis in this.scheduledFunctions_) {
+        this.scheduledFunctions_[runAtMillis].push(funcToSchedule);
       } else {
-        scheduledFunctions[runAtMillis] = [funcToSchedule];
-        scheduledLookup.push(runAtMillis);
-        scheduledLookup.sort(function(a, b) {
+        this.scheduledFunctions_[runAtMillis] = [funcToSchedule];
+        this.scheduledLookup_.push(runAtMillis);
+        this.scheduledLookup_.sort(function(a, b) {
           return a - b;
         });
       }
@@ -3724,19 +3198,19 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
       return timeoutKey;
     };
 
-    self.removeFunctionWithId = function(timeoutKey) {
-      deletedKeys.push(timeoutKey);
+    this.removeFunctionWithId = function(timeoutKey) {
+      this.deletedKeys_.push(timeoutKey);
 
-      for (var runAtMillis in scheduledFunctions) {
-        var funcs = scheduledFunctions[runAtMillis];
-        var i = indexOfFirstToPass(funcs, function(func) {
+      for (const runAtMillis in this.scheduledFunctions_) {
+        const funcs = this.scheduledFunctions_[runAtMillis];
+        const i = indexOfFirstToPass(funcs, function(func) {
           return func.timeoutKey === timeoutKey;
         });
 
         if (i > -1) {
           if (funcs.length === 1) {
-            delete scheduledFunctions[runAtMillis];
-            deleteFromLookup(runAtMillis);
+            delete this.scheduledFunctions_[runAtMillis];
+            this.deleteFromLookup_(runAtMillis);
           } else {
             funcs.splice(i, 1);
           }
@@ -3748,99 +3222,99 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
       }
     };
 
-    return self;
-
-    function indexOfFirstToPass(array, testFn) {
-      var index = -1;
+    return this;
+  }
 
-      for (var i = 0; i < array.length; ++i) {
-        if (testFn(array[i])) {
-          index = i;
-          break;
-        }
+  DelayedFunctionScheduler.prototype.runScheduledFunctions_ = function(
+    endTime,
+    tickDate
+  ) {
+    tickDate = tickDate || function() {};
+    if (
+      this.scheduledLookup_.length === 0 ||
+      this.scheduledLookup_[0] > endTime
+    ) {
+      if (endTime >= this.currentTime_) {
+        tickDate(endTime - this.currentTime_);
+        this.currentTime_ = endTime;
       }
-
-      return index;
+      return;
     }
 
-    function deleteFromLookup(key) {
-      var value = Number(key);
-      var i = indexOfFirstToPass(scheduledLookup, function(millis) {
-        return millis === value;
-      });
-
-      if (i > -1) {
-        scheduledLookup.splice(i, 1);
+    do {
+      this.deletedKeys_ = [];
+      const newCurrentTime = this.scheduledLookup_.shift();
+      if (newCurrentTime >= this.currentTime_) {
+        tickDate(newCurrentTime - this.currentTime_);
+        this.currentTime_ = newCurrentTime;
       }
-    }
 
-    function reschedule(scheduledFn) {
-      self.scheduleFunction(
-        scheduledFn.funcToCall,
-        scheduledFn.millis,
-        scheduledFn.params,
-        true,
-        scheduledFn.timeoutKey,
-        scheduledFn.runAtMillis + scheduledFn.millis
-      );
-    }
+      const funcsToRun = this.scheduledFunctions_[this.currentTime_];
 
-    function forEachFunction(funcsToRun, callback) {
-      for (var i = 0; i < funcsToRun.length; ++i) {
-        callback(funcsToRun[i]);
-      }
-    }
+      delete this.scheduledFunctions_[this.currentTime_];
 
-    function runScheduledFunctions(endTime, tickDate) {
-      tickDate = tickDate || function() {};
-      if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
-        if (endTime >= currentTime) {
-          tickDate(endTime - currentTime);
-          currentTime = endTime;
+      for (const fn of funcsToRun) {
+        if (fn.recurring) {
+          this.reschedule_(fn);
         }
-        return;
       }
 
-      do {
-        deletedKeys = [];
-        var newCurrentTime = scheduledLookup.shift();
-        if (newCurrentTime >= currentTime) {
-          tickDate(newCurrentTime - currentTime);
-          currentTime = newCurrentTime;
+      for (const fn of funcsToRun) {
+        if (this.deletedKeys_.includes(fn.timeoutKey)) {
+          // skip a timeoutKey deleted whilst we were running
+          return;
         }
+        fn.funcToCall.apply(null, fn.params || []);
+      }
+      this.deletedKeys_ = [];
+    } while (
+      this.scheduledLookup_.length > 0 &&
+      // checking first if we're out of time prevents setTimeout(0)
+      // scheduled in a funcToRun from forcing an extra iteration
+      this.currentTime_ !== endTime &&
+      this.scheduledLookup_[0] <= endTime
+    );
 
-        var funcsToRun = scheduledFunctions[currentTime];
+    // ran out of functions to call, but still time left on the clock
+    if (endTime >= this.currentTime_) {
+      tickDate(endTime - this.currentTime_);
+      this.currentTime_ = endTime;
+    }
+  };
 
-        delete scheduledFunctions[currentTime];
+  DelayedFunctionScheduler.prototype.reschedule_ = function(scheduledFn) {
+    this.scheduleFunction(
+      scheduledFn.funcToCall,
+      scheduledFn.millis,
+      scheduledFn.params,
+      true,
+      scheduledFn.timeoutKey,
+      scheduledFn.runAtMillis + scheduledFn.millis
+    );
+  };
 
-        forEachFunction(funcsToRun, function(funcToRun) {
-          if (funcToRun.recurring) {
-            reschedule(funcToRun);
-          }
-        });
+  DelayedFunctionScheduler.prototype.deleteFromLookup_ = function(key) {
+    const value = Number(key);
+    const i = indexOfFirstToPass(this.scheduledLookup_, function(millis) {
+      return millis === value;
+    });
 
-        forEachFunction(funcsToRun, function(funcToRun) {
-          if (j$.util.arrayContains(deletedKeys, funcToRun.timeoutKey)) {
-            // skip a timeoutKey deleted whilst we were running
-            return;
-          }
-          funcToRun.funcToCall.apply(null, funcToRun.params || []);
-        });
-        deletedKeys = [];
-      } while (
-        scheduledLookup.length > 0 &&
-        // checking first if we're out of time prevents setTimeout(0)
-        // scheduled in a funcToRun from forcing an extra iteration
-        currentTime !== endTime &&
-        scheduledLookup[0] <= endTime
-      );
+    if (i > -1) {
+      this.scheduledLookup_.splice(i, 1);
+    }
+  };
 
-      // ran out of functions to call, but still time left on the clock
-      if (endTime >= currentTime) {
-        tickDate(endTime - currentTime);
-        currentTime = endTime;
+  function indexOfFirstToPass(array, testFn) {
+    let index = -1;
+
+    for (let i = 0; i < array.length; ++i) {
+      if (testFn(array[i])) {
+        index = i;
+        break;
       }
     }
+
+    return index;
   }
 
   return DelayedFunctionScheduler;
@@ -3853,7 +3327,7 @@ getJasmineRequireObj().Deprecator = function(j$) {
     this.toSuppress_ = [];
   }
 
-  var verboseNote =
+  const verboseNote =
     'Note: This message will be shown only once. Set the verboseDeprecations ' +
     'config property to true to see every occurrence.';
 
@@ -3883,13 +3357,13 @@ getJasmineRequireObj().Deprecator = function(j$) {
   };
 
   Deprecator.prototype.log_ = function(runnable, deprecation, options) {
-    var context;
-
     if (j$.isError_(deprecation)) {
       console.error(deprecation);
       return;
     }
 
+    let context;
+
     if (runnable === this.topSuite_ || options.ignoreRunnable) {
       context = '';
     } else if (runnable.children) {
@@ -3910,7 +3384,7 @@ getJasmineRequireObj().Deprecator = function(j$) {
   };
 
   Deprecator.prototype.stackTrace_ = function() {
-    var formatter = new j$.ExceptionFormatter();
+    const formatter = new j$.ExceptionFormatter();
     return formatter.stack(j$.util.errorWithStack()).replace(/^Error\n/m, '');
   };
 
@@ -4033,7 +3507,7 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
       let empty = true;
 
       for (const prop in error) {
-        if (j$.util.arrayContains(ignoredProperties, prop)) {
+        if (ignoredProperties.includes(prop)) {
           continue;
         }
         result[prop] = error[prop];
@@ -4338,15 +3812,13 @@ getJasmineRequireObj().ExpectationFilterChain = function() {
   };
 
   ExpectationFilterChain.prototype.modifyFailureMessage = function(msg) {
-    var result = this.callFirst_('modifyFailureMessage', arguments).result;
+    const result = this.callFirst_('modifyFailureMessage', arguments).result;
     return result || msg;
   };
 
   ExpectationFilterChain.prototype.callFirst_ = function(fname, args) {
-    var prevResult;
-
     if (this.prev_) {
-      prevResult = this.prev_.callFirst_(fname, args);
+      const prevResult = this.prev_.callFirst_(fname, args);
 
       if (prevResult.found) {
         return prevResult;
@@ -4387,35 +3859,24 @@ getJasmineRequireObj().Expector = function(j$) {
 
     this.args.unshift(this.actual);
 
-    var matcher = matcherFactory(this.matchersUtil);
+    const matcher = matcherFactory(this.matchersUtil);
 
-    var comparisonFunc = this.filters.selectComparisonFunc(matcher);
+    const comparisonFunc = this.filters.selectComparisonFunc(matcher);
     return comparisonFunc || matcher.compare;
   };
 
   Expector.prototype.buildMessage = function(result) {
-    var self = this;
-
     if (result.pass) {
       return '';
     }
 
-    var msg = this.filters.buildFailureMessage(
-      result,
-      this.matcherName,
-      this.args,
-      this.matchersUtil,
-      defaultMessage
-    );
-    return this.filters.modifyFailureMessage(msg || defaultMessage());
-
-    function defaultMessage() {
+    const defaultMessage = () => {
       if (!result.message) {
-        var args = self.args.slice();
+        const args = this.args.slice();
         args.unshift(false);
-        args.unshift(self.matcherName);
-        return self.matchersUtil.buildFailureMessage.apply(
-          self.matchersUtil,
+        args.unshift(this.matcherName);
+        return this.matchersUtil.buildFailureMessage.apply(
+          this.matchersUtil,
           args
         );
       } else if (j$.isFunction_(result.message)) {
@@ -4423,11 +3884,20 @@ getJasmineRequireObj().Expector = function(j$) {
       } else {
         return result.message;
       }
-    }
+    };
+
+    const msg = this.filters.buildFailureMessage(
+      result,
+      this.matcherName,
+      this.args,
+      this.matchersUtil,
+      defaultMessage
+    );
+    return this.filters.modifyFailureMessage(msg || defaultMessage());
   };
 
   Expector.prototype.compare = function(matcherName, matcherFactory, args) {
-    var matcherCompare = this.instantiateMatcher(
+    const matcherCompare = this.instantiateMatcher(
       matcherName,
       matcherFactory,
       args
@@ -4436,13 +3906,13 @@ getJasmineRequireObj().Expector = function(j$) {
   };
 
   Expector.prototype.addFilter = function(filter) {
-    var result = Object.create(this);
+    const result = Object.create(this);
     result.filters = this.filters.addFilter(filter);
     return result;
   };
 
   Expector.prototype.processResult = function(result, errorForStack) {
-    var message = this.buildMessage(result);
+    const message = this.buildMessage(result);
 
     if (this.expected.length === 1) {
       this.expected = this.expected[0];
@@ -4464,7 +3934,7 @@ getJasmineRequireObj().Expector = function(j$) {
 
 getJasmineRequireObj().formatErrorMsg = function() {
   function generateErrorMsg(domain, usage) {
-    var usageDefinition = usage ? '\nUsage: ' + usage : '';
+    const usageDefinition = usage ? '\nUsage: ' + usage : '';
 
     return function errorMsg(msg) {
       return domain + ' : ' + msg + usageDefinition;
@@ -4476,28 +3946,36 @@ getJasmineRequireObj().formatErrorMsg = function() {
 
 getJasmineRequireObj().GlobalErrors = function(j$) {
   function GlobalErrors(global) {
-    var handlers = [];
     global = global || j$.getGlobal();
 
-    var onerror = function onerror() {
-      var handler = handlers[handlers.length - 1];
+    const handlers = [];
+    let overrideHandler = null,
+      onRemoveOverrideHandler = null;
 
-      if (handler) {
-        handler.apply(null, Array.prototype.slice.call(arguments, 0));
+    function onerror(message, source, lineno, colno, error) {
+      if (overrideHandler) {
+        overrideHandler(error || message);
+        return;
+      }
+
+      const handler = handlers[handlers.length - 1];
+
+      if (handler) {
+        handler.apply(null, Array.prototype.slice.call(arguments, 0));
       } else {
         throw arguments[0];
       }
-    };
+    }
 
     this.originalHandlers = {};
     this.jasmineHandlers = {};
     this.installOne_ = function installOne_(errorType, jasmineMessage) {
       function taggedOnError(error) {
-        var substituteMsg;
-
         if (j$.isError_(error)) {
           error.jasmineMessage = jasmineMessage + ': ' + error;
         } else {
+          let substituteMsg;
+
           if (error) {
             substituteMsg = jasmineMessage + ': ' + error;
           } else {
@@ -4516,7 +3994,12 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
           error = new Error(substituteMsg);
         }
 
-        var handler = handlers[handlers.length - 1];
+        const handler = handlers[handlers.length - 1];
+
+        if (overrideHandler) {
+          overrideHandler(error);
+          return;
+        }
 
         if (handler) {
           handler(error);
@@ -4532,14 +4015,14 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
       global.process.on(errorType, taggedOnError);
 
       this.uninstall = function uninstall() {
-        var errorTypes = Object.keys(this.originalHandlers);
-        for (var iType = 0; iType < errorTypes.length; iType++) {
-          var errorType = errorTypes[iType];
+        const errorTypes = Object.keys(this.originalHandlers);
+        for (const errorType of errorTypes) {
           global.process.removeListener(
             errorType,
             this.jasmineHandlers[errorType]
           );
-          for (var i = 0; i < this.originalHandlers[errorType].length; i++) {
+
+          for (let i = 0; i < this.originalHandlers[errorType].length; i++) {
             global.process.on(errorType, this.originalHandlers[errorType][i]);
           }
           delete this.originalHandlers[errorType];
@@ -4557,10 +4040,12 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
         this.installOne_('uncaughtException', 'Uncaught exception');
         this.installOne_('unhandledRejection', 'Unhandled promise rejection');
       } else {
-        var originalHandler = global.onerror;
+        const originalHandler = global.onerror;
         global.onerror = onerror;
 
-        var browserRejectionHandler = function browserRejectionHandler(event) {
+        const browserRejectionHandler = function browserRejectionHandler(
+          event
+        ) {
           if (j$.isError_(event.reason)) {
             event.reason.jasmineMessage =
               'Unhandled promise rejection: ' + event.reason;
@@ -4600,6 +4085,24 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
 
       handlers.pop();
     };
+
+    this.setOverrideListener = function(listener, onRemove) {
+      if (overrideHandler) {
+        throw new Error("Can't set more than one override listener at a time");
+      }
+
+      overrideHandler = listener;
+      onRemoveOverrideHandler = onRemove;
+    };
+
+    this.removeOverrideListener = function() {
+      if (onRemoveOverrideHandler) {
+        onRemoveOverrideHandler();
+      }
+
+      overrideHandler = null;
+      onRemoveOverrideHandler = null;
+    };
   }
 
   return GlobalErrors;
@@ -4621,7 +4124,7 @@ getJasmineRequireObj().toBePending = function(j$) {
         if (!j$.isPromiseLike(actual)) {
           throw new Error('Expected toBePending to be called on a promise.');
         }
-        var want = {};
+        const want = {};
         return Promise.race([actual, Promise.resolve(want)]).then(
           function(got) {
             return { pass: want === got };
@@ -4752,7 +4255,7 @@ getJasmineRequireObj().toBeRejectedWithError = function(j$) {
           );
         }
 
-        var expected = getExpectedFromArgs(arg1, arg2, matchersUtil);
+        const expected = getExpectedFromArgs(arg1, arg2, matchersUtil);
 
         return actualPromise.then(
           function() {
@@ -4781,7 +4284,7 @@ getJasmineRequireObj().toBeRejectedWithError = function(j$) {
       );
     }
 
-    var actualMessage = actual.message;
+    const actualMessage = actual.message;
 
     if (
       actualMessage === expected.message ||
@@ -4823,7 +4326,7 @@ getJasmineRequireObj().toBeRejectedWithError = function(j$) {
   }
 
   function getExpectedFromArgs(arg1, arg2, matchersUtil) {
-    var error, message;
+    let error, message;
 
     if (isErrorConstructor(arg1)) {
       error = arg1;
@@ -5130,7 +4633,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
 
     if (j$.isNumber_(haystack.length)) {
       // Objects that are shaped like arrays but aren't iterable
-      for (var i = 0; i < haystack.length; i++) {
+      for (let i = 0; i < haystack.length; i++) {
         if (this.equals(haystack[i], needle)) {
           return true;
         }
@@ -5141,8 +4644,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
   };
 
   MatchersUtil.prototype.buildFailureMessage = function() {
-    var self = this;
-    var args = Array.prototype.slice.call(arguments, 0),
+    const args = Array.prototype.slice.call(arguments, 0),
       matcherName = args[0],
       isNot = args[1],
       actual = args[2],
@@ -5151,18 +4653,18 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
         return ' ' + s.toLowerCase();
       });
 
-    var message =
+    let message =
       'Expected ' +
-      self.pp(actual) +
+      this.pp(actual) +
       (isNot ? ' not ' : ' ') +
       englishyPredicate;
 
     if (expected.length > 0) {
-      for (var i = 0; i < expected.length; i++) {
+      for (let i = 0; i < expected.length; i++) {
         if (i > 0) {
           message += ',';
         }
-        message += ' ' + self.pp(expected[i]);
+        message += ' ' + this.pp(expected[i]);
       }
     }
 
@@ -5177,7 +4679,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
     diffBuilder
   ) {
     if (j$.isFunction_(b.valuesForDiff_)) {
-      var values = b.valuesForDiff_(a, this.pp);
+      const values = b.valuesForDiff_(a, this.pp);
       this.eq_(values.other, values.self, aStack, bStack, diffBuilder);
     } else {
       diffBuilder.recordMismatch();
@@ -5191,14 +4693,15 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
     bStack,
     diffBuilder
   ) {
-    var asymmetricA = j$.isAsymmetricEqualityTester_(a),
-      asymmetricB = j$.isAsymmetricEqualityTester_(b),
-      result;
+    const asymmetricA = j$.isAsymmetricEqualityTester_(a);
+    const asymmetricB = j$.isAsymmetricEqualityTester_(b);
 
     if (asymmetricA === asymmetricB) {
       return undefined;
     }
 
+    let result;
+
     if (asymmetricA) {
       result = a.asymmetricMatch(b, this);
       if (!result) {
@@ -5235,11 +4738,9 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
   // Equality function lovingly adapted from isEqual in
   //   [Underscore](http://underscorejs.org)
   MatchersUtil.prototype.eq_ = function(a, b, aStack, bStack, diffBuilder) {
-    var result = true,
-      self = this,
-      i;
+    let result = true;
 
-    var asymmetricResult = this.asymmetricMatch_(
+    const asymmetricResult = this.asymmetricMatch_(
       a,
       b,
       aStack,
@@ -5250,8 +4751,8 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
       return asymmetricResult;
     }
 
-    for (i = 0; i < this.customTesters_.length; i++) {
-      var customTesterResult = this.customTesters_[i](a, b);
+    for (const tester of this.customTesters_) {
+      const customTesterResult = tester(a, b);
       if (!j$.util.isUndefined(customTesterResult)) {
         if (!customTesterResult) {
           diffBuilder.recordMismatch();
@@ -5285,7 +4786,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
       }
       return result;
     }
-    var className = Object.prototype.toString.call(a);
+    const className = Object.prototype.toString.call(a);
     if (className != Object.prototype.toString.call(b)) {
       diffBuilder.recordMismatch();
       return false;
@@ -5322,7 +4823,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
       case '[object ArrayBuffer]':
         // If we have an instance of ArrayBuffer the Uint8Array ctor
         // will be defined as well
-        return self.eq_(
+        return this.eq_(
           new Uint8Array(a),
           new Uint8Array(b),
           aStack,
@@ -5343,8 +4844,8 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
       return false;
     }
 
-    var aIsDomNode = j$.isDomNode(a);
-    var bIsDomNode = j$.isDomNode(b);
+    const aIsDomNode = j$.isDomNode(a);
+    const bIsDomNode = j$.isDomNode(b);
     if (aIsDomNode && bIsDomNode) {
       // At first try to use DOM3 method isEqualNode
       result = a.isEqualNode(b);
@@ -5358,15 +4859,15 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
       return false;
     }
 
-    var aIsPromise = j$.isPromise(a);
-    var bIsPromise = j$.isPromise(b);
+    const aIsPromise = j$.isPromise(a);
+    const bIsPromise = j$.isPromise(b);
     if (aIsPromise && bIsPromise) {
       return a === b;
     }
 
     // Assume equality for cyclic structures. The algorithm for detecting cyclic
     // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
-    var length = aStack.length;
+    let length = aStack.length;
     while (length--) {
       // Linear search. Performance is inversely proportional to the number of
       // unique nested structures.
@@ -5377,12 +4878,12 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
     // Add the first object to the stack of traversed objects.
     aStack.push(a);
     bStack.push(b);
-    var size = 0;
+    let size = 0;
     // Recursively compare objects and arrays.
     // Compare array lengths to determine if a deep comparison is necessary.
     if (className == '[object Array]') {
-      var aLength = a.length;
-      var bLength = b.length;
+      const aLength = a.length;
+      const bLength = b.length;
 
       diffBuilder.withPath('length', function() {
         if (aLength !== bLength) {
@@ -5391,16 +4892,16 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
         }
       });
 
-      for (i = 0; i < aLength || i < bLength; i++) {
-        diffBuilder.withPath(i, function() {
+      for (let i = 0; i < aLength || i < bLength; i++) {
+        diffBuilder.withPath(i, () => {
           if (i >= bLength) {
             diffBuilder.recordMismatch(
-              actualArrayIsLongerFormatter.bind(null, self.pp)
+              actualArrayIsLongerFormatter.bind(null, this.pp)
             );
             result = false;
           } else {
             result =
-              self.eq_(
+              this.eq_(
                 i < aLength ? a[i] : void 0,
                 i < bLength ? b[i] : void 0,
                 aStack,
@@ -5419,8 +4920,8 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
         return false;
       }
 
-      var keysA = [];
-      var keysB = [];
+      const keysA = [];
+      const keysB = [];
       a.forEach(function(valueA, keyA) {
         keysA.push(keyA);
       });
@@ -5430,18 +4931,17 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
 
       // For both sets of keys, check they map to equal values in both maps.
       // Keep track of corresponding keys (in insertion order) in order to handle asymmetric obj keys.
-      var mapKeys = [keysA, keysB];
-      var cmpKeys = [keysB, keysA];
-      var mapIter, mapKey, mapValueA, mapValueB;
-      var cmpIter, cmpKey;
-      for (i = 0; result && i < mapKeys.length; i++) {
-        mapIter = mapKeys[i];
-        cmpIter = cmpKeys[i];
-
-        for (var j = 0; result && j < mapIter.length; j++) {
-          mapKey = mapIter[j];
-          cmpKey = cmpIter[j];
-          mapValueA = a.get(mapKey);
+      const mapKeys = [keysA, keysB];
+      const cmpKeys = [keysB, keysA];
+      for (let i = 0; result && i < mapKeys.length; i++) {
+        const mapIter = mapKeys[i];
+        const cmpIter = cmpKeys[i];
+
+        for (let j = 0; result && j < mapIter.length; j++) {
+          const mapKey = mapIter[j];
+          const cmpKey = cmpIter[j];
+          const mapValueA = a.get(mapKey);
+          let mapValueB;
 
           // Only use the cmpKey when one of the keys is asymmetric and the corresponding key matches,
           // otherwise explicitly look up the mapKey in the other Map since we want keys with unique
@@ -5475,35 +4975,30 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
         return false;
       }
 
-      var valuesA = [];
+      const valuesA = [];
       a.forEach(function(valueA) {
         valuesA.push(valueA);
       });
-      var valuesB = [];
+      const valuesB = [];
       b.forEach(function(valueB) {
         valuesB.push(valueB);
       });
 
       // For both sets, check they are all contained in the other set
-      var setPairs = [[valuesA, valuesB], [valuesB, valuesA]];
-      var stackPairs = [[aStack, bStack], [bStack, aStack]];
-      var baseValues, baseValue, baseStack;
-      var otherValues, otherValue, otherStack;
-      var found;
-      var prevStackSize;
-      for (i = 0; result && i < setPairs.length; i++) {
-        baseValues = setPairs[i][0];
-        otherValues = setPairs[i][1];
-        baseStack = stackPairs[i][0];
-        otherStack = stackPairs[i][1];
+      const setPairs = [[valuesA, valuesB], [valuesB, valuesA]];
+      const stackPairs = [[aStack, bStack], [bStack, aStack]];
+      for (let i = 0; result && i < setPairs.length; i++) {
+        const baseValues = setPairs[i][0];
+        const otherValues = setPairs[i][1];
+        const baseStack = stackPairs[i][0];
+        const otherStack = stackPairs[i][1];
         // For each value in the base set...
-        for (var k = 0; result && k < baseValues.length; k++) {
-          baseValue = baseValues[k];
-          found = false;
+        for (const baseValue of baseValues) {
+          let found = false;
           // ... test that it is present in the other set
-          for (var l = 0; !found && l < otherValues.length; l++) {
-            otherValue = otherValues[l];
-            prevStackSize = baseStack.length;
+          for (let j = 0; !found && j < otherValues.length; j++) {
+            const otherValue = otherValues[j];
+            const prevStackSize = baseStack.length;
             // compare by value equality
             found = this.eq_(
               baseValue,
@@ -5532,7 +5027,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
     } else {
       // Objects with different constructors are not equivalent, but `Object`s
       // or `Array`s from different frames are.
-      var aCtor = a.constructor,
+      const aCtor = a.constructor,
         bCtor = b.constructor;
       if (
         aCtor !== bCtor &&
@@ -5550,8 +5045,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
     }
 
     // Deep compare objects.
-    var aKeys = MatchersUtil.keys(a, className == '[object Array]'),
-      key;
+    const aKeys = MatchersUtil.keys(a, className == '[object Array]');
     size = aKeys.length;
 
     // Ensure that both objects contain the same number of properties before comparing deep equality.
@@ -5562,8 +5056,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
       return false;
     }
 
-    for (i = 0; i < size; i++) {
-      key = aKeys[i];
+    for (const key of aKeys) {
       // Deep compare each member
       if (!j$.util.has(b, key)) {
         diffBuilder.recordMismatch(
@@ -5573,8 +5066,8 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
         continue;
       }
 
-      diffBuilder.withPath(key, function() {
-        if (!self.eq_(a[key], b[key], aStack, bStack, diffBuilder)) {
+      diffBuilder.withPath(key, () => {
+        if (!this.eq_(a[key], b[key], aStack, bStack, diffBuilder)) {
           result = false;
         }
       });
@@ -5592,18 +5085,18 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
   };
 
   MatchersUtil.keys = function(obj, isArray) {
-    var allKeys = (function(o) {
-      var keys = [];
-      for (var key in o) {
+    const allKeys = (function(o) {
+      const keys = [];
+      for (const key in o) {
         if (j$.util.has(o, key)) {
           keys.push(key);
         }
       }
 
-      var symbols = Object.getOwnPropertySymbols(o);
-      for (var i = 0; i < symbols.length; i++) {
-        if (o.propertyIsEnumerable(symbols[i])) {
-          keys.push(symbols[i]);
+      const symbols = Object.getOwnPropertySymbols(o);
+      for (const sym of symbols) {
+        if (o.propertyIsEnumerable(sym)) {
+          keys.push(sym);
         }
       }
 
@@ -5618,10 +5111,10 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
       return allKeys;
     }
 
-    var extraKeys = [];
-    for (var i = 0; i < allKeys.length; i++) {
-      if (typeof allKeys[i] === 'symbol' || !/^[0-9]+$/.test(allKeys[i])) {
-        extraKeys.push(allKeys[i]);
+    const extraKeys = [];
+    for (const k of allKeys) {
+      if (typeof k === 'symbol' || !/^[0-9]+$/.test(k)) {
+        extraKeys.push(k);
       }
     }
 
@@ -5641,7 +5134,7 @@ getJasmineRequireObj().MatchersUtil = function(j$) {
   }
 
   function objectKeysAreDifferentFormatter(pp, actual, expected, path) {
-    var missingProperties = extraKeysAndValues(expected, actual),
+    const missingProperties = extraKeysAndValues(expected, actual),
       extraProperties = extraKeysAndValues(actual, expected),
       missingPropertiesMessage = formatKeyValuePairs(pp, missingProperties),
       extraPropertiesMessage = formatKeyValuePairs(pp, extraProperties),
@@ -5892,7 +5385,7 @@ getJasmineRequireObj().ObjectPath = function(j$) {
 };
 
 getJasmineRequireObj().requireAsyncMatchers = function(jRequire, j$) {
-  var availableMatchers = [
+  const availableMatchers = [
       'toBePending',
       'toBeResolved',
       'toBeRejected',
@@ -5902,8 +5395,7 @@ getJasmineRequireObj().requireAsyncMatchers = function(jRequire, j$) {
     ],
     matchers = {};
 
-  for (var i = 0; i < availableMatchers.length; i++) {
-    var name = availableMatchers[i];
+  for (const name of availableMatchers) {
     matchers[name] = jRequire[name](j$);
   }
 
@@ -5921,12 +5413,12 @@ getJasmineRequireObj().toBe = function(j$) {
    * expect(thing).toBe(realThing);
    */
   function toBe(matchersUtil) {
-    var tip =
+    const tip =
       ' Tip: To check for deep equality, use .toEqual() instead of .toBe().';
 
     return {
       compare: function(actual, expected) {
-        var result = {
+        const result = {
           pass: actual === expected
         };
 
@@ -5985,9 +5477,9 @@ getJasmineRequireObj().toBeCloseTo = function() {
           };
         }
 
-        var pow = Math.pow(10, precision + 1);
-        var delta = Math.abs(expected - actual);
-        var maxDelta = Math.pow(10, -precision) / 2;
+        const pow = Math.pow(10, precision + 1);
+        const delta = Math.abs(expected - actual);
+        const maxDelta = Math.pow(10, -precision) / 2;
 
         return {
           pass: Math.round(delta * pow) <= maxDelta * pow
@@ -6112,7 +5604,7 @@ getJasmineRequireObj().toBeGreaterThanOrEqual = function() {
 };
 
 getJasmineRequireObj().toBeInstanceOf = function(j$) {
-  var usageError = j$.formatErrorMsg(
+  const usageError = j$.formatErrorMsg(
     '<toBeInstanceOf>',
     'expect(value).toBeInstanceOf(<ConstructorFunction>)'
   );
@@ -6131,15 +5623,15 @@ getJasmineRequireObj().toBeInstanceOf = function(j$) {
   function toBeInstanceOf(matchersUtil) {
     return {
       compare: function(actual, expected) {
-        var actualType =
-            actual && actual.constructor
-              ? j$.fnNameFor(actual.constructor)
-              : matchersUtil.pp(actual),
-          expectedType = expected
-            ? j$.fnNameFor(expected)
-            : matchersUtil.pp(expected),
-          expectedMatcher,
-          pass;
+        const actualType =
+          actual && actual.constructor
+            ? j$.fnNameFor(actual.constructor)
+            : matchersUtil.pp(actual);
+        const expectedType = expected
+          ? j$.fnNameFor(expected)
+          : matchersUtil.pp(expected);
+        let expectedMatcher;
+        let pass;
 
         try {
           expectedMatcher = new j$.Any(expected);
@@ -6234,7 +5726,7 @@ getJasmineRequireObj().toBeNaN = function(j$) {
   function toBeNaN(matchersUtil) {
     return {
       compare: function(actual) {
-        var result = {
+        const result = {
           pass: actual !== actual
         };
 
@@ -6266,7 +5758,7 @@ getJasmineRequireObj().toBeNegativeInfinity = function(j$) {
   function toBeNegativeInfinity(matchersUtil) {
     return {
       compare: function(actual) {
-        var result = {
+        const result = {
           pass: actual === Number.NEGATIVE_INFINITY
         };
 
@@ -6320,7 +5812,7 @@ getJasmineRequireObj().toBePositiveInfinity = function(j$) {
   function toBePositiveInfinity(matchersUtil) {
     return {
       compare: function(actual) {
-        var result = {
+        const result = {
           pass: actual === Number.POSITIVE_INFINITY
         };
 
@@ -6443,7 +5935,7 @@ getJasmineRequireObj().toEqual = function(j$) {
   function toEqual(matchersUtil) {
     return {
       compare: function(actual, expected) {
-        var result = {
+        const result = {
             pass: false
           },
           diffBuilder = new j$.DiffBuilder({ prettyPrinter: matchersUtil.pp });
@@ -6462,7 +5954,7 @@ getJasmineRequireObj().toEqual = function(j$) {
 };
 
 getJasmineRequireObj().toHaveBeenCalled = function(j$) {
-  var getErrorMsg = j$.formatErrorMsg(
+  const getErrorMsg = j$.formatErrorMsg(
     '<toHaveBeenCalled>',
     'expect(<spyObj>).toHaveBeenCalled()'
   );
@@ -6479,7 +5971,7 @@ getJasmineRequireObj().toHaveBeenCalled = function(j$) {
   function toHaveBeenCalled(matchersUtil) {
     return {
       compare: function(actual) {
-        var result = {};
+        const result = {};
 
         if (!j$.isSpy(actual)) {
           throw new Error(
@@ -6510,7 +6002,7 @@ getJasmineRequireObj().toHaveBeenCalled = function(j$) {
 };
 
 getJasmineRequireObj().toHaveBeenCalledBefore = function(j$) {
-  var getErrorMsg = j$.formatErrorMsg(
+  const getErrorMsg = j$.formatErrorMsg(
     '<toHaveBeenCalledBefore>',
     'expect(<spyObj>).toHaveBeenCalledBefore(<spyObj>)'
   );
@@ -6542,7 +6034,7 @@ getJasmineRequireObj().toHaveBeenCalledBefore = function(j$) {
           );
         }
 
-        var result = { pass: false };
+        const result = { pass: false };
 
         if (!firstSpy.calls.count()) {
           result.message =
@@ -6555,8 +6047,8 @@ getJasmineRequireObj().toHaveBeenCalledBefore = function(j$) {
           return result;
         }
 
-        var latest1stSpyCall = firstSpy.calls.mostRecent().invocationOrder;
-        var first2ndSpyCall = latterSpy.calls.first().invocationOrder;
+        const latest1stSpyCall = firstSpy.calls.mostRecent().invocationOrder;
+        const first2ndSpyCall = latterSpy.calls.first().invocationOrder;
 
         result.pass = latest1stSpyCall < first2ndSpyCall;
 
@@ -6568,8 +6060,8 @@ getJasmineRequireObj().toHaveBeenCalledBefore = function(j$) {
             latterSpy.and.identity +
             ', but it was';
         } else {
-          var first1stSpyCall = firstSpy.calls.first().invocationOrder;
-          var latest2ndSpyCall = latterSpy.calls.mostRecent().invocationOrder;
+          const first1stSpyCall = firstSpy.calls.first().invocationOrder;
+          const latest2ndSpyCall = latterSpy.calls.mostRecent().invocationOrder;
 
           if (first1stSpyCall < first2ndSpyCall) {
             result.message =
@@ -6603,7 +6095,7 @@ getJasmineRequireObj().toHaveBeenCalledBefore = function(j$) {
 };
 
 getJasmineRequireObj().toHaveBeenCalledOnceWith = function(j$) {
-  var getErrorMsg = j$.formatErrorMsg(
+  const getErrorMsg = j$.formatErrorMsg(
     '<toHaveBeenCalledOnceWith>',
     'expect(<spyObj>).toHaveBeenCalledOnceWith(...arguments)'
   );
@@ -6620,7 +6112,7 @@ getJasmineRequireObj().toHaveBeenCalledOnceWith = function(j$) {
   function toHaveBeenCalledOnceWith(util) {
     return {
       compare: function() {
-        var args = Array.prototype.slice.call(arguments, 0),
+        const args = Array.prototype.slice.call(arguments, 0),
           actual = args[0],
           expectedArgs = args.slice(1);
 
@@ -6630,7 +6122,7 @@ getJasmineRequireObj().toHaveBeenCalledOnceWith = function(j$) {
           );
         }
 
-        var prettyPrintedCalls = actual.calls
+        const prettyPrintedCalls = actual.calls
           .allArgs()
           .map(function(argsForCall) {
             return '  ' + util.pp(argsForCall);
@@ -6657,7 +6149,7 @@ getJasmineRequireObj().toHaveBeenCalledOnceWith = function(j$) {
 
         function getDiffs() {
           return actual.calls.allArgs().map(function(argsForCall, callIx) {
-            var diffBuilder = new j$.DiffBuilder();
+            const diffBuilder = new j$.DiffBuilder();
             util.equals(argsForCall, expectedArgs, diffBuilder);
             return diffBuilder.getMessage();
           });
@@ -6703,7 +6195,7 @@ getJasmineRequireObj().toHaveBeenCalledOnceWith = function(j$) {
 };
 
 getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) {
-  var getErrorMsg = j$.formatErrorMsg(
+  const getErrorMsg = j$.formatErrorMsg(
     '<toHaveBeenCalledTimes>',
     'expect(<spyObj>).toHaveBeenCalledTimes(<Number>)'
   );
@@ -6728,7 +6220,7 @@ getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) {
           );
         }
 
-        var args = Array.prototype.slice.call(arguments, 0),
+        const args = Array.prototype.slice.call(arguments, 0),
           result = { pass: false };
 
         if (!j$.isNumber_(expected)) {
@@ -6740,8 +6232,8 @@ getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) {
         }
 
         actual = args[0];
-        var calls = actual.calls.count();
-        var timesMessage = expected === 1 ? 'once' : expected + ' times';
+        const calls = actual.calls.count();
+        const timesMessage = expected === 1 ? 'once' : expected + ' times';
         result.pass = calls === expected;
         result.message = result.pass
           ? 'Expected spy ' +
@@ -6767,7 +6259,7 @@ getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) {
 };
 
 getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
-  var getErrorMsg = j$.formatErrorMsg(
+  const getErrorMsg = j$.formatErrorMsg(
     '<toHaveBeenCalledWith>',
     'expect(<spyObj>).toHaveBeenCalledWith(...arguments)'
   );
@@ -6784,7 +6276,7 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
   function toHaveBeenCalledWith(matchersUtil) {
     return {
       compare: function() {
-        var args = Array.prototype.slice.call(arguments, 0),
+        const args = Array.prototype.slice.call(arguments, 0),
           actual = args[0],
           expectedArgs = args.slice(1),
           result = { pass: false };
@@ -6825,16 +6317,16 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
           };
         } else {
           result.message = function() {
-            var prettyPrintedCalls = actual.calls
+            const prettyPrintedCalls = actual.calls
               .allArgs()
               .map(function(argsForCall) {
                 return '  ' + matchersUtil.pp(argsForCall);
               });
 
-            var diffs = actual.calls
+            const diffs = actual.calls
               .allArgs()
               .map(function(argsForCall, callIx) {
-                var diffBuilder = new j$.DiffBuilder();
+                const diffBuilder = new j$.DiffBuilder();
                 matchersUtil.equals(argsForCall, expectedArgs, diffBuilder);
                 return (
                   'Call ' +
@@ -6917,7 +6409,7 @@ getJasmineRequireObj().toHaveSize = function(j$) {
   function toHaveSize() {
     return {
       compare: function(actual, expected) {
-        var result = {
+        const result = {
           pass: false
         };
 
@@ -6942,7 +6434,7 @@ getJasmineRequireObj().toHaveSize = function(j$) {
     };
   }
 
-  var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
+  const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
   function isLength(value) {
     return (
       typeof value == 'number' &&
@@ -6956,7 +6448,7 @@ getJasmineRequireObj().toHaveSize = function(j$) {
 };
 
 getJasmineRequireObj().toHaveSpyInteractions = function(j$) {
-  var getErrorMsg = j$.formatErrorMsg(
+  const getErrorMsg = j$.formatErrorMsg(
     '<toHaveSpyInteractions>',
     'expect(<spyObj>).toHaveSpyInteractions()'
   );
@@ -6973,7 +6465,7 @@ getJasmineRequireObj().toHaveSpyInteractions = function(j$) {
   function toHaveSpyInteractions(matchersUtil) {
     return {
       compare: function(actual) {
-        var result = {};
+        const result = {};
 
         if (!j$.isObject_(actual)) {
           throw new Error(
@@ -7032,7 +6524,7 @@ getJasmineRequireObj().toHaveSpyInteractions = function(j$) {
 };
 
 getJasmineRequireObj().toMatch = function(j$) {
-  var getErrorMsg = j$.formatErrorMsg(
+  const getErrorMsg = j$.formatErrorMsg(
     '<toMatch>',
     'expect(<expectation>).toMatch(<string> || <regexp>)'
   );
@@ -7054,7 +6546,7 @@ getJasmineRequireObj().toMatch = function(j$) {
           throw new Error(getErrorMsg('Expected is not a String or a RegExp'));
         }
 
-        var regexp = new RegExp(expected);
+        const regexp = new RegExp(expected);
 
         return {
           pass: regexp.test(actual)
@@ -7067,7 +6559,7 @@ getJasmineRequireObj().toMatch = function(j$) {
 };
 
 getJasmineRequireObj().toThrow = function(j$) {
-  var getErrorMsg = j$.formatErrorMsg(
+  const getErrorMsg = j$.formatErrorMsg(
     '<toThrow>',
     'expect(function() {<expectation>}).toThrow()'
   );
@@ -7085,9 +6577,9 @@ getJasmineRequireObj().toThrow = function(j$) {
   function toThrow(matchersUtil) {
     return {
       compare: function(actual, expected) {
-        var result = { pass: false },
-          threw = false,
-          thrown;
+        const result = { pass: false };
+        let threw = false;
+        let thrown;
 
         if (typeof actual != 'function') {
           throw new Error(getErrorMsg('Actual is not a Function'));
@@ -7148,7 +6640,7 @@ getJasmineRequireObj().toThrow = function(j$) {
 };
 
 getJasmineRequireObj().toThrowError = function(j$) {
-  var getErrorMsg = j$.formatErrorMsg(
+  const getErrorMsg = j$.formatErrorMsg(
     '<toThrowError>',
     'expect(function() {<expectation>}).toThrowError(<ErrorConstructor>, <message>)'
   );
@@ -7170,13 +6662,14 @@ getJasmineRequireObj().toThrowError = function(j$) {
   function toThrowError(matchersUtil) {
     return {
       compare: function(actual) {
-        var errorMatcher = getMatcher.apply(null, arguments),
-          thrown;
+        const errorMatcher = getMatcher.apply(null, arguments);
 
         if (typeof actual != 'function') {
           throw new Error(getErrorMsg('Actual is not a Function'));
         }
 
+        let thrown;
+
         try {
           actual();
           return fail('Expected function to throw an Error.');
@@ -7199,7 +6692,7 @@ getJasmineRequireObj().toThrowError = function(j$) {
     };
 
     function getMatcher() {
-      var expected, errorType;
+      let expected, errorType;
 
       if (arguments[2]) {
         errorType = arguments[1];
@@ -7255,15 +6748,15 @@ getJasmineRequireObj().toThrowError = function(j$) {
         }
       }
 
-      var errorTypeDescription = errorType
+      const errorTypeDescription = errorType
         ? j$.fnNameFor(errorType)
         : 'an exception';
 
       function thrownDescription(thrown) {
-        var thrownName = errorType
-            ? j$.fnNameFor(thrown.constructor)
-            : 'an exception',
-          thrownMessage = '';
+        const thrownName = errorType
+          ? j$.fnNameFor(thrown.constructor)
+          : 'an exception';
+        let thrownMessage = '';
 
         if (expected) {
           thrownMessage = ' with message ' + matchersUtil.pp(thrown.message);
@@ -7325,7 +6818,7 @@ getJasmineRequireObj().toThrowError = function(j$) {
         return false;
       }
 
-      var Surrogate = function() {};
+      const Surrogate = function() {};
       Surrogate.prototype = type.prototype;
       return j$.isError_(new Surrogate());
     }
@@ -7349,7 +6842,7 @@ getJasmineRequireObj().toThrowError = function(j$) {
 };
 
 getJasmineRequireObj().toThrowMatching = function(j$) {
-  var usageError = j$.formatErrorMsg(
+  const usageError = j$.formatErrorMsg(
     '<toThrowMatching>',
     'expect(function() {<expectation>}).toThrowMatching(<Predicate>)'
   );
@@ -7366,8 +6859,6 @@ getJasmineRequireObj().toThrowMatching = function(j$) {
   function toThrowMatching(matchersUtil) {
     return {
       compare: function(actual, predicate) {
-        var thrown;
-
         if (typeof actual !== 'function') {
           throw new Error(usageError('Actual is not a Function'));
         }
@@ -7376,6 +6867,8 @@ getJasmineRequireObj().toThrowMatching = function(j$) {
           throw new Error(usageError('Predicate is not a Function'));
         }
 
+        let thrown;
+
         try {
           actual();
           return fail('Expected function to throw an exception.');
@@ -7432,19 +6925,18 @@ getJasmineRequireObj().toThrowMatching = function(j$) {
 
 getJasmineRequireObj().MockDate = function(j$) {
   function MockDate(global) {
-    var self = this;
-    var currentTime = 0;
+    let currentTime = 0;
 
     if (!global || !global.Date) {
-      self.install = function() {};
-      self.tick = function() {};
-      self.uninstall = function() {};
-      return self;
+      this.install = function() {};
+      this.tick = function() {};
+      this.uninstall = function() {};
+      return this;
     }
 
-    var GlobalDate = global.Date;
+    const GlobalDate = global.Date;
 
-    self.install = function(mockDate) {
+    this.install = function(mockDate) {
       if (mockDate instanceof GlobalDate) {
         currentTime = mockDate.getTime();
       } else {
@@ -7461,19 +6953,19 @@ getJasmineRequireObj().MockDate = function(j$) {
       global.Date = FakeDate;
     };
 
-    self.tick = function(millis) {
+    this.tick = function(millis) {
       millis = millis || 0;
       currentTime = currentTime + millis;
     };
 
-    self.uninstall = function() {
+    this.uninstall = function() {
       currentTime = 0;
       global.Date = GlobalDate;
     };
 
     createDateProperties();
 
-    return self;
+    return this;
 
     function FakeDate() {
       switch (arguments.length) {
@@ -7614,7 +7106,7 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
           } catch (e) {
             this.emitScalar('has-invalid-toString-method');
           }
-        } else if (j$.util.arrayContains(this.seen, value)) {
+        } else if (this.seen.includes(value)) {
           this.emitScalar(
             '<circular reference: ' +
               (j$.isArray_(value) ? 'Array' : 'Object') +
@@ -7912,14 +7404,14 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
 };
 
 getJasmineRequireObj().QueueRunner = function(j$) {
-  var nextid = 1;
+  let nextid = 1;
 
   function StopExecutionError() {}
   StopExecutionError.prototype = new Error();
   j$.StopExecutionError = StopExecutionError;
 
   function once(fn, onTwice) {
-    var called = false;
+    let called = false;
     return function(arg) {
       if (called) {
         if (onTwice) {
@@ -7979,12 +7471,11 @@ getJasmineRequireObj().QueueRunner = function(j$) {
   }
 
   QueueRunner.prototype.execute = function() {
-    var self = this;
-    this.handleFinalError = function(message, source, lineno, colno, error) {
+    this.handleFinalError = (message, source, lineno, colno, error) => {
       // Older browsers would send the error as the first parameter. HTML5
       // specifies the the five parameters above. The error instance should
       // be preffered, otherwise the call stack would get lost.
-      self.onException(error || message);
+      this.onException(error || message);
     };
     this.globalErrors.pushListener(this.handleFinalError);
     this.run(0);
@@ -8005,71 +7496,77 @@ getJasmineRequireObj().QueueRunner = function(j$) {
   };
 
   QueueRunner.prototype.attempt = function attempt(iterativeIndex) {
-    var self = this,
-      completedSynchronously = true,
-      handleError = function handleError(error) {
-        // TODO probably shouldn't next() right away here.
-        // That makes debugging async failures much more confusing.
-        onException(error);
-      },
-      cleanup = once(function cleanup() {
-        if (timeoutId !== void 0) {
-          self.clearTimeout(timeoutId);
-        }
-        self.globalErrors.popListener(handleError);
-      }),
-      next = once(
-        function next(err) {
-          cleanup();
+    let timeoutId;
+    let timedOut;
+    let completedSynchronously = true;
 
-          if (typeof err !== 'undefined') {
-            if (!(err instanceof StopExecutionError) && !err.jasmineMessage) {
-              self.fail(err);
-            }
-            self.recordError_(iterativeIndex);
-          }
+    const onException = e => {
+      this.onException(e);
+      this.recordError_(iterativeIndex);
+    };
 
-          function runNext() {
-            self.run(self.nextFnIx_(iterativeIndex));
-          }
+    function handleError(error) {
+      // TODO probably shouldn't next() right away here.
+      // That makes debugging async failures much more confusing.
+      onException(error);
+    }
+    const cleanup = once(() => {
+      if (timeoutId !== void 0) {
+        this.clearTimeout(timeoutId);
+      }
+      this.globalErrors.popListener(handleError);
+    });
+    const next = once(
+      err => {
+        cleanup();
 
-          if (completedSynchronously) {
-            self.setTimeout(runNext);
-          } else {
-            runNext();
+        if (typeof err !== 'undefined') {
+          if (!(err instanceof StopExecutionError) && !err.jasmineMessage) {
+            this.fail(err);
           }
-        },
-        function() {
-          try {
-            if (!timedOut) {
-              self.onMultipleDone();
-            }
-          } catch (error) {
-            // Any error we catch here is probably due to a bug in Jasmine,
-            // and it's not likely to end up anywhere useful if we let it
-            // propagate. Log it so it can at least show up when debugging.
-            console.error(error);
+          this.recordError_(iterativeIndex);
+        }
+
+        const runNext = () => {
+          this.run(this.nextFnIx_(iterativeIndex));
+        };
+
+        if (completedSynchronously) {
+          this.setTimeout(runNext);
+        } else {
+          runNext();
+        }
+      },
+      () => {
+        try {
+          if (!timedOut) {
+            this.onMultipleDone();
           }
+        } catch (error) {
+          // Any error we catch here is probably due to a bug in Jasmine,
+          // and it's not likely to end up anywhere useful if we let it
+          // propagate. Log it so it can at least show up when debugging.
+          console.error(error);
         }
-      ),
-      timedOut = false,
-      queueableFn = self.queueableFns[iterativeIndex],
-      timeoutId,
-      maybeThenable;
+      }
+    );
+    timedOut = false;
+    const queueableFn = this.queueableFns[iterativeIndex];
 
     next.fail = function nextFail() {
-      self.fail.apply(null, arguments);
-      self.recordError_(iterativeIndex);
+      this.fail.apply(null, arguments);
+      this.recordError_(iterativeIndex);
       next();
-    };
+    }.bind(this);
 
-    self.globalErrors.pushListener(handleError);
+    this.globalErrors.pushListener(handleError);
 
     if (queueableFn.timeout !== undefined) {
-      var timeoutInterval = queueableFn.timeout || j$.DEFAULT_TIMEOUT_INTERVAL;
-      timeoutId = self.setTimeout(function() {
+      const timeoutInterval =
+        queueableFn.timeout || j$.DEFAULT_TIMEOUT_INTERVAL;
+      timeoutId = this.setTimeout(function() {
         timedOut = true;
-        var error = new Error(
+        const error = new Error(
           'Timeout - Async function did not complete within ' +
             timeoutInterval +
             'ms ' +
@@ -8086,8 +7583,10 @@ getJasmineRequireObj().QueueRunner = function(j$) {
     }
 
     try {
+      let maybeThenable;
+
       if (queueableFn.fn.length === 0) {
-        maybeThenable = queueableFn.fn.call(self.userContext);
+        maybeThenable = queueableFn.fn.call(this.userContext);
 
         if (maybeThenable && j$.isFunction_(maybeThenable.then)) {
           maybeThenable.then(
@@ -8098,24 +7597,19 @@ getJasmineRequireObj().QueueRunner = function(j$) {
           return { completedSynchronously: false };
         }
       } else {
-        maybeThenable = queueableFn.fn.call(self.userContext, next);
+        maybeThenable = queueableFn.fn.call(this.userContext, next);
         this.diagnoseConflictingAsync_(queueableFn.fn, maybeThenable);
         completedSynchronously = false;
         return { completedSynchronously: false };
       }
     } catch (e) {
       onException(e);
-      self.recordError_(iterativeIndex);
+      this.recordError_(iterativeIndex);
     }
 
     cleanup();
     return { completedSynchronously: true };
 
-    function onException(e) {
-      self.onException(e);
-      self.recordError_(iterativeIndex);
-    }
-
     function onPromiseRejection(e) {
       onException(e);
       next();
@@ -8123,29 +7617,27 @@ getJasmineRequireObj().QueueRunner = function(j$) {
   };
 
   QueueRunner.prototype.run = function(recursiveIndex) {
-    var length = this.queueableFns.length,
-      self = this,
-      iterativeIndex;
+    const length = this.queueableFns.length;
 
     for (
-      iterativeIndex = recursiveIndex;
+      let iterativeIndex = recursiveIndex;
       iterativeIndex < length;
       iterativeIndex = this.nextFnIx_(iterativeIndex)
     ) {
-      var result = this.attempt(iterativeIndex);
+      const result = this.attempt(iterativeIndex);
 
       if (!result.completedSynchronously) {
         return;
       }
     }
 
-    this.clearStack(function() {
-      self.globalErrors.popListener(self.handleFinalError);
+    this.clearStack(() => {
+      this.globalErrors.popListener(this.handleFinalError);
 
-      if (self.errored_) {
-        self.onComplete(new StopExecutionError());
+      if (this.errored_) {
+        this.onComplete(new StopExecutionError());
       } else {
-        self.onComplete();
+        this.onComplete();
       }
     });
   };
@@ -8203,10 +7695,9 @@ getJasmineRequireObj().QueueRunner = function(j$) {
 
 getJasmineRequireObj().ReportDispatcher = function(j$) {
   function ReportDispatcher(methods, queueRunnerFactory, onLateError) {
-    var dispatchedMethods = methods || [];
+    const dispatchedMethods = methods || [];
 
-    for (var i = 0; i < dispatchedMethods.length; i++) {
-      var method = dispatchedMethods[i];
+    for (const method of dispatchedMethods) {
       this[method] = (function(m) {
         return function() {
           dispatch(m, arguments);
@@ -8214,8 +7705,8 @@ getJasmineRequireObj().ReportDispatcher = function(j$) {
       })(method);
     }
 
-    var reporters = [];
-    var fallbackReporter = null;
+    let reporters = [];
+    let fallbackReporter = null;
 
     this.addReporter = function(reporter) {
       reporters.push(reporter);
@@ -8235,11 +7726,10 @@ getJasmineRequireObj().ReportDispatcher = function(j$) {
       if (reporters.length === 0 && fallbackReporter !== null) {
         reporters.push(fallbackReporter);
       }
-      var onComplete = args[args.length - 1];
-      args = j$.util.argsToArray(args).splice(0, args.length - 1);
-      var fns = [];
-      for (var i = 0; i < reporters.length; i++) {
-        var reporter = reporters[i];
+      const onComplete = args[args.length - 1];
+      args = Array.from(args).splice(0, args.length - 1);
+      const fns = [];
+      for (const reporter of reporters) {
         addFn(fns, reporter, method, args);
       }
 
@@ -8259,12 +7749,12 @@ getJasmineRequireObj().ReportDispatcher = function(j$) {
     }
 
     function addFn(fns, reporter, method, args) {
-      var fn = reporter[method];
+      const fn = reporter[method];
       if (!fn) {
         return;
       }
 
-      var thisArgs = j$.util.cloneArgs(args);
+      const thisArgs = j$.util.cloneArgs(args);
       if (fn.length <= 1) {
         fns.push({
           fn: function() {
@@ -8285,7 +7775,7 @@ getJasmineRequireObj().ReportDispatcher = function(j$) {
 };
 
 getJasmineRequireObj().interface = function(jasmine, env) {
-  var jasmineInterface = {
+  const jasmineInterface = {
     /**
      * Callback passed to parts of the Jasmine base interface.
      *
@@ -8715,6 +8205,403 @@ getJasmineRequireObj().interface = function(jasmine, env) {
   return jasmineInterface;
 };
 
+getJasmineRequireObj().RunableResources = function(j$) {
+  class RunableResources {
+    constructor(options) {
+      this.byRunableId_ = {};
+      this.getCurrentRunableId_ = options.getCurrentRunableId;
+      this.globalErrors_ = options.globalErrors;
+
+      this.spyFactory = new j$.SpyFactory(
+        () => {
+          if (this.getCurrentRunableId_()) {
+            return this.customSpyStrategies();
+          } else {
+            return {};
+          }
+        },
+        () => this.defaultSpyStrategy(),
+        () => this.makeMatchersUtil()
+      );
+
+      this.spyRegistry = new j$.SpyRegistry({
+        currentSpies: () => this.spies(),
+        createSpy: (name, originalFn) =>
+          this.spyFactory.createSpy(name, originalFn)
+      });
+    }
+
+    initForRunable(runableId, parentId) {
+      const newRes = (this.byRunableId_[runableId] = {
+        customEqualityTesters: [],
+        customMatchers: {},
+        customAsyncMatchers: {},
+        customSpyStrategies: {},
+        customObjectFormatters: [],
+        defaultSpyStrategy: undefined,
+        spies: []
+      });
+
+      const parentRes = this.byRunableId_[parentId];
+
+      if (parentRes) {
+        newRes.defaultSpyStrategy = parentRes.defaultSpyStrategy;
+        const toClone = [
+          'customEqualityTesters',
+          'customMatchers',
+          'customAsyncMatchers',
+          'customObjectFormatters',
+          'customSpyStrategies'
+        ];
+
+        for (const k of toClone) {
+          newRes[k] = j$.util.clone(parentRes[k]);
+        }
+      }
+    }
+
+    clearForRunable(runableId) {
+      this.globalErrors_.removeOverrideListener();
+      this.spyRegistry.clearSpies();
+      delete this.byRunableId_[runableId];
+    }
+
+    spies() {
+      return this.forCurrentRunable_(
+        'Spies must be created in a before function or a spec'
+      ).spies;
+    }
+
+    defaultSpyStrategy() {
+      if (!this.getCurrentRunableId_()) {
+        return undefined;
+      }
+
+      return this.byRunableId_[this.getCurrentRunableId_()].defaultSpyStrategy;
+    }
+
+    setDefaultSpyStrategy(fn) {
+      this.forCurrentRunable_(
+        'Default spy strategy must be set in a before function or a spec'
+      ).defaultSpyStrategy = fn;
+    }
+
+    customSpyStrategies() {
+      return this.forCurrentRunable_(
+        'Custom spy strategies must be added in a before function or a spec'
+      ).customSpyStrategies;
+    }
+
+    customEqualityTesters() {
+      return this.forCurrentRunable_(
+        'Custom Equalities must be added in a before function or a spec'
+      ).customEqualityTesters;
+    }
+
+    customMatchers() {
+      return this.forCurrentRunable_(
+        'Matchers must be added in a before function or a spec'
+      ).customMatchers;
+    }
+
+    addCustomMatchers(matchersToAdd) {
+      const matchers = this.customMatchers();
+
+      for (const name in matchersToAdd) {
+        matchers[name] = matchersToAdd[name];
+      }
+    }
+
+    customAsyncMatchers() {
+      return this.forCurrentRunable_(
+        'Async Matchers must be added in a before function or a spec'
+      ).customAsyncMatchers;
+    }
+
+    addCustomAsyncMatchers(matchersToAdd) {
+      const matchers = this.customAsyncMatchers();
+
+      for (const name in matchersToAdd) {
+        matchers[name] = matchersToAdd[name];
+      }
+    }
+
+    customObjectFormatters() {
+      return this.forCurrentRunable_(
+        'Custom object formatters must be added in a before function or a spec'
+      ).customObjectFormatters;
+    }
+
+    makePrettyPrinter() {
+      return j$.makePrettyPrinter(this.customObjectFormatters());
+    }
+
+    makeMatchersUtil() {
+      if (this.getCurrentRunableId_()) {
+        return new j$.MatchersUtil({
+          customTesters: this.customEqualityTesters(),
+          pp: this.makePrettyPrinter()
+        });
+      } else {
+        return new j$.MatchersUtil({ pp: j$.basicPrettyPrinter_ });
+      }
+    }
+
+    forCurrentRunable_(errorMsg) {
+      const resources = this.byRunableId_[this.getCurrentRunableId_()];
+
+      if (!resources && errorMsg) {
+        throw new Error(errorMsg);
+      }
+
+      return resources;
+    }
+  }
+
+  return RunableResources;
+};
+
+getJasmineRequireObj().Runner = function(j$) {
+  class Runner {
+    constructor(options) {
+      this.topSuite_ = options.topSuite;
+      this.totalSpecsDefined_ = options.totalSpecsDefined;
+      this.focusedRunables_ = options.focusedRunables;
+      this.runableResources_ = options.runableResources;
+      this.queueRunnerFactory_ = options.queueRunnerFactory;
+      this.reporter_ = options.reporter;
+      this.getConfig_ = options.getConfig;
+      this.reportSpecDone_ = options.reportSpecDone;
+      this.hasFailures = false;
+      this.executedBefore_ = false;
+
+      this.currentlyExecutingSuites_ = [];
+      this.currentSpec = null;
+    }
+
+    currentRunable() {
+      return this.currentSpec || this.currentSuite();
+    }
+
+    currentSuite() {
+      return this.currentlyExecutingSuites_[
+        this.currentlyExecutingSuites_.length - 1
+      ];
+    }
+
+    // Although execute returns a promise, it isn't async for backwards
+    // compatibility: The "Invalid order" exception needs to be propagated
+    // synchronously from Env#execute.
+    // TODO: make this and Env#execute async in the next major release
+    execute(runablesToRun) {
+      if (this.executedBefore_) {
+        this.topSuite_.reset();
+      }
+      this.executedBefore_ = true;
+
+      this.hasFailures = false;
+      const totalSpecsDefined = this.totalSpecsDefined_();
+      const focusedRunables = this.focusedRunables_();
+      const config = this.getConfig_();
+
+      if (!runablesToRun) {
+        if (focusedRunables.length) {
+          runablesToRun = focusedRunables;
+        } else {
+          runablesToRun = [this.topSuite_.id];
+        }
+      }
+
+      const order = new j$.Order({
+        random: config.random,
+        seed: config.seed
+      });
+
+      const processor = new j$.TreeProcessor({
+        tree: this.topSuite_,
+        runnableIds: runablesToRun,
+        queueRunnerFactory: options => {
+          if (options.isLeaf) {
+            // A spec
+            options.SkipPolicy = j$.CompleteOnFirstErrorSkipPolicy;
+          } else {
+            // A suite
+            if (config.stopOnSpecFailure) {
+              options.SkipPolicy = j$.CompleteOnFirstErrorSkipPolicy;
+            } else {
+              options.SkipPolicy = j$.SkipAfterBeforeAllErrorPolicy;
+            }
+          }
+
+          return this.queueRunnerFactory_(options);
+        },
+        failSpecWithNoExpectations: config.failSpecWithNoExpectations,
+        nodeStart: (suite, next) => {
+          this.currentlyExecutingSuites_.push(suite);
+          this.runableResources_.initForRunable(suite.id, suite.parentSuite.id);
+          this.reporter_.suiteStarted(suite.result, next);
+          suite.startTimer();
+        },
+        nodeComplete: (suite, result, next) => {
+          if (suite !== this.currentSuite()) {
+            throw new Error('Tried to complete the wrong suite');
+          }
+
+          this.runableResources_.clearForRunable(suite.id);
+          this.currentlyExecutingSuites_.pop();
+
+          if (result.status === 'failed') {
+            this.hasFailures = true;
+          }
+          suite.endTimer();
+
+          if (suite.hadBeforeAllFailure) {
+            this.reportChildrenOfBeforeAllFailure_(suite).then(() => {
+              this.reportSuiteDone_(suite, result, next);
+            });
+          } else {
+            this.reportSuiteDone_(suite, result, next);
+          }
+        },
+        orderChildren: function(node) {
+          return order.sort(node.children);
+        },
+        excludeNode: function(spec) {
+          return !config.specFilter(spec);
+        }
+      });
+
+      if (!processor.processTree().valid) {
+        throw new Error(
+          'Invalid order: would cause a beforeAll or afterAll to be run multiple times'
+        );
+      }
+
+      this.runableResources_.initForRunable(this.topSuite_.id);
+      const jasmineTimer = new j$.Timer();
+      jasmineTimer.start();
+
+      return new Promise(resolve => {
+        /**
+         * Information passed to the {@link Reporter#jasmineStarted} event.
+         * @typedef JasmineStartedInfo
+         * @property {Int} totalSpecsDefined - The total number of specs defined in this suite.
+         * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
+         * @since 2.0.0
+         */
+        this.reporter_.jasmineStarted(
+          {
+            totalSpecsDefined,
+            order: order
+          },
+          () => {
+            this.currentlyExecutingSuites_.push(this.topSuite_);
+
+            processor.execute(() => {
+              (async () => {
+                if (this.topSuite_.hadBeforeAllFailure) {
+                  await this.reportChildrenOfBeforeAllFailure_(this.topSuite_);
+                }
+
+                this.runableResources_.clearForRunable(this.topSuite_.id);
+                this.currentlyExecutingSuites_.pop();
+                let overallStatus, incompleteReason;
+
+                if (
+                  this.hasFailures ||
+                  this.topSuite_.result.failedExpectations.length > 0
+                ) {
+                  overallStatus = 'failed';
+                } else if (focusedRunables.length > 0) {
+                  overallStatus = 'incomplete';
+                  incompleteReason = 'fit() or fdescribe() was found';
+                } else if (totalSpecsDefined === 0) {
+                  overallStatus = 'incomplete';
+                  incompleteReason = 'No specs found';
+                } else {
+                  overallStatus = 'passed';
+                }
+
+                /**
+                 * Information passed to the {@link Reporter#jasmineDone} event.
+                 * @typedef JasmineDoneInfo
+                 * @property {OverallStatus} overallStatus - The overall result of the suite: 'passed', 'failed', or 'incomplete'.
+                 * @property {Int} totalTime - The total time (in ms) that it took to execute the suite
+                 * @property {IncompleteReason} incompleteReason - Explanation of why the suite was incomplete.
+                 * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
+                 * @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level.
+                 * @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level.
+                 * @since 2.4.0
+                 */
+                const jasmineDoneInfo = {
+                  overallStatus: overallStatus,
+                  totalTime: jasmineTimer.elapsed(),
+                  incompleteReason: incompleteReason,
+                  order: order,
+                  failedExpectations: this.topSuite_.result.failedExpectations,
+                  deprecationWarnings: this.topSuite_.result.deprecationWarnings
+                };
+                this.topSuite_.reportedDone = true;
+                this.reporter_.jasmineDone(jasmineDoneInfo, function() {
+                  resolve(jasmineDoneInfo);
+                });
+              })();
+            });
+          }
+        );
+      });
+    }
+
+    reportSuiteDone_(suite, result, next) {
+      suite.reportedDone = true;
+      this.reporter_.suiteDone(result, next);
+    }
+
+    async reportChildrenOfBeforeAllFailure_(suite) {
+      for (const child of suite.children) {
+        if (child instanceof j$.Suite) {
+          await new Promise(resolve => {
+            this.reporter_.suiteStarted(child.result, resolve);
+          });
+          await this.reportChildrenOfBeforeAllFailure_(child);
+
+          // Marking the suite passed is consistent with how suites that
+          // contain failed specs but no suite-level failures are reported.
+          child.result.status = 'passed';
+
+          await new Promise(resolve => {
+            this.reporter_.suiteDone(child.result, resolve);
+          });
+        } else {
+          /* a spec */
+          await new Promise(resolve => {
+            this.reporter_.specStarted(child.result, resolve);
+          });
+
+          child.addExpectationResult(
+            false,
+            {
+              passed: false,
+              message:
+                'Not run because a beforeAll function failed. The ' +
+                'beforeAll failure will be reported on the suite that ' +
+                'caused it.'
+            },
+            true
+          );
+          child.result.status = 'failed';
+
+          await new Promise(resolve => {
+            this.reportSpecDone_(child, child.result, resolve);
+          });
+        }
+      }
+    }
+  }
+
+  return Runner;
+};
+
 getJasmineRequireObj().SkipAfterBeforeAllErrorPolicy = function(j$) {
   function SkipAfterBeforeAllErrorPolicy(queueableFns) {
     this.queueableFns_ = queueableFns;
@@ -8755,8 +8642,8 @@ getJasmineRequireObj().SkipAfterBeforeAllErrorPolicy = function(j$) {
 };
 
 getJasmineRequireObj().Spy = function(j$) {
-  var nextOrder = (function() {
-    var order = 0;
+  const nextOrder = (function() {
+    let order = 0;
 
     return function() {
       return order++;
@@ -8771,9 +8658,29 @@ getJasmineRequireObj().Spy = function(j$) {
    * @hideconstructor
    */
   function Spy(name, matchersUtil, optionals) {
+    const spy = function(context, args, invokeNew) {
+      /**
+       * @name Spy.callData
+       * @property {object} object - `this` context for the invocation.
+       * @property {number} invocationOrder - Order of the invocation.
+       * @property {Array} args - The arguments passed for this invocation.
+       * @property returnValue - The value that was returned from this invocation.
+       */
+      const callData = {
+        object: context,
+        invocationOrder: nextOrder(),
+        args: Array.prototype.slice.apply(args)
+      };
+
+      callTracker.track(callData);
+      const returnValue = strategyDispatcher.exec(context, args, invokeNew);
+      callData.returnValue = returnValue;
+
+      return returnValue;
+    };
     const { originalFn, customStrategies, defaultStrategyFn } = optionals || {};
 
-    var numArgs = typeof originalFn === 'function' ? originalFn.length : 0,
+    const numArgs = typeof originalFn === 'function' ? originalFn.length : 0,
       wrapper = makeFunc(numArgs, function(context, args, invokeNew) {
         return spy(context, args, invokeNew);
       }),
@@ -8788,27 +8695,7 @@ getJasmineRequireObj().Spy = function(j$) {
         },
         matchersUtil
       ),
-      callTracker = new j$.CallTracker(),
-      spy = function(context, args, invokeNew) {
-        /**
-         * @name Spy.callData
-         * @property {object} object - `this` context for the invocation.
-         * @property {number} invocationOrder - Order of the invocation.
-         * @property {Array} args - The arguments passed for this invocation.
-         * @property returnValue - The value that was returned from this invocation.
-         */
-        var callData = {
-          object: context,
-          invocationOrder: nextOrder(),
-          args: Array.prototype.slice.apply(args)
-        };
-
-        callTracker.track(callData);
-        var returnValue = strategyDispatcher.exec(context, args, invokeNew);
-        callData.returnValue = returnValue;
-
-        return returnValue;
-      };
+      callTracker = new j$.CallTracker();
 
     function makeFunc(length, fn) {
       switch (length) {
@@ -8855,7 +8742,7 @@ getJasmineRequireObj().Spy = function(j$) {
       }
     }
 
-    for (var prop in originalFn) {
+    for (const prop in originalFn) {
       if (prop === 'and' || prop === 'calls') {
         throw new Error(
           "Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon"
@@ -8900,15 +8787,15 @@ getJasmineRequireObj().Spy = function(j$) {
   }
 
   function SpyStrategyDispatcher(strategyArgs, matchersUtil) {
-    var baseStrategy = new j$.SpyStrategy(strategyArgs);
-    var argsStrategies = new StrategyDict(function() {
+    const baseStrategy = new j$.SpyStrategy(strategyArgs);
+    const argsStrategies = new StrategyDict(function() {
       return new j$.SpyStrategy(strategyArgs);
     }, matchersUtil);
 
     this.and = baseStrategy;
 
     this.exec = function(spy, args, invokeNew) {
-      var strategy = argsStrategies.get(args);
+      let strategy = argsStrategies.get(args);
 
       if (!strategy) {
         if (argsStrategies.any() && !baseStrategy.isConfigured()) {
@@ -8943,7 +8830,7 @@ getJasmineRequireObj().Spy = function(j$) {
   };
 
   StrategyDict.prototype.getOrCreate = function(args) {
-    var strategy = this.get(args);
+    let strategy = this.get(args);
 
     if (!strategy) {
       strategy = this.strategyFactory();
@@ -8957,9 +8844,7 @@ getJasmineRequireObj().Spy = function(j$) {
   };
 
   StrategyDict.prototype.get = function(args) {
-    var i;
-
-    for (i = 0; i < this.strategies.length; i++) {
+    for (let i = 0; i < this.strategies.length; i++) {
       if (this.matchersUtil.equals(args, this.strategies[i].args)) {
         return this.strategies[i].strategy;
       }
@@ -8975,9 +8860,12 @@ getJasmineRequireObj().SpyFactory = function(j$) {
     getDefaultStrategyFn,
     getMatchersUtil
   ) {
-    var self = this;
-
     this.createSpy = function(name, originalFn) {
+      if (j$.isFunction_(name) && originalFn === undefined) {
+        originalFn = name;
+        name = originalFn.name;
+      }
+
       return j$.Spy(name, getMatchersUtil(), {
         originalFn,
         customStrategies: getCustomStrategies(),
@@ -8986,7 +8874,7 @@ getJasmineRequireObj().SpyFactory = function(j$) {
     };
 
     this.createSpyObj = function(baseName, methodNames, propertyNames) {
-      var baseNameIsCollection =
+      const baseNameIsCollection =
         j$.isObject_(baseName) || j$.isArray_(baseName);
 
       if (baseNameIsCollection) {
@@ -8995,25 +8883,24 @@ getJasmineRequireObj().SpyFactory = function(j$) {
         baseName = 'unknown';
       }
 
-      var obj = {};
-      var spy, descriptor;
+      const obj = {};
 
-      var methods = normalizeKeyValues(methodNames);
-      for (var i = 0; i < methods.length; i++) {
-        spy = obj[methods[i][0]] = self.createSpy(
+      const methods = normalizeKeyValues(methodNames);
+      for (let i = 0; i < methods.length; i++) {
+        const spy = (obj[methods[i][0]] = this.createSpy(
           baseName + '.' + methods[i][0]
-        );
+        ));
         if (methods[i].length > 1) {
           spy.and.returnValue(methods[i][1]);
         }
       }
 
-      var properties = normalizeKeyValues(propertyNames);
-      for (var i = 0; i < properties.length; i++) {
-        descriptor = {
+      const properties = normalizeKeyValues(propertyNames);
+      for (let i = 0; i < properties.length; i++) {
+        const descriptor = {
           enumerable: true,
-          get: self.createSpy(baseName + '.' + properties[i][0] + '.get'),
-          set: self.createSpy(baseName + '.' + properties[i][0] + '.set')
+          get: this.createSpy(baseName + '.' + properties[i][0] + '.get'),
+          set: this.createSpy(baseName + '.' + properties[i][0] + '.set')
         };
         if (properties[i].length > 1) {
           descriptor.get.and.returnValue(properties[i][1]);
@@ -9031,13 +8918,13 @@ getJasmineRequireObj().SpyFactory = function(j$) {
   }
 
   function normalizeKeyValues(object) {
-    var result = [];
+    const result = [];
     if (j$.isArray_(object)) {
-      for (var i = 0; i < object.length; i++) {
+      for (let i = 0; i < object.length; i++) {
         result.push([object[i]]);
       }
     } else if (j$.isObject_(object)) {
-      for (var key in object) {
+      for (const key in object) {
         if (object.hasOwnProperty(key)) {
           result.push([key, object[key]]);
         }
@@ -9050,17 +8937,20 @@ getJasmineRequireObj().SpyFactory = function(j$) {
 };
 
 getJasmineRequireObj().SpyRegistry = function(j$) {
-  var spyOnMsg = j$.formatErrorMsg('<spyOn>', 'spyOn(<object>, <methodName>)');
-  var spyOnPropertyMsg = j$.formatErrorMsg(
+  const spyOnMsg = j$.formatErrorMsg(
+    '<spyOn>',
+    'spyOn(<object>, <methodName>)'
+  );
+  const spyOnPropertyMsg = j$.formatErrorMsg(
     '<spyOnProperty>',
     'spyOnProperty(<object>, <propName>, [accessType])'
   );
 
   function SpyRegistry(options) {
     options = options || {};
-    var global = options.global || j$.getGlobal();
-    var createSpy = options.createSpy;
-    var currentSpies =
+    const global = options.global || j$.getGlobal();
+    const createSpy = options.createSpy;
+    const currentSpies =
       options.currentSpies ||
       function() {
         return [];
@@ -9071,7 +8961,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
     };
 
     this.spyOn = function(obj, methodName) {
-      var getErrorMsg = spyOnMsg;
+      const getErrorMsg = spyOnMsg;
 
       if (j$.util.isUndefined(obj) || obj === null) {
         throw new Error(
@@ -9099,7 +8989,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
         }
       }
 
-      var descriptor = Object.getOwnPropertyDescriptor(obj, methodName);
+      const descriptor = Object.getOwnPropertyDescriptor(obj, methodName);
 
       if (descriptor && !(descriptor.writable || descriptor.set)) {
         throw new Error(
@@ -9107,9 +8997,9 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
         );
       }
 
-      var originalMethod = obj[methodName],
-        spiedMethod = createSpy(methodName, originalMethod),
-        restoreStrategy;
+      const originalMethod = obj[methodName];
+      const spiedMethod = createSpy(methodName, originalMethod);
+      let restoreStrategy;
 
       if (
         Object.prototype.hasOwnProperty.call(obj, methodName) ||
@@ -9136,7 +9026,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
     };
 
     this.spyOnProperty = function(obj, propertyName, accessType) {
-      var getErrorMsg = spyOnPropertyMsg;
+      const getErrorMsg = spyOnPropertyMsg;
 
       accessType = accessType || 'get';
 
@@ -9154,7 +9044,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
         throw new Error(getErrorMsg('No property name supplied'));
       }
 
-      var descriptor = j$.util.getPropertyDescriptor(obj, propertyName);
+      const descriptor = j$.util.getPropertyDescriptor(obj, propertyName);
 
       if (!descriptor) {
         throw new Error(getErrorMsg(propertyName + ' property does not exist'));
@@ -9189,9 +9079,9 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
         }
       }
 
-      var originalDescriptor = j$.util.clone(descriptor),
-        spy = createSpy(propertyName, descriptor[accessType]),
-        restoreStrategy;
+      const originalDescriptor = j$.util.clone(descriptor);
+      const spy = createSpy(propertyName, descriptor[accessType]);
+      let restoreStrategy;
 
       if (Object.prototype.hasOwnProperty.call(obj, propertyName)) {
         restoreStrategy = function() {
@@ -9221,7 +9111,7 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
         );
       }
 
-      var pointer = obj,
+      let pointer = obj,
         propsToSpyOn = [],
         properties,
         propertiesToSkip = [];
@@ -9241,24 +9131,24 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
         pointer = Object.getPrototypeOf(pointer);
       }
 
-      for (var i = 0; i < propsToSpyOn.length; i++) {
-        this.spyOn(obj, propsToSpyOn[i]);
+      for (const prop of propsToSpyOn) {
+        this.spyOn(obj, prop);
       }
 
       return obj;
     };
 
     this.clearSpies = function() {
-      var spies = currentSpies();
-      for (var i = spies.length - 1; i >= 0; i--) {
-        var spyEntry = spies[i];
+      const spies = currentSpies();
+      for (let i = spies.length - 1; i >= 0; i--) {
+        const spyEntry = spies[i];
         spyEntry.restoreObjectToOriginalState();
       }
     };
   }
 
   function getProps(obj, includeNonEnumerable) {
-    var enumerableProperties = Object.keys(obj);
+    const enumerableProperties = Object.keys(obj);
 
     if (!includeNonEnumerable) {
       return enumerableProperties;
@@ -9273,10 +9163,9 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
   }
 
   function getSpyableFunctionProps(obj, propertiesToCheck) {
-    var props = [],
-      prop;
-    for (var i = 0; i < propertiesToCheck.length; i++) {
-      prop = propertiesToCheck[i];
+    const props = [];
+
+    for (const prop of propertiesToCheck) {
       if (
         Object.prototype.hasOwnProperty.call(obj, prop) &&
         isSpyableProp(obj, prop)
@@ -9288,14 +9177,15 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
   }
 
   function isSpyableProp(obj, prop) {
-    var value, descriptor;
+    let value;
     try {
       value = obj[prop];
     } catch (e) {
       return false;
     }
+
     if (value instanceof Function) {
-      descriptor = Object.getOwnPropertyDescriptor(obj, prop);
+      const descriptor = Object.getOwnPropertyDescriptor(obj, prop);
       return (descriptor.writable || descriptor.set) && descriptor.configurable;
     }
     return false;
@@ -9311,8 +9201,6 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
   function SpyStrategy(options) {
     options = options || {};
 
-    var self = this;
-
     /**
      * Get the identifying information for the spy.
      * @name SpyStrategy#identity
@@ -9325,9 +9213,8 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
     this.getSpy = options.getSpy || function() {};
     this.plan = this._defaultPlan = function() {};
 
-    var k,
-      cs = options.customStrategies || {};
-    for (k in cs) {
+    const cs = options.customStrategies || {};
+    for (const k in cs) {
       if (j$.util.has(cs, k) && !this[k]) {
         this[k] = createCustomPlan(cs[k]);
       }
@@ -9341,10 +9228,10 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
      * @param {*} value The value to return.
      */
     this.resolveTo = function(value) {
-      self.plan = function() {
+      this.plan = function() {
         return Promise.resolve(value);
       };
-      return self.getSpy();
+      return this.getSpy();
     };
 
     /**
@@ -9355,16 +9242,16 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
      * @param {*} value The value to return.
      */
     this.rejectWith = function(value) {
-      self.plan = function() {
+      this.plan = function() {
         return Promise.reject(value);
       };
-      return self.getSpy();
+      return this.getSpy();
     };
   }
 
   function createCustomPlan(factory) {
     return function() {
-      var plan = factory.apply(null, arguments);
+      const plan = factory.apply(null, arguments);
 
       if (!j$.isFunction_(plan)) {
         throw new Error('Spy strategy must return a function');
@@ -9382,10 +9269,10 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
    * @function
    */
   SpyStrategy.prototype.exec = function(context, args, invokeNew) {
-    var contextArgs = [context].concat(
+    const contextArgs = [context].concat(
       args ? Array.prototype.slice.call(args) : []
     );
-    var target = this.plan.bind.apply(this.plan, contextArgs);
+    const target = this.plan.bind.apply(this.plan, contextArgs);
 
     return invokeNew ? new target() : target();
   };
@@ -9423,7 +9310,7 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
    * @param {...*} values - Values to be returned on subsequent calls to the spy.
    */
   SpyStrategy.prototype.returnValues = function() {
-    var values = Array.prototype.slice.call(arguments);
+    const values = Array.prototype.slice.call(arguments);
     this.plan = function() {
       return values.shift();
     };
@@ -9438,7 +9325,7 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
    * @param {Error|Object|String} something Thing to throw
    */
   SpyStrategy.prototype.throwError = function(something) {
-    var error = j$.isString_(something) ? new Error(something) : something;
+    const error = j$.isString_(something) ? new Error(something) : something;
     this.plan = function() {
       throw error;
     };
@@ -9488,23 +9375,23 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
 
 getJasmineRequireObj().StackTrace = function(j$) {
   function StackTrace(error) {
-    var lines = error.stack.split('\n').filter(function(line) {
+    let lines = error.stack.split('\n').filter(function(line) {
       return line !== '';
     });
 
-    var extractResult = extractMessage(error.message, lines);
+    const extractResult = extractMessage(error.message, lines);
 
     if (extractResult) {
       this.message = extractResult.message;
       lines = extractResult.remainder;
     }
 
-    var parseResult = tryParseFrames(lines);
+    const parseResult = tryParseFrames(lines);
     this.frames = parseResult.frames;
     this.style = parseResult.style;
   }
 
-  var framePatterns = [
+  const framePatterns = [
     // Node, Chrome, Edge
     // e.g. "   at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)"
     // Note that the "function name" can include a surprisingly large set of
@@ -9534,16 +9421,15 @@ getJasmineRequireObj().StackTrace = function(j$) {
   // regexes should capture the function name (if any) as group 1
   // and the file, line, and column as group 2.
   function tryParseFrames(lines) {
-    var style = null;
-    var frames = lines.map(function(line) {
-      var convertedLine = first(framePatterns, function(pattern) {
-        var overallMatch = line.match(pattern.re),
-          fileLineColMatch;
+    let style = null;
+    const frames = lines.map(function(line) {
+      const convertedLine = first(framePatterns, function(pattern) {
+        const overallMatch = line.match(pattern.re);
         if (!overallMatch) {
           return null;
         }
 
-        fileLineColMatch = overallMatch[pattern.fileLineColIx].match(
+        const fileLineColMatch = overallMatch[pattern.fileLineColIx].match(
           /^(.*):(\d+):\d+$/
         );
         if (!fileLineColMatch) {
@@ -9569,10 +9455,8 @@ getJasmineRequireObj().StackTrace = function(j$) {
   }
 
   function first(items, fn) {
-    var i, result;
-
-    for (i = 0; i < items.length; i++) {
-      result = fn(items[i]);
+    for (const item of items) {
+      const result = fn(item);
 
       if (result) {
         return result;
@@ -9581,7 +9465,7 @@ getJasmineRequireObj().StackTrace = function(j$) {
   }
 
   function extractMessage(message, stackLines) {
-    var len = messagePrefixLength(message, stackLines);
+    const len = messagePrefixLength(message, stackLines);
 
     if (len > 0) {
       return {
@@ -9596,10 +9480,9 @@ getJasmineRequireObj().StackTrace = function(j$) {
       return 0;
     }
 
-    var messageLines = message.split('\n');
-    var i;
+    const messageLines = message.split('\n');
 
-    for (i = 1; i < messageLines.length; i++) {
+    for (let i = 1; i < messageLines.length; i++) {
       if (messageLines[i] !== stackLines[i]) {
         return 0;
       }
@@ -9648,9 +9531,9 @@ getJasmineRequireObj().Suite = function(j$) {
   };
 
   Suite.prototype.getFullName = function() {
-    var fullName = [];
+    const fullName = [];
     for (
-      var parentSuite = this;
+      let parentSuite = this;
       parentSuite;
       parentSuite = parentSuite.parentSuite
     ) {
@@ -9702,8 +9585,8 @@ getJasmineRequireObj().Suite = function(j$) {
   };
 
   function removeFns(queueableFns) {
-    for (var i = 0; i < queueableFns.length; i++) {
-      queueableFns[i].fn = null;
+    for (const qf of queueableFns) {
+      qf.fn = null;
     }
   }
 
@@ -9840,6 +9723,11 @@ getJasmineRequireObj().Suite = function(j$) {
         this.onLateError(expectationResult);
       } else {
         this.result.failedExpectations.push(expectationResult);
+
+        // TODO: refactor so that we don't need to override cached status
+        if (this.result.status) {
+          this.result.status = 'failed';
+        }
       }
 
       if (this.throwOnExpectationFailure) {
@@ -9931,8 +9819,311 @@ getJasmineRequireObj().Suite = function(j$) {
   return Suite;
 };
 
+getJasmineRequireObj().SuiteBuilder = function(j$) {
+  class SuiteBuilder {
+    constructor(options) {
+      this.env_ = options.env;
+      this.expectationFactory_ = options.expectationFactory;
+      this.suiteAsyncExpectationFactory_ = function(actual, suite) {
+        return options.asyncExpectationFactory(actual, suite, 'Suite');
+      };
+      this.specAsyncExpectationFactory_ = function(actual, suite) {
+        return options.asyncExpectationFactory(actual, suite, 'Spec');
+      };
+      this.onLateError_ = options.onLateError;
+      this.specResultCallback_ = options.specResultCallback;
+      this.specStarted_ = options.specStarted;
+
+      this.nextSuiteId_ = 0;
+      this.nextSpecId_ = 0;
+
+      this.topSuite = this.suiteFactory_('Jasmine__TopLevel__Suite');
+      this.currentDeclarationSuite_ = this.topSuite;
+      this.totalSpecsDefined = 0;
+      this.focusedRunables = [];
+    }
+
+    describe(description, definitionFn) {
+      ensureIsFunction(definitionFn, 'describe');
+      const suite = this.suiteFactory_(description);
+      if (definitionFn.length > 0) {
+        throw new Error('describe does not expect any arguments');
+      }
+      if (this.currentDeclarationSuite_.markedExcluding) {
+        suite.exclude();
+      }
+      this.addSpecsToSuite_(suite, definitionFn);
+      if (suite.parentSuite && !suite.children.length) {
+        throw new Error(
+          `describe with no children (describe() or it()): ${suite.getFullName()}`
+        );
+      }
+      return suite;
+    }
+
+    fdescribe(description, definitionFn) {
+      ensureIsFunction(definitionFn, 'fdescribe');
+      const suite = this.suiteFactory_(description);
+      suite.isFocused = true;
+
+      this.focusedRunables.push(suite.id);
+      this.unfocusAncestor_();
+      this.addSpecsToSuite_(suite, definitionFn);
+
+      return suite;
+    }
+
+    xdescribe(description, definitionFn) {
+      ensureIsFunction(definitionFn, 'xdescribe');
+      const suite = this.suiteFactory_(description);
+      suite.exclude();
+      this.addSpecsToSuite_(suite, definitionFn);
+
+      return suite;
+    }
+
+    it(description, fn, timeout) {
+      // it() sometimes doesn't have a fn argument, so only check the type if
+      // it's given.
+      if (arguments.length > 1 && typeof fn !== 'undefined') {
+        ensureIsFunctionOrAsync(fn, 'it');
+      }
+
+      return this.it_(description, fn, timeout);
+    }
+
+    xit(description, fn, timeout) {
+      // xit(), like it(), doesn't always have a fn argument, so only check the
+      // type when needed.
+      if (arguments.length > 1 && typeof fn !== 'undefined') {
+        ensureIsFunctionOrAsync(fn, 'xit');
+      }
+      const spec = this.it_(description, fn, timeout);
+      spec.exclude('Temporarily disabled with xit');
+      return spec;
+    }
+
+    fit(description, fn, timeout) {
+      // Unlike it and xit, the function is required because it doesn't make
+      // sense to focus on nothing.
+      ensureIsFunctionOrAsync(fn, 'fit');
+
+      if (timeout) {
+        j$.util.validateTimeout(timeout);
+      }
+      const spec = this.specFactory_(description, fn, timeout);
+      this.currentDeclarationSuite_.addChild(spec);
+      this.focusedRunables.push(spec.id);
+      this.unfocusAncestor_();
+      return spec;
+    }
+
+    beforeEach(beforeEachFunction, timeout) {
+      ensureIsFunctionOrAsync(beforeEachFunction, 'beforeEach');
+
+      if (timeout) {
+        j$.util.validateTimeout(timeout);
+      }
+
+      this.currentDeclarationSuite_.beforeEach({
+        fn: beforeEachFunction,
+        timeout: timeout || 0
+      });
+    }
+
+    beforeAll(beforeAllFunction, timeout) {
+      ensureIsFunctionOrAsync(beforeAllFunction, 'beforeAll');
+
+      if (timeout) {
+        j$.util.validateTimeout(timeout);
+      }
+
+      this.currentDeclarationSuite_.beforeAll({
+        fn: beforeAllFunction,
+        timeout: timeout || 0
+      });
+    }
+
+    afterEach(afterEachFunction, timeout) {
+      ensureIsFunctionOrAsync(afterEachFunction, 'afterEach');
+
+      if (timeout) {
+        j$.util.validateTimeout(timeout);
+      }
+
+      afterEachFunction.isCleanup = true;
+      this.currentDeclarationSuite_.afterEach({
+        fn: afterEachFunction,
+        timeout: timeout || 0
+      });
+    }
+
+    afterAll(afterAllFunction, timeout) {
+      ensureIsFunctionOrAsync(afterAllFunction, 'afterAll');
+
+      if (timeout) {
+        j$.util.validateTimeout(timeout);
+      }
+
+      this.currentDeclarationSuite_.afterAll({
+        fn: afterAllFunction,
+        timeout: timeout || 0
+      });
+    }
+
+    it_(description, fn, timeout) {
+      if (timeout) {
+        j$.util.validateTimeout(timeout);
+      }
+
+      const spec = this.specFactory_(description, fn, timeout);
+      if (this.currentDeclarationSuite_.markedExcluding) {
+        spec.exclude();
+      }
+      this.currentDeclarationSuite_.addChild(spec);
+
+      return spec;
+    }
+
+    suiteFactory_(description) {
+      const config = this.env_.configuration();
+      return new j$.Suite({
+        id: 'suite' + this.nextSuiteId_++,
+        description,
+        parentSuite: this.currentDeclarationSuite_,
+        timer: new j$.Timer(),
+        expectationFactory: this.expectationFactory_,
+        asyncExpectationFactory: this.suiteAsyncExpectationFactory_,
+        throwOnExpectationFailure: config.stopSpecOnExpectationFailure,
+        autoCleanClosures: config.autoCleanClosures,
+        onLateError: this.onLateError_
+      });
+    }
+
+    addSpecsToSuite_(suite, definitionFn) {
+      const parentSuite = this.currentDeclarationSuite_;
+      parentSuite.addChild(suite);
+      this.currentDeclarationSuite_ = suite;
+
+      try {
+        definitionFn();
+      } catch (e) {
+        suite.handleException(e);
+      }
+
+      this.currentDeclarationSuite_ = parentSuite;
+    }
+
+    specFactory_(description, fn, timeout) {
+      this.totalSpecsDefined++;
+      const config = this.env_.configuration();
+      const suite = this.currentDeclarationSuite_;
+      const spec = new j$.Spec({
+        id: 'spec' + this.nextSpecId_++,
+        beforeAndAfterFns: beforeAndAfterFns(suite),
+        expectationFactory: this.expectationFactory_,
+        asyncExpectationFactory: this.specAsyncExpectationFactory_,
+        onLateError: this.onLateError_,
+        resultCallback: (result, next) => {
+          this.specResultCallback_(spec, result, next);
+        },
+        getSpecName: function(spec) {
+          return getSpecName(spec, suite);
+        },
+        onStart: (spec, next) => this.specStarted_(spec, suite, next),
+        description: description,
+        userContext: function() {
+          return suite.clonedSharedUserContext();
+        },
+        queueableFn: {
+          fn: fn,
+          timeout: timeout || 0
+        },
+        throwOnExpectationFailure: config.stopSpecOnExpectationFailure,
+        autoCleanClosures: config.autoCleanClosures,
+        timer: new j$.Timer()
+      });
+      return spec;
+    }
+
+    unfocusAncestor_() {
+      const focusedAncestor = findFocusedAncestor(
+        this.currentDeclarationSuite_
+      );
+
+      if (focusedAncestor) {
+        for (let i = 0; i < this.focusedRunables.length; i++) {
+          if (this.focusedRunables[i] === focusedAncestor) {
+            this.focusedRunables.splice(i, 1);
+            break;
+          }
+        }
+      }
+    }
+  }
+
+  function findFocusedAncestor(suite) {
+    while (suite) {
+      if (suite.isFocused) {
+        return suite.id;
+      }
+      suite = suite.parentSuite;
+    }
+
+    return null;
+  }
+
+  function ensureIsFunction(fn, caller) {
+    if (!j$.isFunction_(fn)) {
+      throw new Error(
+        caller + ' expects a function argument; received ' + j$.getType_(fn)
+      );
+    }
+  }
+
+  function ensureIsFunctionOrAsync(fn, caller) {
+    if (!j$.isFunction_(fn) && !j$.isAsyncFunction_(fn)) {
+      throw new Error(
+        caller + ' expects a function argument; received ' + j$.getType_(fn)
+      );
+    }
+  }
+
+  function beforeAndAfterFns(targetSuite) {
+    return function() {
+      let befores = [],
+        afters = [],
+        suite = targetSuite;
+
+      while (suite) {
+        befores = befores.concat(suite.beforeFns);
+        afters = afters.concat(suite.afterFns);
+
+        suite = suite.parentSuite;
+      }
+
+      return {
+        befores: befores.reverse(),
+        afters: afters
+      };
+    };
+  }
+
+  function getSpecName(spec, suite) {
+    const fullName = [spec.description],
+      suiteFullName = suite.getFullName();
+
+    if (suiteFullName !== '') {
+      fullName.unshift(suiteFullName);
+    }
+    return fullName.join(' ');
+  }
+
+  return SuiteBuilder;
+};
+
 getJasmineRequireObj().Timer = function() {
-  var defaultNow = (function(Date) {
+  const defaultNow = (function(Date) {
     return function() {
       return new Date().getTime();
     };
@@ -9941,8 +10132,8 @@ getJasmineRequireObj().Timer = function() {
   function Timer(options) {
     options = options || {};
 
-    var now = options.now || defaultNow,
-      startTime;
+    const now = options.now || defaultNow;
+    let startTime;
 
     this.start = function() {
       startTime = now();
@@ -9958,26 +10149,26 @@ getJasmineRequireObj().Timer = function() {
 
 getJasmineRequireObj().TreeProcessor = function() {
   function TreeProcessor(attrs) {
-    var tree = attrs.tree,
-      runnableIds = attrs.runnableIds,
-      queueRunnerFactory = attrs.queueRunnerFactory,
-      nodeStart = attrs.nodeStart || function() {},
-      nodeComplete = attrs.nodeComplete || function() {},
-      failSpecWithNoExpectations = !!attrs.failSpecWithNoExpectations,
-      orderChildren =
-        attrs.orderChildren ||
-        function(node) {
-          return node.children;
-        },
-      excludeNode =
-        attrs.excludeNode ||
-        function(node) {
-          return false;
-        },
-      stats = { valid: true },
-      processed = false,
-      defaultMin = Infinity,
-      defaultMax = 1 - Infinity;
+    const tree = attrs.tree;
+    const runnableIds = attrs.runnableIds;
+    const queueRunnerFactory = attrs.queueRunnerFactory;
+    const nodeStart = attrs.nodeStart || function() {};
+    const nodeComplete = attrs.nodeComplete || function() {};
+    const failSpecWithNoExpectations = !!attrs.failSpecWithNoExpectations;
+    const orderChildren =
+      attrs.orderChildren ||
+      function(node) {
+        return node.children;
+      };
+    const excludeNode =
+      attrs.excludeNode ||
+      function(node) {
+        return false;
+      };
+    let stats = { valid: true };
+    let processed = false;
+    const defaultMin = Infinity;
+    const defaultMax = 1 - Infinity;
 
     this.processTree = function() {
       processNode(tree, true);
@@ -9994,7 +10185,7 @@ getJasmineRequireObj().TreeProcessor = function() {
         throw 'invalid order';
       }
 
-      var childFns = wrapChildren(tree, 0);
+      const childFns = wrapChildren(tree, 0);
 
       queueRunnerFactory({
         queueableFns: childFns,
@@ -10010,7 +10201,7 @@ getJasmineRequireObj().TreeProcessor = function() {
     };
 
     function runnableIndex(id) {
-      for (var i = 0; i < runnableIds.length; i++) {
+      for (let i = 0; i < runnableIds.length; i++) {
         if (runnableIds[i] === id) {
           return i;
         }
@@ -10018,14 +10209,14 @@ getJasmineRequireObj().TreeProcessor = function() {
     }
 
     function processNode(node, parentExcluded) {
-      var executableIndex = runnableIndex(node.id);
+      const executableIndex = runnableIndex(node.id);
 
       if (executableIndex !== undefined) {
         parentExcluded = false;
       }
 
       if (!node.children) {
-        var excluded = parentExcluded || excludeNode(node);
+        const excluded = parentExcluded || excludeNode(node);
         stats[node.id] = {
           excluded: excluded,
           willExecute: !excluded && !node.markedPending,
@@ -10040,12 +10231,12 @@ getJasmineRequireObj().TreeProcessor = function() {
           ]
         };
       } else {
-        var hasExecutableChild = false;
+        let hasExecutableChild = false;
 
-        var orderedChildren = orderChildren(node);
+        const orderedChildren = orderChildren(node);
 
-        for (var i = 0; i < orderedChildren.length; i++) {
-          var child = orderedChildren[i];
+        for (let i = 0; i < orderedChildren.length; i++) {
+          const child = orderedChildren[i];
 
           processNode(child, parentExcluded);
 
@@ -10053,7 +10244,7 @@ getJasmineRequireObj().TreeProcessor = function() {
             return;
           }
 
-          var childStats = stats[child.id];
+          const childStats = stats[child.id];
 
           hasExecutableChild = hasExecutableChild || childStats.willExecute;
         }
@@ -10085,7 +10276,7 @@ getJasmineRequireObj().TreeProcessor = function() {
       nodeStats,
       executableIndex
     ) {
-      var currentSegment = {
+      let currentSegment = {
           index: 0,
           owner: node,
           nodes: [],
@@ -10104,8 +10295,8 @@ getJasmineRequireObj().TreeProcessor = function() {
         );
       }
 
-      for (var i = 0; i < orderedChildSegments.length; i++) {
-        var childSegment = orderedChildSegments[i],
+      for (let i = 0; i < orderedChildSegments.length; i++) {
+        const childSegment = orderedChildSegments[i],
           maxIndex = childSegment.max,
           minIndex = childSegment.min;
 
@@ -10130,15 +10321,15 @@ getJasmineRequireObj().TreeProcessor = function() {
     }
 
     function orderChildSegments(children) {
-      var specifiedOrder = [],
+      const specifiedOrder = [],
         unspecifiedOrder = [];
 
-      for (var i = 0; i < children.length; i++) {
-        var child = children[i],
+      for (let i = 0; i < children.length; i++) {
+        const child = children[i],
           segments = stats[child.id].segments;
 
-        for (var j = 0; j < segments.length; j++) {
-          var seg = segments[j];
+        for (let j = 0; j < segments.length; j++) {
+          const seg = segments[j];
 
           if (seg.min === defaultMin) {
             unspecifiedOrder.push(seg);
@@ -10159,7 +10350,7 @@ getJasmineRequireObj().TreeProcessor = function() {
       if (node.children) {
         return {
           fn: function(done) {
-            var onStart = {
+            const onStart = {
               fn: function(next) {
                 nodeStart(node, next);
               }
@@ -10167,7 +10358,7 @@ getJasmineRequireObj().TreeProcessor = function() {
 
             queueRunnerFactory({
               onComplete: function() {
-                var args = Array.prototype.slice.call(arguments, [0]);
+                const args = Array.prototype.slice.call(arguments, [0]);
                 node.cleanupBeforeAfter();
                 nodeComplete(node, node.getResult(), function() {
                   done.apply(undefined, args);
@@ -10188,6 +10379,7 @@ getJasmineRequireObj().TreeProcessor = function() {
         return {
           fn: function(done) {
             node.execute(
+              queueRunnerFactory,
               done,
               stats[node.id].excluded,
               failSpecWithNoExpectations
@@ -10198,10 +10390,10 @@ getJasmineRequireObj().TreeProcessor = function() {
     }
 
     function wrapChildren(node, segmentNumber) {
-      var result = [],
+      const result = [],
         segmentChildren = stats[node.id].segments[segmentNumber].nodes;
 
-      for (var i = 0; i < segmentChildren.length; i++) {
+      for (let i = 0; i < segmentChildren.length; i++) {
         result.push(
           executeNode(segmentChildren[i].owner, segmentChildren[i].index)
         );
@@ -10222,9 +10414,9 @@ getJasmineRequireObj().UserContext = function(j$) {
   function UserContext() {}
 
   UserContext.fromExisting = function(oldContext) {
-    var context = new UserContext();
+    const context = new UserContext();
 
-    for (var prop in oldContext) {
+    for (const prop in oldContext) {
       if (oldContext.hasOwnProperty(prop)) {
         context[prop] = oldContext[prop];
       }
@@ -10237,5 +10429,5 @@ getJasmineRequireObj().UserContext = function(j$) {
 };
 
 getJasmineRequireObj().version = function() {
-  return '4.2.0';
+  return '4.3.0';
 };
diff --git a/tobago-theme/package-lock.json b/tobago-theme/package-lock.json
index d5c43a04f4..c9cecaf9ff 100644
--- a/tobago-theme/package-lock.json
+++ b/tobago-theme/package-lock.json
@@ -11,35 +11,35 @@
       "dependencies": {
         "@trevoreyre/autocomplete-js": "^2.2.0",
         "bootstrap": "5.1.3",
-        "bootstrap-icons": "1.8.3"
+        "bootstrap-icons": "1.9.1"
       },
       "devDependencies": {
         "@popperjs/core": "^2.11.5",
         "@rollup/plugin-node-resolve": "^13.3.0",
         "@rollup/plugin-replace": "^4.0.0",
-        "@types/bootstrap": "^5.1.12",
-        "@types/jest": "^28.1.4",
-        "@typescript-eslint/eslint-plugin": "^5.30.5",
-        "@typescript-eslint/parser": "^5.30.5",
-        "autoprefixer": "^10.4.7",
-        "clean-css-cli": "^5.6.0",
-        "eslint": "^8.19.0",
+        "@types/bootstrap": "^5.1.13",
+        "@types/jest": "^28.1.6",
+        "@typescript-eslint/eslint-plugin": "^5.32.0",
+        "@typescript-eslint/parser": "^5.32.0",
+        "autoprefixer": "^10.4.8",
+        "clean-css-cli": "^5.6.1",
+        "eslint": "^8.21.0",
         "eslint-plugin-compat": "^4.0.2",
-        "jest": "^28.1.2",
+        "jest": "^28.1.3",
         "jsf.js_next_gen": "^1.0.0-beta-1",
         "lodash": "^4.17.21",
         "ncp": "^2.0.0",
         "npm-run-all": "^4.1.5",
         "postcss": "^8.4.14",
         "postcss-cli": "^10.0.0",
-        "rollup": "^2.75.7",
+        "rollup": "^2.77.2",
         "rollup-plugin-terser": "^7.0.2",
         "rollup-plugin-typescript2": "^0.32.1",
-        "sass": "^1.53.0",
-        "ts-jest": "^28.0.5",
+        "sass": "^1.54.1",
+        "ts-jest": "^28.0.7",
         "tslib": "^2.4.0",
         "typescript": "^4.7.4",
-        "uglify-js": "^3.16.2"
+        "uglify-js": "^3.16.3"
       }
     },
     "node_modules/@ampproject/remapping": {
@@ -77,21 +77,21 @@
       }
     },
     "node_modules/@babel/core": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.9.tgz",
-      "integrity": "sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz",
+      "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==",
       "dev": true,
       "dependencies": {
         "@ampproject/remapping": "^2.1.0",
         "@babel/code-frame": "^7.18.6",
-        "@babel/generator": "^7.18.9",
+        "@babel/generator": "^7.18.10",
         "@babel/helper-compilation-targets": "^7.18.9",
         "@babel/helper-module-transforms": "^7.18.9",
         "@babel/helpers": "^7.18.9",
-        "@babel/parser": "^7.18.9",
-        "@babel/template": "^7.18.6",
-        "@babel/traverse": "^7.18.9",
-        "@babel/types": "^7.18.9",
+        "@babel/parser": "^7.18.10",
+        "@babel/template": "^7.18.10",
+        "@babel/traverse": "^7.18.10",
+        "@babel/types": "^7.18.10",
         "convert-source-map": "^1.7.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.2",
@@ -116,12 +116,12 @@
       }
     },
     "node_modules/@babel/generator": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.9.tgz",
-      "integrity": "sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.10.tgz",
+      "integrity": "sha512-0+sW7e3HjQbiHbj1NeU/vN8ornohYlacAfZIaXhdoGweQqgcNy69COVciYYqEXJ/v+9OBA7Frxm4CVAuNqKeNA==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.18.9",
+        "@babel/types": "^7.18.10",
         "@jridgewell/gen-mapping": "^0.3.2",
         "jsesc": "^2.5.1"
       },
@@ -268,6 +268,15 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz",
+      "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/@babel/helper-validator-identifier": {
       "version": "7.18.6",
       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
@@ -386,9 +395,9 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.9.tgz",
-      "integrity": "sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.10.tgz",
+      "integrity": "sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg==",
       "dev": true,
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -560,33 +569,33 @@
       }
     },
     "node_modules/@babel/template": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz",
-      "integrity": "sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
+      "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.18.6",
-        "@babel/parser": "^7.18.6",
-        "@babel/types": "^7.18.6"
+        "@babel/parser": "^7.18.10",
+        "@babel/types": "^7.18.10"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.9.tgz",
-      "integrity": "sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.10.tgz",
+      "integrity": "sha512-J7ycxg0/K9XCtLyHf0cz2DqDihonJeIo+z+HEdRe9YuT8TY4A66i+Ab2/xZCEW7Ro60bPCBBfqqboHSamoV3+g==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.18.6",
-        "@babel/generator": "^7.18.9",
+        "@babel/generator": "^7.18.10",
         "@babel/helper-environment-visitor": "^7.18.9",
         "@babel/helper-function-name": "^7.18.9",
         "@babel/helper-hoist-variables": "^7.18.6",
         "@babel/helper-split-export-declaration": "^7.18.6",
-        "@babel/parser": "^7.18.9",
-        "@babel/types": "^7.18.9",
+        "@babel/parser": "^7.18.10",
+        "@babel/types": "^7.18.10",
         "debug": "^4.1.0",
         "globals": "^11.1.0"
       },
@@ -604,11 +613,12 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.9.tgz",
-      "integrity": "sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz",
+      "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==",
       "dev": true,
       "dependencies": {
+        "@babel/helper-string-parser": "^7.18.10",
         "@babel/helper-validator-identifier": "^7.18.6",
         "to-fast-properties": "^2.0.0"
       },
@@ -643,9 +653,9 @@
       }
     },
     "node_modules/@humanwhocodes/config-array": {
-      "version": "0.9.5",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
-      "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+      "version": "0.10.4",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz",
+      "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==",
       "dev": true,
       "dependencies": {
         "@humanwhocodes/object-schema": "^1.2.1",
@@ -656,6 +666,16 @@
         "node": ">=10.10.0"
       }
     },
+    "node_modules/@humanwhocodes/gitignore-to-minimatch": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz",
+      "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==",
+      "dev": true,
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
+      }
+    },
     "node_modules/@humanwhocodes/object-schema": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
@@ -1221,9 +1241,9 @@
       }
     },
     "node_modules/@sinclair/typebox": {
-      "version": "0.24.20",
-      "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.20.tgz",
-      "integrity": "sha512-kVaO5aEFZb33nPMTZBxiPEkY+slxiPtqC7QX8f9B3eGOMBvEfuMfxp9DSTTCsRJPumPKjrge4yagyssO4q6qzQ==",
+      "version": "0.24.26",
+      "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.26.tgz",
+      "integrity": "sha512-1ZVIyyS1NXDRVT8GjWD5jULjhDyM3IsIHef2VGUMdnWOlX2tkPjyEX/7K0TGSH2S8EaPhp1ylFdjSjUGQ+gecg==",
       "dev": true
     },
     "node_modules/@sinonjs/commons": {
@@ -1291,9 +1311,9 @@
       }
     },
     "node_modules/@types/bootstrap": {
-      "version": "5.1.13",
-      "resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-5.1.13.tgz",
-      "integrity": "sha512-1hIIOgfkMlyQCQz/3ae53xr6ZN2d6EDj/n3G+Sh/LBsBUVigyDmnCbLwsaXJJ1GBGlkjgfXVoyIvEPowQw25xQ==",
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-5.2.1.tgz",
+      "integrity": "sha512-jPdLpDnBTHeocqelEz+ZVP2eY12hIBXgJLV/n0URiQiiNLdCgHwDqaI0chijjn1qwvDNbjzhKDeYAHxsnIGtIA==",
       "dev": true,
       "dependencies": {
         "@popperjs/core": "^2.9.2"
@@ -1355,15 +1375,15 @@
       "dev": true
     },
     "node_modules/@types/node": {
-      "version": "18.0.6",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.6.tgz",
-      "integrity": "sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw==",
+      "version": "18.6.3",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz",
+      "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==",
       "dev": true
     },
     "node_modules/@types/prettier": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz",
-      "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==",
+      "version": "2.6.4",
+      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.4.tgz",
+      "integrity": "sha512-fOwvpvQYStpb/zHMx0Cauwywu9yLDmzWiiQBC7gJyq5tYLUXFZvDG7VK1B7WBxxjBJNKFOZ0zLoOQn8vmATbhw==",
       "dev": true
     },
     "node_modules/@types/resolve": {
@@ -1397,14 +1417,14 @@
       "dev": true
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.7.tgz",
-      "integrity": "sha512-l4L6Do+tfeM2OK0GJsU7TUcM/1oN/N25xHm3Jb4z3OiDU4Lj8dIuxX9LpVMS9riSXQs42D1ieX7b85/r16H9Fw==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.32.0.tgz",
+      "integrity": "sha512-CHLuz5Uz7bHP2WgVlvoZGhf0BvFakBJKAD/43Ty0emn4wXWv5k01ND0C0fHcl/Im8Td2y/7h44E9pca9qAu2ew==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "5.30.7",
-        "@typescript-eslint/type-utils": "5.30.7",
-        "@typescript-eslint/utils": "5.30.7",
+        "@typescript-eslint/scope-manager": "5.32.0",
+        "@typescript-eslint/type-utils": "5.32.0",
+        "@typescript-eslint/utils": "5.32.0",
         "debug": "^4.3.4",
         "functional-red-black-tree": "^1.0.1",
         "ignore": "^5.2.0",
@@ -1430,14 +1450,14 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.7.tgz",
-      "integrity": "sha512-Rg5xwznHWWSy7v2o0cdho6n+xLhK2gntImp0rJroVVFkcYFYQ8C8UJTSuTw/3CnExBmPjycjmUJkxVmjXsld6A==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.32.0.tgz",
+      "integrity": "sha512-IxRtsehdGV9GFQ35IGm5oKKR2OGcazUoiNBxhRV160iF9FoyuXxjY+rIqs1gfnd+4eL98OjeGnMpE7RF/NBb3A==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "5.30.7",
-        "@typescript-eslint/types": "5.30.7",
-        "@typescript-eslint/typescript-estree": "5.30.7",
+        "@typescript-eslint/scope-manager": "5.32.0",
+        "@typescript-eslint/types": "5.32.0",
+        "@typescript-eslint/typescript-estree": "5.32.0",
         "debug": "^4.3.4"
       },
       "engines": {
@@ -1457,13 +1477,13 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.7.tgz",
-      "integrity": "sha512-7BM1bwvdF1UUvt+b9smhqdc/eniOnCKxQT/kj3oXtj3LqnTWCAM0qHRHfyzCzhEfWX0zrW7KqXXeE4DlchZBKw==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.32.0.tgz",
+      "integrity": "sha512-KyAE+tUON0D7tNz92p1uetRqVJiiAkeluvwvZOqBmW9z2XApmk5WSMV9FrzOroAcVxJZB3GfUwVKr98Dr/OjOg==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.30.7",
-        "@typescript-eslint/visitor-keys": "5.30.7"
+        "@typescript-eslint/types": "5.32.0",
+        "@typescript-eslint/visitor-keys": "5.32.0"
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1474,12 +1494,12 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.30.7.tgz",
-      "integrity": "sha512-nD5qAE2aJX/YLyKMvOU5jvJyku4QN5XBVsoTynFrjQZaDgDV6i7QHFiYCx10wvn7hFvfuqIRNBtsgaLe0DbWhw==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.32.0.tgz",
+      "integrity": "sha512-0gSsIhFDduBz3QcHJIp3qRCvVYbqzHg8D6bHFsDMrm0rURYDj+skBK2zmYebdCp+4nrd9VWd13egvhYFJj/wZg==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/utils": "5.30.7",
+        "@typescript-eslint/utils": "5.32.0",
         "debug": "^4.3.4",
         "tsutils": "^3.21.0"
       },
@@ -1500,9 +1520,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.7.tgz",
-      "integrity": "sha512-ocVkETUs82+U+HowkovV6uxf1AnVRKCmDRNUBUUo46/5SQv1owC/EBFkiu4MOHeZqhKz2ktZ3kvJJ1uFqQ8QPg==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.32.0.tgz",
+      "integrity": "sha512-EBUKs68DOcT/EjGfzywp+f8wG9Zw6gj6BjWu7KV/IYllqKJFPlZlLSYw/PTvVyiRw50t6wVbgv4p9uE2h6sZrQ==",
       "dev": true,
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1513,13 +1533,13 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.7.tgz",
-      "integrity": "sha512-tNslqXI1ZdmXXrHER83TJ8OTYl4epUzJC0aj2i4DMDT4iU+UqLT3EJeGQvJ17BMbm31x5scSwo3hPM0nqQ1AEA==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.32.0.tgz",
+      "integrity": "sha512-ZVAUkvPk3ITGtCLU5J4atCw9RTxK+SRc6hXqLtllC2sGSeMFWN+YwbiJR9CFrSFJ3w4SJfcWtDwNb/DmUIHdhg==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.30.7",
-        "@typescript-eslint/visitor-keys": "5.30.7",
+        "@typescript-eslint/types": "5.32.0",
+        "@typescript-eslint/visitor-keys": "5.32.0",
         "debug": "^4.3.4",
         "globby": "^11.1.0",
         "is-glob": "^4.0.3",
@@ -1540,15 +1560,15 @@
       }
     },
     "node_modules/@typescript-eslint/utils": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.30.7.tgz",
-      "integrity": "sha512-Z3pHdbFw+ftZiGUnm1GZhkJgVqsDL5CYW2yj+TB2mfXDFOMqtbzQi2dNJIyPqPbx9mv2kUxS1gU+r2gKlKi1rQ==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.32.0.tgz",
+      "integrity": "sha512-W7lYIAI5Zlc5K082dGR27Fczjb3Q57ECcXefKU/f0ajM5ToM0P+N9NmJWip8GmGu/g6QISNT+K6KYB+iSHjXCQ==",
       "dev": true,
       "dependencies": {
         "@types/json-schema": "^7.0.9",
-        "@typescript-eslint/scope-manager": "5.30.7",
-        "@typescript-eslint/types": "5.30.7",
-        "@typescript-eslint/typescript-estree": "5.30.7",
+        "@typescript-eslint/scope-manager": "5.32.0",
+        "@typescript-eslint/types": "5.32.0",
+        "@typescript-eslint/typescript-estree": "5.32.0",
         "eslint-scope": "^5.1.1",
         "eslint-utils": "^3.0.0"
       },
@@ -1564,12 +1584,12 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.7.tgz",
-      "integrity": "sha512-KrRXf8nnjvcpxDFOKej4xkD7657+PClJs5cJVSG7NNoCNnjEdc46juNAQt7AyuWctuCgs6mVRc1xGctEqrjxWw==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.32.0.tgz",
+      "integrity": "sha512-S54xOHZgfThiZ38/ZGTgB2rqx51CMJ5MCfVT2IplK4Q7hgzGfe0nLzLCcenDnc/cSjP568hdeKfeDcBgqNHD/g==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "5.30.7",
+        "@typescript-eslint/types": "5.32.0",
         "eslint-visitor-keys": "^3.3.0"
       },
       "engines": {
@@ -1581,9 +1601,9 @@
       }
     },
     "node_modules/acorn": {
-      "version": "8.7.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
-      "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+      "version": "8.8.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+      "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
       "dev": true,
       "bin": {
         "acorn": "bin/acorn"
@@ -1712,9 +1732,9 @@
       "dev": true
     },
     "node_modules/autoprefixer": {
-      "version": "10.4.7",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz",
-      "integrity": "sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA==",
+      "version": "10.4.8",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.8.tgz",
+      "integrity": "sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==",
       "dev": true,
       "funding": [
         {
@@ -1727,8 +1747,8 @@
         }
       ],
       "dependencies": {
-        "browserslist": "^4.20.3",
-        "caniuse-lite": "^1.0.30001335",
+        "browserslist": "^4.21.3",
+        "caniuse-lite": "^1.0.30001373",
         "fraction.js": "^4.2.0",
         "normalize-range": "^0.1.2",
         "picocolors": "^1.0.0",
@@ -1863,9 +1883,9 @@
       }
     },
     "node_modules/bootstrap-icons": {
-      "version": "1.8.3",
-      "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.8.3.tgz",
-      "integrity": "sha512-s5kmttnbq4BXbx3Bwnj39y+t7Vc3blTtyD77W3aYQ1LlNoS3lNbbGvSYhIbg26Im8KmjScyFpHEevlPOBcIDdA=="
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.9.1.tgz",
+      "integrity": "sha512-d4ZkO30MIkAhQ2nNRJqKXJVEQorALGbLWTuRxyCTJF96lRIV6imcgMehWGJUiJMJhglN0o2tqLIeDnMdiQEE9g=="
     },
     "node_modules/brace-expansion": {
       "version": "1.1.11",
@@ -1890,9 +1910,9 @@
       }
     },
     "node_modules/browserslist": {
-      "version": "4.21.2",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.2.tgz",
-      "integrity": "sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA==",
+      "version": "4.21.3",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz",
+      "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==",
       "dev": true,
       "funding": [
         {
@@ -1905,10 +1925,10 @@
         }
       ],
       "dependencies": {
-        "caniuse-lite": "^1.0.30001366",
-        "electron-to-chromium": "^1.4.188",
+        "caniuse-lite": "^1.0.30001370",
+        "electron-to-chromium": "^1.4.202",
         "node-releases": "^2.0.6",
-        "update-browserslist-db": "^1.0.4"
+        "update-browserslist-db": "^1.0.5"
       },
       "bin": {
         "browserslist": "cli.js"
@@ -1988,9 +2008,9 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001367",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001367.tgz",
-      "integrity": "sha512-XDgbeOHfifWV3GEES2B8rtsrADx4Jf+juKX2SICJcaUhjYBO3bR96kvEIHa15VU6ohtOhBZuPGGYGbXMRn0NCw==",
+      "version": "1.0.30001373",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz",
+      "integrity": "sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ==",
       "dev": true,
       "funding": [
         {
@@ -2042,7 +2062,7 @@
       "dependencies": {
         "anymatch": "~3.1.2",
         "braces": "~3.0.2",
-        "glob-parent": "~6.0.0",
+        "glob-parent": "~5.1.2",
         "is-binary-path": "~2.1.0",
         "is-glob": "~4.0.1",
         "normalize-path": "~3.0.0",
@@ -2173,9 +2193,9 @@
       }
     },
     "node_modules/core-js": {
-      "version": "3.23.5",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.5.tgz",
-      "integrity": "sha512-7Vh11tujtAZy82da4duVreQysIoO2EvVrur7y6IzZkH1IHPSekuDi8Vuw1+YKjkbfWLRD7Nc9ICQ/sIUDutcyg==",
+      "version": "3.24.1",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.24.1.tgz",
+      "integrity": "sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg==",
       "dev": true,
       "hasInstallScript": true,
       "funding": {
@@ -2303,9 +2323,9 @@
       }
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.4.194",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.194.tgz",
-      "integrity": "sha512-ola5UH0xAP1oYY0FFUsPvwtucEzCQHucXnT7PQ1zjHJMccZhCDktEugI++JUR3YuIs7Ff7afz+OVEhVAIMhLAQ==",
+      "version": "1.4.210",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.210.tgz",
+      "integrity": "sha512-kSiX4tuyZijV7Cz0MWVmGT8K2siqaOA4Z66K5dCttPPRh0HicOcOAEj1KlC8O8J1aOS/1M8rGofOzksLKaHWcQ==",
       "dev": true
     },
     "node_modules/emittery": {
@@ -2411,13 +2431,14 @@
       }
     },
     "node_modules/eslint": {
-      "version": "8.20.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz",
-      "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==",
+      "version": "8.21.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.21.0.tgz",
+      "integrity": "sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==",
       "dev": true,
       "dependencies": {
         "@eslint/eslintrc": "^1.3.0",
-        "@humanwhocodes/config-array": "^0.9.2",
+        "@humanwhocodes/config-array": "^0.10.4",
+        "@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
         "ajv": "^6.10.0",
         "chalk": "^4.0.0",
         "cross-spawn": "^7.0.2",
@@ -2427,14 +2448,17 @@
         "eslint-scope": "^7.1.1",
         "eslint-utils": "^3.0.0",
         "eslint-visitor-keys": "^3.3.0",
-        "espree": "^9.3.2",
+        "espree": "^9.3.3",
         "esquery": "^1.4.0",
         "esutils": "^2.0.2",
         "fast-deep-equal": "^3.1.3",
         "file-entry-cache": "^6.0.1",
+        "find-up": "^5.0.0",
         "functional-red-black-tree": "^1.0.1",
         "glob-parent": "^6.0.1",
         "globals": "^13.15.0",
+        "globby": "^11.1.0",
+        "grapheme-splitter": "^1.0.4",
         "ignore": "^5.2.0",
         "import-fresh": "^3.0.0",
         "imurmurhash": "^0.1.4",
@@ -2570,18 +2594,33 @@
         "node": ">=4.0"
       }
     },
+    "node_modules/eslint/node_modules/glob-parent": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+      "dev": true,
+      "dependencies": {
+        "is-glob": "^4.0.3"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
     "node_modules/espree": {
-      "version": "9.3.2",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
-      "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+      "version": "9.3.3",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz",
+      "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==",
       "dev": true,
       "dependencies": {
-        "acorn": "^8.7.1",
+        "acorn": "^8.8.0",
         "acorn-jsx": "^5.3.2",
         "eslint-visitor-keys": "^3.3.0"
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/esprima": {
@@ -2725,7 +2764,7 @@
       "dependencies": {
         "@nodelib/fs.stat": "^2.0.2",
         "@nodelib/fs.walk": "^1.2.3",
-        "glob-parent": "^6.0.0",
+        "glob-parent": "^5.1.2",
         "merge2": "^1.3.0",
         "micromatch": "^4.0.4"
       },
@@ -3027,21 +3066,21 @@
       }
     },
     "node_modules/glob-parent": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
-      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
       "dev": true,
       "dependencies": {
-        "is-glob": "^4.0.3"
+        "is-glob": "^4.0.1"
       },
       "engines": {
-        "node": ">=10.13.0"
+        "node": ">= 6"
       }
     },
     "node_modules/globals": {
-      "version": "13.16.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.16.0.tgz",
-      "integrity": "sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q==",
+      "version": "13.17.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
+      "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
       "dev": true,
       "dependencies": {
         "type-fest": "^0.20.2"
@@ -3079,6 +3118,12 @@
       "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
+    "node_modules/grapheme-splitter": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+      "dev": true
+    },
     "node_modules/has": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -3305,15 +3350,18 @@
       }
     },
     "node_modules/is-builtin-module": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz",
-      "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz",
+      "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==",
       "dev": true,
       "dependencies": {
-        "builtin-modules": "^3.0.0"
+        "builtin-modules": "^3.3.0"
       },
       "engines": {
         "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
     "node_modules/is-callable": {
@@ -5472,9 +5520,9 @@
       }
     },
     "node_modules/rollup": {
-      "version": "2.77.0",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.0.tgz",
-      "integrity": "sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g==",
+      "version": "2.77.2",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.2.tgz",
+      "integrity": "sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==",
       "dev": true,
       "bin": {
         "rollup": "dist/bin/rollup"
@@ -5581,9 +5629,9 @@
       "dev": true
     },
     "node_modules/sass": {
-      "version": "1.53.0",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.53.0.tgz",
-      "integrity": "sha512-zb/oMirbKhUgRQ0/GFz8TSAwRq2IlR29vOUJZOx0l8sV+CkHUfHa4u5nqrG+1VceZp7Jfj59SVW9ogdhTvJDcQ==",
+      "version": "1.54.1",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.1.tgz",
+      "integrity": "sha512-GHJJr31Me32RjjUBagyzx8tzjKBUcDwo5239XANIRBq0adDu5iIG0aFO0i/TBb/4I9oyxkEv44nq/kL1DxdDhA==",
       "dev": true,
       "dependencies": {
         "chokidar": ">=3.0.0 <4.0.0",
@@ -6147,9 +6195,9 @@
       }
     },
     "node_modules/uglify-js": {
-      "version": "3.16.2",
-      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.2.tgz",
-      "integrity": "sha512-AaQNokTNgExWrkEYA24BTNMSjyqEXPSfhqoS0AxmHkCJ4U+Dyy5AvbGV/sqxuxficEfGGoX3zWw9R7QpLFfEsg==",
+      "version": "3.16.3",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.3.tgz",
+      "integrity": "sha512-uVbFqx9vvLhQg0iBaau9Z75AxWJ8tqM9AV890dIZCLApF4rTcyHwmAvLeEdYRs+BzYWu8Iw81F79ah0EfTXbaw==",
       "dev": true,
       "bin": {
         "uglifyjs": "bin/uglifyjs"
@@ -6423,21 +6471,21 @@
       "dev": true
     },
     "@babel/core": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.9.tgz",
-      "integrity": "sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz",
+      "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==",
       "dev": true,
       "requires": {
         "@ampproject/remapping": "^2.1.0",
         "@babel/code-frame": "^7.18.6",
-        "@babel/generator": "^7.18.9",
+        "@babel/generator": "^7.18.10",
         "@babel/helper-compilation-targets": "^7.18.9",
         "@babel/helper-module-transforms": "^7.18.9",
         "@babel/helpers": "^7.18.9",
-        "@babel/parser": "^7.18.9",
-        "@babel/template": "^7.18.6",
-        "@babel/traverse": "^7.18.9",
-        "@babel/types": "^7.18.9",
+        "@babel/parser": "^7.18.10",
+        "@babel/template": "^7.18.10",
+        "@babel/traverse": "^7.18.10",
+        "@babel/types": "^7.18.10",
         "convert-source-map": "^1.7.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.2",
@@ -6454,12 +6502,12 @@
       }
     },
     "@babel/generator": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.9.tgz",
-      "integrity": "sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.10.tgz",
+      "integrity": "sha512-0+sW7e3HjQbiHbj1NeU/vN8ornohYlacAfZIaXhdoGweQqgcNy69COVciYYqEXJ/v+9OBA7Frxm4CVAuNqKeNA==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.18.9",
+        "@babel/types": "^7.18.10",
         "@jridgewell/gen-mapping": "^0.3.2",
         "jsesc": "^2.5.1"
       },
@@ -6571,6 +6619,12 @@
         "@babel/types": "^7.18.6"
       }
     },
+    "@babel/helper-string-parser": {
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz",
+      "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==",
+      "dev": true
+    },
     "@babel/helper-validator-identifier": {
       "version": "7.18.6",
       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
@@ -6664,9 +6718,9 @@
       }
     },
     "@babel/parser": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.9.tgz",
-      "integrity": "sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.10.tgz",
+      "integrity": "sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg==",
       "dev": true
     },
     "@babel/plugin-syntax-async-generators": {
@@ -6787,30 +6841,30 @@
       }
     },
     "@babel/template": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz",
-      "integrity": "sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
+      "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
       "dev": true,
       "requires": {
         "@babel/code-frame": "^7.18.6",
-        "@babel/parser": "^7.18.6",
-        "@babel/types": "^7.18.6"
+        "@babel/parser": "^7.18.10",
+        "@babel/types": "^7.18.10"
       }
     },
     "@babel/traverse": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.9.tgz",
-      "integrity": "sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.10.tgz",
+      "integrity": "sha512-J7ycxg0/K9XCtLyHf0cz2DqDihonJeIo+z+HEdRe9YuT8TY4A66i+Ab2/xZCEW7Ro60bPCBBfqqboHSamoV3+g==",
       "dev": true,
       "requires": {
         "@babel/code-frame": "^7.18.6",
-        "@babel/generator": "^7.18.9",
+        "@babel/generator": "^7.18.10",
         "@babel/helper-environment-visitor": "^7.18.9",
         "@babel/helper-function-name": "^7.18.9",
         "@babel/helper-hoist-variables": "^7.18.6",
         "@babel/helper-split-export-declaration": "^7.18.6",
-        "@babel/parser": "^7.18.9",
-        "@babel/types": "^7.18.9",
+        "@babel/parser": "^7.18.10",
+        "@babel/types": "^7.18.10",
         "debug": "^4.1.0",
         "globals": "^11.1.0"
       },
@@ -6824,11 +6878,12 @@
       }
     },
     "@babel/types": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.9.tgz",
-      "integrity": "sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz",
+      "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==",
       "dev": true,
       "requires": {
+        "@babel/helper-string-parser": "^7.18.10",
         "@babel/helper-validator-identifier": "^7.18.6",
         "to-fast-properties": "^2.0.0"
       }
@@ -6857,9 +6912,9 @@
       }
     },
     "@humanwhocodes/config-array": {
-      "version": "0.9.5",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
-      "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+      "version": "0.10.4",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz",
+      "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==",
       "dev": true,
       "requires": {
         "@humanwhocodes/object-schema": "^1.2.1",
@@ -6867,6 +6922,12 @@
         "minimatch": "^3.0.4"
       }
     },
+    "@humanwhocodes/gitignore-to-minimatch": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz",
+      "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==",
+      "dev": true
+    },
     "@humanwhocodes/object-schema": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
@@ -7311,9 +7372,9 @@
       }
     },
     "@sinclair/typebox": {
-      "version": "0.24.20",
-      "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.20.tgz",
-      "integrity": "sha512-kVaO5aEFZb33nPMTZBxiPEkY+slxiPtqC7QX8f9B3eGOMBvEfuMfxp9DSTTCsRJPumPKjrge4yagyssO4q6qzQ==",
+      "version": "0.24.26",
+      "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.26.tgz",
+      "integrity": "sha512-1ZVIyyS1NXDRVT8GjWD5jULjhDyM3IsIHef2VGUMdnWOlX2tkPjyEX/7K0TGSH2S8EaPhp1ylFdjSjUGQ+gecg==",
       "dev": true
     },
     "@sinonjs/commons": {
@@ -7381,9 +7442,9 @@
       }
     },
     "@types/bootstrap": {
-      "version": "5.1.13",
-      "resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-5.1.13.tgz",
-      "integrity": "sha512-1hIIOgfkMlyQCQz/3ae53xr6ZN2d6EDj/n3G+Sh/LBsBUVigyDmnCbLwsaXJJ1GBGlkjgfXVoyIvEPowQw25xQ==",
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/@types/bootstrap/-/bootstrap-5.2.1.tgz",
+      "integrity": "sha512-jPdLpDnBTHeocqelEz+ZVP2eY12hIBXgJLV/n0URiQiiNLdCgHwDqaI0chijjn1qwvDNbjzhKDeYAHxsnIGtIA==",
       "dev": true,
       "requires": {
         "@popperjs/core": "^2.9.2"
@@ -7445,15 +7506,15 @@
       "dev": true
     },
     "@types/node": {
-      "version": "18.0.6",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.6.tgz",
-      "integrity": "sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw==",
+      "version": "18.6.3",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz",
+      "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg==",
       "dev": true
     },
     "@types/prettier": {
-      "version": "2.6.3",
-      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz",
-      "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==",
+      "version": "2.6.4",
+      "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.4.tgz",
+      "integrity": "sha512-fOwvpvQYStpb/zHMx0Cauwywu9yLDmzWiiQBC7gJyq5tYLUXFZvDG7VK1B7WBxxjBJNKFOZ0zLoOQn8vmATbhw==",
       "dev": true
     },
     "@types/resolve": {
@@ -7487,14 +7548,14 @@
       "dev": true
     },
     "@typescript-eslint/eslint-plugin": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.7.tgz",
-      "integrity": "sha512-l4L6Do+tfeM2OK0GJsU7TUcM/1oN/N25xHm3Jb4z3OiDU4Lj8dIuxX9LpVMS9riSXQs42D1ieX7b85/r16H9Fw==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.32.0.tgz",
+      "integrity": "sha512-CHLuz5Uz7bHP2WgVlvoZGhf0BvFakBJKAD/43Ty0emn4wXWv5k01ND0C0fHcl/Im8Td2y/7h44E9pca9qAu2ew==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/scope-manager": "5.30.7",
-        "@typescript-eslint/type-utils": "5.30.7",
-        "@typescript-eslint/utils": "5.30.7",
+        "@typescript-eslint/scope-manager": "5.32.0",
+        "@typescript-eslint/type-utils": "5.32.0",
+        "@typescript-eslint/utils": "5.32.0",
         "debug": "^4.3.4",
         "functional-red-black-tree": "^1.0.1",
         "ignore": "^5.2.0",
@@ -7504,52 +7565,52 @@
       }
     },
     "@typescript-eslint/parser": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.7.tgz",
-      "integrity": "sha512-Rg5xwznHWWSy7v2o0cdho6n+xLhK2gntImp0rJroVVFkcYFYQ8C8UJTSuTw/3CnExBmPjycjmUJkxVmjXsld6A==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.32.0.tgz",
+      "integrity": "sha512-IxRtsehdGV9GFQ35IGm5oKKR2OGcazUoiNBxhRV160iF9FoyuXxjY+rIqs1gfnd+4eL98OjeGnMpE7RF/NBb3A==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/scope-manager": "5.30.7",
-        "@typescript-eslint/types": "5.30.7",
-        "@typescript-eslint/typescript-estree": "5.30.7",
+        "@typescript-eslint/scope-manager": "5.32.0",
+        "@typescript-eslint/types": "5.32.0",
+        "@typescript-eslint/typescript-estree": "5.32.0",
         "debug": "^4.3.4"
       }
     },
     "@typescript-eslint/scope-manager": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.7.tgz",
-      "integrity": "sha512-7BM1bwvdF1UUvt+b9smhqdc/eniOnCKxQT/kj3oXtj3LqnTWCAM0qHRHfyzCzhEfWX0zrW7KqXXeE4DlchZBKw==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.32.0.tgz",
+      "integrity": "sha512-KyAE+tUON0D7tNz92p1uetRqVJiiAkeluvwvZOqBmW9z2XApmk5WSMV9FrzOroAcVxJZB3GfUwVKr98Dr/OjOg==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "5.30.7",
-        "@typescript-eslint/visitor-keys": "5.30.7"
+        "@typescript-eslint/types": "5.32.0",
+        "@typescript-eslint/visitor-keys": "5.32.0"
       }
     },
     "@typescript-eslint/type-utils": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.30.7.tgz",
-      "integrity": "sha512-nD5qAE2aJX/YLyKMvOU5jvJyku4QN5XBVsoTynFrjQZaDgDV6i7QHFiYCx10wvn7hFvfuqIRNBtsgaLe0DbWhw==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.32.0.tgz",
+      "integrity": "sha512-0gSsIhFDduBz3QcHJIp3qRCvVYbqzHg8D6bHFsDMrm0rURYDj+skBK2zmYebdCp+4nrd9VWd13egvhYFJj/wZg==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/utils": "5.30.7",
+        "@typescript-eslint/utils": "5.32.0",
         "debug": "^4.3.4",
         "tsutils": "^3.21.0"
       }
     },
     "@typescript-eslint/types": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.7.tgz",
-      "integrity": "sha512-ocVkETUs82+U+HowkovV6uxf1AnVRKCmDRNUBUUo46/5SQv1owC/EBFkiu4MOHeZqhKz2ktZ3kvJJ1uFqQ8QPg==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.32.0.tgz",
+      "integrity": "sha512-EBUKs68DOcT/EjGfzywp+f8wG9Zw6gj6BjWu7KV/IYllqKJFPlZlLSYw/PTvVyiRw50t6wVbgv4p9uE2h6sZrQ==",
       "dev": true
     },
     "@typescript-eslint/typescript-estree": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.7.tgz",
-      "integrity": "sha512-tNslqXI1ZdmXXrHER83TJ8OTYl4epUzJC0aj2i4DMDT4iU+UqLT3EJeGQvJ17BMbm31x5scSwo3hPM0nqQ1AEA==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.32.0.tgz",
+      "integrity": "sha512-ZVAUkvPk3ITGtCLU5J4atCw9RTxK+SRc6hXqLtllC2sGSeMFWN+YwbiJR9CFrSFJ3w4SJfcWtDwNb/DmUIHdhg==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "5.30.7",
-        "@typescript-eslint/visitor-keys": "5.30.7",
+        "@typescript-eslint/types": "5.32.0",
+        "@typescript-eslint/visitor-keys": "5.32.0",
         "debug": "^4.3.4",
         "globby": "^11.1.0",
         "is-glob": "^4.0.3",
@@ -7558,33 +7619,33 @@
       }
     },
     "@typescript-eslint/utils": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.30.7.tgz",
-      "integrity": "sha512-Z3pHdbFw+ftZiGUnm1GZhkJgVqsDL5CYW2yj+TB2mfXDFOMqtbzQi2dNJIyPqPbx9mv2kUxS1gU+r2gKlKi1rQ==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.32.0.tgz",
+      "integrity": "sha512-W7lYIAI5Zlc5K082dGR27Fczjb3Q57ECcXefKU/f0ajM5ToM0P+N9NmJWip8GmGu/g6QISNT+K6KYB+iSHjXCQ==",
       "dev": true,
       "requires": {
         "@types/json-schema": "^7.0.9",
-        "@typescript-eslint/scope-manager": "5.30.7",
-        "@typescript-eslint/types": "5.30.7",
-        "@typescript-eslint/typescript-estree": "5.30.7",
+        "@typescript-eslint/scope-manager": "5.32.0",
+        "@typescript-eslint/types": "5.32.0",
+        "@typescript-eslint/typescript-estree": "5.32.0",
         "eslint-scope": "^5.1.1",
         "eslint-utils": "^3.0.0"
       }
     },
     "@typescript-eslint/visitor-keys": {
-      "version": "5.30.7",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.7.tgz",
-      "integrity": "sha512-KrRXf8nnjvcpxDFOKej4xkD7657+PClJs5cJVSG7NNoCNnjEdc46juNAQt7AyuWctuCgs6mVRc1xGctEqrjxWw==",
+      "version": "5.32.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.32.0.tgz",
+      "integrity": "sha512-S54xOHZgfThiZ38/ZGTgB2rqx51CMJ5MCfVT2IplK4Q7hgzGfe0nLzLCcenDnc/cSjP568hdeKfeDcBgqNHD/g==",
       "dev": true,
       "requires": {
-        "@typescript-eslint/types": "5.30.7",
+        "@typescript-eslint/types": "5.32.0",
         "eslint-visitor-keys": "^3.3.0"
       }
     },
     "acorn": {
-      "version": "8.7.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
-      "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+      "version": "8.8.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+      "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
       "dev": true
     },
     "acorn-jsx": {
@@ -7678,13 +7739,13 @@
       }
     },
     "autoprefixer": {
-      "version": "10.4.7",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz",
-      "integrity": "sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA==",
+      "version": "10.4.8",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.8.tgz",
+      "integrity": "sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==",
       "dev": true,
       "requires": {
-        "browserslist": "^4.20.3",
-        "caniuse-lite": "^1.0.30001335",
+        "browserslist": "^4.21.3",
+        "caniuse-lite": "^1.0.30001373",
         "fraction.js": "^4.2.0",
         "normalize-range": "^0.1.2",
         "picocolors": "^1.0.0",
@@ -7780,9 +7841,9 @@
       "requires": {}
     },
     "bootstrap-icons": {
-      "version": "1.8.3",
-      "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.8.3.tgz",
-      "integrity": "sha512-s5kmttnbq4BXbx3Bwnj39y+t7Vc3blTtyD77W3aYQ1LlNoS3lNbbGvSYhIbg26Im8KmjScyFpHEevlPOBcIDdA=="
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.9.1.tgz",
+      "integrity": "sha512-d4ZkO30MIkAhQ2nNRJqKXJVEQorALGbLWTuRxyCTJF96lRIV6imcgMehWGJUiJMJhglN0o2tqLIeDnMdiQEE9g=="
     },
     "brace-expansion": {
       "version": "1.1.11",
@@ -7804,15 +7865,15 @@
       }
     },
     "browserslist": {
-      "version": "4.21.2",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.2.tgz",
-      "integrity": "sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA==",
+      "version": "4.21.3",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz",
+      "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==",
       "dev": true,
       "requires": {
-        "caniuse-lite": "^1.0.30001366",
-        "electron-to-chromium": "^1.4.188",
+        "caniuse-lite": "^1.0.30001370",
+        "electron-to-chromium": "^1.4.202",
         "node-releases": "^2.0.6",
-        "update-browserslist-db": "^1.0.4"
+        "update-browserslist-db": "^1.0.5"
       }
     },
     "bs-logger": {
@@ -7868,9 +7929,9 @@
       "dev": true
     },
     "caniuse-lite": {
-      "version": "1.0.30001367",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001367.tgz",
-      "integrity": "sha512-XDgbeOHfifWV3GEES2B8rtsrADx4Jf+juKX2SICJcaUhjYBO3bR96kvEIHa15VU6ohtOhBZuPGGYGbXMRn0NCw==",
+      "version": "1.0.30001373",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz",
+      "integrity": "sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ==",
       "dev": true
     },
     "chalk": {
@@ -7898,7 +7959,7 @@
         "anymatch": "~3.1.2",
         "braces": "~3.0.2",
         "fsevents": "~2.3.2",
-        "glob-parent": "~6.0.0",
+        "glob-parent": "~5.1.2",
         "is-binary-path": "~2.1.0",
         "is-glob": "~4.0.1",
         "normalize-path": "~3.0.0",
@@ -8004,9 +8065,9 @@
       }
     },
     "core-js": {
-      "version": "3.23.5",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.5.tgz",
-      "integrity": "sha512-7Vh11tujtAZy82da4duVreQysIoO2EvVrur7y6IzZkH1IHPSekuDi8Vuw1+YKjkbfWLRD7Nc9ICQ/sIUDutcyg==",
+      "version": "3.24.1",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.24.1.tgz",
+      "integrity": "sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg==",
       "dev": true
     },
     "cross-spawn": {
@@ -8094,9 +8155,9 @@
       }
     },
     "electron-to-chromium": {
-      "version": "1.4.194",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.194.tgz",
-      "integrity": "sha512-ola5UH0xAP1oYY0FFUsPvwtucEzCQHucXnT7PQ1zjHJMccZhCDktEugI++JUR3YuIs7Ff7afz+OVEhVAIMhLAQ==",
+      "version": "1.4.210",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.210.tgz",
+      "integrity": "sha512-kSiX4tuyZijV7Cz0MWVmGT8K2siqaOA4Z66K5dCttPPRh0HicOcOAEj1KlC8O8J1aOS/1M8rGofOzksLKaHWcQ==",
       "dev": true
     },
     "emittery": {
@@ -8175,13 +8236,14 @@
       "dev": true
     },
     "eslint": {
-      "version": "8.20.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz",
-      "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==",
+      "version": "8.21.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.21.0.tgz",
+      "integrity": "sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==",
       "dev": true,
       "requires": {
         "@eslint/eslintrc": "^1.3.0",
-        "@humanwhocodes/config-array": "^0.9.2",
+        "@humanwhocodes/config-array": "^0.10.4",
+        "@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
         "ajv": "^6.10.0",
         "chalk": "^4.0.0",
         "cross-spawn": "^7.0.2",
@@ -8191,14 +8253,17 @@
         "eslint-scope": "^7.1.1",
         "eslint-utils": "^3.0.0",
         "eslint-visitor-keys": "^3.3.0",
-        "espree": "^9.3.2",
+        "espree": "^9.3.3",
         "esquery": "^1.4.0",
         "esutils": "^2.0.2",
         "fast-deep-equal": "^3.1.3",
         "file-entry-cache": "^6.0.1",
+        "find-up": "^5.0.0",
         "functional-red-black-tree": "^1.0.1",
         "glob-parent": "^6.0.1",
         "globals": "^13.15.0",
+        "globby": "^11.1.0",
+        "grapheme-splitter": "^1.0.4",
         "ignore": "^5.2.0",
         "import-fresh": "^3.0.0",
         "imurmurhash": "^0.1.4",
@@ -8232,6 +8297,15 @@
           "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
           "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
           "dev": true
+        },
+        "glob-parent": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+          "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+          "dev": true,
+          "requires": {
+            "is-glob": "^4.0.3"
+          }
         }
       }
     },
@@ -8296,12 +8370,12 @@
       "dev": true
     },
     "espree": {
-      "version": "9.3.2",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
-      "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+      "version": "9.3.3",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz",
+      "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==",
       "dev": true,
       "requires": {
-        "acorn": "^8.7.1",
+        "acorn": "^8.8.0",
         "acorn-jsx": "^5.3.2",
         "eslint-visitor-keys": "^3.3.0"
       }
@@ -8414,7 +8488,7 @@
       "requires": {
         "@nodelib/fs.stat": "^2.0.2",
         "@nodelib/fs.walk": "^1.2.3",
-        "glob-parent": "^6.0.0",
+        "glob-parent": "^5.1.2",
         "merge2": "^1.3.0",
         "micromatch": "^4.0.4"
       }
@@ -8630,18 +8704,18 @@
       }
     },
     "glob-parent": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
-      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
       "dev": true,
       "requires": {
-        "is-glob": "^4.0.3"
+        "is-glob": "^4.0.1"
       }
     },
     "globals": {
-      "version": "13.16.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.16.0.tgz",
-      "integrity": "sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q==",
+      "version": "13.17.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
+      "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
       "dev": true,
       "requires": {
         "type-fest": "^0.20.2"
@@ -8667,6 +8741,12 @@
       "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
+    "grapheme-splitter": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+      "dev": true
+    },
     "has": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -8830,12 +8910,12 @@
       }
     },
     "is-builtin-module": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz",
-      "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz",
+      "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==",
       "dev": true,
       "requires": {
-        "builtin-modules": "^3.0.0"
+        "builtin-modules": "^3.3.0"
       }
     },
     "is-callable": {
@@ -10413,9 +10493,9 @@
       }
     },
     "rollup": {
-      "version": "2.77.0",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.0.tgz",
-      "integrity": "sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g==",
+      "version": "2.77.2",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.2.tgz",
+      "integrity": "sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==",
       "dev": true,
       "requires": {
         "fsevents": "~2.3.2"
@@ -10493,9 +10573,9 @@
       "dev": true
     },
     "sass": {
-      "version": "1.53.0",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.53.0.tgz",
-      "integrity": "sha512-zb/oMirbKhUgRQ0/GFz8TSAwRq2IlR29vOUJZOx0l8sV+CkHUfHa4u5nqrG+1VceZp7Jfj59SVW9ogdhTvJDcQ==",
+      "version": "1.54.1",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.1.tgz",
+      "integrity": "sha512-GHJJr31Me32RjjUBagyzx8tzjKBUcDwo5239XANIRBq0adDu5iIG0aFO0i/TBb/4I9oyxkEv44nq/kL1DxdDhA==",
       "dev": true,
       "requires": {
         "chokidar": ">=3.0.0 <4.0.0",
@@ -10911,9 +10991,9 @@
       "dev": true
     },
     "uglify-js": {
-      "version": "3.16.2",
-      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.2.tgz",
-      "integrity": "sha512-AaQNokTNgExWrkEYA24BTNMSjyqEXPSfhqoS0AxmHkCJ4U+Dyy5AvbGV/sqxuxficEfGGoX3zWw9R7QpLFfEsg==",
+      "version": "3.16.3",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.3.tgz",
+      "integrity": "sha512-uVbFqx9vvLhQg0iBaau9Z75AxWJ8tqM9AV890dIZCLApF4rTcyHwmAvLeEdYRs+BzYWu8Iw81F79ah0EfTXbaw==",
       "dev": true
     },
     "unbox-primitive": {
diff --git a/tobago-theme/package.json b/tobago-theme/package.json
index 337ac2a4fb..12d2bf2e79 100644
--- a/tobago-theme/package.json
+++ b/tobago-theme/package.json
@@ -67,34 +67,34 @@
   "dependencies": {
     "@trevoreyre/autocomplete-js": "^2.2.0",
     "bootstrap": "5.1.3",
-    "bootstrap-icons": "1.8.3"
+    "bootstrap-icons": "1.9.1"
   },
   "devDependencies": {
     "@popperjs/core": "^2.11.5",
     "@rollup/plugin-node-resolve": "^13.3.0",
     "@rollup/plugin-replace": "^4.0.0",
-    "@types/bootstrap": "^5.1.12",
-    "@types/jest": "^28.1.4",
-    "@typescript-eslint/eslint-plugin": "^5.30.5",
-    "@typescript-eslint/parser": "^5.30.5",
-    "autoprefixer": "^10.4.7",
-    "clean-css-cli": "^5.6.0",
-    "eslint": "^8.19.0",
+    "@types/bootstrap": "^5.1.13",
+    "@types/jest": "^28.1.6",
+    "@typescript-eslint/eslint-plugin": "^5.32.0",
+    "@typescript-eslint/parser": "^5.32.0",
+    "autoprefixer": "^10.4.8",
+    "clean-css-cli": "^5.6.1",
+    "eslint": "^8.21.0",
     "eslint-plugin-compat": "^4.0.2",
-    "jest": "^28.1.2",
+    "jest": "^28.1.3",
     "jsf.js_next_gen": "^1.0.0-beta-1",
     "lodash": "^4.17.21",
     "ncp": "^2.0.0",
     "npm-run-all": "^4.1.5",
     "postcss": "^8.4.14",
     "postcss-cli": "^10.0.0",
-    "rollup": "^2.75.7",
+    "rollup": "^2.77.2",
     "rollup-plugin-terser": "^7.0.2",
     "rollup-plugin-typescript2": "^0.32.1",
-    "sass": "^1.53.0",
-    "ts-jest": "^28.0.5",
+    "sass": "^1.54.1",
+    "ts-jest": "^28.0.7",
     "tslib": "^2.4.0",
     "typescript": "^4.7.4",
-    "uglify-js": "^3.16.2"
+    "uglify-js": "^3.16.3"
   }
 }
diff --git a/tobago-theme/tobago-theme-standard/src/main/css/bootstrap-icons.css b/tobago-theme/tobago-theme-standard/src/main/css/bootstrap-icons.css
index 4fb8787fe3..7f0bd54b15 100644
--- a/tobago-theme/tobago-theme-standard/src/main/css/bootstrap-icons.css
+++ b/tobago-theme/tobago-theme-standard/src/main/css/bootstrap-icons.css
@@ -1,14 +1,14 @@
 @font-face {
+  font-display: block;
   font-family: "bootstrap-icons";
-  src: url("./fonts/bootstrap-icons.woff2?08efbba7c53d8c5413793eecb19b20bb") format("woff2"),
-url("./fonts/bootstrap-icons.woff?08efbba7c53d8c5413793eecb19b20bb") format("woff");
+  src: url("./fonts/bootstrap-icons.woff2?8d200481aa7f02a2d63a331fc782cfaf") format("woff2"),
+url("./fonts/bootstrap-icons.woff?8d200481aa7f02a2d63a331fc782cfaf") format("woff");
 }
 
 .bi::before,
 [class^="bi-"]::before,
 [class*=" bi-"]::before {
   display: inline-block;
-  font-display: block;
   font-family: bootstrap-icons !important;
   font-style: normal;
   font-weight: normal !important;
@@ -1703,3 +1703,174 @@ url("./fonts/bootstrap-icons.woff?08efbba7c53d8c5413793eecb19b20bb") format("wof
 .bi-filetype-json::before { content: "\f791"; }
 .bi-filetype-pptx::before { content: "\f792"; }
 .bi-filetype-xlsx::before { content: "\f793"; }
+.bi-1-circle-1::before { content: "\f794"; }
+.bi-1-circle-fill-1::before { content: "\f795"; }
+.bi-1-circle-fill::before { content: "\f796"; }
+.bi-1-circle::before { content: "\f797"; }
+.bi-1-square-fill::before { content: "\f798"; }
+.bi-1-square::before { content: "\f799"; }
+.bi-2-circle-1::before { content: "\f79a"; }
+.bi-2-circle-fill-1::before { content: "\f79b"; }
+.bi-2-circle-fill::before { content: "\f79c"; }
+.bi-2-circle::before { content: "\f79d"; }
+.bi-2-square-fill::before { content: "\f79e"; }
+.bi-2-square::before { content: "\f79f"; }
+.bi-3-circle-1::before { content: "\f7a0"; }
+.bi-3-circle-fill-1::before { content: "\f7a1"; }
+.bi-3-circle-fill::before { content: "\f7a2"; }
+.bi-3-circle::before { content: "\f7a3"; }
+.bi-3-square-fill::before { content: "\f7a4"; }
+.bi-3-square::before { content: "\f7a5"; }
+.bi-4-circle-1::before { content: "\f7a6"; }
+.bi-4-circle-fill-1::before { content: "\f7a7"; }
+.bi-4-circle-fill::before { content: "\f7a8"; }
+.bi-4-circle::before { content: "\f7a9"; }
+.bi-4-square-fill::before { content: "\f7aa"; }
+.bi-4-square::before { content: "\f7ab"; }
+.bi-5-circle-1::before { content: "\f7ac"; }
+.bi-5-circle-fill-1::before { content: "\f7ad"; }
+.bi-5-circle-fill::before { content: "\f7ae"; }
+.bi-5-circle::before { content: "\f7af"; }
+.bi-5-square-fill::before { content: "\f7b0"; }
+.bi-5-square::before { content: "\f7b1"; }
+.bi-6-circle-1::before { content: "\f7b2"; }
+.bi-6-circle-fill-1::before { content: "\f7b3"; }
+.bi-6-circle-fill::before { content: "\f7b4"; }
+.bi-6-circle::before { content: "\f7b5"; }
+.bi-6-square-fill::before { content: "\f7b6"; }
+.bi-6-square::before { content: "\f7b7"; }
+.bi-7-circle-1::before { content: "\f7b8"; }
+.bi-7-circle-fill-1::before { content: "\f7b9"; }
+.bi-7-circle-fill::before { content: "\f7ba"; }
+.bi-7-circle::before { content: "\f7bb"; }
+.bi-7-square-fill::before { content: "\f7bc"; }
+.bi-7-square::before { content: "\f7bd"; }
+.bi-8-circle-1::before { content: "\f7be"; }
+.bi-8-circle-fill-1::before { content: "\f7bf"; }
+.bi-8-circle-fill::before { content: "\f7c0"; }
+.bi-8-circle::before { content: "\f7c1"; }
+.bi-8-square-fill::before { content: "\f7c2"; }
+.bi-8-square::before { content: "\f7c3"; }
+.bi-9-circle-1::before { content: "\f7c4"; }
+.bi-9-circle-fill-1::before { content: "\f7c5"; }
+.bi-9-circle-fill::before { content: "\f7c6"; }
+.bi-9-circle::before { content: "\f7c7"; }
+.bi-9-square-fill::before { content: "\f7c8"; }
+.bi-9-square::before { content: "\f7c9"; }
+.bi-airplane-engines-fill::before { content: "\f7ca"; }
+.bi-airplane-engines::before { content: "\f7cb"; }
+.bi-airplane-fill::before { content: "\f7cc"; }
+.bi-airplane::before { content: "\f7cd"; }
+.bi-alexa::before { content: "\f7ce"; }
+.bi-alipay::before { content: "\f7cf"; }
+.bi-android::before { content: "\f7d0"; }
+.bi-android2::before { content: "\f7d1"; }
+.bi-box-fill::before { content: "\f7d2"; }
+.bi-box-seam-fill::before { content: "\f7d3"; }
+.bi-browser-chrome::before { content: "\f7d4"; }
+.bi-browser-edge::before { content: "\f7d5"; }
+.bi-browser-firefox::before { content: "\f7d6"; }
+.bi-browser-safari::before { content: "\f7d7"; }
+.bi-c-circle-1::before { content: "\f7d8"; }
+.bi-c-circle-fill-1::before { content: "\f7d9"; }
+.bi-c-circle-fill::before { content: "\f7da"; }
+.bi-c-circle::before { content: "\f7db"; }
+.bi-c-square-fill::before { content: "\f7dc"; }
+.bi-c-square::before { content: "\f7dd"; }
+.bi-capsule-pill::before { content: "\f7de"; }
+.bi-capsule::before { content: "\f7df"; }
+.bi-car-front-fill::before { content: "\f7e0"; }
+.bi-car-front::before { content: "\f7e1"; }
+.bi-cassette-fill::before { content: "\f7e2"; }
+.bi-cassette::before { content: "\f7e3"; }
+.bi-cc-circle-1::before { content: "\f7e4"; }
+.bi-cc-circle-fill-1::before { content: "\f7e5"; }
+.bi-cc-circle-fill::before { content: "\f7e6"; }
... 94 lines suppressed ...