mediawiki/services/change-propagation (main)

sourcepatches
From 905aabe4a4c47dd8d17c48ae339b0a51d7e4f18e Mon Sep 17 00:00:00 2001
From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org>
Date: Mon, 29 Apr 2024 19:24:31 +0000
Subject: [PATCH] build: Updating npm dependencies
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* eslint-config-wikimedia: 0.25.1 → 0.27.0
  The following rules are failing and were disabled:
  * es-x/no-array-prototype-with

* @babel/traverse: 7.12.12 → 7.24.5
  * https://github.com/advisories/GHSA-67hx-6x53-jw92
* ansi-regex: 2.1.1, 3.0.0, 4.1.0, 5.0.0, 5.0.1 → 2.1.1, 3.0.1, 4.1.1, 5.0.1
  * https://github.com/advisories/GHSA-93q8-gq69-wqmw
* json-schema: 0.2.3 → 0.4.0
  * https://github.com/advisories/GHSA-896r-f27r-55mw
* json5: 2.1.3 → 2.2.3
  * https://github.com/advisories/GHSA-9c47-m6qq-7p4h
* jsprim: 1.4.1 → 1.4.2
  * https://github.com/advisories/GHSA-896r-f27r-55mw
* kad: 1.3.6 →
  * https://github.com/advisories/GHSA-7wpw-2hjm-89gp
  * https://github.com/advisories/GHSA-w9mr-4mfr-499f
* limitation: 0.2.1 → 0.2.3
  * https://github.com/advisories/GHSA-7wpw-2hjm-89gp
  * https://github.com/advisories/GHSA-w9mr-4mfr-499f
* merge: 1.2.1 →
  * https://github.com/advisories/GHSA-7wpw-2hjm-89gp
* minimist: 0.0.8, 1.2.0, 1.2.5 → 0.0.8, 1.2.0, 1.2.8
  * https://github.com/advisories/GHSA-vh95-rmgr-6w4m
  * https://github.com/advisories/GHSA-xvch-5gv4-984h
* moment: 2.29.1 → 2.30.1
  * https://github.com/advisories/GHSA-8hfj-j24r-96c4
  * https://github.com/advisories/GHSA-wc69-rhjr-hc9g
* ms: 0.7.3, 2.1.1, 2.1.2 → 0.7.3, 2.1.1, 2.1.2, 2.1.3
  * https://github.com/advisories/GHSA-w9mr-4mfr-499f
* msgpack5: 3.6.0 → 3.6.1
  * https://github.com/advisories/GHSA-gmjw-49p4-pcfm
* qs: 6.5.2 → 6.5.3
  * https://github.com/advisories/GHSA-hrpp-h998-j3pp
* redis: 3.0.2 → 3.1.2
  * https://github.com/advisories/GHSA-35q2-47q7-3pc3
* semver: 5.7.0, 5.7.1, 5.7.2, 6.3.0, 7.6.0 → 5.7.0, 5.7.2, 6.3.1, 7.6.0
  * https://github.com/advisories/GHSA-c2qf-rxjj-qqgw
* underscore: 1.12.0 → 1.13.6
  * https://github.com/advisories/GHSA-cf4h-3jhx-xvhq

Change-Id: Iebb4320518a1e7b9fc0197b6f64e553f243a9742
---
 .eslintrc.json                   |    3 +-
 .travis.yml                      |    4 +-
 config.example.wikimedia.yaml    |  224 ++--
 config.example.yaml              |    2 +-
 config.jobqueue.wikimedia.yaml   |   46 +-
 config.test.yaml                 |   54 +-
 lib/base_executor.js             |   32 +-
 lib/kafka_factory.js             |    6 +-
 lib/retry_executor.js            |    4 +-
 lib/rule.js                      |   60 +-
 lib/rule_executor.js             |    8 +-
 lib/utils.js                     |   10 +-
 package-lock.json                | 1837 +++++++++++++++++++-----------
 package.json                     |    2 +-
 sys/deduplicator.js              |   16 +-
 sys/dep_updates.js               |    4 +-
 sys/kafka.js                     |    4 +-
 sys/ores_updates.js              |    4 +-
 sys/partitioner.js               |    2 +-
 sys/purge.js                     |    2 +-
 sys/rate_limiter.js              |   12 +-
 test/feature/job_rules.js        |   10 +-
 test/feature/static_rules.js     |   22 +-
 test/feature/update_rules.js     |   88 +-
 test/utils/changeProp.js         |    2 +-
 test/utils/common.js             |    8 +-
 test/utils/mock_kafka_factory.js |    9 +-
 27 files changed, 1501 insertions(+), 974 deletions(-)

diff --git a/.eslintrc.json b/.eslintrc.json
index 78d1a0d..86f22c4 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -33,6 +33,7 @@
 		"arrow-parens": "off",
 		"no-multi-spaces": "off",
 		"jsdoc/no-undefined-types": "off",
-		"no-shadow": "warn"
+		"no-shadow": "warn",
+		"es-x/no-array-prototype-with": "warn"
 	}
 }
diff --git a/.travis.yml b/.travis.yml
index 74da3eb..7b3f6e3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,8 +19,8 @@ addons:
       - openjdk-8-jre-headless
 
 before_script:
-- export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
-- npm run install-kafka
+  - export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
+  - npm run install-kafka
 
 script: npm test && npm run start-kafka && npm run coverage && (npm run coveralls || exit 0)
 
diff --git a/config.example.wikimedia.yaml b/config.example.wikimedia.yaml
index 5b2b015..444112d 100644
--- a/config.example.wikimedia.yaml
+++ b/config.example.wikimedia.yaml
@@ -14,8 +14,8 @@ spec: &spec
         - path: sys/ores_updates.js
           options:
             ores_precache_uris:
-              - 'https://ores.wikimedia.org/v3/precache'
-            event_service_uri: 'https://eventgate.stubfortests.org/v1/events'
+              - "https://ores.wikimedia.org/v3/precache"
+            event_service_uri: "https://eventgate.stubfortests.org/v1/events"
     /sys/limit:
       x-modules:
         - path: sys/rate_limiter.js
@@ -52,11 +52,11 @@ spec: &spec
           options:
             templates:
               mw_api:
-                  uri: 'https://{{message.meta.domain}}/w/api.php'
-                  headers:
-                    host: '{{message.meta.domain}}'
-                  body:
-                    formatversion: 2
+                uri: "https://{{message.meta.domain}}/w/api.php"
+                headers:
+                  host: "{{message.meta.domain}}"
+                body:
+                  formatversion: 2
     /sys/queue:
       x-modules:
         - path: sys/kafka.js
@@ -76,22 +76,22 @@ spec: &spec
               compression.codec: snappy
             concurrency: 250
             # Redis-mock does not support evalsha that rate limiting depend on.
-            disable_ratelimit: '{env(MOCK_SERVICES)}'
+            disable_ratelimit: "{env(MOCK_SERVICES)}"
             blacklist:
               en.wikipedia.org:
-                - 'User:Nolelover'
+                - "User:Nolelover"
                 - '/User:Cyberbot_I\//'
             templates:
 
               summary_definition_rerender: &summary_definition_rerender_spec
-                topic: 'resource_change'
+                topic: resource_change
                 retry_limit: 2
                 retry_delay: 500
                 retry_on:
                   status:
-                    - '5xx'
+                    - 5xx
                 limiters:
-                  blacklist: 'summary:{message.meta.uri}'
+                  blacklist: "summary:{message.meta.uri}"
                 cases: # Non wiktionary domains - rerender summary
                   - match:
                       meta:
@@ -100,13 +100,13 @@ spec: &spec
                         - restbase
                     match_not:
                       - meta:
-                          domain: '/wiktionary.org$/'
+                          domain: /wiktionary.org$/
                       - meta:
                           domain: /\.wikidata\.org$/
                     exec:
                       method: get
                       # Don't encode title since it should be already encoded
-                      uri: '{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}'
+                      uri: "{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}"
                       query:
                         redirect: false
                       headers:
@@ -122,7 +122,7 @@ spec: &spec
                     exec:
                       method: get
                       # Don't encode title since it should be already encoded
-                      uri: '{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/definition/{{match.meta.uri.title}}'
+                      uri: "{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/definition/{{match.meta.uri.title}}"
                       query:
                         redirect: false
                       headers:
@@ -130,17 +130,17 @@ spec: &spec
 
               summary_definition_rerender_transcludes: &summary_definition_rerender_transcludes_spec
                 <<: *summary_definition_rerender_spec
-                topic: 'change-prop.transcludes.resource-change'
+                topic: change-prop.transcludes.resource-change
 
               mobile_rerender: &mobile_rerender_spec
-                topic: 'resource_change'
+                topic: resource_change
                 retry_limit: 2
                 retry_delay: 500
                 retry_on:
                   status:
-                    - '5xx'
+                    - 5xx
                 limiters:
-                  blacklist: 'mobile:{message.meta.uri}'
+                  blacklist: "mobile:{message.meta.uri}"
                 match:
                   meta:
                     uri: '/^(?<proto>https?):\/\/[^\/]+\/api\/rest_v1\/page\/html\/(?<title>[^/]+)$/'
@@ -149,24 +149,24 @@ spec: &spec
                     - restbase
                 exec:
                   - method: get
-                    uri: '{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{{match.meta.uri.title}}'
+                    uri: "{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{{match.meta.uri.title}}"
                     query:
                       redirect: false
                     headers:
                       cache-control: no-cache
                     # Until we start storing and actively rerendering PCS endpoints we still need to purge it from Varnish
                   - method: post
-                    uri: '/sys/purge/'
+                    uri: /sys/purge/
                     body:
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/media-list/{{match.meta.uri.title}}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/media-list/{{match.meta.uri.title}}"
 
               mobile_rerender_transcludes: &mobile_rerender_transcludes_spec
                 <<: *mobile_rerender_spec
-                topic: 'change-prop.transcludes.resource-change'
+                topic: change-prop.transcludes.resource-change
 
               purge_varnish: &purge_varnish_spec
-                topic: 'resource_change'
+                topic: resource_change
                 match:
                   meta:
                     uri: '/^https?:\/\/[^\/]+\/api\/rest_v1\/(?<title>.+)$/'
@@ -174,20 +174,20 @@ spec: &spec
                     - restbase
                 exec:
                   method: post
-                  uri: '/sys/purge/'
+                  uri: /sys/purge/
                   body:
                     - meta:
-                        uri: '//{{message.meta.domain}}/api/rest_v1/{{match.meta.uri.title}}'
+                        uri: "//{{message.meta.domain}}/api/rest_v1/{{match.meta.uri.title}}"
 
               purge_varnish_transcludes: &purge_varnish_transcludes_spec
                 <<: *purge_varnish_spec
-                topic: 'change-prop.transcludes.resource-change'
+                topic: change-prop.transcludes.resource-change
 
               # RESTBase update jobs
               mw_purge:
                 topic: resource_change
                 limiters:
-                  blacklist: 'html:{message.meta.uri}'
+                  blacklist: "html:{message.meta.uri}"
                 cases:
                   - match:
                       meta:
@@ -199,22 +199,22 @@ spec: &spec
                       - method: get
                         # This even comes directly from MediaWiki, so title is encoded in MW-specific way.
                         # Re-encode the title in standard `encodeURIComponent` encoding.
-                        uri: '{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}'
+                        uri: "{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
-                          if-unmodified-since: '{{date(message.meta.dt)}}'
+                          if-unmodified-since: "{{date(message.meta.dt)}}"
                         query:
                           redirect: false
                         # The HTML might not change but sometimes editors use a purge to drop incorrectly rendered summary/MCS
                         # content, so let's purge them as well just in case. The rate is low.
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/summary/{decode(match.meta.uri.title)}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/summary/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
                         query:
                           redirect: false
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{decode(match.meta.uri.title)}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
                         query:
@@ -229,16 +229,16 @@ spec: &spec
                       - method: get
                         # This even comes directly from MediaWiki, so title is encoded in MW-specific way.
                         # Re-encode the title in standard `encodeURIComponent` encoding.
-                        uri: '{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}'
+                        uri: "{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
-                          if-unmodified-since: '{{date(message.meta.dt)}}'
+                          if-unmodified-since: "{{date(message.meta.dt)}}"
                         query:
                           redirect: false
                         # The HTML might not change but sometimes editors use a purge to drop incorrectly rendered summary/MCS
                         # content, so let's purge them as well just in case. The rate is low.
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/definition/{decode(match.meta.uri.title)}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/definition/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
                         query:
@@ -263,16 +263,16 @@ spec: &spec
                       - method: get
                         # This even comes directly from MediaWiki, so title is encoded in MW-specific way.
                         # Re-encode the title in standard `encodeURIComponent` encoding.
-                        uri: '{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}'
+                        uri: "{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
-                          if-unmodified-since: '{{date(message.meta.dt)}}'
+                          if-unmodified-since: "{{date(message.meta.dt)}}"
                         query:
                           redirect: false
                         # The HTML might not change but sometimes editors use a purge to drop incorrectly rendered summary/MCS
                         # content, so let's purge them as well just in case. The rate is low.
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/summary/{decode(match.meta.uri.title)}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/summary/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
                         query:
@@ -285,7 +285,7 @@ spec: &spec
                     - 403 # Ignoring 403 since some of the pages with high number of null_edit events are blacklisted
                     - 412
                 limiters:
-                  blacklist: 'html:{message.meta.uri}'
+                  blacklist: "html:{message.meta.uri}"
                 cases:
                   - match:
                       meta:
@@ -312,18 +312,18 @@ spec: &spec
               page_edit:
                 topic: mediawiki.revision-create
                 limiters:
-                  blacklist: 'html:{message.meta.uri}'
+                  blacklist: "html:{message.meta.uri}"
                 retry_on:
                   status:
-                    - '5xx'
+                    - 5xx
                     - 404 # Sometimes occasional 404s happen because of the mysql replication lag, so retry
                 match:
                   rev_content_changed: true
                 match_not:
-                # Test-only. We use undefined rev_parent_id to test backlinks so we
-                # don't want transclusions to interfere with backlinks test
+                  # Test-only. We use undefined rev_parent_id to test backlinks so we
+                  # don't want transclusions to interfere with backlinks test
                   - rev_parent_id: undefined
-                # end of test-only config
+                  # end of test-only config
                   - meta:
                       domain: /\.wikidata\.org$/
                     page_namespace: 0
@@ -332,16 +332,16 @@ spec: &spec
                     page_namespace: 120
                 exec:
                   - method: get
-                    uri: 'https://{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}'
+                    uri: "https://{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}"
                     headers:
                       cache-control: no-cache
-                      x-restbase-parentrevision: '{{message.rev_parent_id}}'
-                      if-unmodified-since: '{{date(message.meta.dt)}}'
+                      x-restbase-parentrevision: "{{message.rev_parent_id}}"
+                      if-unmodified-since: "{{date(message.meta.dt)}}"
                     query:
                       redirect: false
                   - method: post
-                    uri: '/sys/links/transcludes/{message.page_title}'
-                    body: '{{globals.message}}'
+                    uri: "/sys/links/transcludes/{message.page_title}"
+                    body: "{{globals.message}}"
 
               revision_visibility_change:
                 topic: mediawiki.revision-visibility-change
@@ -358,7 +358,7 @@ spec: &spec
                     page_namespace: 120
                 exec:
                   - method: get
-                    uri: 'https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}/{{message.rev_id}}'
+                    uri: "https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}/{{message.rev_id}}"
                     headers:
                       cache-control: no-cache
                     query:
@@ -368,16 +368,16 @@ spec: &spec
                   # we need to add many workarounds/shortcurst in RESTBase. So having this list here is an OK compromise.
                   # Only purge the URIs with a rev_id since the latest revision can not be restricted.
                   - method: post
-                    uri: '/sys/purge/'
+                    uri: /sys/purge/
                     body:
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}/{{message.rev_id}}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}/{{message.rev_id}}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-lead/{message.page_title}/{{message.rev_id}}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-lead/{message.page_title}/{{message.rev_id}}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-remaining/{message.page_title}/{{message.rev_id}}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-remaining/{message.page_title}/{{message.rev_id}}"
 
               page_delete:
                 topic: mediawiki.page-delete
@@ -394,37 +394,37 @@ spec: &spec
                     page_namespace: 120
                 exec:
                   - method: get
-                    uri: 'https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}'
+                    uri: "https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}"
                     headers:
                       cache-control: no-cache
                     query:
                       redirect: false
                   # The links to the deleted page should become red again
                   - method: post
-                    uri: '/sys/links/backlinks/{message.page_title}'
-                    body: '{{globals.message}}'
+                    uri: "/sys/links/backlinks/{message.page_title}"
+                    body: "{{globals.message}}"
                   # For page deletion RESTBase doesn't emit resource_change events, and to go through
                   # the normal purge chain (html update -> html resource_change -> summary update -> summary resource_change)
                   # we need to add many workarounds/shortcuts in RESTBase. So having this list here is an OK compromise.
                   - method: post
-                    uri: '/sys/purge/'
+                    uri: /sys/purge/
                     body:
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/definition/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/definition/{message.page_title}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-lead/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-lead/{message.page_title}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-remaining/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-remaining/{message.page_title}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/media-list/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/media-list/{message.page_title}"
 
               page_restore:
                 topic: mediawiki.page-undelete
@@ -437,15 +437,15 @@ spec: &spec
                     page_namespace: 120
                 exec:
                   - method: get
-                    uri: 'https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}'
+                    uri: "https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}"
                     headers:
                       cache-control: no-cache
                     query:
                       redirect: false
                   # The links to the deleted page should become red again
                   - method: post
-                    uri: '/sys/links/backlinks/{message.page_title}'
-                    body: '{{globals.message}}'
+                    uri: "/sys/links/backlinks/{message.page_title}"
+                    body: "{{globals.message}}"
 
               page_move:
                 topic: mediawiki.page-move
@@ -458,14 +458,14 @@ spec: &spec
                     page_namespace: 120
                 exec:
                   - method: get
-                    uri: 'https://{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}'
+                    uri: "https://{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}"
                     headers:
                       cache-control: no-cache
-                      if-unmodified-since: '{{date(message.meta.dt)}}'
+                      if-unmodified-since: "{{date(message.meta.dt)}}"
                     query:
                       redirect: false
                   - method: get
-                    uri: 'https://{{message.meta.domain}}/api/rest_v1/page/title/{message.prior_state.page_title}'
+                    uri: "https://{{message.meta.domain}}/api/rest_v1/page/title/{message.prior_state.page_title}"
                     headers:
                       cache-control: no-cache
                     query:
@@ -474,34 +474,34 @@ spec: &spec
               on_transclusion_update:
                 topic: change-prop.transcludes.resource-change
                 limiters:
-                  blacklist: 'html:{message.meta.uri}'
+                  blacklist: "html:{message.meta.uri}"
                 cases:
                   - match:
                       $schema: '/^\/resource_change\/.*/'
                       meta:
                         uri: '/https?:\/\/[^\/]+\/wiki\/(?<title>.+)/'
-                      tags: [ 'transcludes' ]
+                      tags: [ transcludes ]
                     exec:
                       method: get
-                      uri: 'https://{{message.meta.domain}}/api/rest_v1/page/html/{{match.meta.uri.title}}'
+                      uri: "https://{{message.meta.domain}}/api/rest_v1/page/html/{{match.meta.uri.title}}"
                       headers:
                         cache-control: no-cache
-                        if-unmodified-since: '{{date(message.root_event.dt)}}'
-                        x-restbase-mode: '{{message.tags[1]}}'
+                        if-unmodified-since: "{{date(message.root_event.dt)}}"
+                        x-restbase-mode: "{{message.tags[1]}}"
                       query:
                         redirect: false
                   - match:
                       $schema: '/^\/change-prop\/continue\/.*/'
                     exec:
                       method: post
-                      uri: '/sys/links/transcludes/{message.original_event.page_title}'
-                      body: '{{globals.message}}'
+                      uri: "/sys/links/transcludes/{message.original_event.page_title}"
+                      body: "{{globals.message}}"
 
               page_create:
                 topic: mediawiki.page-create
                 retry_on:
                   status:
-                    - '5xx'
+                    - 5xx
                     - 404 # Sometimes occasional 404s happen because of the mysql replication lag, so retry
                 match_not:
                   - meta:
@@ -512,34 +512,34 @@ spec: &spec
                     page_namespace: 120
                 exec:
                   - method: post
-                    uri: '/sys/links/backlinks/{message.page_title}'
-                    body: '{{globals.message}}'
+                    uri: "/sys/links/backlinks/{message.page_title}"
+                    body: "{{globals.message}}"
 
               on_backlinks_update:
                 topic: change-prop.backlinks.resource-change
                 limiters:
-                  blacklist: 'html:{message.meta.uri}'
+                  blacklist: "html:{message.meta.uri}"
                 cases:
                   - match:
                       $schema: '/^\/resource_change\/.*/'
                       meta:
                         uri: '/https?:\/\/[^\/]+\/wiki\/(?<title>.+)/'
-                      tags: [ 'backlinks' ]
+                      tags: [ backlinks ]
                     exec:
                       method: get
-                      uri: 'https://{{message.meta.domain}}/api/rest_v1/page/html/{{match.meta.uri.title}}'
+                      uri: "https://{{message.meta.domain}}/api/rest_v1/page/html/{{match.meta.uri.title}}"
                       headers:
                         cache-control: no-cache
-                        if-unmodified-since: '{{date(message.root_event.dt)}}'
-                        x-restbase-mode: '{{message.tags[1]}}'
+                        if-unmodified-since: "{{date(message.root_event.dt)}}"
+                        x-restbase-mode: "{{message.tags[1]}}"
                       query:
                         redirect: false
                   - match:
                       $schema: '/^\/change-prop\/continue\/.*/'
                     exec:
                       method: post
-                      uri: '/sys/links/backlinks/{message.original_event.page_title}'
-                      body: '{{globals.message}}'
+                      uri: "/sys/links/backlinks/{message.original_event.page_title}"
+                      body: "{{globals.message}}"
 
               # ORES caching updates
               ores_cache:
@@ -550,10 +550,10 @@ spec: &spec
                     - 503
                 exec:
                   method: post
-                  uri: '/sys/ores/'
+                  uri: /sys/ores/
                   query:
                     postevent: true
-                  body: '{{globals.message}}'
+                  body: "{{globals.message}}"
 
               wikidata_description_on_edit:
                 topic: mediawiki.revision-create
@@ -563,12 +563,12 @@ spec: &spec
                   page_namespace: 0
                   # It's impossible to modify a comment in wikidata while editing the entity.
                   # TODO: This is a temp solution until we get a more general fragment support T148079
-                  comment: '/wbeditentity|wbsetdescription|undo|restore/'
+                  comment: "/wbeditentity|wbsetdescription|undo|restore/"
                   rev_content_changed: true
                 exec:
                   method: post
-                  uri: '/sys/links/wikidata_descriptions'
-                  body: '{{globals.message}}'
+                  uri: /sys/links/wikidata_descriptions
+                  body: "{{globals.message}}"
 
               wikidata_description_on_undelete:
                 topic: mediawiki.page-undelete
@@ -578,8 +578,8 @@ spec: &spec
                   page_namespace: 0
                 exec:
                   method: post
-                  uri: '/sys/links/wikidata_descriptions'
-                  body: '{{globals.message}}'
+                  uri: /sys/links/wikidata_descriptions
+                  body: "{{globals.message}}"
 
               on_wikidata_description_change:
                 topic: change-prop.wikidata.resource-change
@@ -588,16 +588,16 @@ spec: &spec
                       meta:
                         uri: '/https:\/\/[^\/]+\/wiki\/(?<title>.+)/'
                         domain: '/.*\.wikipedia.org$/'
-                      tags: [ 'wikidata' ]
+                      tags: [ wikidata ]
                     exec:
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}"
                         headers:
                           cache-control: no-cache
                         query:
                           redirect: false
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{{match.meta.uri.title}}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{{match.meta.uri.title}}"
                         headers:
                           cache-control: no-cache
                         query:
@@ -605,11 +605,11 @@ spec: &spec
                   - match:
                       meta:
                         uri: '/https:\/\/[^\/]+\/wiki\/(?<title>.+)/'
-                      tags: [ 'wikidata' ]
+                      tags: [ wikidata ]
                     match_not: *others_match_not
                     exec:
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}"
                         headers:
                           cache-control: no-cache
                         query:
@@ -623,27 +623,27 @@ spec: &spec
                       meta:
                         domain: '/.*\.wikipedia.org$/'
                       added_properties:
-                        page_image: '/.+/'
+                        page_image: "/.+/"
                     exec: &page_images_wikipedia_rerender
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}"
                         headers:
                           cache-control: no-cache
                         query:
                           redirect: false
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}"
                         headers:
                           cache-control: no-cache
                         query:
                           redirect: false
                   - match:
                       added_properties:
-                        page_image: '/.+/'
+                        page_image: "/.+/"
                     match_not: *others_match_not
                     exec: &page_images_others_rerender
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}"
                         headers:
                           cache-control: no-cache
                         query:
@@ -652,26 +652,26 @@ spec: &spec
                       meta:
                         domain: '/.*\.wikipedia.org$/'
                       removed_properties:
-                        page_image: '/.+/'
+                        page_image: "/.+/"
                     exec: *page_images_wikipedia_rerender
                   - match:
                       removed_properties:
-                        page_image: '/.+/'
+                        page_image: "/.+/"
                     match_not: *others_match_not
                     exec: *page_images_others_rerender
 
               # Map tile cache invalidation
               purge_map_tile:
-                topic: 'resource_change'
+                topic: resource_change
                 match:
                   tags:
                     - tilerator
                 exec:
                   method: post
-                  uri: '/sys/purge/'
+                  uri: /sys/purge/
                   body:
                     - meta:
-                        uri: '{{message.meta.uri}}'
+                        uri: "{{message.meta.uri}}"
 
 num_workers: 0
 logging:
diff --git a/config.example.yaml b/config.example.yaml
index e8c1b81..fc78c48 100644
--- a/config.example.yaml
+++ b/config.example.yaml
@@ -28,7 +28,7 @@ services:
       # IP address to bind to, all IPs by default
       # interface: localhost # uncomment to only listen on localhost
       # allow cross-domain requests to the API (default '*')
-      cors: '*'
+      cors: "*"
       # to disable use:
       # cors: false
       # to restrict to a particular domain, use:
diff --git a/config.jobqueue.wikimedia.yaml b/config.jobqueue.wikimedia.yaml
index 4b859e8..2ee0c12 100644
--- a/config.jobqueue.wikimedia.yaml
+++ b/config.jobqueue.wikimedia.yaml
@@ -35,61 +35,61 @@ spec: &spec
               queue.buffering.max.messages: "10"
               compression.codec: snappy
             # Redis-mock does not support evalsha that rate limiting depend on.
-            disable_ratelimit: '{env(MOCK_SERVICES)}'
+            disable_ratelimit: "{env(MOCK_SERVICES)}"
             concurrency: 250
             reenqueue_delay: 5
             templates:
               normal_job_rule:
                 topics:
-                  - 'mediawiki.job.updateBetaFeaturesUserCounts'
-                  - 'mediawiki.job.cdnPurge'
+                  - mediawiki.job.updateBetaFeaturesUserCounts
+                  - mediawiki.job.cdnPurge
                 exec:
                   method: post
-                  uri: 'http://jobrunner.wikipedia.org/wiki/Special:RunSingleJob'
+                  uri: "http://jobrunner.wikipedia.org/wiki/Special:RunSingleJob"
                   headers:
                     content-type: application/json
-                    host: '{{message.meta.domain}}'
-                  body: '{{globals.message}}'
+                    host: "{{message.meta.domain}}"
+                  body: "{{globals.message}}"
               htmlCacheUpdate_partitioner:
-                topic: 'mediawiki.job.htmlCacheUpdate'
+                topic: mediawiki.job.htmlCacheUpdate
                 exec:
-                  method: 'post'
-                  uri: '/sys/partition/'
+                  method: post
+                  uri: /sys/partition/
                   headers:
                     content-type: application/json
-                  body: '{{globals.message}}'
+                  body: "{{globals.message}}"
               htmlCacheUpdate:
-                topic: 'cpjobqueue.partitioned.mediawiki.job.htmlCacheUpdate'
+                topic: cpjobqueue.partitioned.mediawiki.job.htmlCacheUpdate
                 exec:
                   method: post
-                  uri: 'http://jobrunner.wikipedia.org/wiki/Special:RunSingleJob'
+                  uri: "http://jobrunner.wikipedia.org/wiki/Special:RunSingleJob"
                   headers:
                     content-type: application/json
-                    host: '{{message.meta.domain}}'
-                  body: '{{globals.message}}'
+                    host: "{{message.meta.domain}}"
+                  body: "{{globals.message}}"
               refreshLinks_partitioner:
-                topic: 'mediawiki.job.refreshLinks'
+                topic: mediawiki.job.refreshLinks
                 exec:
-                  method: 'post'
-                  uri: '/sys/partition/'
+                  method: post
+                  uri: /sys/partition/
                   headers:
                     content-type: application/json
-                  body: '{{globals.message}}'
+                  body: "{{globals.message}}"
               refreshLinks:
-                topic: 'cpjobqueue.partitioned.mediawiki.job.refreshLinks'
+                topic: cpjobqueue.partitioned.mediawiki.job.refreshLinks
                 exec:
                   method: post
-                  uri: 'http://jobrunner.wikipedia.org/wiki/Special:RunSingleJob'
+                  uri: "http://jobrunner.wikipedia.org/wiki/Special:RunSingleJob"
                   headers:
                     content-type: application/json
-                    host: '{{message.meta.domain}}'
-                  body: '{{globals.message}}'
+                    host: "{{message.meta.domain}}"
+                  body: "{{globals.message}}"
     /sys/partition:
       x-modules:
         - path: sys/partitioner.js
           options:
             templates:
-              partition_stream: 'cpjobqueue.partitioned.{{message.meta.stream}}'
+              partition_stream: "cpjobqueue.partitioned.{{message.meta.stream}}"
             partition_key: database
             partition_default: 2
             partition_map:
diff --git a/config.test.yaml b/config.test.yaml
index 3624b4b..485bb2f 100644
--- a/config.test.yaml
+++ b/config.test.yaml
@@ -36,7 +36,7 @@ spec: &spec
               compression.codec: snappy
             concurrency: 1
             # Redis-mock does not support evalsha that rate limiting depend on.
-            disable_ratelimit: '{env(MOCK_SERVICES)}'
+            disable_ratelimit: "{env(MOCK_SERVICES)}"
             templates:
               simple_test_rule:
                 topic: /^simple_test_rule$/
@@ -44,7 +44,7 @@ spec: &spec
                 retry_delay: 10
                 retry_on:
                   status:
-                    - '50x'
+                    - 50x
                     - 400
                 ignore:
                   status:
@@ -52,59 +52,59 @@ spec: &spec
                     - 412
                 match:
                   meta:
-                    uri: 'https://en.wikipedia.org/wiki/SamplePage'
-                  message: 'test'
+                    uri: "https://en.wikipedia.org/wiki/SamplePage"
+                  message: test
                 limiters:
-                  blacklist: '{{message.message}}'
+                  blacklist: "{{message.message}}"
                 exec:
                   method: post
-                  uri: 'http://mock.com'
+                  uri: "http://mock.com"
                   headers:
                     test_header_name: test_header_value
                     content-type: application/json
                   body:
                     test_field_name: test_field_value
-                    derived_field: '{{message.message}}'
-                    random_field: '{{message.random}}'
+                    derived_field: "{{message.message}}"
+                    random_field: "{{message.random}}"
               redirect_testing_rule:
                 topic: simple_test_rule
                 match:
                   meta:
-                    uri: 'https://en.wikipedia.org/wiki/SamplePage'
-                  message: 'redirect'
+                    uri: "https://en.wikipedia.org/wiki/SamplePage"
+                  message: redirect
                 exec:
                   method: get
-                  uri: 'http://mock.com/will_redirect'
+                  uri: "http://mock.com/will_redirect"
 
               kafka_producing_rule:
                 topic: kafka_producing_rule
                 exec:
-                  method: 'post'
-                  uri: '/sys/queue/events'
+                  method: post
+                  uri: /sys/queue/events
                   body:
                     - meta:
-                        stream: '{{message.produce_to_topic}}'
-                        uri: '{{message.meta.uri}}'
-                      message: 'test'
-                      triggered_by: '{{message.meta.stream}}:{{message.meta.uri}}'
+                        stream: "{{message.produce_to_topic}}"
+                        uri: "{{message.meta.uri}}"
+                      message: test
+                      triggered_by: "{{message.meta.stream}}:{{message.meta.uri}}"
                     - meta:
-                        stream: '{{message.produce_to_topic}}'
-                        uri: '{{message.meta.uri}}'
-                      message: 'test'
-                      triggered_by: '{{message.meta.stream}}:{{message.meta.uri}}'
+                        stream: "{{message.produce_to_topic}}"
+                        uri: "{{message.meta.uri}}"
+                      message: test
+                      triggered_by: "{{message.meta.stream}}:{{message.meta.uri}}"
 
               sample_testing_rule:
                 topic: sample_test_rule
                 sample:
                   rate: 0.5
-                  hash_template: '{{message.meta.domain}}-{{message.page_title}}'
+                  hash_template: "{{message.meta.domain}}-{{message.page_title}}"
                 match:
                   meta:
-                    uri: 'https://en.wikipedia.org/wiki/SamplePage'
-                  message: 'sampled'
+                    uri: "https://en.wikipedia.org/wiki/SamplePage"
+                  message: sampled
                 exec:
                   method: get
-                  uri: 'http://mock.com/{{message.meta.domain}}/{{message.page_title}}'
+                  uri: "http://mock.com/{{message.meta.domain}}/{{message.page_title}}"
 
               array_rule:
                 topics:
@@ -115,9 +115,9 @@ spec: &spec
                   - simple_test_rule3
                 exec:
                   method: post
-                  uri: 'http://mock2.org'
+                  uri: "http://mock2.org"
                   body:
-                    topic: '{{message.meta.stream}}'
+                    topic: "{{message.meta.stream}}"
 num_workers: 0
 logging:
   name: changeprop
diff --git a/lib/base_executor.js b/lib/base_executor.js
index 864fedf..df1774e 100644
--- a/lib/base_executor.js
+++ b/lib/base_executor.js
@@ -131,9 +131,9 @@ class BaseExecutor {
     }
 
     subscribe() {
-        const prefix = this.options.test_mode ? `test-${this._hyper.config.service_name}` : `${this._hyper.config.service_name}`;
+        const prefix = this.options.test_mode ? `test-${ this._hyper.config.service_name }` : `${ this._hyper.config.service_name }`;
         return this.kafkaFactory.createConsumer(
-            `${prefix}-${this.rule.name}`,
+            `${ prefix }-${ this.rule.name }`,
             this.subscribeTopics,
             this._hyper.metrics,
             this._hyper.logger
@@ -183,7 +183,7 @@ class BaseExecutor {
                 }
 
                 this._hyper.metrics.increment(
-                    `${this.statName(message)}_dequeue`,
+                    `${ this.statName(message) }_dequeue`,
                     1,
                     0.1);
 
@@ -257,7 +257,7 @@ class BaseExecutor {
         return P.all(this.rule.getRateLimiterTypes().map((type) => {
             const key = this.rule.getLimiterKey(type, expander);
             return this._hyper.get({
-                uri: new URI(`/sys/limit/${type}/${key}`)
+                uri: new URI(`/sys/limit/${ type }/${ key }`)
             });
         }))
         .thenReturn(false)
@@ -290,7 +290,7 @@ class BaseExecutor {
             if (status >= 500) {
                 const limiterKey = this.rule.getLimiterKey(type, expander);
                 return this._hyper.post({
-                    uri: new URI(`/sys/limit/${type}/${limiterKey}`)
+                    uri: new URI(`/sys/limit/${ type }/${ limiterKey }`)
                 }).catch({ status: 429 }, () => {
                     // No need to react here, we'll reject the next message
                 }).catch({ status: 404 }, () => {
@@ -390,7 +390,7 @@ class BaseExecutor {
                 message: 'Processed event sample',
                 event_str: utils.stringify(event),
                 request: {
-                    uri: `${request.uri}`,
+                    uri: `${ request.uri }`,
                     headers: request.headers,
                     // Don't include the full body in the log
                     body: request.body && utils.stringify(request.body).slice(0, 1024)
@@ -433,7 +433,7 @@ class BaseExecutor {
                 stream: origEvent.meta.stream,
                 uri: origEvent.meta.uri
             });
-            this._hyper.metrics.increment(`${this.statName(origEvent)}_blacklist`);
+            this._hyper.metrics.increment(`${ this.statName(origEvent) }_blacklist`);
             return P.resolve({ status: 200 });
         }
 
@@ -496,7 +496,7 @@ class BaseExecutor {
         // Latency from the event (if it's a retry - an original event)
         // creation time to execution time
         this._hyper.metrics.endTiming(
-            [`${this.statName(origEvent)}_delay`],
+            [`${ this.statName(origEvent) }_delay`],
             metricStartTime
         );
 
@@ -504,7 +504,7 @@ class BaseExecutor {
         if (origEvent.root_event && !retryEvent) {
             // Latency from the beginning of the recursive event chain
             // to the event execution
-            this._hyper.metrics.endTiming([`${this.statName(origEvent)}_totaldelay`],
+            this._hyper.metrics.endTiming([`${ this.statName(origEvent) }_totaldelay`],
                 new Date(origEvent.root_event.dt));
         }
 
@@ -550,7 +550,7 @@ class BaseExecutor {
                 .tap(() => this._updateLimiters(expander, 200))
                 .tapCatch(e => this._updateLimiters(expander, e.status))
                 .finally(() => this._hyper.metrics.endTiming(
-                    [`${this.statName(origEvent)}_exec`],
+                    [`${ this.statName(origEvent) }_exec`],
                     startTime)
                 );
             });
@@ -558,15 +558,15 @@ class BaseExecutor {
     }
 
     retryStreamName(topic) {
-        return `${this._hyper.config.service_name}.retry.${topic}`;
+        return `${ this._hyper.config.service_name }.retry.${ topic }`;
     }
 
     emitterId() {
-        return `${this._hyper.config.service_name}#${this.rule.name}`;
+        return `${ this._hyper.config.service_name }#${ this.rule.name }`;
     }
 
     _errorStreamName() {
-        return `${this._hyper.config.service_name}.error`;
+        return `${ this._hyper.config.service_name }.error`;
     }
 
     _constructRetryMessage(event, errorRes, retriesLeft, retryEvent) {
@@ -627,8 +627,8 @@ class BaseExecutor {
             // We've got an error, but it's not from the update request, it's
             // some bug in change-prop. Log and send a fatal error message.
             this._logger.log('fatal/internal_error', () => ({
-                message: `Internal error in ${this._hyper.config.service_name}`,
-                description: `${e}`,
+                message: `Internal error in ${ this._hyper.config.service_name }`,
+                description: `${ e }`,
                 stack: e.stack,
                 event_str: utils.stringify(message),
                 stream: message.meta.stream
@@ -650,7 +650,7 @@ class BaseExecutor {
 
         if (!this.rule.shouldIgnoreError(e)) {
             this._logger.log('error/exec_error', () => ({
-                message: `Exec error in ${this._hyper.config.service_name}`,
+                message: `Exec error in ${ this._hyper.config.service_name }`,
                 status: e.status,
                 event_str: utils.stringify(message),
                 stream: message.meta.stream,
diff --git a/lib/kafka_factory.js b/lib/kafka_factory.js
index 6d47d2d..02313ff 100644
--- a/lib/kafka_factory.js
+++ b/lib/kafka_factory.js
@@ -145,7 +145,7 @@ class MetadataWatch extends EventEmitter {
 
     getTopics() {
         /* eslint-disable-next-line security/detect-non-literal-regexp */
-        const dcRemoveRegex = new RegExp(`^${this._consumeDC}\\.`);
+        const dcRemoveRegex = new RegExp(`^${ this._consumeDC }\\.`);
         return new P((resolve, reject) => {
             this._consumer.getMetadata(undefined, (err, res) => {
                 if (err) {
@@ -243,7 +243,7 @@ class KafkaFactory {
     createConsumer(groupId, topics, metrics, logger) {
         const conf = Object.assign({}, this._consumerConf);
         conf['group.id'] = groupId;
-        conf['client.id'] = `${Math.floor(Math.random() * 1000000)}`;
+        conf['client.id'] = `${ Math.floor(Math.random() * 1000000) }`;
 
         return new P((resolve, reject) => {
             const consumer = new kafka.KafkaConsumer(conf, this._consumerTopicConf);
@@ -261,7 +261,7 @@ class KafkaFactory {
     createMetadataWatch(groupId) {
         const conf = Object.assign({}, this._consumerConf);
         conf['group.id'] = groupId;
-        conf['client.id'] = `${Math.floor(Math.random() * 1000000)}`;
+        conf['client.id'] = `${ Math.floor(Math.random() * 1000000) }`;
 
         return new P((resolve, reject) => {
             const consumer = new kafka.KafkaConsumer(conf, this._consumerTopicConf);
diff --git a/lib/retry_executor.js b/lib/retry_executor.js
index 44e0e85..b2d5b32 100644
--- a/lib/retry_executor.js
+++ b/lib/retry_executor.js
@@ -10,12 +10,12 @@ const BaseExecutor = require('./base_executor');
 class RetryExecutor extends BaseExecutor {
     get subscribeTopics() {
         return this.rule.topics.map(topic =>
-            `${this.kafkaFactory.consumeDC}.${this.retryStreamName(topic)}`);
+            `${ this.kafkaFactory.consumeDC }.${ this.retryStreamName(topic) }`);
     }
 
     statName(event) {
         return this._hyper.metrics.normalizeName(
-            `${this.rule.name}-${event.meta.stream.replace(/\./g, '_')}_retry`);
+            `${ this.rule.name }-${ event.meta.stream.replace(/\./g, '_') }_retry`);
     }
 
     _delay(message) {
diff --git a/lib/rule.js b/lib/rule.js
index 98b18fc..943b3f9 100644
--- a/lib/rule.js
+++ b/lib/rule.js
@@ -52,14 +52,14 @@ function _compileErrorCheckCondition(retryDefinition) {
         if (retryCond === 'status') {
             const opt = option.toString();
             if (/^[0-9]+$/.test(opt)) {
-                return `(res["${retryCond}"] === ${opt})`;
+                return `(res["${ retryCond }"] === ${ opt })`;
             }
             if (/^[0-9x]+$/.test(opt)) {
-                return `/^${opt.replace(/x/g, '\\d')}$/.test(res["${retryCond}"])`;
+                return `/^${ opt.replace(/x/g, '\\d') }$/.test(res["${ retryCond }"])`;
             }
-            throw new Error(`Invalid retry_on condition ${opt}`);
+            throw new Error(`Invalid retry_on condition ${ opt }`);
         } else {
-            return `(stringify(res["${retryCond}"]) === '${stringify(option)}')`;
+            return `(stringify(res["${ retryCond }"]) === '${ stringify(option) }')`;
         }
     }
 
@@ -68,12 +68,12 @@ function _compileErrorCheckCondition(retryDefinition) {
         if (Array.isArray(retryDefinition[catchCond])) {
             const orCondition = retryDefinition[catchCond].map(option =>
                 createCondition(catchCond, option));
-            condition.push(`(${orCondition.join(' || ')})`);
+            condition.push(`(${ orCondition.join(' || ') })`);
         } else {
             condition.push(createCondition(catchCond, retryDefinition[catchCond]));
         }
     });
-    const code = `return (${condition.join(' && ')});`;
+    const code = `return (${ condition.join(' && ') });`;
     /* jslint evil: true */
     /* eslint-disable no-new-func */
     return new Function('stringify', 'res', code).bind(null, stringify);
@@ -82,9 +82,9 @@ function _compileErrorCheckCondition(retryDefinition) {
 
 function _getMatchObjCode(obj) {
     if (obj.constructor === Object) {
-        return `{${Object.keys(obj).map((key) => {
-            return `${key}: ${_getMatchObjCode(obj[key])}`;
-        }).join(', ')}}`;
+        return `{${ Object.keys(obj).map((key) => {
+            return `${ key }: ${ _getMatchObjCode(obj[key]) }`;
+        }).join(', ') }}`;
     }
     return obj;
 }
@@ -96,32 +96,32 @@ function _compileNamedRegex(obj, result, name, fieldName) {
         return '(';
     });
     /* eslint-disable-next-line security/detect-non-literal-regexp */
-    const numGroups = (new RegExp(`${normalRegex.toString()}|`)).exec('').length - 1;
+    const numGroups = (new RegExp(`${ normalRegex.toString() }|`)).exec('').length - 1;
 
     if (captureNames.length && captureNames.length !== numGroups) {
-        throw new Error(`${'Invalid match regex. ' +
-        'Mixing named and unnamed capture groups are not supported. Regex: '}${obj}`);
+        throw new Error(`${ 'Invalid match regex. ' +
+        'Mixing named and unnamed capture groups are not supported. Regex: ' }${ obj }`);
     }
 
     if (!captureNames.length) {
         // No named captures
-        result[fieldName] = `${normalRegex}.exec(${name})`;
+        result[fieldName] = `${ normalRegex }.exec(${ name })`;
     } else {
-        let code = `(() => { const execRes = ${normalRegex}.exec(${name}); const res = {}; `;
+        let code = `(() => { const execRes = ${ normalRegex }.exec(${ name }); const res = {}; `;
         captureNames.forEach((captureName, index) => {
-            code += `res['${captureName}'] = execRes[${index + 1}]; `;
+            code += `res['${ captureName }'] = execRes[${ index + 1 }]; `;
         });
-        result[fieldName] = `${code}return res; })()`;
+        result[fieldName] = `${ code }return res; })()`;
     }
 
-    return `typeof ${name} === "string" && ${normalRegex}.test(${name})`;
+    return `typeof ${ name } === "string" && ${ normalRegex }.test(${ name })`;
 }
 
 function _compileMatch(obj, result, name, fieldName) {
     function _compileArrayMatch(objToSearch, nameToSearch) {
         const itemsCheck = objToSearch.map((item, index) =>
-            `${nameToSearch}.find((item) => ${_compileMatch(item, {}, 'item', index)})`).join(' && ');
-        return `Array.isArray(${nameToSearch})${itemsCheck.length ? (` && ${itemsCheck}`) : ''}`;
+            `${ nameToSearch }.find((item) => ${ _compileMatch(item, {}, 'item', index) })`).join(' && ');
+        return `Array.isArray(${ nameToSearch })${ itemsCheck.length ? (` && ${ itemsCheck }`) : '' }`;
     }
 
     if (obj.constructor !== Object) {
@@ -129,17 +129,17 @@ function _compileMatch(obj, result, name, fieldName) {
             return _compileArrayMatch(obj, name);
         }
         if (obj === 'undefined') {
-            return `${name} === undefined`;
+            return `${ name } === undefined`;
         }
         if (typeof obj !== 'string') {
             // not a string, so it has to match exactly
             result[fieldName] = obj;
-            return `${name} === ${obj}`;
+            return `${ name } === ${ obj }`;
         }
         if (!/^\/.+\/[gimuy]{0,5}$/.test(obj)) {
             // not a regex, quote the string
-            result[fieldName] = `'${obj}'`;
-            return `${name} === '${obj}'`;
+            result[fieldName] = `'${ obj }'`;
+            return `${ name } === '${ obj }'`;
         }
         // it's a regex, we have to the test the arg
         return _compileNamedRegex(obj, result, name, fieldName);
@@ -149,9 +149,9 @@ function _compileMatch(obj, result, name, fieldName) {
     const subObj = fieldName ? {} : result;
     const test = Object.keys(obj).map(
         (key) => {
-            const propertyName = `${name}['${key}']`;
+            const propertyName = `${ name }['${ key }']`;
             if (obj[key].constructor === Object) {
-                return `${propertyName} && ${_compileMatch(obj[key], subObj, propertyName, key)}`;
+                return `${ propertyName } && ${ _compileMatch(obj[key], subObj, propertyName, key) }`;
             }
             return _compileMatch(obj[key], subObj, propertyName, key);
         })
@@ -169,7 +169,7 @@ class Rule {
 
         const topics = this.spec.topics || (this.spec.topic && [ this.spec.topic ]);
         if (!topics || !Array.isArray(topics) || !topics.length) {
-            throw new Error(`No topics specified for rule ${this.name}`);
+            throw new Error(`No topics specified for rule ${ this.name }`);
         }
         this.topics = topics;
         if (this.spec.exclude_topics) {
@@ -208,7 +208,7 @@ class Rule {
                 try {
                     this._limiterKeyTemplates[type] = new Template(this.spec.limiters[type]);
                 } catch (e) {
-                    throw new Error(`Compilation failed for limiter ${type}. Error: ${e.message}`);
+                    throw new Error(`Compilation failed for limiter ${ type }. Error: ${ e.message }`);
                 }
             });
         }
@@ -344,9 +344,9 @@ class Rule {
             return {
                 /* eslint-disable no-new-func */
                 /* jslint evil: true  */
-                test: new Function('message', `return ${test}`),
+                test: new Function('message', `return ${ test }`),
                 /* jslint evil: true  */
-                expand: new Function('message', `return ${_getMatchObjCode(obj)}`)
+                expand: new Function('message', `return ${ _getMatchObjCode(obj) }`)
                 /* eslint-enable no-new-func */
             };
         } catch (e) {
@@ -369,7 +369,7 @@ class Rule {
         for (let idx = 0; idx < exec.length; idx++) {
             const req = exec[idx];
             if (req.constructor !== Object || !req.uri) {
-                throw new Error(`In rule ${this.name}, request number ${idx}
+                throw new Error(`In rule ${ this.name }, request number ${ idx }
                     must be an object and must have the "uri" property`);
             }
             req.method = req.method || 'get';
diff --git a/lib/rule_executor.js b/lib/rule_executor.js
index c2b277e..7b1a972 100644
--- a/lib/rule_executor.js
+++ b/lib/rule_executor.js
@@ -8,12 +8,12 @@ const URI = require('hyperswitch').URI;
  */
 class RuleExecutor extends BaseExecutor {
     get subscribeTopics() {
-        return this.rule.topics.map(topic => `${this.kafkaFactory.consumeDC}.${topic}`);
+        return this.rule.topics.map(topic => `${ this.kafkaFactory.consumeDC }.${ topic }`);
     }
 
     statName(event) {
         return this._hyper.metrics.normalizeName(
-            `${this.rule.name}-${event.meta.stream.replace(/\./g, '_')}`);
+            `${ this.rule.name }-${ event.meta.stream.replace(/\./g, '_') }`);
     }
 
     /**
@@ -48,10 +48,10 @@ class RuleExecutor extends BaseExecutor {
         if (this.rule.topics.length === 1) {
             dedupeKey = this.rule.name;
         } else {
-            dedupeKey = `${this.rule.name}-${expander.message.meta.stream}`;
+            dedupeKey = `${ this.rule.name }-${ expander.message.meta.stream }`;
         }
         return this._hyper.post({
-            uri: new URI(`/sys/dedupe/${dedupeKey}`),
+            uri: new URI(`/sys/dedupe/${ dedupeKey }`),
             body: expander.message
         })
         .get('body')
diff --git a/lib/utils.js b/lib/utils.js
index e76b34e..d345b05 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -15,9 +15,9 @@ utils.triggeredBy = (event) => {
     if (prevTrigger) {
         prevTrigger += ',';
     } else {
-        prevTrigger = `req:${event.meta.request_id},`;
+        prevTrigger = `req:${ event.meta.request_id },`;
     }
-    return `${prevTrigger + event.meta.stream}:${event.meta.uri}`;
+    return `${ prevTrigger + event.meta.stream }:${ event.meta.uri }`;
 };
 
 utils.requestId = () => uuidv1();
@@ -50,12 +50,12 @@ utils.constructRegex = (list) => {
     const regex = list.map((regexString) => {
         regexString = regexString.trim();
         if (/^\/.+\/$/.test(regexString)) {
-            return `(?:${regexString.slice(1, regexString.length - 1)})`;
+            return `(?:${ regexString.slice(1, regexString.length - 1) })`;
         }
         // Compare strings, instead
         const slash = /^\//.test(regexString) ? '' : '/';
-        return `(?:${slash}${decodeURIComponent(regexString)
-        .replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&')}$)`;
+        return `(?:${ slash }${ decodeURIComponent(regexString)
+        .replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&') }$)`;
     }).join('|');
     /* eslint-disable-next-line security/detect-non-literal-regexp */
     return new RegExp(regex);
diff --git a/package-lock.json b/package-lock.json
index 510da93..3d58699 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
 	"name": "change-propagation",
-	"version": "0.11.0",
+	"version": "0.12.0",
 	"lockfileVersion": 3,
 	"requires": true,
 	"packages": {
 		"": {
 			"name": "change-propagation",
-			"version": "0.11.0",
+			"version": "0.12.0",
 			"license": "Apache-2.0",
 			"dependencies": {
 				"bluebird": "^3.7.2",
@@ -26,7 +26,7 @@
 				"@wikimedia/jsonschema-tools": "^0.7.5",
 				"ajv": "^6.12.2",
 				"coveralls": "^3.1.0",
-				"eslint-config-wikimedia": "0.25.1",
+				"eslint-config-wikimedia": "0.27.0",
 				"js-yaml": "^3.14.0",
 				"kafka-test-tools": "^0.1.13",
 				"mocha": "^8.0.1",
@@ -50,12 +50,16 @@
 			}
 		},
 		"node_modules/@babel/code-frame": {
-			"version": "7.12.11",
-			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
-			"integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
+			"version": "7.24.2",
+			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
+			"integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
 			"dev": true,
 			"dependencies": {
-				"@babel/highlight": "^7.10.4"
+				"@babel/highlight": "^7.24.2",
+				"picocolors": "^1.0.0"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/core": {
@@ -89,43 +93,61 @@
 			}
 		},
 		"node_modules/@babel/core/node_modules/semver": {
-			"version": "5.7.1",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-			"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+			"version": "5.7.2",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+			"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
 			"dev": true,
 			"bin": {
 				"semver": "bin/semver"
 			}
 		},
 		"node_modules/@babel/generator": {
-			"version": "7.12.11",
-			"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz",
-			"integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz",
+			"integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==",
 			"dev": true,
 			"dependencies": {
-				"@babel/types": "^7.12.11",
-				"jsesc": "^2.5.1",
-				"source-map": "^0.5.0"
+				"@babel/types": "^7.24.5",
+				"@jridgewell/gen-mapping": "^0.3.5",
+				"@jridgewell/trace-mapping": "^0.3.25",
+				"jsesc": "^2.5.1"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-environment-visitor": {
+			"version": "7.22.20",
+			"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+			"integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+			"dev": true,
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/helper-function-name": {
-			"version": "7.12.11",
-			"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz",
-			"integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==",
+			"version": "7.23.0",
+			"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+			"integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
 			"dev": true,
 			"dependencies": {
-				"@babel/helper-get-function-arity": "^7.12.10",
-				"@babel/template": "^7.12.7",
-				"@babel/types": "^7.12.11"
+				"@babel/template": "^7.22.15",
+				"@babel/types": "^7.23.0"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
-		"node_modules/@babel/helper-get-function-arity": {
-			"version": "7.12.10",
-			"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz",
-			"integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==",
+		"node_modules/@babel/helper-hoist-variables": {
+			"version": "7.22.5",
+			"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+			"integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
 			"dev": true,
 			"dependencies": {
-				"@babel/types": "^7.12.10"
+				"@babel/types": "^7.22.5"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/helper-member-expression-to-functions": {
@@ -194,18 +216,30 @@
 			}
 		},
 		"node_modules/@babel/helper-split-export-declaration": {
-			"version": "7.12.11",
-			"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz",
-			"integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz",
+			"integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==",
 			"dev": true,
 			"dependencies": {
-				"@babel/types": "^7.12.11"
+				"@babel/types": "^7.24.5"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-string-parser": {
+			"version": "7.24.1",
+			"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
+			"integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
+			"dev": true,
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/helper-validator-identifier": {
-			"version": "7.22.20",
-			"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
-			"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz",
+			"integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==",
 			"dev": true,
 			"engines": {
 				"node": ">=6.9.0"
@@ -223,20 +257,24 @@
 			}
 		},
 		"node_modules/@babel/highlight": {
-			"version": "7.10.4",
-			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
-			"integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz",
+			"integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==",
 			"dev": true,
 			"dependencies": {
-				"@babel/helper-validator-identifier": "^7.10.4",
-				"chalk": "^2.0.0",
-				"js-tokens": "^4.0.0"
+				"@babel/helper-validator-identifier": "^7.24.5",
+				"chalk": "^2.4.2",
+				"js-tokens": "^4.0.0",
+				"picocolors": "^1.0.0"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/parser": {
-			"version": "7.12.11",
-			"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz",
-			"integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz",
+			"integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==",
 			"dev": true,
 			"bin": {
 				"parser": "bin/babel-parser.js"
@@ -246,31 +284,38 @@
 			}
 		},
 		"node_modules/@babel/template": {
-			"version": "7.12.7",
-			"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz",
-			"integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==",
+			"version": "7.24.0",
+			"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
+			"integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
 			"dev": true,
 			"dependencies": {
-				"@babel/code-frame": "^7.10.4",
-				"@babel/parser": "^7.12.7",
-				"@babel/types": "^7.12.7"
+				"@babel/code-frame": "^7.23.5",
+				"@babel/parser": "^7.24.0",
+				"@babel/types": "^7.24.0"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/traverse": {
-			"version": "7.12.12",
-			"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz",
-			"integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.5.tgz",
+			"integrity": "sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==",
 			"dev": true,
 			"dependencies": {
-				"@babel/code-frame": "^7.12.11",
-				"@babel/generator": "^7.12.11",
-				"@babel/helper-function-name": "^7.12.11",
-				"@babel/helper-split-export-declaration": "^7.12.11",
-				"@babel/parser": "^7.12.11",
-				"@babel/types": "^7.12.12",
-				"debug": "^4.1.0",
-				"globals": "^11.1.0",
-				"lodash": "^4.17.19"
+				"@babel/code-frame": "^7.24.2",
+				"@babel/generator": "^7.24.5",
+				"@babel/helper-environment-visitor": "^7.22.20",
+				"@babel/helper-function-name": "^7.23.0",
+				"@babel/helper-hoist-variables": "^7.22.5",
+				"@babel/helper-split-export-declaration": "^7.24.5",
+				"@babel/parser": "^7.24.5",
+				"@babel/types": "^7.24.5",
+				"debug": "^4.3.1",
+				"globals": "^11.1.0"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/traverse/node_modules/globals": {
@@ -283,28 +328,31 @@
 			}
 		},
 		"node_modules/@babel/types": {
-			"version": "7.12.12",
-			"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz",
-			"integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz",
+			"integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==",
 			"dev": true,
 			"dependencies": {
-				"@babel/helper-validator-identifier": "^7.12.11",
-				"lodash": "^4.17.19",
+				"@babel/helper-string-parser": "^7.24.1",
+				"@babel/helper-validator-identifier": "^7.24.5",
 				"to-fast-properties": "^2.0.0"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@es-joy/jsdoccomment": {
-			"version": "0.23.6",
-			"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.23.6.tgz",
-			"integrity": "sha512-cCtumxG+qrYORGeOkDQ58GtSt/bb2XiP9GC0x2YduoUEX2EmBQ48FtoZMUs+8wiIdTDN1izUiRUD2FDu+p+Lvg==",
+			"version": "0.42.0",
+			"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz",
+			"integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==",
 			"dev": true,
 			"dependencies": {
-				"comment-parser": "1.3.1",
-				"esquery": "^1.4.0",
-				"jsdoc-type-pratt-parser": "~2.2.5"
+				"comment-parser": "1.4.1",
+				"esquery": "^1.5.0",
+				"jsdoc-type-pratt-parser": "~4.0.0"
 			},
 			"engines": {
-				"node": "^12 || ^14 || ^16 || ^17"
+				"node": ">=16"
 			}
 		},
 		"node_modules/@eslint-community/eslint-utils": {
@@ -332,9 +380,9 @@
 			}
 		},
 		"node_modules/@eslint/eslintrc": {
-			"version": "2.1.2",
-			"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz",
-			"integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==",
+			"version": "2.1.4",
+			"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+			"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
 			"dev": true,
 			"dependencies": {
 				"ajv": "^6.12.4",
@@ -385,9 +433,9 @@
 			}
 		},
 		"node_modules/@eslint/js": {
-			"version": "8.51.0",
-			"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz",
-			"integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==",
+			"version": "8.57.0",
+			"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+			"integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
 			"dev": true,
 			"engines": {
 				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -401,13 +449,13 @@
 			"dev": true
 		},
 		"node_modules/@humanwhocodes/config-array": {
-			"version": "0.11.11",
-			"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
-			"integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==",
+			"version": "0.11.14",
+			"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
+			"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
 			"dev": true,
 			"dependencies": {
-				"@humanwhocodes/object-schema": "^1.2.1",
-				"debug": "^4.1.1",
+				"@humanwhocodes/object-schema": "^2.0.2",
+				"debug": "^4.3.1",
 				"minimatch": "^3.0.5"
 			},
 			"engines": {
@@ -440,9 +488,9 @@
 			}
 		},
 		"node_modules/@humanwhocodes/object-schema": {
-			"version": "1.2.1",
-			"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
-			"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+			"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
 			"dev": true
 		},
 		"node_modules/@istanbuljs/load-nyc-config": {
@@ -525,6 +573,54 @@
 				"node": ">=8"
 			}
 		},
+		"node_modules/@jridgewell/gen-mapping": {
+			"version": "0.3.5",
+			"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+			"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+			"dev": true,
+			"dependencies": {
+				"@jridgewell/set-array": "^1.2.1",
+				"@jridgewell/sourcemap-codec": "^1.4.10",
+				"@jridgewell/trace-mapping": "^0.3.24"
+			},
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
+		"node_modules/@jridgewell/resolve-uri": {
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+			"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+			"dev": true,
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
+		"node_modules/@jridgewell/set-array": {
+			"version": "1.2.1",
+			"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+			"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+			"dev": true,
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
+		"node_modules/@jridgewell/sourcemap-codec": {
+			"version": "1.4.15",
+			"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+			"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+			"dev": true
+		},
+		"node_modules/@jridgewell/trace-mapping": {
+			"version": "0.3.25",
+			"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+			"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+			"dev": true,
+			"dependencies": {
+				"@jridgewell/resolve-uri": "^3.1.0",
+				"@jridgewell/sourcemap-codec": "^1.4.14"
+			}
+		},
 		"node_modules/@mdn/browser-compat-data": {
 			"version": "5.3.23",
 			"resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.3.23.tgz",
@@ -566,18 +662,158 @@
 				"node": ">= 8"
 			}
 		},
+		"node_modules/@types/json-schema": {
+			"version": "7.0.15",
+			"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+			"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+			"dev": true
+		},
 		"node_modules/@types/normalize-package-data": {
-			"version": "2.4.2",
-			"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.2.tgz",
-			"integrity": "sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==",
+			"version": "2.4.4",
+			"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
+			"integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
+			"dev": true
+		},
+		"node_modules/@types/semver": {
+			"version": "7.5.8",
+			"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
+			"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
 			"dev": true
 		},
+		"node_modules/@typescript-eslint/scope-manager": {
+			"version": "5.62.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
+			"integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "5.62.0",
+				"@typescript-eslint/visitor-keys": "5.62.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@typescript-eslint/types": {
+			"version": "5.62.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
+			"integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
+			"dev": true,
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@typescript-eslint/typescript-estree": {
+			"version": "5.62.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz",
+			"integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "5.62.0",
+				"@typescript-eslint/visitor-keys": "5.62.0",
+				"debug": "^4.3.4",
+				"globby": "^11.1.0",
+				"is-glob": "^4.0.3",
+				"semver": "^7.3.7",
+				"tsutils": "^3.21.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependenciesMeta": {
+				"typescript": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/@typescript-eslint/utils": {
+			"version": "5.62.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz",
+			"integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==",
+			"dev": true,
+			"dependencies": {
+				"@eslint-community/eslint-utils": "^4.2.0",
+				"@types/json-schema": "^7.0.9",
+				"@types/semver": "^7.3.12",
+				"@typescript-eslint/scope-manager": "5.62.0",
+				"@typescript-eslint/types": "5.62.0",
+				"@typescript-eslint/typescript-estree": "5.62.0",
+				"eslint-scope": "^5.1.1",
+				"semver": "^7.3.7"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+			}
+		},
+		"node_modules/@typescript-eslint/utils/node_modules/eslint-scope": {
+			"version": "5.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+			"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+			"dev": true,
+			"dependencies": {
+				"esrecurse": "^4.3.0",
+				"estraverse": "^4.1.1"
+			},
+			"engines": {
+				"node": ">=8.0.0"
+			}
+		},
+		"node_modules/@typescript-eslint/utils/node_modules/estraverse": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+			"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+			"dev": true,
+			"engines": {
+				"node": ">=4.0"
+			}
+		},
+		"node_modules/@typescript-eslint/visitor-keys": {
+			"version": "5.62.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
+			"integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "5.62.0",
+				"eslint-visitor-keys": "^3.3.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
 		"node_modules/@ungap/promise-all-settled": {
 			"version": "1.1.2",
 			"resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
 			"integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
 			"dev": true
 		},
+		"node_modules/@ungap/structured-clone": {
+			"version": "1.2.0",
+			"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+			"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
+			"dev": true
+		},
 		"node_modules/@wikimedia/jsonschema-tools": {
 			"version": "0.7.7",
 			"resolved": "https://registry.npmjs.org/@wikimedia/jsonschema-tools/-/jsonschema-tools-0.7.7.tgz",
@@ -602,9 +838,9 @@
 			}
 		},
 		"node_modules/@wikimedia/jsonschema-tools/node_modules/semver": {
-			"version": "6.3.0",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-			"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+			"version": "6.3.1",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+			"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
 			"dev": true,
 			"bin": {
 				"semver": "bin/semver.js"
@@ -669,9 +905,9 @@
 			}
 		},
 		"node_modules/ansi-regex": {
-			"version": "4.1.0",
-			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
-			"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+			"version": "4.1.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+			"integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
 			"engines": {
 				"node": ">=6"
 			}
@@ -688,9 +924,9 @@
 			}
 		},
 		"node_modules/anymatch": {
-			"version": "3.1.1",
-			"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
-			"integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+			"version": "3.1.3",
+			"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+			"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
 			"dev": true,
 			"dependencies": {
 				"normalize-path": "^3.0.0",
@@ -718,6 +954,15 @@
 			"integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
 			"dev": true
 		},
+		"node_modules/are-docs-informative": {
+			"version": "0.0.2",
+			"resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz",
+			"integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==",
+			"dev": true,
+			"engines": {
+				"node": ">=14"
+			}
+		},
 		"node_modules/argparse": {
 			"version": "1.0.10",
 			"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -750,6 +995,15 @@
 				"node": ">=6"
 			}
 		},
+		"node_modules/array-union": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+			"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/asap": {
 			"version": "2.0.6",
 			"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
@@ -827,12 +1081,15 @@
 			}
 		},
 		"node_modules/binary-extensions": {
-			"version": "2.2.0",
-			"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
-			"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+			"version": "2.3.0",
+			"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+			"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
 			"dev": true,
 			"engines": {
 				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
 		"node_modules/bindings": {
@@ -897,9 +1154,9 @@
 			"dev": true
 		},
 		"node_modules/browserslist": {
-			"version": "4.22.1",
-			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
-			"integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
+			"version": "4.23.0",
+			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
+			"integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
 			"dev": true,
 			"funding": [
 				{
@@ -916,9 +1173,9 @@
 				}
 			],
 			"dependencies": {
-				"caniuse-lite": "^1.0.30001541",
-				"electron-to-chromium": "^1.4.535",
-				"node-releases": "^2.0.13",
+				"caniuse-lite": "^1.0.30001587",
+				"electron-to-chromium": "^1.4.668",
+				"node-releases": "^2.0.14",
 				"update-browserslist-db": "^1.0.13"
 			},
 			"bin": {
@@ -929,9 +1186,9 @@
 			}
 		},
 		"node_modules/browserslist-config-wikimedia": {
-			"version": "0.5.1",
-			"resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.5.1.tgz",
-			"integrity": "sha512-jf532fUf/gaxiKdHgGCQUT552P5up3RpG+CzLixOQBJ5FwDmYQSRLYHCFUA9s3KMOHh4P3xVp+NUaGNxvtoT9g==",
+			"version": "0.6.1",
+			"resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.6.1.tgz",
+			"integrity": "sha512-F3O+12ud7ZwBaiB/RZIMGDgz3nEuXz8RhtdPB4Lkd/WVP5Vy77EqBWRMz4vJ64x8LTTH3BOaHCD2ZuUcgShqyQ==",
 			"dev": true
 		},
 		"node_modules/builtin-modules": {
@@ -946,6 +1203,15 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
+		"node_modules/builtins": {
+			"version": "5.1.0",
+			"resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz",
+			"integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==",
+			"dev": true,
+			"dependencies": {
+				"semver": "^7.0.0"
+			}
+		},
 		"node_modules/bunyan": {
 			"version": "1.8.15",
 			"resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz",
@@ -1018,9 +1284,9 @@
 			}
 		},
 		"node_modules/caniuse-lite": {
-			"version": "1.0.30001549",
-			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001549.tgz",
-			"integrity": "sha512-qRp48dPYSCYaP+KurZLhDYdVE+yEyht/3NlmcJgVQ2VMGt6JL36ndQ/7rgspdZsJuxDPFIo/OzBT2+GmIJ53BA==",
+			"version": "1.0.30001614",
+			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001614.tgz",
+			"integrity": "sha512-jmZQ1VpmlRwHgdP1/uiKzgiAuGOfLEJsYFP4+GBou/QQ4U6IOJCB4NP1c+1p9RGLpwObcT94jA5/uO+F1vBbog==",
 			"dev": true,
 			"funding": [
 				{
@@ -1057,9 +1323,9 @@
 			}
 		},
 		"node_modules/chokidar": {
-			"version": "3.4.3",
-			"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz",
-			"integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==",
+			"version": "3.5.1",
+			"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
+			"integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
 			"dev": true,
 			"dependencies": {
 				"anymatch": "~3.1.1",
@@ -1074,13 +1340,13 @@
 				"node": ">= 8.10.0"
 			},
 			"optionalDependencies": {
-				"fsevents": "~2.1.2"
+				"fsevents": "~2.3.1"
 			}
 		},
 		"node_modules/ci-info": {
-			"version": "3.9.0",
-			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
-			"integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz",
+			"integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==",
 			"dev": true,
 			"funding": [
 				{
@@ -1095,7 +1361,7 @@
 		"node_modules/clarinet": {
 			"version": "0.11.0",
 			"resolved": "https://registry.npmjs.org/clarinet/-/clarinet-0.11.0.tgz",
-			"integrity": "sha1-bMkSuTE43IZ/wnPNNOqQ6D4FRxk=",
+			"integrity": "sha512-6hgoCgDgdyEtrXsk1tMomUl+S6wnslv2F1muNTOuhQemOhauR+Q0FtBdrj9k+qyIDLm0TVW0QMZ10aeWwRDgIA==",
 			"engines": {
 				"chrome": ">=16.0.912",
 				"firefox": ">=0.8.0",
@@ -1166,9 +1432,9 @@
 			}
 		},
 		"node_modules/comment-parser": {
-			"version": "1.3.1",
-			"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz",
-			"integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==",
+			"version": "1.4.1",
+			"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
+			"integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
 			"dev": true,
 			"engines": {
 				"node": ">= 12.0.0"
@@ -1224,15 +1490,28 @@
 			"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
 			"dev": true
 		},
+		"node_modules/core-js-compat": {
+			"version": "3.37.0",
+			"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz",
+			"integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==",
+			"dev": true,
+			"dependencies": {
+				"browserslist": "^4.23.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/core-js"
+			}
+		},
 		"node_modules/core-util-is": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
 			"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
 		},
 		"node_modules/coveralls": {
-			"version": "3.1.0",
-			"resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.0.tgz",
-			"integrity": "sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ==",
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz",
+			"integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==",
 			"dev": true,
 			"dependencies": {
 				"js-yaml": "^3.13.1",
@@ -1371,14 +1650,26 @@
 			}
 		},
 		"node_modules/diff": {
-			"version": "4.0.2",
-			"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
-			"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+			"version": "5.0.0",
+			"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
+			"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
 			"dev": true,
 			"engines": {
 				"node": ">=0.3.1"
 			}
 		},
+		"node_modules/dir-glob": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+			"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+			"dev": true,
+			"dependencies": {
+				"path-type": "^4.0.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/dnscache": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/dnscache/-/dnscache-1.0.2.tgz",
@@ -1431,9 +1722,9 @@
 			}
 		},
 		"node_modules/electron-to-chromium": {
-			"version": "1.4.556",
-			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.556.tgz",
-			"integrity": "sha512-6RPN0hHfzDU8D56E72YkDvnLw5Cj2NMXZGg3UkgyoHxjVhG99KZpsKgBWMmTy0Ei89xwan+rbRsVB9yzATmYzQ==",
+			"version": "1.4.751",
+			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.751.tgz",
+			"integrity": "sha512-2DEPi++qa89SMGRhufWTiLmzqyuGmNF3SK4+PQetW1JKiZdEpF4XQonJXJCzyuYSA6mauiMhbyVhqYAP45Hvfw==",
 			"dev": true
 		},
 		"node_modules/emoji-regex": {
@@ -1484,18 +1775,19 @@
 			}
 		},
 		"node_modules/eslint": {
-			"version": "8.51.0",
-			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz",
-			"integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==",
+			"version": "8.57.0",
+			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+			"integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
 			"dev": true,
 			"dependencies": {
 				"@eslint-community/eslint-utils": "^4.2.0",
 				"@eslint-community/regexpp": "^4.6.1",
-				"@eslint/eslintrc": "^2.1.2",
-				"@eslint/js": "8.51.0",
-				"@humanwhocodes/config-array": "^0.11.11",
+				"@eslint/eslintrc": "^2.1.4",
+				"@eslint/js": "8.57.0",
+				"@humanwhocodes/config-array": "^0.11.14",
 				"@humanwhocodes/module-importer": "^1.0.1",
 				"@nodelib/fs.walk": "^1.2.8",
+				"@ungap/structured-clone": "^1.2.0",
 				"ajv": "^6.12.4",
 				"chalk": "^4.0.0",
 				"cross-spawn": "^7.0.2",
@@ -1537,28 +1829,44 @@
 				"url": "https://opencollective.com/eslint"
 			}
 		},
+		"node_modules/eslint-compat-utils": {
+			"version": "0.5.0",
+			"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz",
+			"integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==",
+			"dev": true,
+			"dependencies": {
+				"semver": "^7.5.4"
+			},
+			"engines": {
+				"node": ">=12"
+			},
+			"peerDependencies": {
+				"eslint": ">=6.0.0"
+			}
+		},
 		"node_modules/eslint-config-wikimedia": {
-			"version": "0.25.1",
-			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.25.1.tgz",
-			"integrity": "sha512-1ppDlbwSSPuMLAIzvTXSDWNOEq3VnRu82jbc1jaG0aCjE3PpBVOEKUh0bbCk/mFVWEocUNeYIYeL9BHADq9ReA==",
+			"version": "0.27.0",
+			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.27.0.tgz",
+			"integrity": "sha512-KkZ54+MUnggz17C/RCEMXQSpiiqZRF7p9fjrz4phaaeKlTrjg0B+QbM5zcDWcjGiAWaJUptHaH17+RZldadkUw==",
 			"dev": true,
 			"dependencies": {
-				"browserslist-config-wikimedia": "^0.5.0",
-				"eslint": "^8.31.0",
-				"eslint-plugin-compat": "^4.1.4",
-				"eslint-plugin-es-x": "^5.2.1",
-				"eslint-plugin-jsdoc": "39.2.2",
+				"browserslist-config-wikimedia": "^0.6.1",
+				"eslint": "^8.57.0",
+				"eslint-plugin-compat": "^4.2.0",
+				"eslint-plugin-es-x": "^7.6.0",
+				"eslint-plugin-jest": "^27.9.0",
+				"eslint-plugin-jsdoc": "48.2.1",
 				"eslint-plugin-json-es": "^1.5.7",
-				"eslint-plugin-mediawiki": "^0.5.0",
-				"eslint-plugin-mocha": "^9.0.0",
+				"eslint-plugin-mediawiki": "^0.6.0",
+				"eslint-plugin-mocha": "^10.4.1",
+				"eslint-plugin-n": "^16.6.2",
 				"eslint-plugin-no-jquery": "^2.7.0",
-				"eslint-plugin-node": "^11.1.0",
-				"eslint-plugin-qunit": "^7.3.0",
+				"eslint-plugin-qunit": "^8.1.1",
 				"eslint-plugin-security": "^1.7.1",
-				"eslint-plugin-unicorn": "^42.0.0",
-				"eslint-plugin-vue": "^8.7.1",
-				"eslint-plugin-wdio": "^7.19.4",
-				"eslint-plugin-yml": "^0.14.0"
+				"eslint-plugin-unicorn": "^51.0.1",
+				"eslint-plugin-vue": "^9.23.0",
+				"eslint-plugin-wdio": "^8.24.12",
+				"eslint-plugin-yml": "^1.13.2"
 			}
 		},
 		"node_modules/eslint-plugin-compat": {
@@ -1653,43 +1961,71 @@
 			}
 		},
 		"node_modules/eslint-plugin-es-x": {
-			"version": "5.4.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-5.4.0.tgz",
-			"integrity": "sha512-6Mniw760Nhd6brnDy+rz857LD+icZe5wXmsvXSuJ84svM0Q53ulJxpMhTJmpqHaLzYh7fuGAJ8V62ohbmqF+jA==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz",
+			"integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==",
 			"dev": true,
 			"dependencies": {
-				"eslint-utils": "^2.0.0 || ^3.0.0",
-				"regexpp": "^3.0.0"
+				"@eslint-community/eslint-utils": "^4.1.2",
+				"@eslint-community/regexpp": "^4.6.0",
+				"eslint-compat-utils": "^0.5.0"
 			},
 			"engines": {
-				"node": ">=8.10.0"
+				"node": "^14.18.0 || >=16.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/ota-meshi"
 			},
 			"peerDependencies": {
-				"eslint": ">=4.19.1"
+				"eslint": ">=8"
+			}
+		},
+		"node_modules/eslint-plugin-jest": {
+			"version": "27.9.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz",
+			"integrity": "sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/utils": "^5.10.0"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			},
+			"peerDependencies": {
+				"@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0 || ^7.0.0",
+				"eslint": "^7.0.0 || ^8.0.0",
+				"jest": "*"
+			},
+			"peerDependenciesMeta": {
+				"@typescript-eslint/eslint-plugin": {
+					"optional": true
+				},
+				"jest": {
+					"optional": true
+				}
 			}
 		},
 		"node_modules/eslint-plugin-jsdoc": {
-			"version": "39.2.2",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.2.2.tgz",
-			"integrity": "sha512-ybkvja0p9JRzHEd2ST9h+Z47DLOuPyXpeb6r18/zKHdMmggPU1J0/zl+F0phea8ze9rMxi42MJVmGXi2NZ7PpA==",
+			"version": "48.2.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.1.tgz",
+			"integrity": "sha512-iUvbcyDZSO/9xSuRv2HQBw++8VkV/pt3UWtX9cpPH0l7GKPq78QC/6+PmyQHHvNZaTjAce6QVciEbnc6J/zH5g==",
 			"dev": true,
 			"dependencies": {
-				"@es-joy/jsdoccomment": "~0.23.1",
-				"comment-parser": "1.3.1",
+				"@es-joy/jsdoccomment": "~0.42.0",
+				"are-docs-informative": "^0.0.2",
+				"comment-parser": "1.4.1",
 				"debug": "^4.3.4",
 				"escape-string-regexp": "^4.0.0",
-				"esquery": "^1.4.0",
-				"semver": "^7.3.7",
-				"spdx-expression-parse": "^3.0.1"
+				"esquery": "^1.5.0",
+				"is-builtin-module": "^3.2.1",
+				"semver": "^7.6.0",
+				"spdx-expression-parse": "^4.0.0"
 			},
 			"engines": {
-				"node": "^14 || ^16 || ^17"
+				"node": ">=18"
 			},
 			"peerDependencies": {
-				"eslint": "^7.0.0 || ^8.0.0"
+				"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
 			}
 		},
 		"node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": {
@@ -1718,12 +2054,12 @@
 			}
 		},
 		"node_modules/eslint-plugin-mediawiki": {
-			"version": "0.5.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.5.0.tgz",
-			"integrity": "sha512-rjkHFyv3VDan/dmu7YpD1Rl9h64NOlz4mqqesRN316R+571+ymmb6lXVOdNMbT8H1iPhmtHc+nijVLVkn7pYDw==",
+			"version": "0.6.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.6.0.tgz",
+			"integrity": "sha512-a2Zm18N5nPyflBajM2ZWATxucIpYPEmOSjFzUR1OBH3hAL0GY9fx1mpezEwzqAQ862d+kPkolgQOzktnZe8nKA==",
 			"dev": true,
 			"dependencies": {
-				"eslint-plugin-vue": "^8.7.1",
+				"eslint-plugin-vue": "^9.23.0",
 				"upath": "^2.0.1"
 			},
 			"peerDependencies": {
@@ -1731,143 +2067,82 @@
 			}
 		},
 		"node_modules/eslint-plugin-mocha": {
-			"version": "9.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-9.0.0.tgz",
-			"integrity": "sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg==",
-			"dev": true,
-			"dependencies": {
-				"eslint-utils": "^3.0.0",
-				"ramda": "^0.27.1"
-			},
-			"engines": {
-				"node": ">=12.0.0"
-			},
-			"peerDependencies": {
-				"eslint": ">=7.0.0"
-			}
-		},
-		"node_modules/eslint-plugin-mocha/node_modules/eslint-utils": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-			"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
-			"dev": true,
-			"dependencies": {
-				"eslint-visitor-keys": "^2.0.0"
-			},
-			"engines": {
-				"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/mysticatea"
-			},
-			"peerDependencies": {
-				"eslint": ">=5"
-			}
-		},
-		"node_modules/eslint-plugin-mocha/node_modules/eslint-visitor-keys": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
-			"dev": true,
-			"engines": {
-				"node": ">=10"
-			}
-		},
-		"node_modules/eslint-plugin-no-jquery": {
-			"version": "2.7.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.7.0.tgz",
-			"integrity": "sha512-Aeg7dA6GTH1AcWLlBtWNzOU9efK5KpNi7b0EhBO0o0M+awyzguUUo8gF6hXGjQ9n5h8/uRtYv9zOqQkeC5CG0w==",
-			"dev": true,
-			"peerDependencies": {
-				"eslint": ">=2.3.0"
-			}
-		},
-		"node_modules/eslint-plugin-node": {
-			"version": "11.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
-			"integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==",
-			"dev": true,
-			"dependencies": {
-				"eslint-plugin-es": "^3.0.0",
-				"eslint-utils": "^2.0.0",
-				"ignore": "^5.1.1",
-				"minimatch": "^3.0.4",
-				"resolve": "^1.10.1",
-				"semver": "^6.1.0"
-			},
-			"engines": {
-				"node": ">=8.10.0"
-			},
-			"peerDependencies": {
-				"eslint": ">=5.16.0"
-			}
-		},
-		"node_modules/eslint-plugin-node/node_modules/eslint-plugin-es": {
-			"version": "3.0.1",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz",
-			"integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==",
-			"dev": true,
-			"dependencies": {
-				"eslint-utils": "^2.0.0",
-				"regexpp": "^3.0.0"
-			},
-			"engines": {
-				"node": ">=8.10.0"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/mysticatea"
-			},
-			"peerDependencies": {
-				"eslint": ">=4.19.1"
-			}
-		},
-		"node_modules/eslint-plugin-node/node_modules/semver": {
-			"version": "6.3.0",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-			"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-			"dev": true,
-			"bin": {
-				"semver": "bin/semver.js"
-			}
-		},
-		"node_modules/eslint-plugin-qunit": {
-			"version": "7.3.4",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-7.3.4.tgz",
-			"integrity": "sha512-EbDM0zJerH9zVdUswMJpcFF7wrrpvsGuYfNexUpa5hZkkdFhaFcX+yD+RSK4Nrauw4psMGlcqeWUMhaVo+Manw==",
+			"version": "10.4.3",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.3.tgz",
+			"integrity": "sha512-emc4TVjq5Ht0/upR+psftuz6IBG5q279p+1dSRDeHf+NS9aaerBi3lXKo1SEzwC29hFIW21gO89CEWSvRsi8IQ==",
 			"dev": true,
 			"dependencies": {
 				"eslint-utils": "^3.0.0",
-				"requireindex": "^1.2.0"
+				"globals": "^13.24.0",
+				"rambda": "^7.4.0"
 			},
 			"engines": {
-				"node": "12.x || 14.x || >=16.0.0"
+				"node": ">=14.0.0"
+			},
+			"peerDependencies": {
+				"eslint": ">=7.0.0"
 			}
 		},
-		"node_modules/eslint-plugin-qunit/node_modules/eslint-utils": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-			"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+		"node_modules/eslint-plugin-n": {
+			"version": "16.6.2",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz",
+			"integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==",
 			"dev": true,
 			"dependencies": {
-				"eslint-visitor-keys": "^2.0.0"
+				"@eslint-community/eslint-utils": "^4.4.0",
+				"builtins": "^5.0.1",
+				"eslint-plugin-es-x": "^7.5.0",
+				"get-tsconfig": "^4.7.0",
+				"globals": "^13.24.0",
+				"ignore": "^5.2.4",
+				"is-builtin-module": "^3.2.1",
+				"is-core-module": "^2.12.1",
+				"minimatch": "^3.1.2",
+				"resolve": "^1.22.2",
+				"semver": "^7.5.3"
 			},
 			"engines": {
-				"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
+				"node": ">=16.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/mysticatea"
 			},
 			"peerDependencies": {
-				"eslint": ">=5"
+				"eslint": ">=7.0.0"
 			}
 		},
-		"node_modules/eslint-plugin-qunit/node_modules/eslint-visitor-keys": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+		"node_modules/eslint-plugin-n/node_modules/minimatch": {
+			"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"
+			},
 			"engines": {
-				"node": ">=10"
+				"node": "*"
+			}
+		},
+		"node_modules/eslint-plugin-no-jquery": {
+			"version": "2.7.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.7.0.tgz",
+			"integrity": "sha512-Aeg7dA6GTH1AcWLlBtWNzOU9efK5KpNi7b0EhBO0o0M+awyzguUUo8gF6hXGjQ9n5h8/uRtYv9zOqQkeC5CG0w==",
+			"dev": true,
+			"peerDependencies": {
+				"eslint": ">=2.3.0"
+			}
+		},
+		"node_modules/eslint-plugin-qunit": {
+			"version": "8.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-8.1.1.tgz",
+			"integrity": "sha512-j3xhiAf2Wvr8Dfwl5T6tlJ+F55vqYE9ZdAHUOTzq1lGerYrXzOS46RvK4SSWug2D8sl3ZYr2lA4/hgVXgLloxw==",
+			"dev": true,
+			"dependencies": {
+				"eslint-utils": "^3.0.0",
+				"requireindex": "^1.2.0"
+			},
+			"engines": {
+				"node": "^16.0.0 || ^18.0.0 || >=20.0.0"
 			}
 		},
 		"node_modules/eslint-plugin-security": {
@@ -1880,132 +2155,95 @@
 			}
 		},
 		"node_modules/eslint-plugin-unicorn": {
-			"version": "42.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-42.0.0.tgz",
-			"integrity": "sha512-ixBsbhgWuxVaNlPTT8AyfJMlhyC5flCJFjyK3oKE8TRrwBnaHvUbuIkCM1lqg8ryYrFStL/T557zfKzX4GKSlg==",
+			"version": "51.0.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz",
+			"integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==",
 			"dev": true,
 			"dependencies": {
-				"@babel/helper-validator-identifier": "^7.15.7",
-				"ci-info": "^3.3.0",
+				"@babel/helper-validator-identifier": "^7.22.20",
+				"@eslint-community/eslint-utils": "^4.4.0",
+				"@eslint/eslintrc": "^2.1.4",
+				"ci-info": "^4.0.0",
 				"clean-regexp": "^1.0.0",
-				"eslint-utils": "^3.0.0",
-				"esquery": "^1.4.0",
+				"core-js-compat": "^3.34.0",
+				"esquery": "^1.5.0",
 				"indent-string": "^4.0.0",
-				"is-builtin-module": "^3.1.0",
-				"lodash": "^4.17.21",
+				"is-builtin-module": "^3.2.1",
+				"jsesc": "^3.0.2",
 				"pluralize": "^8.0.0",
 				"read-pkg-up": "^7.0.1",
-				"regexp-tree": "^0.1.24",
-				"safe-regex": "^2.1.1",
-				"semver": "^7.3.5",
+				"regexp-tree": "^0.1.27",
+				"regjsparser": "^0.10.0",
+				"semver": "^7.5.4",
 				"strip-indent": "^3.0.0"
 			},
 			"engines": {
-				"node": ">=12"
+				"node": ">=16"
 			},
 			"funding": {
 				"url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1"
 			},
 			"peerDependencies": {
-				"eslint": ">=8.8.0"
+				"eslint": ">=8.56.0"
 			}
 		},
-		"node_modules/eslint-plugin-unicorn/node_modules/eslint-utils": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-			"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+		"node_modules/eslint-plugin-unicorn/node_modules/jsesc": {
+			"version": "3.0.2",
+			"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+			"integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
 			"dev": true,
-			"dependencies": {
-				"eslint-visitor-keys": "^2.0.0"
-			},
-			"engines": {
-				"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/mysticatea"
+			"bin": {
+				"jsesc": "bin/jsesc"
 			},
-			"peerDependencies": {
-				"eslint": ">=5"
-			}
-		},
-		"node_modules/eslint-plugin-unicorn/node_modules/eslint-visitor-keys": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
-			"dev": true,
 			"engines": {
-				"node": ">=10"
+				"node": ">=6"
 			}
 		},
 		"node_modules/eslint-plugin-vue": {
-			"version": "8.7.1",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.7.1.tgz",
-			"integrity": "sha512-28sbtm4l4cOzoO1LtzQPxfxhQABararUb1JtqusQqObJpWX2e/gmVyeYVfepizPFne0Q5cILkYGiBoV36L12Wg==",
+			"version": "9.25.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.25.0.tgz",
+			"integrity": "sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==",
 			"dev": true,
 			"dependencies": {
-				"eslint-utils": "^3.0.0",
+				"@eslint-community/eslint-utils": "^4.4.0",
+				"globals": "^13.24.0",
 				"natural-compare": "^1.4.0",
-				"nth-check": "^2.0.1",
-				"postcss-selector-parser": "^6.0.9",
-				"semver": "^7.3.5",
-				"vue-eslint-parser": "^8.0.1"
-			},
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			},
-			"peerDependencies": {
-				"eslint": "^6.2.0 || ^7.0.0 || ^8.0.0"
-			}
-		},
-		"node_modules/eslint-plugin-vue/node_modules/eslint-utils": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-			"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
-			"dev": true,
-			"dependencies": {
-				"eslint-visitor-keys": "^2.0.0"
+				"nth-check": "^2.1.1",
+				"postcss-selector-parser": "^6.0.15",
+				"semver": "^7.6.0",
+				"vue-eslint-parser": "^9.4.2",
+				"xml-name-validator": "^4.0.0"
 			},
 			"engines": {
-				"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/mysticatea"
+				"node": "^14.17.0 || >=16.0.0"
 			},
 			"peerDependencies": {
-				"eslint": ">=5"
-			}
-		},
-		"node_modules/eslint-plugin-vue/node_modules/eslint-visitor-keys": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
-			"dev": true,
-			"engines": {
-				"node": ">=10"
+				"eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
 			}
 		},
 		"node_modules/eslint-plugin-wdio": {
-			"version": "7.25.3",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-7.25.3.tgz",
-			"integrity": "sha512-2zbYwV14Md9FNlyhaIILVGPB6w4bu2eJdOTywDUs2Qy4ebcQNwrxB0qCaf7Rm4O+T0Ir+tdYHYBBfbDocSLKng==",
+			"version": "8.24.12",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-8.24.12.tgz",
+			"integrity": "sha512-OmzGteXFOQnJDdkTNnTfksaVa18WlFCyeLjZXHvDpkbomLWAg9wc296Pr0wnTCagqNj8qfEHpy+N2XVew5VCMA==",
 			"dev": true,
 			"engines": {
-				"node": ">=12.0.0"
+				"node": "^16.13 || >=18"
 			}
 		},
 		"node_modules/eslint-plugin-yml": {
-			"version": "0.14.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-0.14.0.tgz",
-			"integrity": "sha512-+0+bBV/07txENbxfrHF9olGoLCHez64vmnOmjWOoLwmXOwfdaSRleBSPIi4nWQs7WwX8lm/fSLadOjbVEcsXQQ==",
+			"version": "1.14.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.14.0.tgz",
+			"integrity": "sha512-ESUpgYPOcAYQO9czugcX5OqRvn/ydDVwGCPXY4YjPqc09rHaUVUA6IE6HLQys4rXk/S+qx3EwTd1wHCwam/OWQ==",
 			"dev": true,
 			"dependencies": {
 				"debug": "^4.3.2",
+				"eslint-compat-utils": "^0.5.0",
 				"lodash": "^4.17.21",
 				"natural-compare": "^1.4.0",
-				"yaml-eslint-parser": "^0.5.0"
+				"yaml-eslint-parser": "^1.2.1"
 			},
 			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+				"node": "^14.17.0 || >=16.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/ota-meshi"
@@ -2031,27 +2269,30 @@
 			}
 		},
 		"node_modules/eslint-utils": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
-			"integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+			"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
 			"dev": true,
 			"dependencies": {
-				"eslint-visitor-keys": "^1.1.0"
+				"eslint-visitor-keys": "^2.0.0"
 			},
 			"engines": {
-				"node": ">=6"
+				"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/mysticatea"
+			},
+			"peerDependencies": {
+				"eslint": ">=5"
 			}
 		},
 		"node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
-			"version": "1.3.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
-			"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
 			"dev": true,
 			"engines": {
-				"node": ">=4"
+				"node": ">=10"
 			}
 		},
 		"node_modules/eslint-visitor-keys": {
@@ -2370,6 +2611,22 @@
 			"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
 			"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
 		},
+		"node_modules/fast-glob": {
+			"version": "3.3.2",
+			"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+			"integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+			"dev": true,
+			"dependencies": {
+				"@nodelib/fs.stat": "^2.0.2",
+				"@nodelib/fs.walk": "^1.2.3",
+				"glob-parent": "^5.1.2",
+				"merge2": "^1.3.0",
+				"micromatch": "^4.0.4"
+			},
+			"engines": {
+				"node": ">=8.6.0"
+			}
+		},
 		"node_modules/fast-json-stable-stringify": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -2606,10 +2863,9 @@
 			"dev": true
 		},
 		"node_modules/fsevents": {
-			"version": "2.1.3",
-			"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
-			"integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
-			"deprecated": "\"Please update to latest v2.3 or v2.2\"",
+			"version": "2.3.3",
+			"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+			"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
 			"dev": true,
 			"hasInstallScript": true,
 			"optional": true,
@@ -2621,10 +2877,13 @@
 			}
 		},
 		"node_modules/function-bind": {
-			"version": "1.1.1",
-			"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-			"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-			"dev": true
+			"version": "1.1.2",
+			"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+			"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+			"dev": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
 		},
 		"node_modules/gc-stats": {
 			"version": "1.4.0",
@@ -3296,6 +3555,18 @@
 				"node": ">=8.0.0"
 			}
 		},
+		"node_modules/get-tsconfig": {
+			"version": "4.7.3",
+			"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz",
+			"integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==",
+			"dev": true,
+			"dependencies": {
+				"resolve-pkg-maps": "^1.0.0"
+			},
+			"funding": {
+				"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+			}
+		},
 		"node_modules/getpass": {
 			"version": "0.1.7",
 			"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@@ -3333,9 +3604,9 @@
 			}
 		},
 		"node_modules/globals": {
-			"version": "13.23.0",
-			"resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
-			"integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
+			"version": "13.24.0",
+			"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+			"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
 			"dev": true,
 			"dependencies": {
 				"type-fest": "^0.20.2"
@@ -3359,6 +3630,26 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
+		"node_modules/globby": {
+			"version": "11.1.0",
+			"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+			"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+			"dev": true,
+			"dependencies": {
+				"array-union": "^2.1.0",
+				"dir-glob": "^3.0.1",
+				"fast-glob": "^3.2.9",
+				"ignore": "^5.2.0",
+				"merge2": "^1.4.1",
+				"slash": "^3.0.0"
+			},
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/graceful-fs": {
 			"version": "4.2.4",
 			"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
@@ -3401,18 +3692,6 @@
 				"node": ">=6"
 			}
 		},
-		"node_modules/has": {
-			"version": "1.0.3",
-			"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-			"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-			"dev": true,
-			"dependencies": {
-				"function-bind": "^1.1.1"
-			},
-			"engines": {
-				"node": ">= 0.4.0"
-			}
-		},
 		"node_modules/has-flag": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@@ -3438,10 +3717,22 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
+		"node_modules/hasown": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+			"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+			"dev": true,
+			"dependencies": {
+				"function-bind": "^1.1.2"
+			},
+			"engines": {
+				"node": ">= 0.4"
+			}
+		},
 		"node_modules/hat": {
 			"version": "0.0.3",
 			"resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz",
-			"integrity": "sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo=",
+			"integrity": "sha512-zpImx2GoKXy42fVDSEad2BPKuSQdLcqsCYa48K3zHSzM/ugWuYjLDr8IXxpVuL7uCLHw56eaiLxCRthhOzf5ug==",
 			"engines": {
 				"node": "*"
 			}
@@ -3543,9 +3834,9 @@
 			}
 		},
 		"node_modules/ignore": {
-			"version": "5.2.4",
-			"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
-			"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+			"version": "5.3.1",
+			"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
+			"integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
 			"dev": true,
 			"engines": {
 				"node": ">= 4"
@@ -3634,12 +3925,12 @@
 			}
 		},
 		"node_modules/is-core-module": {
-			"version": "2.2.0",
-			"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
-			"integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
+			"version": "2.13.1",
+			"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
+			"integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
 			"dev": true,
 			"dependencies": {
-				"has": "^1.0.3"
+				"hasown": "^2.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/ljharb"
@@ -3727,7 +4018,7 @@
 		"node_modules/isarray": {
 			"version": "1.0.0",
 			"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-			"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+			"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
 		},
 		"node_modules/isexe": {
 			"version": "2.0.0",
@@ -3777,9 +4068,9 @@
 			}
 		},
 		"node_modules/istanbul-lib-instrument/node_modules/semver": {
-			"version": "6.3.0",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-			"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+			"version": "6.3.1",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+			"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
 			"dev": true,
 			"bin": {
 				"semver": "bin/semver.js"
@@ -3961,9 +4252,9 @@
 			"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
 		},
 		"node_modules/jsdoc-type-pratt-parser": {
-			"version": "2.2.5",
-			"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.2.5.tgz",
-			"integrity": "sha512-2a6eRxSxp1BW040hFvaJxhsCMI9lT8QB8t14t+NY5tC5rckIR0U9cr2tjOeaFirmEOy6MHvmJnY7zTBHq431Lw==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz",
+			"integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==",
 			"dev": true,
 			"engines": {
 				"node": ">=12.0.0"
@@ -3988,9 +4279,9 @@
 			"dev": true
 		},
 		"node_modules/json-schema": {
-			"version": "0.2.3",
-			"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-			"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+			"version": "0.4.0",
+			"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+			"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
 		},
 		"node_modules/json-schema-compare": {
 			"version": "0.2.2",
@@ -4041,13 +4332,10 @@
 			"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
 		},
 		"node_modules/json5": {
-			"version": "2.1.3",
-			"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
-			"integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
+			"version": "2.2.3",
+			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+			"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
 			"dev": true,
-			"dependencies": {
-				"minimist": "^1.2.5"
-			},
 			"bin": {
 				"json5": "lib/cli.js"
 			},
@@ -4065,42 +4353,23 @@
 			}
 		},
 		"node_modules/jsprim": {
-			"version": "1.4.1",
-			"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-			"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
-			"engines": [
-				"node >=0.6.0"
-			],
+			"version": "1.4.2",
+			"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+			"integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
 			"dependencies": {
 				"assert-plus": "1.0.0",
 				"extsprintf": "1.3.0",
-				"json-schema": "0.2.3",
+				"json-schema": "0.4.0",
 				"verror": "1.10.0"
-			}
-		},
-		"node_modules/kad": {
-			"version": "1.3.6",
-			"resolved": "git+ssh://git@github.com/wikimedia/kad.git#96f8f5c8e5a88f5dffed47abc20756e93e16387e",
-			"integrity": "sha512-vGPFf2DWtyb6DnpVkUKNPKlVyiLOxdAaN3Ubbiz2vu2dhBTgq306Rmw4h30i2cluphBRngTMyHqLwSO50PuPUg==",
-			"license": "GPL-3.0",
-			"dependencies": {
-				"async": "^0.9.0",
-				"clarinet": "^0.11.0",
-				"colors": "^1.0.3",
-				"hat": "0.0.3",
-				"kad-fs": "0.0.4",
-				"kad-localstorage": "0.0.7",
-				"kad-memstore": "0.0.1",
-				"lodash": "^4.17.11",
-				"merge": "^1.2.0",
-				"ms": "^0.7.0",
-				"msgpack5": "^3.3.0"
+			},
+			"engines": {
+				"node": ">=0.6.0"
 			}
 		},
 		"node_modules/kad-fs": {
 			"version": "0.0.4",
 			"resolved": "https://registry.npmjs.org/kad-fs/-/kad-fs-0.0.4.tgz",
-			"integrity": "sha1-Aupapc8iIlclV5YnzP1tJmNyKJo=",
+			"integrity": "sha512-VlLY7MuXy+3Tlqn1NJNgNkta6BRposNsJhqqcLv/M5e/rGBAETU33DhlPwV6/RBZKGzylQFkeYaKaoYin+mGZw==",
 			"deprecated": "This package is no longer maintained.",
 			"dependencies": {
 				"readable-stream": "^2.0.4"
@@ -4109,7 +4378,7 @@
 		"node_modules/kad-localstorage": {
 			"version": "0.0.7",
 			"resolved": "https://registry.npmjs.org/kad-localstorage/-/kad-localstorage-0.0.7.tgz",
-			"integrity": "sha1-96LngNpT+yi5Q8LFqJTCeaqBDxc=",
+			"integrity": "sha512-3BEFBPa9cbPvW7WvZSTQHy6dSgw7ob7yTqT+eORWrxm4f4fE26BUVorg36KRbg/W+YWEnippuM68ybFyF3heiA==",
 			"dependencies": {
 				"dom-storage": "^2.0.1"
 			}
@@ -4117,7 +4386,7 @@
 		"node_modules/kad-memstore": {
 			"version": "0.0.1",
 			"resolved": "https://registry.npmjs.org/kad-memstore/-/kad-memstore-0.0.1.tgz",
-			"integrity": "sha1-g8t0hJasSRxxNRBMvla4jKc5JHc=",
+			"integrity": "sha512-fwGvRXWjaSzMed8iQHkZH41wvaoq+3tIhuIbkqBBYFuuJtWoDWqgCYTADGPqLyaLX4Ct8aP5NtAxCaxk4cfcCg==",
 			"deprecated": "This package is no longer maintained.",
 			"dependencies": {
 				"readable-stream": "^2.0.5"
@@ -4161,13 +4430,13 @@
 			}
 		},
 		"node_modules/limitation": {
-			"version": "0.2.1",
-			"resolved": "https://registry.npmjs.org/limitation/-/limitation-0.2.1.tgz",
-			"integrity": "sha512-5lMmsPc9ZtMjBk8rJ8ADKIj6AOgYvRtAuNfboO2TVPZsmcn6gSRyijUsA8KG6DUcJ89/hyQ3cnVRyzO1hbDavw==",
+			"version": "0.2.3",
+			"resolved": "https://registry.npmjs.org/limitation/-/limitation-0.2.3.tgz",
+			"integrity": "sha512-IpIBG7WniPI1Og0HYxlo8JRD2E2pExwuol7hjobcNZSYBBxAamPJdV91Q47uw5/KiUKA+We8a33sh6vD1PQ+Yw==",
 			"dependencies": {
 				"bluebird": "^3.3.1",
-				"kad": "git+https://github.com/wikimedia/kad.git#master",
-				"readable-stream": "^2.0.5"
+				"readable-stream": "^2.0.5",
+				"wikimedia-kad-fork": "^1.3.6"
 			}
 		},
 		"node_modules/lines-and-columns": {
@@ -4339,9 +4608,9 @@
 			}
 		},
 		"node_modules/make-dir/node_modules/semver": {
-			"version": "6.3.0",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-			"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+			"version": "6.3.1",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+			"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
 			"dev": true,
 			"bin": {
 				"semver": "bin/semver.js"
@@ -4352,10 +4621,27 @@
 			"resolved": "https://registry.npmjs.org/mediawiki-title/-/mediawiki-title-0.7.3.tgz",
 			"integrity": "sha512-WFemxDGfv+XMZuF/D+XR7/wggW7Aen6J0MPeJl+UIIeQIrbvVJmMArKLROCDZ0emqZltBUdaxEar7eQEfJKdZQ=="
 		},
-		"node_modules/merge": {
-			"version": "1.2.1",
-			"resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz",
-			"integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ=="
+		"node_modules/merge2": {
+			"version": "1.4.1",
+			"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+			"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+			"dev": true,
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/micromatch": {
+			"version": "4.0.5",
+			"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+			"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+			"dev": true,
+			"dependencies": {
+				"braces": "^3.0.2",
+				"picomatch": "^2.3.1"
+			},
+			"engines": {
+				"node": ">=8.6"
+			}
 		},
 		"node_modules/mime-db": {
 			"version": "1.45.0",
@@ -4398,10 +4684,13 @@
 			}
 		},
 		"node_modules/minimist": {
-			"version": "1.2.5",
-			"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-			"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
-			"devOptional": true
+			"version": "1.2.8",
+			"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+			"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+			"devOptional": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
 		},
 		"node_modules/mkdirp": {
 			"version": "0.5.5",
@@ -4416,35 +4705,35 @@
 			}
 		},
 		"node_modules/mocha": {
-			"version": "8.2.1",
-			"resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz",
-			"integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==",
+			"version": "8.4.0",
+			"resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz",
+			"integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==",
 			"dev": true,
 			"dependencies": {
 				"@ungap/promise-all-settled": "1.1.2",
 				"ansi-colors": "4.1.1",
 				"browser-stdout": "1.3.1",
-				"chokidar": "3.4.3",
-				"debug": "4.2.0",
-				"diff": "4.0.2",
+				"chokidar": "3.5.1",
+				"debug": "4.3.1",
+				"diff": "5.0.0",
 				"escape-string-regexp": "4.0.0",
 				"find-up": "5.0.0",
 				"glob": "7.1.6",
 				"growl": "1.10.5",
 				"he": "1.2.0",
-				"js-yaml": "3.14.0",
+				"js-yaml": "4.0.0",
 				"log-symbols": "4.0.0",
 				"minimatch": "3.0.4",
-				"ms": "2.1.2",
-				"nanoid": "3.1.12",
+				"ms": "2.1.3",
+				"nanoid": "3.1.20",
 				"serialize-javascript": "5.0.1",
 				"strip-json-comments": "3.1.1",
-				"supports-color": "7.2.0",
+				"supports-color": "8.1.1",
 				"which": "2.0.2",
 				"wide-align": "1.1.3",
-				"workerpool": "6.0.2",
-				"yargs": "13.3.2",
-				"yargs-parser": "13.1.2",
+				"workerpool": "6.1.0",
+				"yargs": "16.2.0",
+				"yargs-parser": "20.2.4",
 				"yargs-unparser": "2.0.0"
 			},
 			"bin": {
@@ -4459,11 +4748,69 @@
 				"url": "https://opencollective.com/mochajs"
 			}
 		},
+		"node_modules/mocha/node_modules/ansi-regex": {
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+			"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/mocha/node_modules/ansi-styles": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+			"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+			"dev": true,
+			"dependencies": {
+				"color-convert": "^2.0.1"
+			},
+			"engines": {
+				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/ansi-styles?sponsor=1"
+			}
+		},
+		"node_modules/mocha/node_modules/argparse": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+			"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+			"dev": true
+		},
+		"node_modules/mocha/node_modules/cliui": {
+			"version": "7.0.4",
+			"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+			"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+			"dev": true,
+			"dependencies": {
+				"string-width": "^4.2.0",
+				"strip-ansi": "^6.0.0",
+				"wrap-ansi": "^7.0.0"
+			}
+		},
+		"node_modules/mocha/node_modules/color-convert": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+			"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+			"dev": true,
+			"dependencies": {
+				"color-name": "~1.1.4"
+			},
+			"engines": {
+				"node": ">=7.0.0"
+			}
+		},
+		"node_modules/mocha/node_modules/color-name": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+			"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+			"dev": true
+		},
 		"node_modules/mocha/node_modules/debug": {
-			"version": "4.2.0",
-			"resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
-			"integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
-			"deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
+			"version": "4.3.1",
+			"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+			"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
 			"dev": true,
 			"dependencies": {
 				"ms": "2.1.2"
@@ -4477,6 +4824,18 @@
 				}
 			}
 		},
+		"node_modules/mocha/node_modules/debug/node_modules/ms": {
+			"version": "2.1.2",
+			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+			"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+			"dev": true
+		},
+		"node_modules/mocha/node_modules/emoji-regex": {
+			"version": "8.0.0",
+			"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+			"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+			"dev": true
+		},
 		"node_modules/mocha/node_modules/escape-string-regexp": {
 			"version": "4.0.0",
 			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
@@ -4525,6 +4884,18 @@
 				"url": "https://github.com/sponsors/isaacs"
 			}
 		},
+		"node_modules/mocha/node_modules/glob/node_modules/minimatch": {
+			"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"
+			},
+			"engines": {
+				"node": "*"
+			}
+		},
 		"node_modules/mocha/node_modules/has-flag": {
 			"version": "4.0.0",
 			"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -4534,14 +4905,22 @@
 				"node": ">=8"
 			}
 		},
+		"node_modules/mocha/node_modules/is-fullwidth-code-point": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+			"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/mocha/node_modules/js-yaml": {
-			"version": "3.14.0",
-			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
-			"integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
+			"integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
 			"dev": true,
 			"dependencies": {
-				"argparse": "^1.0.7",
-				"esprima": "^4.0.0"
+				"argparse": "^2.0.1"
 			},
 			"bin": {
 				"js-yaml": "bin/js-yaml.js"
@@ -4563,9 +4942,9 @@
 			}
 		},
 		"node_modules/mocha/node_modules/ms": {
-			"version": "2.1.2",
-			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-			"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+			"version": "2.1.3",
+			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+			"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
 			"dev": true
 		},
 		"node_modules/mocha/node_modules/p-limit": {
@@ -4607,105 +4986,98 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/mocha/node_modules/supports-color": {
-			"version": "7.2.0",
-			"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-			"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+		"node_modules/mocha/node_modules/string-width": {
+			"version": "4.2.3",
+			"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+			"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
 			"dev": true,
 			"dependencies": {
-				"has-flag": "^4.0.0"
+				"emoji-regex": "^8.0.0",
+				"is-fullwidth-code-point": "^3.0.0",
+				"strip-ansi": "^6.0.1"
 			},
 			"engines": {
 				"node": ">=8"
 			}
 		},
-		"node_modules/mocha/node_modules/yargs": {
-			"version": "13.3.2",
-			"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
-			"integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
-			"dev": true,
-			"dependencies": {
-				"cliui": "^5.0.0",
-				"find-up": "^3.0.0",
-				"get-caller-file": "^2.0.1",
-				"require-directory": "^2.1.1",
-				"require-main-filename": "^2.0.0",
-				"set-blocking": "^2.0.0",
-				"string-width": "^3.0.0",
-				"which-module": "^2.0.0",
-				"y18n": "^4.0.0",
-				"yargs-parser": "^13.1.2"
-			}
-		},
-		"node_modules/mocha/node_modules/yargs-parser": {
-			"version": "13.1.2",
-			"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
-			"integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
-			"dev": true,
-			"dependencies": {
-				"camelcase": "^5.0.0",
-				"decamelize": "^1.2.0"
-			}
-		},
-		"node_modules/mocha/node_modules/yargs/node_modules/find-up": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
-			"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+		"node_modules/mocha/node_modules/strip-ansi": {
+			"version": "6.0.1",
+			"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+			"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
 			"dev": true,
 			"dependencies": {
-				"locate-path": "^3.0.0"
+				"ansi-regex": "^5.0.1"
 			},
 			"engines": {
-				"node": ">=6"
+				"node": ">=8"
 			}
 		},
-		"node_modules/mocha/node_modules/yargs/node_modules/locate-path": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
-			"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+		"node_modules/mocha/node_modules/supports-color": {
+			"version": "8.1.1",
+			"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+			"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
 			"dev": true,
 			"dependencies": {
-				"p-locate": "^3.0.0",
-				"path-exists": "^3.0.0"
+				"has-flag": "^4.0.0"
 			},
 			"engines": {
-				"node": ">=6"
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/supports-color?sponsor=1"
 			}
 		},
-		"node_modules/mocha/node_modules/yargs/node_modules/p-limit": {
-			"version": "2.3.0",
-			"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-			"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+		"node_modules/mocha/node_modules/wrap-ansi": {
+			"version": "7.0.0",
+			"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+			"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
 			"dev": true,
 			"dependencies": {
-				"p-try": "^2.0.0"
+				"ansi-styles": "^4.0.0",
+				"string-width": "^4.1.0",
+				"strip-ansi": "^6.0.0"
 			},
 			"engines": {
-				"node": ">=6"
+				"node": ">=10"
 			},
 			"funding": {
-				"url": "https://github.com/sponsors/sindresorhus"
+				"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
 			}
 		},
-		"node_modules/mocha/node_modules/yargs/node_modules/p-locate": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
-			"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+		"node_modules/mocha/node_modules/y18n": {
+			"version": "5.0.8",
+			"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+			"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+			"dev": true,
+			"engines": {
+				"node": ">=10"
+			}
+		},
+		"node_modules/mocha/node_modules/yargs": {
+			"version": "16.2.0",
+			"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+			"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
 			"dev": true,
 			"dependencies": {
-				"p-limit": "^2.0.0"
+				"cliui": "^7.0.2",
+				"escalade": "^3.1.1",
+				"get-caller-file": "^2.0.5",
+				"require-directory": "^2.1.1",
+				"string-width": "^4.2.0",
+				"y18n": "^5.0.5",
+				"yargs-parser": "^20.2.2"
 			},
 			"engines": {
-				"node": ">=6"
+				"node": ">=10"
 			}
 		},
-		"node_modules/mocha/node_modules/yargs/node_modules/path-exists": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-			"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+		"node_modules/mocha/node_modules/yargs-parser": {
+			"version": "20.2.4",
+			"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+			"integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
 			"dev": true,
 			"engines": {
-				"node": ">=4"
+				"node": ">=10"
 			}
 		},
 		"node_modules/mock-require": {
@@ -4740,9 +5112,9 @@
 			}
 		},
 		"node_modules/moment": {
-			"version": "2.29.1",
-			"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
-			"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
+			"version": "2.30.1",
+			"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
+			"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
 			"optional": true,
 			"engines": {
 				"node": "*"
@@ -4760,12 +5132,12 @@
 		"node_modules/ms": {
 			"version": "0.7.3",
 			"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz",
-			"integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8="
+			"integrity": "sha512-lrKNzMWqQZgwJahtrtrM+9NgOoDUveDrVmm5aGXrf3BdtL0mq7X6IVzoZaw+TfNti29eHd1/8GI+h45K5cQ6/w=="
 		},
 		"node_modules/msgpack5": {
-			"version": "3.6.0",
-			"resolved": "https://registry.npmjs.org/msgpack5/-/msgpack5-3.6.0.tgz",
-			"integrity": "sha512-6HuCZHA57WtNUzrKIvjJ8OMxigzveJ6D5i13y6TsgGu3X3zxABpuBvChpppOoGdB9SyWZcmqUs1fwUV/PpSQ7Q==",
+			"version": "3.6.1",
+			"resolved": "https://registry.npmjs.org/msgpack5/-/msgpack5-3.6.1.tgz",
+			"integrity": "sha512-VoY2AaoowHZLLKyEb5FRzuhdSzXn5quGjcMKJOJHJPxp9baYZx5t6jiHUhp5aNRlqqlt+5GXQGovMLNKsrm1hg==",
 			"dependencies": {
 				"bl": "^1.2.1",
 				"inherits": "^2.0.3",
@@ -4798,15 +5170,15 @@
 			"integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w=="
 		},
 		"node_modules/nanoid": {
-			"version": "3.1.12",
-			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz",
-			"integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==",
+			"version": "3.1.20",
+			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
+			"integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==",
 			"dev": true,
 			"bin": {
 				"nanoid": "bin/nanoid.cjs"
 			},
 			"engines": {
-				"node": "^10 || ^12 || >=13.7"
+				"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
 			}
 		},
 		"node_modules/natural-compare": {
@@ -4865,9 +5237,9 @@
 			}
 		},
 		"node_modules/node-releases": {
-			"version": "2.0.13",
-			"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
-			"integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
+			"version": "2.0.14",
+			"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+			"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
 			"dev": true
 		},
 		"node_modules/normalize-package-data": {
@@ -4954,9 +5326,9 @@
 			}
 		},
 		"node_modules/nyc/node_modules/ansi-regex": {
-			"version": "5.0.0",
-			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
-			"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+			"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
 			"dev": true,
 			"engines": {
 				"node": ">=8"
@@ -5348,6 +5720,15 @@
 			"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
 			"dev": true
 		},
+		"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/performance-now": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -5360,9 +5741,9 @@
 			"dev": true
 		},
 		"node_modules/picomatch": {
-			"version": "2.2.2",
-			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
-			"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+			"version": "2.3.1",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+			"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
 			"dev": true,
 			"engines": {
 				"node": ">=8.6"
@@ -5498,9 +5879,9 @@
 			}
 		},
 		"node_modules/postcss-selector-parser": {
-			"version": "6.0.13",
-			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
-			"integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
+			"version": "6.0.16",
+			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz",
+			"integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==",
 			"dev": true,
 			"dependencies": {
 				"cssesc": "^3.0.0",
@@ -5593,9 +5974,9 @@
 			}
 		},
 		"node_modules/qs": {
-			"version": "6.5.2",
-			"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
-			"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+			"version": "6.5.3",
+			"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+			"integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
 			"engines": {
 				"node": ">=0.6"
 			}
@@ -5626,10 +6007,10 @@
 			"integrity": "sha512-dy1yjycmn9blucmJLXOfZDx1ikZJUi6E8bBZLnhPG5gBrVhHXx2xVyqqgKBubVNEXmx51dBACMHpoMQK/N/AXQ==",
 			"dev": true
 		},
-		"node_modules/ramda": {
-			"version": "0.27.2",
-			"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz",
-			"integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==",
+		"node_modules/rambda": {
+			"version": "7.5.0",
+			"resolved": "https://registry.npmjs.org/rambda/-/rambda-7.5.0.tgz",
+			"integrity": "sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA==",
 			"dev": true
 		},
 		"node_modules/randombytes": {
@@ -5739,9 +6120,9 @@
 			}
 		},
 		"node_modules/readable-stream": {
-			"version": "2.3.7",
-			"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
-			"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+			"version": "2.3.8",
+			"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+			"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
 			"dependencies": {
 				"core-util-is": "~1.0.0",
 				"inherits": "~2.0.3",
@@ -5776,17 +6157,17 @@
 			"dev": true
 		},
 		"node_modules/redis": {
-			"version": "3.0.2",
-			"resolved": "https://registry.npmjs.org/redis/-/redis-3.0.2.tgz",
-			"integrity": "sha512-PNhLCrjU6vKVuMOyFu7oSP296mwBkcE6lrAjruBYG5LgdSqtRBoVQIylrMyVZD/lkF24RSNNatzvYag6HRBHjQ==",
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz",
+			"integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==",
 			"dependencies": {
-				"denque": "^1.4.1",
-				"redis-commands": "^1.5.0",
+				"denque": "^1.5.0",
+				"redis-commands": "^1.7.0",
 				"redis-errors": "^1.2.0",
 				"redis-parser": "^3.0.0"
 			},
 			"engines": {
-				"node": ">=6"
+				"node": ">=10"
 			},
 			"funding": {
 				"type": "opencollective",
@@ -5794,9 +6175,9 @@
 			}
 		},
 		"node_modules/redis-commands": {
-			"version": "1.6.0",
-			"resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.6.0.tgz",
-			"integrity": "sha512-2jnZ0IkjZxvguITjFTrGiLyzQZcTvaw8DAaCXxZq/dsHXz7KfMQ3OUJy7Tz9vnRtZRVz6VRCPDvruvU8Ts44wQ=="
+			"version": "1.7.0",
+			"resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz",
+			"integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ=="
 		},
 		"node_modules/redis-errors": {
 			"version": "1.2.0",
@@ -5845,16 +6226,25 @@
 			"resolved": "https://registry.npmjs.org/regexp-utils/-/regexp-utils-0.3.2.tgz",
 			"integrity": "sha1-Q3bAMYqioP33v8fRUv0BDzJhcPQ="
 		},
-		"node_modules/regexpp": {
-			"version": "3.1.0",
-			"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
-			"integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
+		"node_modules/regjsparser": {
+			"version": "0.10.0",
+			"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz",
+			"integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==",
 			"dev": true,
-			"engines": {
-				"node": ">=8"
+			"dependencies": {
+				"jsesc": "~0.5.0"
 			},
-			"funding": {
-				"url": "https://github.com/sponsors/mysticatea"
+			"bin": {
+				"regjsparser": "bin/parser"
+			}
+		},
+		"node_modules/regjsparser/node_modules/jsesc": {
+			"version": "0.5.0",
+			"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+			"integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+			"dev": true,
+			"bin": {
+				"jsesc": "bin/jsesc"
 			}
 		},
 		"node_modules/release-zalgo": {
@@ -5951,13 +6341,17 @@
 			}
 		},
 		"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.8",
+			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+			"integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
 			"dev": true,
 			"dependencies": {
-				"is-core-module": "^2.2.0",
-				"path-parse": "^1.0.6"
+				"is-core-module": "^2.13.0",
+				"path-parse": "^1.0.7",
+				"supports-preserve-symlinks-flag": "^1.0.0"
+			},
+			"bin": {
+				"resolve": "bin/resolve"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/ljharb"
@@ -5972,6 +6366,15 @@
 				"node": ">=4"
 			}
 		},
+		"node_modules/resolve-pkg-maps": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+			"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+			"dev": true,
+			"funding": {
+				"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+			}
+		},
 		"node_modules/reusify": {
 			"version": "1.0.4",
 			"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -6057,9 +6460,9 @@
 			"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
 		},
 		"node_modules/semver": {
-			"version": "7.5.4",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
-			"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+			"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
 			"dependencies": {
 				"lru-cache": "^6.0.0"
 			},
@@ -6140,6 +6543,15 @@
 			"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
 			"dev": true
 		},
+		"node_modules/slash": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+			"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/sonic-boom": {
 			"version": "0.7.7",
 			"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-0.7.7.tgz",
@@ -6221,16 +6633,26 @@
 				"spdx-license-ids": "^3.0.0"
 			}
 		},
+		"node_modules/spdx-correct/node_modules/spdx-expression-parse": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"dev": true,
+			"dependencies": {
+				"spdx-exceptions": "^2.1.0",
+				"spdx-license-ids": "^3.0.0"
+			}
+		},
 		"node_modules/spdx-exceptions": {
-			"version": "2.3.0",
-			"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
-			"integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+			"version": "2.5.0",
+			"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+			"integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
 			"dev": true
 		},
 		"node_modules/spdx-expression-parse": {
-			"version": "3.0.1",
-			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
-			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
+			"integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
 			"dev": true,
 			"dependencies": {
 				"spdx-exceptions": "^2.1.0",
@@ -6238,9 +6660,9 @@
 			}
 		},
 		"node_modules/spdx-license-ids": {
-			"version": "3.0.16",
-			"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz",
-			"integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==",
+			"version": "3.0.17",
+			"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz",
+			"integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==",
 			"dev": true
 		},
 		"node_modules/split2": {
@@ -6385,6 +6807,18 @@
 				"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/swagger-router": {
 			"version": "0.7.4",
 			"resolved": "https://registry.npmjs.org/swagger-router/-/swagger-router-0.7.4.tgz",
@@ -6407,9 +6841,9 @@
 			}
 		},
 		"node_modules/swagger-ui-dist": {
-			"version": "3.40.0",
-			"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.40.0.tgz",
-			"integrity": "sha512-R0eaS61/cOE6wiFOY7AtmoTBV5lZqmyosuE14G9nAudp5MNsNfCTdI9MWJLs8iF28HXdtH8EACiFFtUbQomHog=="
+			"version": "3.52.5",
+			"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.52.5.tgz",
+			"integrity": "sha512-8z18eX8G/jbTXYzyNIaobrnD7PSN7yU/YkSasMmajrXtw0FGS64XjrKn5v37d36qmU3o1xLeuYnktshRr7uIFw=="
 		},
 		"node_modules/tassembly": {
 			"version": "0.2.3",
@@ -6502,6 +6936,27 @@
 				"node": ">=0.8"
 			}
 		},
+		"node_modules/tslib": {
+			"version": "1.14.1",
+			"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+			"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+			"dev": true
+		},
+		"node_modules/tsutils": {
+			"version": "3.21.0",
+			"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+			"integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+			"dev": true,
+			"dependencies": {
+				"tslib": "^1.8.1"
+			},
+			"engines": {
+				"node": ">= 6"
+			},
+			"peerDependencies": {
+				"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
+			}
+		},
 		"node_modules/tunnel-agent": {
 			"version": "0.6.0",
 			"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -6548,10 +7003,24 @@
 				"is-typedarray": "^1.0.0"
 			}
 		},
+		"node_modules/typescript": {
+			"version": "5.4.5",
+			"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
+			"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
+			"dev": true,
+			"peer": true,
+			"bin": {
+				"tsc": "bin/tsc",
+				"tsserver": "bin/tsserver"
+			},
+			"engines": {
+				"node": ">=14.17"
+			}
+		},
 		"node_modules/underscore": {
-			"version": "1.12.0",
-			"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.0.tgz",
-			"integrity": "sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ=="
+			"version": "1.13.6",
+			"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
+			"integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A=="
 		},
 		"node_modules/universalify": {
 			"version": "0.1.2",
@@ -6651,6 +7120,16 @@
 				"spdx-expression-parse": "^3.0.0"
 			}
 		},
+		"node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"dev": true,
+			"dependencies": {
+				"spdx-exceptions": "^2.1.0",
+				"spdx-license-ids": "^3.0.0"
+			}
+		},
 		"node_modules/validate.io-array": {
 			"version": "1.0.6",
 			"resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz",
@@ -6702,21 +7181,21 @@
 			}
 		},
 		"node_modules/vue-eslint-parser": {
-			"version": "8.3.0",
-			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz",
-			"integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==",
+			"version": "9.4.2",
+			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
+			"integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
 			"dev": true,
 			"dependencies": {
-				"debug": "^4.3.2",
-				"eslint-scope": "^7.0.0",
-				"eslint-visitor-keys": "^3.1.0",
-				"espree": "^9.0.0",
+				"debug": "^4.3.4",
+				"eslint-scope": "^7.1.1",
+				"eslint-visitor-keys": "^3.3.0",
+				"espree": "^9.3.1",
 				"esquery": "^1.4.0",
 				"lodash": "^4.17.21",
-				"semver": "^7.3.5"
+				"semver": "^7.3.6"
 			},
 			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+				"node": "^14.17.0 || >=16.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/mysticatea"
@@ -6760,9 +7239,9 @@
 			}
 		},
 		"node_modules/wide-align/node_modules/ansi-regex": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
-			"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
+			"integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
 			"dev": true,
 			"engines": {
 				"node": ">=4"
@@ -6793,10 +7272,27 @@
 				"node": ">=4"
 			}
 		},
+		"node_modules/wikimedia-kad-fork": {
+			"version": "1.3.6",
+			"resolved": "https://registry.npmjs.org/wikimedia-kad-fork/-/wikimedia-kad-fork-1.3.6.tgz",
+			"integrity": "sha512-m+IxFN4JatoQPRo0N46xMh7tR6FSznb/ithIchAy7Wg9mrkc4/bE/3BhlJS410quFJFrJp8lJJp93g4uTbj4lA==",
+			"dependencies": {
+				"async": "^0.9.0",
+				"clarinet": "^0.11.0",
+				"colors": "^1.0.3",
+				"hat": "0.0.3",
+				"kad-fs": "0.0.4",
+				"kad-localstorage": "0.0.7",
+				"kad-memstore": "0.0.1",
+				"lodash": "^4.17.11",
+				"ms": "^0.7.0",
+				"msgpack5": "^3.3.0"
+			}
+		},
 		"node_modules/workerpool": {
-			"version": "6.0.2",
-			"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz",
-			"integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==",
+			"version": "6.1.0",
+			"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz",
+			"integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==",
 			"dev": true
 		},
 		"node_modules/wrap-ansi": {
@@ -6830,6 +7326,15 @@
 				"typedarray-to-buffer": "^3.1.5"
 			}
 		},
+		"node_modules/xml-name-validator": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
+			"integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
+			"dev": true,
+			"engines": {
+				"node": ">=12"
+			}
+		},
 		"node_modules/y18n": {
 			"version": "4.0.1",
 			"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
@@ -6841,26 +7346,32 @@
 			"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
 		},
 		"node_modules/yaml": {
-			"version": "1.10.2",
-			"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
-			"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+			"version": "2.4.2",
+			"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz",
+			"integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==",
 			"dev": true,
+			"bin": {
+				"yaml": "bin.mjs"
+			},
 			"engines": {
-				"node": ">= 6"
+				"node": ">= 14"
 			}
 		},
 		"node_modules/yaml-eslint-parser": {
-			"version": "0.5.0",
-			"resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-0.5.0.tgz",
-			"integrity": "sha512-nJeyLA3YHAzhBTZbRAbu3W6xrSCucyxExmA+ZDtEdUFpGllxAZpto2Zxo2IG0r0eiuEiBM4e+wiAdxTziTq94g==",
+			"version": "1.2.2",
+			"resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz",
+			"integrity": "sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==",
 			"dev": true,
 			"dependencies": {
 				"eslint-visitor-keys": "^3.0.0",
 				"lodash": "^4.17.21",
-				"yaml": "^1.10.2"
+				"yaml": "^2.0.0"
 			},
 			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+				"node": "^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ota-meshi"
 			}
 		},
 		"node_modules/yargs": {
diff --git a/package.json b/package.json
index 97f2c6f..6e15f3b 100644
--- a/package.json
+++ b/package.json
@@ -56,7 +56,7 @@
 		"@wikimedia/jsonschema-tools": "^0.7.5",
 		"ajv": "^6.12.2",
 		"coveralls": "^3.1.0",
-		"eslint-config-wikimedia": "0.25.1",
+		"eslint-config-wikimedia": "0.27.0",
 		"js-yaml": "^3.14.0",
 		"kafka-test-tools": "^0.1.13",
 		"mocha": "^8.0.1",
diff --git a/sys/deduplicator.js b/sys/deduplicator.js
index e34bd53..101d98a 100644
--- a/sys/deduplicator.js
+++ b/sys/deduplicator.js
@@ -25,12 +25,12 @@ class Deduplicator extends mixins.mix(Object).with(mixins.Redis) {
     checkDuplicate(hyper, req) {
         const name = req.params.name;
         const message = req.body;
-        const prefix = `${this._prefix}_dedupe_${name}`;
+        const prefix = `${ this._prefix }_dedupe_${ name }`;
 
         // First, look at the individual event duplication based on ID
         // This happens when we restart ChangeProp and reread some of the
         // exact same events which were executed but was not committed.
-        const messageKeyWithId = `${prefix}_${message.meta.domain}_${message.meta.id}`;
+        const messageKeyWithId = `${ prefix }_${ message.meta.domain }_${ message.meta.id }`;
         return this._redis.setnxAsync(messageKeyWithId, '1')
         // Expire the key or renew the expiration timestamp if the key existed
         .tap(() => this._redis.expireAsync(messageKeyWithId, Math.ceil(this._expire_timeout / 24)))
@@ -39,7 +39,7 @@ class Deduplicator extends mixins.mix(Object).with(mixins.Redis) {
             if (setResult) {
                 return NOT_DUPLICATE;
             }
-            hyper.metrics.increment(`${name}_dedupe`);
+            hyper.metrics.increment(`${ name }_dedupe`);
             hyper.logger.log('trace/dedupe', () => ({
                 message: 'Event was deduplicated based on id',
                 event_str: utils.stringify(message)
@@ -52,7 +52,7 @@ class Deduplicator extends mixins.mix(Object).with(mixins.Redis) {
                 // don't try to deduplicate by SHA-1
                 return individualDuplicate;
             }
-            const messageKeyWithSha = `${prefix}_${message.meta.domain}_${message.sha1}`;
+            const messageKeyWithSha = `${ prefix }_${ message.meta.domain }_${ message.sha1 }`;
             return this._redis.getAsync(messageKeyWithSha)
             .then((previousExecutionTime) => {
                 // If the same event (by sha1) was created before the previous execution
@@ -65,7 +65,7 @@ class Deduplicator extends mixins.mix(Object).with(mixins.Redis) {
                         // side - subtract 1 second from the previous execution time to allow for
                         // some lag.
                         new Date(previousExecutionTime) - 1000 > new Date(message.meta.dt)) {
-                    hyper.metrics.increment(`${name}_dedupe`);
+                    hyper.metrics.increment(`${ name }_dedupe`);
                     hyper.logger.log('trace/dedupe', () => ({
                         message: 'Event was deduplicated based on sha1',
                         event_str: utils.stringify(message),
@@ -80,7 +80,7 @@ class Deduplicator extends mixins.mix(Object).with(mixins.Redis) {
                         message.root_event &&
                         new Date(previousExecutionTime) - 1000 >
                             new Date(message.root_event.dt)) {
-                    hyper.metrics.increment(`${name}_dedupe`);
+                    hyper.metrics.increment(`${ name }_dedupe`);
                     hyper.logger.log('trace/dedupe', () => ({
                         message: 'Event was deduplicated based on sha1 and root_event dt',
                         event_str: utils.stringify(message),
@@ -101,14 +101,14 @@ class Deduplicator extends mixins.mix(Object).with(mixins.Redis) {
                 return sha1Duplicate;
             }
 
-            const rootEventKey = `${prefix}_${message.root_event.signature}`;
+            const rootEventKey = `${ prefix }_${ message.root_event.signature }`;
             return this._redis.getAsync(rootEventKey)
             .then((oldEventTimestamp) => {
                 // If this event was caused by root event and there was a leaf event executed
                 // already that belonged to a later root_event we can cut off this chain.
                 if (oldEventTimestamp &&
                         new Date(oldEventTimestamp) > new Date(message.root_event.dt)) {
-                    hyper.metrics.increment(`${name}_dedupe`);
+                    hyper.metrics.increment(`${ name }_dedupe`);
                     hyper.logger.log('trace/dedupe', () => ({
                         message: 'Event was deduplicated based on root event',
                         event_str: utils.stringify(message),
diff --git a/sys/dep_updates.js b/sys/dep_updates.js
index beee6d6..8f363b8 100644
--- a/sys/dep_updates.js
+++ b/sys/dep_updates.js
@@ -143,7 +143,7 @@ function _sendResourceChanges(hyper, items, originalEvent, tags, streamName) {
         body: items.map((item) => {
             // TODO: need to check whether a wiki is http or https!
             const resourceURI =
-                `https://${item.domain}/wiki/${encodeURIComponent(item.title)}`;
+                `https://${ item.domain }/wiki/${ encodeURIComponent(item.title) }`;
             return {
                 $schema: '/resource_change/1.0.0',
                 meta: {
@@ -275,7 +275,7 @@ class DependencyProcessor {
             }))
             .then((res) => {
                 if (!res || !res.body || !res.body.query || !res.body.query.general) {
-                    throw new Error(`SiteInfo is unavailable for ${message.meta.domain}`);
+                    throw new Error(`SiteInfo is unavailable for ${ message.meta.domain }`);
                 }
                 return {
                     general: {
diff --git a/sys/kafka.js b/sys/kafka.js
index 1578c66..1468bd1 100644
--- a/sys/kafka.js
+++ b/sys/kafka.js
@@ -88,8 +88,8 @@ class Kafka {
                 });
             }
             hyper.metrics.increment(
-                `produce_${hyper.metrics.normalizeName(message.meta.stream.replace(/\./g, '_'))}.${partition}`);
-            return this.producer.produce(`${this.kafkaFactory.produceDC}.${message.meta.stream}`,
+                `produce_${ hyper.metrics.normalizeName(message.meta.stream.replace(/\./g, '_')) }.${ partition }`);
+            return this.producer.produce(`${ this.kafkaFactory.produceDC }.${ message.meta.stream }`,
                 partition,
                 Buffer.from(JSON.stringify(message)));
         }))
diff --git a/sys/ores_updates.js b/sys/ores_updates.js
index e4c930c..594a2f5 100644
--- a/sys/ores_updates.js
+++ b/sys/ores_updates.js
@@ -54,7 +54,7 @@ class OresProcessor {
             // https://phabricator.wikimedia.org/T210465#4797591
 
             const domainScores = res.body[newMessage.database];
-            const revScores = domainScores.scores[`${newMessage.rev_id}`];
+            const revScores = domainScores.scores[`${ newMessage.rev_id }`];
             Object.keys(revScores).forEach((modelName) => {
                 // The example schema for the score object:
                 //   {
@@ -88,7 +88,7 @@ class OresProcessor {
                     if (!Array.isArray(prediction)) {
                         prediction = [ prediction ];
                     }
-                    score[modelName].prediction = prediction.map(p => `${p}`);
+                    score[modelName].prediction = prediction.map(p => `${ p }`);
                     // Convert probabilities to an array of name-value pairs.
                     score[modelName].probability = Object.keys(originalScore.probability)
                         .reduce((obj, probName) => Object.assign(
diff --git a/sys/partitioner.js b/sys/partitioner.js
index 0b11f48..8d72c71 100644
--- a/sys/partitioner.js
+++ b/sys/partitioner.js
@@ -62,7 +62,7 @@ class Partitioner {
             message: event
         });
         return hyper.post({
-            uri: `/sys/queue/events/${partition}`,
+            uri: `/sys/queue/events/${ partition }`,
             body: [ event ]
         });
     }
diff --git a/sys/purge.js b/sys/purge.js
index ee15491..89d8ddb 100644
--- a/sys/purge.js
+++ b/sys/purge.js
@@ -43,7 +43,7 @@ class PurgeService {
                 }));
                 return undefined;
             }
-            return `http:${event.meta.uri.replace(/^https?:/, '')}`;
+            return `http:${ event.meta.uri.replace(/^https?:/, '') }`;
         }).filter(event => !!event))
         .thenReturn({ status: 201 })
         .catch((e) => {
diff --git a/sys/rate_limiter.js b/sys/rate_limiter.js
index 0fd1a8c..c9b45bd 100644
--- a/sys/rate_limiter.js
+++ b/sys/rate_limiter.js
@@ -22,12 +22,12 @@ class RateLimiter extends mixins.mix(Object).with(mixins.Redis) {
 
             limiterOpts.forEach((opt) => {
                 if (!opt.interval || !opt.limit) {
-                    throw new Error(`Limiter ${type} is miconfigured`);
+                    throw new Error(`Limiter ${ type } is miconfigured`);
                 }
             });
 
             this._LIMITERS.set(type, new Limiter(this._redis, limiterOpts,
-                { prefix: `CPLimiter_${type}` }));
+                { prefix: `CPLimiter_${ type }` }));
         });
     }
 
@@ -48,24 +48,24 @@ class RateLimiter extends mixins.mix(Object).with(mixins.Redis) {
             limiter[fun](key, (err, isRateLimited) => {
                 if (err) {
                     hyper.logger.log('error/ratelimit', err);
-                    hyper.metrics.endTiming(`ratelimit.${fun}.err`, startTime);
+                    hyper.metrics.endTiming(`ratelimit.${ fun }.err`, startTime);
                     // In case we've got problems with limiting just allow everything
                     return resolve({ status: 200 });
                 }
 
                 if (isRateLimited) {
-                    hyper.metrics.endTiming(`ratelimit.${fun}.block`, startTime);
+                    hyper.metrics.endTiming(`ratelimit.${ fun }.block`, startTime);
                     return reject(new HTTPError({
                         status: 429,
                         body: {
                             type: 'rate_limit',
-                            message: `Message rejected by limiter ${type}`,
+                            message: `Message rejected by limiter ${ type }`,
                             key
                         }
                     }));
                 }
 
-                hyper.metrics.endTiming(`ratelimit.${fun}.allow`, startTime);
+                hyper.metrics.endTiming(`ratelimit.${ fun }.allow`, startTime);
                 return resolve({ status: 201 });
             });
         });
diff --git a/test/feature/job_rules.js b/test/feature/job_rules.js
index 57a0fce..987f86b 100644
--- a/test/feature/job_rules.js
+++ b/test/feature/job_rules.js
@@ -18,14 +18,16 @@ describe('JobQueue rules', function () {
         this.timeout(50000);
         return changeProp.start()
         .then(() => common.getKafkaFactory().createProducer({ log: console.log.bind(console) }))
-        .then((result) => { producer = result; });
+        .then((result) => {
+ producer = result;
+});
     });
 
     [
         'updateBetaFeaturesUserCounts',
         'cdnPurge'
     ].forEach((jobType) => {
-        it(`Should propagate ${jobType} job`, function () {
+        it(`Should propagate ${ jobType } job`, function () {
             this.timeout(10000);
             const sampleEvent = common.jobs[jobType];
             const service = nock('http://jobrunner.wikipedia.org', {
@@ -36,7 +38,7 @@ describe('JobQueue rules', function () {
             })
             .post('/wiki/Special%3ARunSingleJob', sampleEvent)
             .reply(200, {});
-            return producer.produce(`test_dc.mediawiki.job.${jobType}`, 0, sampleEvent.toBuffer())
+            return producer.produce(`test_dc.mediawiki.job.${ jobType }`, 0, sampleEvent.toBuffer())
             .then(() => common.checkAPIDone(service))
             .finally(() => nock.cleanAll());
         });
@@ -151,7 +153,7 @@ describe('JobQueue rules', function () {
     it('Should support delayed jobs with re-enqueue', () => {
         this.timeout(20000);
         const sampleEvent = common.jobs.cdnPurge;
-        sampleEvent.delay_until = `${new Date(Date.parse(sampleEvent.delay_until) + 10000).toISOString()}`;
+        sampleEvent.delay_until = `${ new Date(Date.parse(sampleEvent.delay_until) + 10000).toISOString() }`;
         const service = nock('http://jobrunner.wikipedia.org', {
             reqheaders: {
                 host: sampleEvent.meta.domain,
diff --git a/test/feature/static_rules.js b/test/feature/static_rules.js
index 1e595dd..d090195 100644
--- a/test/feature/static_rules.js
+++ b/test/feature/static_rules.js
@@ -21,7 +21,9 @@ describe('Basic rule management', function () {
         this.timeout(50000);
         return changeProp.start()
         .then(() => common.getKafkaFactory().createProducer({ log: console.log.bind(console) }))
-        .then((result) => { producer = result; });
+        .then((result) => {
+ producer = result;
+});
     });
 
     it('Should call simple executor', () => {
@@ -30,7 +32,7 @@ describe('Basic rule management', function () {
             reqheaders: {
                 test_header_name: 'test_header_value',
                 'content-type': 'application/json',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`,
                 'user-agent': 'ChangePropTestSuite'
             }
         })
@@ -65,14 +67,14 @@ describe('Basic rule management', function () {
             derived_field: 'test',
             random_field: random
         })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
         .reply(500, {})
         .post('/', {
             test_field_name: 'test_field_value',
             derived_field: 'test',
             random_field: random
         })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
         .reply(200, {});
 
         return P.try(() => producer.produce('test_dc.simple_test_rule', 0,
@@ -95,21 +97,21 @@ describe('Basic rule management', function () {
             derived_field: 'test',
             random_field: random
         })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
         .reply(500, {})
         .post('/', {
             test_field_name: 'test_field_value',
             derived_field: 'test',
             random_field: random
         })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
         .reply(500, {})
         .post('/', {
             test_field_name: 'test_field_value',
             derived_field: 'test',
             random_field: random
         })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
         .reply(500, {})
         // Next one must never get called, we verify that by checking pending mocks
         .post('/', {
@@ -176,7 +178,7 @@ describe('Basic rule management', function () {
                             return check();
                         }
 
-                        if (msg.triggered_by !== `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`) {
+                        if (msg.triggered_by !== `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`) {
                             throw new Error('TriggeredBy should be equal to simple_test_rule:https://en.wikipedia.org/wiki/SamplePage');
                         }
                     });
@@ -192,7 +194,7 @@ describe('Basic rule management', function () {
             reqheaders: {
                 test_header_name: 'test_header_value',
                 'content-type': 'application/json',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`,
                 'user-agent': 'ChangePropTestSuite'
             }
         })
@@ -237,7 +239,7 @@ describe('Basic rule management', function () {
             reqheaders: {
                 test_header_name: 'test_header_value',
                 'content-type': 'application/json',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`,
                 'user-agent': 'ChangePropTestSuite'
             }
         })
diff --git a/test/feature/update_rules.js b/test/feature/update_rules.js
index f461be1..e073ddc 100644
--- a/test/feature/update_rules.js
+++ b/test/feature/update_rules.js
@@ -33,9 +33,13 @@ describe('update rules', function () {
                 }
             });
         })
-        .then((res) => { siteInfoResponse = res.body; })
+        .then((res) => {
+ siteInfoResponse = res.body;
+})
         .then(() => common.getKafkaFactory().createProducer({ log: console.log.bind(console) }))
-        .then((result) => { producer = result; });
+        .then((result) => {
+ producer = result;
+});
     });
 
     const nockWithOptionalSiteInfo = () => nock('https://en.wikipedia.org')
@@ -53,7 +57,7 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},${topic}:https://en.wikipedia.org/api/rest_v1/page/html/Main_Page`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },${ topic }:https://en.wikipedia.org/api/rest_v1/page/html/Main_Page`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
@@ -61,7 +65,7 @@ describe('update rules', function () {
         .query({ redirect: false })
         .reply(200, { });
 
-        return P.try(() => producer.produce(`test_dc.${topic}`, 0, common.events.resourceChange(
+        return P.try(() => producer.produce(`test_dc.${ topic }`, 0, common.events.resourceChange(
             'https://en.wikipedia.org/api/rest_v1/page/html/Main_Page', topic
         ).toBuffer()))
         .then(() => common.checkAPIDone(mwAPI))
@@ -114,11 +118,11 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.page-properties-change:${SAMPLE_EVENT.meta.uri}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.page-properties-change:${ SAMPLE_EVENT.meta.uri }`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/summary/${SAMPLE_EVENT.page_title}`)
+        .get(`/api/rest_v1/page/summary/${ SAMPLE_EVENT.page_title }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -131,7 +135,7 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},resource_change:https://en.wikipedia.org/api/rest_v1/page/html/User%3ACyberbot_I%2FTest`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },resource_change:https://en.wikipedia.org/api/rest_v1/page/html/User%3ACyberbot_I%2FTest`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
@@ -150,7 +154,7 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wiktionary.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},resource_change:https://en.wiktionary.org/api/rest_v1/page/html/Main_Page`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },resource_change:https://en.wiktionary.org/api/rest_v1/page/html/Main_Page`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
@@ -182,7 +186,7 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},resource_change:https://en.wikipedia.org/api/rest_v1/page/html/Main_Page`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },resource_change:https://en.wikipedia.org/api/rest_v1/page/html/Main_Page`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
@@ -217,7 +221,7 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},resource_change:https://en.wikipedia.org/wiki/Main_Page`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },resource_change:https://en.wikipedia.org/wiki/Main_Page`,
                 'if-unmodified-since': 'Tue, 20 Feb 1990 19:31:13 +0000',
                 'user-agent': 'SampleChangePropInstance'
             }
@@ -246,13 +250,13 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-create:${SAMPLE_EVENT.meta.uri}`,
-                'x-restbase-parentrevision': `${SAMPLE_EVENT.rev_parent_id}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-create:${ SAMPLE_EVENT.meta.uri }`,
+                'x-restbase-parentrevision': `${ SAMPLE_EVENT.rev_parent_id }`,
                 'if-unmodified-since': SAMPLE_DATE,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/html/${SAMPLE_EVENT.page_title}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/html/${ SAMPLE_EVENT.page_title }/${ SAMPLE_EVENT.rev_id }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -270,13 +274,13 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-create:${SAMPLE_EVENT.meta.uri}`,
-                'x-restbase-parentrevision': `${SAMPLE_EVENT.rev_parent_id}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-create:${ SAMPLE_EVENT.meta.uri }`,
+                'x-restbase-parentrevision': `${ SAMPLE_EVENT.rev_parent_id }`,
                 'if-unmodified-since': SAMPLE_DATE,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/html/${encodeURIComponent(SAMPLE_EVENT.page_title)}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/html/${ encodeURIComponent(SAMPLE_EVENT.page_title) }/${ SAMPLE_EVENT.rev_id }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -288,7 +292,7 @@ describe('update rules', function () {
     it('Should not update RESTBase on revision create for wikidata', () => {
         const SAMPLE_EVENT = common.events.revisionCreate('https://www.wikidata.org/wiki/Q1');
         const mwAPI = nock('https://www.wikidata.org')
-        .get(`/api/rest_v1/page/html/${SAMPLE_EVENT.page_title}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/html/${ SAMPLE_EVENT.page_title }/${ SAMPLE_EVENT.rev_id }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -302,11 +306,11 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.page-delete:${SAMPLE_EVENT.meta.uri}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.page-delete:${ SAMPLE_EVENT.meta.uri }`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/title/${encodeURIComponent(SAMPLE_EVENT.page_title)}`)
+        .get(`/api/rest_v1/page/title/${ encodeURIComponent(SAMPLE_EVENT.page_title) }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -320,11 +324,11 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.page-undelete:${SAMPLE_EVENT.meta.uri}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.page-undelete:${ SAMPLE_EVENT.meta.uri }`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/title/${encodeURIComponent(SAMPLE_EVENT.page_title)}`)
+        .get(`/api/rest_v1/page/title/${ encodeURIComponent(SAMPLE_EVENT.page_title) }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -343,15 +347,15 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.page-move:${SAMPLE_EVENT.meta.uri}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.page-move:${ SAMPLE_EVENT.meta.uri }`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/html/${SAMPLE_EVENT.page_title}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/html/${ SAMPLE_EVENT.page_title }/${ SAMPLE_EVENT.rev_id }`)
         .matchHeader('if-unmodified-since', SAMPLE_DATE)
         .query({ redirect: false })
         .reply(200, { })
-        .get(`/api/rest_v1/page/title/${SAMPLE_EVENT.prior_state.page_title}`)
+        .get(`/api/rest_v1/page/title/${ SAMPLE_EVENT.prior_state.page_title }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -365,11 +369,11 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-visibility-change:${SAMPLE_EVENT.meta.uri}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-visibility-change:${ SAMPLE_EVENT.meta.uri }`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/title/${SAMPLE_EVENT.page_title}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/title/${ SAMPLE_EVENT.page_title }/${ SAMPLE_EVENT.rev_id }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -496,7 +500,7 @@ describe('update rules', function () {
                 'cache-control': 'no-cache',
                 'x-request-id': common.SAMPLE_REQUEST_ID,
                 'user-agent': 'SampleChangePropInstance',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},${stream}:${SAMPLE_EVENT.meta.uri},change-prop.wikidata.resource-change:https://ru.wikipedia.org/wiki/%D0%9F%D1%91%D1%82%D1%80`
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },${ stream }:${ SAMPLE_EVENT.meta.uri },change-prop.wikidata.resource-change:https://ru.wikipedia.org/wiki/%D0%9F%D1%91%D1%82%D1%80`
             }
         })
         .get('/api/rest_v1/page/summary/%D0%9F%D1%91%D1%82%D1%80')
@@ -506,7 +510,7 @@ describe('update rules', function () {
         .query({ redirect: false })
         .reply(200, { });
 
-        return P.try(() => producer.produce(`test_dc.${stream}`, 0, SAMPLE_EVENT.toBuffer()))
+        return P.try(() => producer.produce(`test_dc.${ stream }`, 0, SAMPLE_EVENT.toBuffer()))
         .delay(common.REQUEST_CHECK_DELAY)
         .then(() => common.checkAPIDone(wikidataAPI))
         .then(() => common.checkAPIDone(restbase))
@@ -602,7 +606,7 @@ describe('update rules', function () {
             SAMPLE_DATE
         );
         const mwAPI = nockWithOptionalSiteInfo()
-        .get(`/api/rest_v1/page/html/${encodeURIComponent(SAMPLE_EVENT.page_title)}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/html/${ encodeURIComponent(SAMPLE_EVENT.page_title) }/${ SAMPLE_EVENT.rev_id }`)
         .query({ redirect: false })
         .reply(200)
         .post('/w/api.php', {
@@ -625,7 +629,7 @@ describe('update rules', function () {
         })
         .get('/api/rest_v1/page/html/File_Transcluded_Page')
         .query({ redirect: false })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-create:${SAMPLE_EVENT.meta.uri},change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/File_Transcluded_Page`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-create:${ SAMPLE_EVENT.meta.uri },change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/File_Transcluded_Page`)
         .matchHeader('if-unmodified-since', SAMPLE_DATE)
         .matchHeader('x-restbase-mode', 'files')
         .times(2)
@@ -647,7 +651,7 @@ describe('update rules', function () {
         })
         .get('/api/rest_v1/page/html/File_Transcluded_Page')
         .query({ redirect: false })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-create:${SAMPLE_EVENT.meta.uri},change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/File_Transcluded_Page`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-create:${ SAMPLE_EVENT.meta.uri },change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/File_Transcluded_Page`)
         .matchHeader('if-unmodified-since', SAMPLE_DATE)
         .matchHeader('x-restbase-mode', 'files')
         .reply(200);
@@ -664,7 +668,7 @@ describe('update rules', function () {
             '1990-02-20T19:31:13+00:00'
         );
         const mwAPI = nockWithOptionalSiteInfo()
-        .get(`/api/rest_v1/page/html/${SAMPLE_EVENT.page_title}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/html/${ SAMPLE_EVENT.page_title }/${ SAMPLE_EVENT.rev_id }`)
         .query({ redirect: false })
         .reply(200)
         .post('/w/api.php', {
@@ -693,7 +697,7 @@ describe('update rules', function () {
         })
         .get('/api/rest_v1/page/html/Transcluded_Here')
         .query({ redirect: false })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-create:https://en.wikipedia.org/wiki/${SAMPLE_EVENT.page_title},change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/Transcluded_Here`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-create:https://en.wikipedia.org/wiki/${ SAMPLE_EVENT.page_title },change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/Transcluded_Here`)
         .matchHeader('if-unmodified-since', SAMPLE_DATE)
         .matchHeader('x-restbase-mode', 'templates')
         .times(2)
@@ -721,7 +725,7 @@ describe('update rules', function () {
         })
         .get('/api/rest_v1/page/html/Transcluded_Here')
         .query({ redirect: false })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-create:https://en.wikipedia.org/wiki/${SAMPLE_EVENT.page_title},change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/Transcluded_Here`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-create:https://en.wikipedia.org/wiki/${ SAMPLE_EVENT.page_title },change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/Transcluded_Here`)
         .matchHeader('if-unmodified-since', SAMPLE_DATE)
         .matchHeader('x-restbase-mode', 'templates')
         .reply(200);
@@ -732,7 +736,7 @@ describe('update rules', function () {
 
     function backlinksTest(pageTitle, topic) {
         const mwAPI = nockWithOptionalSiteInfo()
-            .get(`/api/rest_v1/page/title/${pageTitle}`)
+            .get(`/api/rest_v1/page/title/${ pageTitle }`)
             .query({ redirect: false })
             .optionally()
             .reply(200)
@@ -752,13 +756,13 @@ describe('update rules', function () {
                     continue: '-||'
                 },
                 query: {
-                    backlinks: common.arrayWithLinks(`Linked_${pageTitle}`, 2)
+                    backlinks: common.arrayWithLinks(`Linked_${ pageTitle }`, 2)
                 }
             })
-            .get(`/api/rest_v1/page/html/Linked_${pageTitle}`)
+            .get(`/api/rest_v1/page/html/Linked_${ pageTitle }`)
             .times(2)
             .query({ redirect: false })
-            .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},${topic}:https://en.wikipedia.org/wiki/SamplePage,change-prop.backlinks.resource-change:https://en.wikipedia.org/wiki/Linked_${pageTitle}`)
+            .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },${ topic }:https://en.wikipedia.org/wiki/SamplePage,change-prop.backlinks.resource-change:https://en.wikipedia.org/wiki/Linked_${ pageTitle }`)
             .reply(200)
             .post('/w/api.php', {
                 format: 'json',
@@ -773,15 +777,15 @@ describe('update rules', function () {
             .reply(200, {
                 batchcomplete: '',
                 query: {
-                    backlinks: common.arrayWithLinks(`Linked_${pageTitle}`, 1)
+                    backlinks: common.arrayWithLinks(`Linked_${ pageTitle }`, 1)
                 }
             })
-            .get(`/api/rest_v1/page/html/Linked_${pageTitle}`)
+            .get(`/api/rest_v1/page/html/Linked_${ pageTitle }`)
             .query({ redirect: false })
-            .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},${topic}:https://en.wikipedia.org/wiki/SamplePage,change-prop.backlinks.resource-change:https://en.wikipedia.org/wiki/Linked_${pageTitle}`)
+            .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },${ topic }:https://en.wikipedia.org/wiki/SamplePage,change-prop.backlinks.resource-change:https://en.wikipedia.org/wiki/Linked_${ pageTitle }`)
             .reply(200);
 
-        return P.try(() => producer.produce(`test_dc.${topic}`, 0,
+        return P.try(() => producer.produce(`test_dc.${ topic }`, 0,
             Buffer.from(JSON.stringify(common.eventWithProperties(topic,
                 {
                     page_title: pageTitle
diff --git a/test/utils/changeProp.js b/test/utils/changeProp.js
index 6a99c18..713b3fc 100644
--- a/test/utils/changeProp.js
+++ b/test/utils/changeProp.js
@@ -8,7 +8,7 @@ const CHANGE_PROP_STOP_DELAY = 1000;
 const CHANGE_PROP_START_DELAY = 30000;
 
 class ChangePropServer extends TestServer {
-    constructor(configPath = `${__dirname}/../../config.test.yaml`) {
+    constructor(configPath = `${ __dirname }/../../config.test.yaml`) {
         super(configPath);
     }
 
diff --git a/test/utils/common.js b/test/utils/common.js
index 519dd67..edf31c0 100644
--- a/test/utils/common.js
+++ b/test/utils/common.js
@@ -117,7 +117,7 @@ const ajv = new Ajv({
     loadSchema: (uri) => preq.get({ uri })
     .then((content) => {
         if (content.status !== 200) {
-            throw new Error(`Failed to load meta schema at ${uri}`);
+            throw new Error(`Failed to load meta schema at ${ uri }`);
         }
         const metaSchema = content.body;
         // Need to reassign the ID cause we're using https in the meta-schema URIs
@@ -127,7 +127,7 @@ const ajv = new Ajv({
 });
 
 common.fetchEventValidator = (schemaUri, version = 1) => {
-    const schemaPath = `${schemaUri}/${version}.yaml`;
+    const schemaPath = `${ schemaUri }/${ version }.yaml`;
     if (validatorCache.has(schemaPath)) {
         return P.resolve(validatorCache.get(schemaPath));
     }
@@ -149,7 +149,7 @@ common.fetchEventValidator = (schemaUri, version = 1) => {
         });
     } catch (e) {
         return preq.get({
-            uri: `https://raw.githubusercontent.com/wikimedia/mediawiki-event-schemas/master/jsonschema/${schemaPath}`
+            uri: `https://raw.githubusercontent.com/wikimedia/mediawiki-event-schemas/master/jsonschema/${ schemaPath }`
         })
         .then((res) => ajv.compileAsync(yaml.safeLoad(res.body)))
         .then((validator) => {
@@ -409,7 +409,7 @@ common.jobs = {
             __proto__: eventMethods,
             $schema: 'mediawiki/job/1.0.0',
             database: 'commonswiki',
-            delay_until: `${releaseTimestamp}`,
+            delay_until: `${ releaseTimestamp }`,
             mediawiki_signature: 'e6ff5af8f89ac6441c6ad7b34bdcf44fb1746c1ef6e07d8b9653c75d0005193e',
             meta: {
                 domain: 'commons.wikimedia.org',
diff --git a/test/utils/mock_kafka_factory.js b/test/utils/mock_kafka_factory.js
index 071b0c2..7335a38 100644
--- a/test/utils/mock_kafka_factory.js
+++ b/test/utils/mock_kafka_factory.js
@@ -4,7 +4,7 @@ const P = require('bluebird');
 const EventEmitter = require('events').EventEmitter;
 const fs = require('fs');
 
-const fixtureTopics = fs.readFileSync(`${__dirname}/test_topics`, 'utf8')
+const fixtureTopics = fs.readFileSync(`${ __dirname }/test_topics`, 'utf8')
     .split('\n')
     .map((line) => line.split(' ')[0].replace(/^test_dc\./, ''))
     .filter((line) => line.length);
@@ -13,6 +13,7 @@ class MockMetadataWatch extends EventEmitter {
     getTopics() {
         return P.resolve(fixtureTopics);
     }
+
     disconnect() {}
 }
 
@@ -20,6 +21,7 @@ class MockProducer {
     constructor(messages) {
         this._messages = messages;
     }
+
     produce(topic, partition, message) {
         if (!this._messages.has(topic)) {
             this._messages.set(topic, []);
@@ -31,6 +33,7 @@ class MockProducer {
         });
         return P.resolve();
     }
+
     disconnect() {}
 }
 
@@ -41,13 +44,16 @@ class MockConsumer extends EventEmitter {
         this._messages = messages;
         this._currentTopicOffsets = new Map();
     }
+
     _getCurrentOffset(topic) {
         if (this._currentTopicOffsets.has(topic)) {
             return this._currentTopicOffsets.get(topic);
         }
         return 0;
     }
+
     disconnect() {}
+
     disconnectAsync() {}
 
     consumeAsync() {
@@ -68,6 +74,7 @@ class MockConsumer extends EventEmitter {
         }
         return P.resolve([]);
     }
+
     commitMessageAsync() {
         return P.resolve();
     }
-- 
2.39.2

$ date
--- stdout ---
Mon Apr 29 19:13:00 UTC 2024

--- end ---
$ git clone file:///srv/git/mediawiki-services-change-propagation.git repo --depth=1 -b master
--- stderr ---
Cloning into 'repo'...
--- stdout ---

--- end ---
$ git config user.name libraryupgrader
--- stdout ---

--- end ---
$ git config user.email tools.libraryupgrader@tools.wmflabs.org
--- stdout ---

--- end ---
$ git submodule update --init
--- stdout ---

--- end ---
$ grr init
--- stdout ---
Installed commit-msg hook.

--- end ---
$ git show-ref refs/heads/master
--- stdout ---
0de70bcb10fc05bc6e248cdbe139d7b3c3146f7a refs/heads/master

--- end ---
$ /usr/bin/npm audit --json
--- stdout ---
{
  "auditReportVersion": 2,
  "vulnerabilities": {
    "@babel/traverse": {
      "name": "@babel/traverse",
      "severity": "critical",
      "isDirect": false,
      "via": [
        {
          "source": 1096886,
          "name": "@babel/traverse",
          "dependency": "@babel/traverse",
          "title": "Babel vulnerable to arbitrary code execution when compiling specifically crafted malicious code",
          "url": "https://github.com/advisories/GHSA-67hx-6x53-jw92",
          "severity": "critical",
          "cwe": [
            "CWE-184",
            "CWE-697"
          ],
          "cvss": {
            "score": 9.4,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H"
          },
          "range": "<7.23.2"
        }
      ],
      "effects": [],
      "range": "<7.23.2",
      "nodes": [
        "node_modules/@babel/traverse"
      ],
      "fixAvailable": true
    },
    "ansi-regex": {
      "name": "ansi-regex",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1094090,
          "name": "ansi-regex",
          "dependency": "ansi-regex",
          "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex",
          "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw",
          "severity": "high",
          "cwe": [
            "CWE-697",
            "CWE-1333"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": ">=3.0.0 <3.0.1"
        },
        {
          "source": 1094091,
          "name": "ansi-regex",
          "dependency": "ansi-regex",
          "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex",
          "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw",
          "severity": "high",
          "cwe": [
            "CWE-697",
            "CWE-1333"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": ">=4.0.0 <4.1.1"
        },
        {
          "source": 1094092,
          "name": "ansi-regex",
          "dependency": "ansi-regex",
          "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex",
          "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw",
          "severity": "high",
          "cwe": [
            "CWE-697",
            "CWE-1333"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": ">=5.0.0 <5.0.1"
        }
      ],
      "effects": [],
      "range": "3.0.0 || 4.0.0 - 4.1.0 || 5.0.0",
      "nodes": [
        "node_modules/ansi-regex",
        "node_modules/nyc/node_modules/ansi-regex",
        "node_modules/wide-align/node_modules/ansi-regex"
      ],
      "fixAvailable": true
    },
    "busboy": {
      "name": "busboy",
      "severity": "high",
      "isDirect": false,
      "via": [
        "dicer"
      ],
      "effects": [
        "hyperswitch"
      ],
      "range": "<=0.3.1",
      "nodes": [
        "node_modules/busboy"
      ],
      "fixAvailable": {
        "name": "hyperswitch",
        "version": "0.10.5",
        "isSemVerMajor": true
      }
    },
    "coveralls": {
      "name": "coveralls",
      "severity": "moderate",
      "isDirect": true,
      "via": [
        "request"
      ],
      "effects": [],
      "range": "*",
      "nodes": [
        "node_modules/coveralls"
      ],
      "fixAvailable": false
    },
    "debug": {
      "name": "debug",
      "severity": "low",
      "isDirect": false,
      "via": [
        {
          "source": 1096792,
          "name": "debug",
          "dependency": "debug",
          "title": "Regular Expression Denial of Service in debug",
          "url": "https://github.com/advisories/GHSA-gxpj-cx7g-858c",
          "severity": "low",
          "cwe": [
            "CWE-400"
          ],
          "cvss": {
            "score": 3.7,
            "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L"
          },
          "range": ">=4.0.0 <4.3.1"
        }
      ],
      "effects": [
        "mocha"
      ],
      "range": "4.0.0 - 4.3.0",
      "nodes": [
        "node_modules/gc-stats/node_modules/debug",
        "node_modules/mocha/node_modules/debug"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "dicer": {
      "name": "dicer",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1093150,
          "name": "dicer",
          "dependency": "dicer",
          "title": "Crash in HeaderParser in dicer",
          "url": "https://github.com/advisories/GHSA-wm7h-9275-46v2",
          "severity": "high",
          "cwe": [
            "CWE-248"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": "<=0.3.1"
        }
      ],
      "effects": [
        "busboy"
      ],
      "range": "*",
      "nodes": [
        "node_modules/dicer"
      ],
      "fixAvailable": {
        "name": "hyperswitch",
        "version": "0.10.5",
        "isSemVerMajor": true
      }
    },
    "hyperswitch": {
      "name": "hyperswitch",
      "severity": "high",
      "isDirect": true,
      "via": [
        "busboy",
        "preq",
        "swagger-ui-dist"
      ],
      "effects": [],
      "range": ">=0.1.0",
      "nodes": [
        "node_modules/hyperswitch"
      ],
      "fixAvailable": {
        "name": "hyperswitch",
        "version": "0.10.5",
        "isSemVerMajor": true
      }
    },
    "ini": {
      "name": "ini",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1093224,
          "name": "ini",
          "dependency": "ini",
          "title": "ini before 1.3.6 vulnerable to Prototype Pollution via ini.parse",
          "url": "https://github.com/advisories/GHSA-qqgx-2p2h-9c37",
          "severity": "high",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 7.3,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L"
          },
          "range": "<1.3.6"
        }
      ],
      "effects": [],
      "range": "<1.3.6",
      "nodes": [
        "node_modules/gc-stats/node_modules/ini"
      ],
      "fixAvailable": true
    },
    "json-schema": {
      "name": "json-schema",
      "severity": "critical",
      "isDirect": false,
      "via": [
        {
          "source": 1095057,
          "name": "json-schema",
          "dependency": "json-schema",
          "title": "json-schema is vulnerable to Prototype Pollution",
          "url": "https://github.com/advisories/GHSA-896r-f27r-55mw",
          "severity": "critical",
          "cwe": [
            "CWE-915",
            "CWE-1321"
          ],
          "cvss": {
            "score": 9.8,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
          },
          "range": "<0.4.0"
        }
      ],
      "effects": [
        "jsprim"
      ],
      "range": "<0.4.0",
      "nodes": [
        "node_modules/json-schema"
      ],
      "fixAvailable": true
    },
    "json5": {
      "name": "json5",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1096544,
          "name": "json5",
          "dependency": "json5",
          "title": "Prototype Pollution in JSON5 via Parse Method",
          "url": "https://github.com/advisories/GHSA-9c47-m6qq-7p4h",
          "severity": "high",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 7.1,
            "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:L/A:H"
          },
          "range": ">=2.0.0 <2.2.2"
        }
      ],
      "effects": [],
      "range": "2.0.0 - 2.2.1",
      "nodes": [
        "node_modules/json5"
      ],
      "fixAvailable": true
    },
    "jsprim": {
      "name": "jsprim",
      "severity": "critical",
      "isDirect": false,
      "via": [
        "json-schema"
      ],
      "effects": [],
      "range": "0.3.0 - 1.4.1 || 2.0.0 - 2.0.1",
      "nodes": [
        "node_modules/jsprim"
      ],
      "fixAvailable": true
    },
    "kad": {
      "name": "kad",
      "severity": "high",
      "isDirect": false,
      "via": [
        "merge",
        "ms"
      ],
      "effects": [
        "limitation"
      ],
      "range": "*",
      "nodes": [
        "node_modules/kad"
      ],
      "fixAvailable": true
    },
    "limitation": {
      "name": "limitation",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        "kad"
      ],
      "effects": [],
      "range": "<=0.2.2",
      "nodes": [
        "node_modules/limitation"
      ],
      "fixAvailable": true
    },
    "merge": {
      "name": "merge",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1096479,
          "name": "merge",
          "dependency": "merge",
          "title": "Prototype Pollution in merge",
          "url": "https://github.com/advisories/GHSA-7wpw-2hjm-89gp",
          "severity": "high",
          "cwe": [
            "CWE-915"
          ],
          "cvss": {
            "score": 7.3,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L"
          },
          "range": "<2.1.1"
        }
      ],
      "effects": [
        "kad"
      ],
      "range": "<2.1.1",
      "nodes": [
        "node_modules/merge"
      ],
      "fixAvailable": true
    },
    "minimatch": {
      "name": "minimatch",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1096485,
          "name": "minimatch",
          "dependency": "minimatch",
          "title": "minimatch ReDoS vulnerability",
          "url": "https://github.com/advisories/GHSA-f8q6-p94x-37v3",
          "severity": "high",
          "cwe": [
            "CWE-400",
            "CWE-1333"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": "<3.0.5"
        }
      ],
      "effects": [
        "mocha"
      ],
      "range": "<3.0.5",
      "nodes": [
        "node_modules/gc-stats/node_modules/minimatch",
        "node_modules/minimatch"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "minimist": {
      "name": "minimist",
      "severity": "critical",
      "isDirect": false,
      "via": [
        {
          "source": 1096465,
          "name": "minimist",
          "dependency": "minimist",
          "title": "Prototype Pollution in minimist",
          "url": "https://github.com/advisories/GHSA-vh95-rmgr-6w4m",
          "severity": "moderate",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 5.6,
            "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"
          },
          "range": ">=1.0.0 <1.2.3"
        },
        {
          "source": 1096466,
          "name": "minimist",
          "dependency": "minimist",
          "title": "Prototype Pollution in minimist",
          "url": "https://github.com/advisories/GHSA-vh95-rmgr-6w4m",
          "severity": "moderate",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 5.6,
            "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"
          },
          "range": "<0.2.1"
        },
        {
          "source": 1096548,
          "name": "minimist",
          "dependency": "minimist",
          "title": "Prototype Pollution in minimist",
          "url": "https://github.com/advisories/GHSA-xvch-5gv4-984h",
          "severity": "critical",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 9.8,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
          },
          "range": "<0.2.4"
        },
        {
          "source": 1096549,
          "name": "minimist",
          "dependency": "minimist",
          "title": "Prototype Pollution in minimist",
          "url": "https://github.com/advisories/GHSA-xvch-5gv4-984h",
          "severity": "critical",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 9.8,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
          },
          "range": ">=1.0.0 <1.2.6"
        }
      ],
      "effects": [
        "mkdirp"
      ],
      "range": "<=0.2.3 || 1.0.0 - 1.2.5",
      "nodes": [
        "node_modules/gc-stats/node_modules/minimist",
        "node_modules/gc-stats/node_modules/rc/node_modules/minimist",
        "node_modules/minimist"
      ],
      "fixAvailable": true
    },
    "mkdirp": {
      "name": "mkdirp",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        "minimist"
      ],
      "effects": [],
      "range": "0.4.1 - 0.5.1",
      "nodes": [
        "node_modules/gc-stats/node_modules/mkdirp"
      ],
      "fixAvailable": true
    },
    "mocha": {
      "name": "mocha",
      "severity": "high",
      "isDirect": true,
      "via": [
        "debug",
        "minimatch",
        "nanoid"
      ],
      "effects": [],
      "range": "5.1.0 - 9.2.1",
      "nodes": [
        "node_modules/mocha"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "moment": {
      "name": "moment",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1095072,
          "name": "moment",
          "dependency": "moment",
          "title": "Moment.js vulnerable to Inefficient Regular Expression Complexity",
          "url": "https://github.com/advisories/GHSA-wc69-rhjr-hc9g",
          "severity": "high",
          "cwe": [
            "CWE-400",
            "CWE-1333"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": ">=2.18.0 <2.29.4"
        },
        {
          "source": 1095083,
          "name": "moment",
          "dependency": "moment",
          "title": "Path Traversal: 'dir/../../filename' in moment.locale",
          "url": "https://github.com/advisories/GHSA-8hfj-j24r-96c4",
          "severity": "high",
          "cwe": [
            "CWE-22",
            "CWE-27"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N"
          },
          "range": "<2.29.2"
        }
      ],
      "effects": [],
      "range": "<=2.29.3",
      "nodes": [
        "node_modules/moment"
      ],
      "fixAvailable": true
    },
    "ms": {
      "name": "ms",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1094419,
          "name": "ms",
          "dependency": "ms",
          "title": "Vercel ms Inefficient Regular Expression Complexity vulnerability",
          "url": "https://github.com/advisories/GHSA-w9mr-4mfr-499f",
          "severity": "moderate",
          "cwe": [
            "CWE-1333"
          ],
          "cvss": {
            "score": 5.3,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"
          },
          "range": "<2.0.0"
        }
      ],
      "effects": [
        "kad"
      ],
      "range": "<2.0.0",
      "nodes": [
        "node_modules/ms"
      ],
      "fixAvailable": true
    },
    "msgpack5": {
      "name": "msgpack5",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1089202,
          "name": "msgpack5",
          "dependency": "msgpack5",
          "title": "Prototype poisoning",
          "url": "https://github.com/advisories/GHSA-gmjw-49p4-pcfm",
          "severity": "moderate",
          "cwe": [
            "CWE-915",
            "CWE-1321"
          ],
          "cvss": {
            "score": 6.7,
            "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:H/A:H"
          },
          "range": "<3.6.1"
        }
      ],
      "effects": [],
      "range": "<3.6.1",
      "nodes": [
        "node_modules/msgpack5"
      ],
      "fixAvailable": true
    },
    "nanoid": {
      "name": "nanoid",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1089011,
          "name": "nanoid",
          "dependency": "nanoid",
          "title": "Exposure of Sensitive Information to an Unauthorized Actor in nanoid",
          "url": "https://github.com/advisories/GHSA-qrpm-p2h7-hrv2",
          "severity": "moderate",
          "cwe": [
            "CWE-200"
          ],
          "cvss": {
            "score": 5.5,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N"
          },
          "range": ">=3.0.0 <3.1.31"
        }
      ],
      "effects": [
        "mocha"
      ],
      "range": "3.0.0 - 3.1.30",
      "nodes": [
        "node_modules/nanoid"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "preq": {
      "name": "preq",
      "severity": "high",
      "isDirect": true,
      "via": [
        "request",
        "requestretry"
      ],
      "effects": [],
      "range": "*",
      "nodes": [
        "node_modules/preq"
      ],
      "fixAvailable": false
    },
    "qs": {
      "name": "qs",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1096470,
          "name": "qs",
          "dependency": "qs",
          "title": "qs vulnerable to Prototype Pollution",
          "url": "https://github.com/advisories/GHSA-hrpp-h998-j3pp",
          "severity": "high",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": ">=6.5.0 <6.5.3"
        }
      ],
      "effects": [],
      "range": "6.5.0 - 6.5.2",
      "nodes": [
        "node_modules/qs"
      ],
      "fixAvailable": true
    },
    "redis": {
      "name": "redis",
      "severity": "high",
      "isDirect": true,
      "via": [
        {
          "source": 1089196,
          "name": "redis",
          "dependency": "redis",
          "title": "Node-Redis potential exponential regex in monitor mode",
          "url": "https://github.com/advisories/GHSA-35q2-47q7-3pc3",
          "severity": "high",
          "cwe": [
            "CWE-400"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": ">=2.6.0 <3.1.1"
        }
      ],
      "effects": [],
      "range": "2.6.0 - 3.1.0",
      "nodes": [
        "node_modules/redis"
      ],
      "fixAvailable": true
    },
    "request": {
      "name": "request",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1096727,
          "name": "request",
          "dependency": "request",
          "title": "Server-Side Request Forgery in Request",
          "url": "https://github.com/advisories/GHSA-p8p7-x288-28g6",
          "severity": "moderate",
          "cwe": [
            "CWE-918"
          ],
          "cvss": {
            "score": 6.1,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
          },
          "range": "<=2.88.2"
        },
        "tough-cookie"
      ],
      "effects": [
        "coveralls",
        "preq",
        "requestretry"
      ],
      "range": "*",
      "nodes": [
        "node_modules/request"
      ],
      "fixAvailable": false
    },
    "requestretry": {
      "name": "requestretry",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1090420,
          "name": "requestretry",
          "dependency": "requestretry",
          "title": "Cookie exposure in requestretry",
          "url": "https://github.com/advisories/GHSA-hjp8-2cm3-cc45",
          "severity": "high",
          "cwe": [
            "CWE-200"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"
          },
          "range": "<7.0.0"
        },
        "request"
      ],
      "effects": [
        "preq"
      ],
      "range": "*",
      "nodes": [
        "node_modules/requestretry"
      ],
      "fixAvailable": false
    },
    "semver": {
      "name": "semver",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1096483,
          "name": "semver",
          "dependency": "semver",
          "title": "semver vulnerable to Regular Expression Denial of Service",
          "url": "https://github.com/advisories/GHSA-c2qf-rxjj-qqgw",
          "severity": "moderate",
          "cwe": [
            "CWE-1333"
          ],
          "cvss": {
            "score": 5.3,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"
          },
          "range": "<5.7.2"
        },
        {
          "source": 1096484,
          "name": "semver",
          "dependency": "semver",
          "title": "semver vulnerable to Regular Expression Denial of Service",
          "url": "https://github.com/advisories/GHSA-c2qf-rxjj-qqgw",
          "severity": "moderate",
          "cwe": [
            "CWE-1333"
          ],
          "cvss": {
            "score": 5.3,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"
          },
          "range": ">=6.0.0 <6.3.1"
        }
      ],
      "effects": [],
      "range": "<5.7.2 || >=6.0.0 <6.3.1",
      "nodes": [
        "node_modules/@babel/core/node_modules/semver",
        "node_modules/@wikimedia/jsonschema-tools/node_modules/semver",
        "node_modules/eslint-plugin-node/node_modules/semver",
        "node_modules/gc-stats/node_modules/semver",
        "node_modules/istanbul-lib-instrument/node_modules/semver",
        "node_modules/make-dir/node_modules/semver"
      ],
      "fixAvailable": true
    },
    "swagger-ui-dist": {
      "name": "swagger-ui-dist",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1088759,
          "name": "swagger-ui-dist",
          "dependency": "swagger-ui-dist",
          "title": "Spoofing attack in swagger-ui-dist",
          "url": "https://github.com/advisories/GHSA-6c9x-mj3g-h47x",
          "severity": "moderate",
          "cwe": [
            "CWE-1021"
          ],
          "cvss": {
            "score": 6.1,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
          },
          "range": "<4.1.3"
        },
        {
          "source": 1092160,
          "name": "swagger-ui-dist",
          "dependency": "swagger-ui-dist",
          "title": "Server side request forgery in SwaggerUI",
          "url": "https://github.com/advisories/GHSA-qrmm-w75w-3wpx",
          "severity": "moderate",
          "cwe": [
            "CWE-918"
          ],
          "cvss": {
            "score": 0,
            "vectorString": null
          },
          "range": "<4.1.3"
        }
      ],
      "effects": [
        "hyperswitch"
      ],
      "range": "<=4.1.2",
      "nodes": [
        "node_modules/swagger-ui-dist"
      ],
      "fixAvailable": {
        "name": "hyperswitch",
        "version": "0.10.5",
        "isSemVerMajor": true
      }
    },
    "tar": {
      "name": "tar",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1089684,
          "name": "tar",
          "dependency": "tar",
          "title": "Arbitrary File Creation/Overwrite due to insufficient absolute path sanitization",
          "url": "https://github.com/advisories/GHSA-3jfq-g458-7qm9",
          "severity": "high",
          "cwe": [
            "CWE-22"
          ],
          "cvss": {
            "score": 8.2,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
          },
          "range": ">=4.0.0 <4.4.14"
        },
        {
          "source": 1095117,
          "name": "tar",
          "dependency": "tar",
          "title": "Arbitrary File Creation/Overwrite on Windows via insufficient relative path sanitization",
          "url": "https://github.com/advisories/GHSA-5955-9wpr-37jh",
          "severity": "high",
          "cwe": [
            "CWE-22"
          ],
          "cvss": {
            "score": 8.2,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
          },
          "range": "<4.4.18"
        },
        {
          "source": 1096309,
          "name": "tar",
          "dependency": "tar",
          "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning",
          "url": "https://github.com/advisories/GHSA-r628-mhmh-qjhw",
          "severity": "high",
          "cwe": [
            "CWE-22",
            "CWE-23",
            "CWE-59"
          ],
          "cvss": {
            "score": 8.2,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
          },
          "range": ">=4.0.0 <4.4.15"
        },
        {
          "source": 1096376,
          "name": "tar",
          "dependency": "tar",
          "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning using symbolic links",
          "url": "https://github.com/advisories/GHSA-9r2w-394v-53qc",
          "severity": "high",
          "cwe": [
            "CWE-22",
            "CWE-59"
          ],
          "cvss": {
            "score": 8.2,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
          },
          "range": ">=3.0.0 <4.4.16"
        },
        {
          "source": 1096411,
          "name": "tar",
          "dependency": "tar",
          "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning using symbolic links",
          "url": "https://github.com/advisories/GHSA-qq89-hq3f-393p",
          "severity": "high",
          "cwe": [
            "CWE-22",
            "CWE-59"
          ],
          "cvss": {
            "score": 8.2,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
          },
          "range": ">=3.0.0 <4.4.18"
        },
        {
          "source": 1096915,
          "name": "tar",
          "dependency": "tar",
          "title": "Denial of service while parsing a tar file due to lack of folders count validation",
          "url": "https://github.com/advisories/GHSA-f5x3-32g6-xq36",
          "severity": "moderate",
          "cwe": [
            "CWE-400"
          ],
          "cvss": {
            "score": 6.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H"
          },
          "range": "<6.2.1"
        }
      ],
      "effects": [],
      "range": "<=6.2.0",
      "nodes": [
        "node_modules/gc-stats/node_modules/tar"
      ],
      "fixAvailable": true
    },
    "tough-cookie": {
      "name": "tough-cookie",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1096643,
          "name": "tough-cookie",
          "dependency": "tough-cookie",
          "title": "tough-cookie Prototype Pollution vulnerability",
          "url": "https://github.com/advisories/GHSA-72xf-g2v4-qvf3",
          "severity": "moderate",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 6.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N"
          },
          "range": "<4.1.3"
        }
      ],
      "effects": [
        "request"
      ],
      "range": "<4.1.3",
      "nodes": [
        "node_modules/tough-cookie"
      ],
      "fixAvailable": false
    },
    "underscore": {
      "name": "underscore",
      "severity": "critical",
      "isDirect": false,
      "via": [
        {
          "source": 1095097,
          "name": "underscore",
          "dependency": "underscore",
          "title": "Arbitrary Code Execution in underscore",
          "url": "https://github.com/advisories/GHSA-cf4h-3jhx-xvhq",
          "severity": "critical",
          "cwe": [
            "CWE-94"
          ],
          "cvss": {
            "score": 9.8,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
          },
          "range": ">=1.3.2 <1.12.1"
        }
      ],
      "effects": [],
      "range": "1.3.2 - 1.12.0",
      "nodes": [
        "node_modules/underscore"
      ],
      "fixAvailable": true
    }
  },
  "metadata": {
    "vulnerabilities": {
      "info": 0,
      "low": 1,
      "moderate": 10,
      "high": 16,
      "critical": 5,
      "total": 32
    },
    "dependencies": {
      "prod": 157,
      "dev": 404,
      "optional": 78,
      "peer": 0,
      "peerOptional": 0,
      "total": 637
    }
  }
}

--- end ---
Upgrading n:eslint-config-wikimedia from 0.25.1 -> 0.27.0
$ /usr/bin/npm install
--- stderr ---
npm WARN skipping integrity check for git dependency ssh://git@github.com/wikimedia/kad.git 
npm WARN deprecated kad-fs@0.0.4: This package is no longer maintained.
npm WARN deprecated @hapi/bourne@1.3.2: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated kad-memstore@0.0.1: This package is no longer maintained.
npm WARN deprecated debug@4.2.0: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated json-schema-ref-parser@7.1.4: Please switch to @apidevtools/json-schema-ref-parser
--- stdout ---

added 595 packages, and audited 662 packages in 2m

65 packages are looking for funding
  run `npm fund` for details

32 vulnerabilities (1 low, 10 moderate, 16 high, 5 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues possible (including breaking changes), run:
  npm audit fix --force

Some issues need review, and may require choosing
a different dependency.

Run `npm audit` for details.

--- end ---
$ package-lock-lint package-lock.json
--- stdout ---
Checking package-lock.json

--- end ---
$ package-lock-lint package-lock.json
--- stdout ---
Checking package-lock.json

--- end ---
$ ./node_modules/.bin/eslint . --fix
--- stdout ---

/src/repo/config.example.wikimedia.yaml
  116:1  warning  This line has a length of 112. Maximum allowed is 100  max-len
  157:1  warning  This line has a length of 122. Maximum allowed is 100  max-len
  200:1  warning  This line has a length of 106. Maximum allowed is 100  max-len
  208:1  warning  This line has a length of 126. Maximum allowed is 100  max-len
  230:1  warning  This line has a length of 106. Maximum allowed is 100  max-len
  238:1  warning  This line has a length of 126. Maximum allowed is 100  max-len
  264:1  warning  This line has a length of 106. Maximum allowed is 100  max-len
  272:1  warning  This line has a length of 126. Maximum allowed is 100  max-len
  285:1  warning  This line has a length of 117. Maximum allowed is 100  max-len
  319:1  warning  This line has a length of 107. Maximum allowed is 100  max-len
  350:1  warning  This line has a length of 112. Maximum allowed is 100  max-len
  366:1  warning  This line has a length of 113. Maximum allowed is 100  max-len
  367:1  warning  This line has a length of 125. Maximum allowed is 100  max-len
  368:1  warning  This line has a length of 121. Maximum allowed is 100  max-len
  369:1  warning  This line has a length of 102. Maximum allowed is 100  max-len
  406:1  warning  This line has a length of 101. Maximum allowed is 100  max-len
  407:1  warning  This line has a length of 125. Maximum allowed is 100  max-len
  408:1  warning  This line has a length of 120. Maximum allowed is 100  max-len
  505:1  warning  This line has a length of 107. Maximum allowed is 100  max-len
  565:1  warning  This line has a length of 102. Maximum allowed is 100  max-len
  620:1  warning  This line has a length of 109. Maximum allowed is 100  max-len

/src/repo/sys/deduplicator.js
  9:28  error  ES2023 'Array.prototype.with' method is forbidden  es-x/no-array-prototype-with

/src/repo/sys/rate_limiter.js
  9:27  error  ES2023 'Array.prototype.with' method is forbidden  es-x/no-array-prototype-with

✖ 23 problems (2 errors, 21 warnings)


--- end ---
$ ./node_modules/.bin/eslint . -f json
--- stdout ---
[{"filePath":"/src/repo/.eslintrc.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/.mocharc.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/.travis.yml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/app.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/config.example.wikimedia.yaml","messages":[{"ruleId":"max-len","severity":1,"message":"This line has a length of 112. Maximum allowed is 100.","line":116,"column":1,"nodeType":"Program","messageId":"max","endLine":116,"endColumn":113},{"ruleId":"max-len","severity":1,"message":"This line has a length of 122. Maximum allowed is 100.","line":157,"column":1,"nodeType":"Program","messageId":"max","endLine":157,"endColumn":123},{"ruleId":"max-len","severity":1,"message":"This line has a length of 106. Maximum allowed is 100.","line":200,"column":1,"nodeType":"Program","messageId":"max","endLine":200,"endColumn":107},{"ruleId":"max-len","severity":1,"message":"This line has a length of 126. Maximum allowed is 100.","line":208,"column":1,"nodeType":"Program","messageId":"max","endLine":208,"endColumn":127},{"ruleId":"max-len","severity":1,"message":"This line has a length of 106. Maximum allowed is 100.","line":230,"column":1,"nodeType":"Program","messageId":"max","endLine":230,"endColumn":107},{"ruleId":"max-len","severity":1,"message":"This line has a length of 126. Maximum allowed is 100.","line":238,"column":1,"nodeType":"Program","messageId":"max","endLine":238,"endColumn":127},{"ruleId":"max-len","severity":1,"message":"This line has a length of 106. Maximum allowed is 100.","line":264,"column":1,"nodeType":"Program","messageId":"max","endLine":264,"endColumn":107},{"ruleId":"max-len","severity":1,"message":"This line has a length of 126. Maximum allowed is 100.","line":272,"column":1,"nodeType":"Program","messageId":"max","endLine":272,"endColumn":127},{"ruleId":"max-len","severity":1,"message":"This line has a length of 117. Maximum allowed is 100.","line":285,"column":1,"nodeType":"Program","messageId":"max","endLine":285,"endColumn":118},{"ruleId":"max-len","severity":1,"message":"This line has a length of 107. Maximum allowed is 100.","line":319,"column":1,"nodeType":"Program","messageId":"max","endLine":319,"endColumn":108},{"ruleId":"max-len","severity":1,"message":"This line has a length of 112. Maximum allowed is 100.","line":350,"column":1,"nodeType":"Program","messageId":"max","endLine":350,"endColumn":113},{"ruleId":"max-len","severity":1,"message":"This line has a length of 113. Maximum allowed is 100.","line":366,"column":1,"nodeType":"Program","messageId":"max","endLine":366,"endColumn":114},{"ruleId":"max-len","severity":1,"message":"This line has a length of 125. Maximum allowed is 100.","line":367,"column":1,"nodeType":"Program","messageId":"max","endLine":367,"endColumn":126},{"ruleId":"max-len","severity":1,"message":"This line has a length of 121. Maximum allowed is 100.","line":368,"column":1,"nodeType":"Program","messageId":"max","endLine":368,"endColumn":122},{"ruleId":"max-len","severity":1,"message":"This line has a length of 102. Maximum allowed is 100.","line":369,"column":1,"nodeType":"Program","messageId":"max","endLine":369,"endColumn":103},{"ruleId":"max-len","severity":1,"message":"This line has a length of 101. Maximum allowed is 100.","line":406,"column":1,"nodeType":"Program","messageId":"max","endLine":406,"endColumn":102},{"ruleId":"max-len","severity":1,"message":"This line has a length of 125. Maximum allowed is 100.","line":407,"column":1,"nodeType":"Program","messageId":"max","endLine":407,"endColumn":126},{"ruleId":"max-len","severity":1,"message":"This line has a length of 120. Maximum allowed is 100.","line":408,"column":1,"nodeType":"Program","messageId":"max","endLine":408,"endColumn":121},{"ruleId":"max-len","severity":1,"message":"This line has a length of 107. Maximum allowed is 100.","line":505,"column":1,"nodeType":"Program","messageId":"max","endLine":505,"endColumn":108},{"ruleId":"max-len","severity":1,"message":"This line has a length of 102. Maximum allowed is 100.","line":565,"column":1,"nodeType":"Program","messageId":"max","endLine":565,"endColumn":103},{"ruleId":"max-len","severity":1,"message":"This line has a length of 109. Maximum allowed is 100.","line":620,"column":1,"nodeType":"Program","messageId":"max","endLine":620,"endColumn":110}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":21,"fixableErrorCount":0,"fixableWarningCount":0,"source":"spec: &spec\n  x-sub-request-filters:\n    - type: default\n      name: http\n      options:\n        allow:\n          - pattern: /^https?:\\/\\//\n            forward_headers:\n              user-agent: true\n  title: The Change Propagation root\n  paths:\n    /sys/ores:\n      x-modules:\n        - path: sys/ores_updates.js\n          options:\n            ores_precache_uris:\n              - \"https://ores.wikimedia.org/v3/precache\"\n            event_service_uri: \"https://eventgate.stubfortests.org/v1/events\"\n    /sys/limit:\n      x-modules:\n        - path: sys/rate_limiter.js\n          options:\n            redis: &redis_config\n              host: localhost\n              port: 6379\n\n            limiters:\n              blacklist:\n                # First, allow no more then 100 errors per week\n                # The precision parameter controls the step a sliding window moves by\n                - interval: 604800\n                  limit: 100\n                  precision: 86400\n                # Secondly to avoid bursts in case of outages, don't allow more then 10\n                # errors per hour\n                - interval: 3600\n                  limit: 10\n    /sys/dedupe:\n      x-modules:\n        - path: sys/deduplicator.js\n          options:\n            redis: *redis_config\n    /sys/purge:\n      x-modules:\n        - path: sys/purge.js\n          options:\n            host: 127.0.0.1\n            port: 4321\n    /sys/links:\n      x-modules:\n        - path: sys/dep_updates.js\n          options:\n            templates:\n              mw_api:\n                uri: \"https://{{message.meta.domain}}/w/api.php\"\n                headers:\n                  host: \"{{message.meta.domain}}\"\n                body:\n                  formatversion: 2\n    /sys/queue:\n      x-modules:\n        - path: sys/kafka.js\n          options:\n            metadata_broker_list: 127.0.0.1:9092\n            dc_name: test_dc\n            startup_delay: 0\n            consumer:\n              # These options should not be copied to puppet config.\n              # We're using this config for testing, so need to configure\n              # for minimal latency\n              fetch.wait.max.ms: \"1\"\n              fetch.min.bytes: \"1\"\n              queue.buffering.max.ms: \"1\"\n            producer:\n              queue.buffering.max.messages: \"10\"\n              compression.codec: snappy\n            concurrency: 250\n            # Redis-mock does not support evalsha that rate limiting depend on.\n            disable_ratelimit: \"{env(MOCK_SERVICES)}\"\n            blacklist:\n              en.wikipedia.org:\n                - \"User:Nolelover\"\n                - '/User:Cyberbot_I\\//'\n            templates:\n\n              summary_definition_rerender: &summary_definition_rerender_spec\n                topic: resource_change\n                retry_limit: 2\n                retry_delay: 500\n                retry_on:\n                  status:\n                    - 5xx\n                limiters:\n                  blacklist: \"summary:{message.meta.uri}\"\n                cases: # Non wiktionary domains - rerender summary\n                  - match:\n                      meta:\n                        uri: '/^(?<proto>https?):\\/\\/[^\\/]+\\/api\\/rest_v1\\/page\\/html\\/(?<title>[^/]+)$/'\n                      tags:\n                        - restbase\n                    match_not:\n                      - meta:\n                          domain: /wiktionary.org$/\n                      - meta:\n                          domain: /\\.wikidata\\.org$/\n                    exec:\n                      method: get\n                      # Don't encode title since it should be already encoded\n                      uri: \"{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}\"\n                      query:\n                        redirect: false\n                      headers:\n                        cache-control: no-cache\n                  - match: # Wiktionary domains - rerender definitions\n                      meta:\n                        # These URIs are coming from RESTBase, so we know that article titles will be normalized\n                        # and main namespace articles will not have : (uri-encoded, so %3a or %3A)\n                        uri: '/^(?<proto>https?):\\/\\/[^\\/]+\\/api\\/rest_v1\\/page\\/html\\/(?<title>(?:(?!%3a|%3A|\\/).)+)$/'\n                        domain: '/^en\\.wiktionary\\.org$/'\n                      tags:\n                        - restbase\n                    exec:\n                      method: get\n                      # Don't encode title since it should be already encoded\n                      uri: \"{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/definition/{{match.meta.uri.title}}\"\n                      query:\n                        redirect: false\n                      headers:\n                        cache-control: no-cache\n\n              summary_definition_rerender_transcludes: &summary_definition_rerender_transcludes_spec\n                <<: *summary_definition_rerender_spec\n                topic: change-prop.transcludes.resource-change\n\n              mobile_rerender: &mobile_rerender_spec\n                topic: resource_change\n                retry_limit: 2\n                retry_delay: 500\n                retry_on:\n                  status:\n                    - 5xx\n                limiters:\n                  blacklist: \"mobile:{message.meta.uri}\"\n                match:\n                  meta:\n                    uri: '/^(?<proto>https?):\\/\\/[^\\/]+\\/api\\/rest_v1\\/page\\/html\\/(?<title>[^/]+)$/'\n                    domain: '/^.+\\.wikipedia\\.org$/'\n                  tags:\n                    - restbase\n                exec:\n                  - method: get\n                    uri: \"{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{{match.meta.uri.title}}\"\n                    query:\n                      redirect: false\n                    headers:\n                      cache-control: no-cache\n                    # Until we start storing and actively rerendering PCS endpoints we still need to purge it from Varnish\n                  - method: post\n                    uri: /sys/purge/\n                    body:\n                      - meta:\n                          uri: \"//{{message.meta.domain}}/api/rest_v1/page/media-list/{{match.meta.uri.title}}\"\n\n              mobile_rerender_transcludes: &mobile_rerender_transcludes_spec\n                <<: *mobile_rerender_spec\n                topic: change-prop.transcludes.resource-change\n\n              purge_varnish: &purge_varnish_spec\n                topic: resource_change\n                match:\n                  meta:\n                    uri: '/^https?:\\/\\/[^\\/]+\\/api\\/rest_v1\\/(?<title>.+)$/'\n                  tags:\n                    - restbase\n                exec:\n                  method: post\n                  uri: /sys/purge/\n                  body:\n                    - meta:\n                        uri: \"//{{message.meta.domain}}/api/rest_v1/{{match.meta.uri.title}}\"\n\n              purge_varnish_transcludes: &purge_varnish_transcludes_spec\n                <<: *purge_varnish_spec\n                topic: change-prop.transcludes.resource-change\n\n              # RESTBase update jobs\n              mw_purge:\n                topic: resource_change\n                limiters:\n                  blacklist: \"html:{message.meta.uri}\"\n                cases:\n                  - match:\n                      meta:\n                        uri: '/^(?<proto>https?):\\/\\/[^\\/]+\\/wiki\\/(?<title>.+)$/'\n                        domain: '/.*\\.wikipedia.org$/'\n                      tags:\n                        - purge\n                    exec: &mw_purge_wikipedia_rerender\n                      - method: get\n                        # This even comes directly from MediaWiki, so title is encoded in MW-specific way.\n                        # Re-encode the title in standard `encodeURIComponent` encoding.\n                        uri: \"{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}\"\n                        headers:\n                          cache-control: no-cache\n                          if-unmodified-since: \"{{date(message.meta.dt)}}\"\n                        query:\n                          redirect: false\n                        # The HTML might not change but sometimes editors use a purge to drop incorrectly rendered summary/MCS\n                        # content, so let's purge them as well just in case. The rate is low.\n                      - method: get\n                        uri: \"https://{{message.meta.domain}}/api/rest_v1/page/summary/{decode(match.meta.uri.title)}\"\n                        headers:\n                          cache-control: no-cache\n                        query:\n                          redirect: false\n                      - method: get\n                        uri: \"https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{decode(match.meta.uri.title)}\"\n                        headers:\n                          cache-control: no-cache\n                        query:\n                          redirect: false\n                  - match:\n                      meta:\n                        uri: '/^(?<proto>https?):\\/\\/[^\\/]+\\/wiki\\/(?<title>.+)$/'\n                        domain: '/.*\\.wiktionary.org$/'\n                      tags:\n                        - purge\n                    exec: &mw_purge_wiktionary_rerender\n                      - method: get\n                        # This even comes directly from MediaWiki, so title is encoded in MW-specific way.\n                        # Re-encode the title in standard `encodeURIComponent` encoding.\n                        uri: \"{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}\"\n                        headers:\n                          cache-control: no-cache\n                          if-unmodified-since: \"{{date(message.meta.dt)}}\"\n                        query:\n                          redirect: false\n                        # The HTML might not change but sometimes editors use a purge to drop incorrectly rendered summary/MCS\n                        # content, so let's purge them as well just in case. The rate is low.\n                      - method: get\n                        uri: \"https://{{message.meta.domain}}/api/rest_v1/page/definition/{decode(match.meta.uri.title)}\"\n                        headers:\n                          cache-control: no-cache\n                        query:\n                          redirect: false\n                  - match:\n                      meta:\n                        uri: '/^(?<proto>https?):\\/\\/[^\\/]+\\/wiki\\/(?<title>.+)$/'\n                      tags:\n                        - purge\n                    match_not: &others_match_not\n                      - meta:\n                          domain: '/.*\\.wikipedia\\.org$/'\n                      - meta:\n                          domain: '/.*\\.wiktionary\\.org$/'\n                      - meta:\n                          domain: /\\.wikidata\\.org$/\n                        page_namespace: 0\n                      - meta:\n                          domain: /\\.wikidata\\.org$/\n                        page_namespace: 120\n                    exec: &mw_purge_others_rerender\n                      - method: get\n                        # This even comes directly from MediaWiki, so title is encoded in MW-specific way.\n                        # Re-encode the title in standard `encodeURIComponent` encoding.\n                        uri: \"{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}\"\n                        headers:\n                          cache-control: no-cache\n                          if-unmodified-since: \"{{date(message.meta.dt)}}\"\n                        query:\n                          redirect: false\n                        # The HTML might not change but sometimes editors use a purge to drop incorrectly rendered summary/MCS\n                        # content, so let's purge them as well just in case. The rate is low.\n                      - method: get\n                        uri: \"https://{{message.meta.domain}}/api/rest_v1/page/summary/{decode(match.meta.uri.title)}\"\n                        headers:\n                          cache-control: no-cache\n                        query:\n                          redirect: false\n\n              null_edit:\n                topic: resource_change\n                ignore:\n                  status:\n                    - 403 # Ignoring 403 since some of the pages with high number of null_edit events are blacklisted\n                    - 412\n                limiters:\n                  blacklist: \"html:{message.meta.uri}\"\n                cases:\n                  - match:\n                      meta:\n                        uri: '/^(?<proto>https?):\\/\\/[^\\/]+\\/wiki\\/(?<title>.+)$/'\n                        domain: '/.*\\.wikipedia.org$/'\n                      tags:\n                        - null_edit\n                    exec: *mw_purge_wikipedia_rerender\n                  - match:\n                      meta:\n                        uri: '/^(?<proto>https?):\\/\\/[^\\/]+\\/wiki\\/(?<title>.+)$/'\n                        domain: '/.*\\.wiktionary.org$/'\n                      tags:\n                        - purge\n                    exec: *mw_purge_wiktionary_rerender\n                  - match:\n                      meta:\n                        uri: '/^(?<proto>https?):\\/\\/[^\\/]+\\/wiki\\/(?<title>.+)$/'\n                      tags:\n                        - purge\n                    match_not: *others_match_not\n                    exec: *mw_purge_others_rerender\n\n              page_edit:\n                topic: mediawiki.revision-create\n                limiters:\n                  blacklist: \"html:{message.meta.uri}\"\n                retry_on:\n                  status:\n                    - 5xx\n                    - 404 # Sometimes occasional 404s happen because of the mysql replication lag, so retry\n                match:\n                  rev_content_changed: true\n                match_not:\n                  # Test-only. We use undefined rev_parent_id to test backlinks so we\n                  # don't want transclusions to interfere with backlinks test\n                  - rev_parent_id: undefined\n                  # end of test-only config\n                  - meta:\n                      domain: /\\.wikidata\\.org$/\n                    page_namespace: 0\n                  - meta:\n                      domain: /\\.wikidata\\.org$/\n                    page_namespace: 120\n                exec:\n                  - method: get\n                    uri: \"https://{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}\"\n                    headers:\n                      cache-control: no-cache\n                      x-restbase-parentrevision: \"{{message.rev_parent_id}}\"\n                      if-unmodified-since: \"{{date(message.meta.dt)}}\"\n                    query:\n                      redirect: false\n                  - method: post\n                    uri: \"/sys/links/transcludes/{message.page_title}\"\n                    body: \"{{globals.message}}\"\n\n              revision_visibility_change:\n                topic: mediawiki.revision-visibility-change\n                ignore:\n                  status:\n                    - 403 # When the revision is hidden 403 will be returned by RESTBase, it's a valid situation\n                    - 412\n                match_not:\n                  - meta:\n                      domain: /\\.wikidata\\.org$/\n                    page_namespace: 0\n                  - meta:\n                      domain: /\\.wikidata\\.org$/\n                    page_namespace: 120\n                exec:\n                  - method: get\n                    uri: \"https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}/{{message.rev_id}}\"\n                    headers:\n                      cache-control: no-cache\n                    query:\n                      redirect: false\n                  # For page revision restriction RESTBase doesn't emit resource_change events, and to go through\n                  # the normal purge chain (html update -> html resource_change -> summary update -> summary resource_change)\n                  # we need to add many workarounds/shortcurst in RESTBase. So having this list here is an OK compromise.\n                  # Only purge the URIs with a rev_id since the latest revision can not be restricted.\n                  - method: post\n                    uri: /sys/purge/\n                    body:\n                      - meta:\n                          uri: \"//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}\"\n                      - meta:\n                          uri: \"//{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}/{{message.rev_id}}\"\n                      - meta:\n                          uri: \"//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-lead/{message.page_title}/{{message.rev_id}}\"\n                      - meta:\n                          uri: \"//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-remaining/{message.page_title}/{{message.rev_id}}\"\n\n              page_delete:\n                topic: mediawiki.page-delete\n                ignore:\n                  status:\n                    - 404 # 404 is a normal response for page deletion\n                    - 412\n                match_not:\n                  - meta:\n                      domain: /\\.wikidata\\.org$/\n                    page_namespace: 0\n                  - meta:\n                      domain: /\\.wikidata\\.org$/\n                    page_namespace: 120\n                exec:\n                  - method: get\n                    uri: \"https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}\"\n                    headers:\n                      cache-control: no-cache\n                    query:\n                      redirect: false\n                  # The links to the deleted page should become red again\n                  - method: post\n                    uri: \"/sys/links/backlinks/{message.page_title}\"\n                    body: \"{{globals.message}}\"\n                  # For page deletion RESTBase doesn't emit resource_change events, and to go through\n                  # the normal purge chain (html update -> html resource_change -> summary update -> summary resource_change)\n                  # we need to add many workarounds/shortcuts in RESTBase. So having this list here is an OK compromise.\n                  - method: post\n                    uri: /sys/purge/\n                    body:\n                      - meta:\n                          uri: \"//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}\"\n                      - meta:\n                          uri: \"//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}\"\n                      - meta:\n                          uri: \"//{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}\"\n                      - meta:\n                          uri: \"//{{message.meta.domain}}/api/rest_v1/page/definition/{message.page_title}\"\n                      - meta:\n                          uri: \"//{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}\"\n                      - meta:\n                          uri: \"//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-lead/{message.page_title}\"\n                      - meta:\n                          uri: \"//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-remaining/{message.page_title}\"\n                      - meta:\n                          uri: \"//{{message.meta.domain}}/api/rest_v1/page/media-list/{message.page_title}\"\n\n              page_restore:\n                topic: mediawiki.page-undelete\n                match_not:\n                  - meta:\n                      domain: /\\.wikidata\\.org$/\n                    page_namespace: 0\n                  - meta:\n                      domain: /\\.wikidata\\.org$/\n                    page_namespace: 120\n                exec:\n                  - method: get\n                    uri: \"https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}\"\n                    headers:\n                      cache-control: no-cache\n                    query:\n                      redirect: false\n                  # The links to the deleted page should become red again\n                  - method: post\n                    uri: \"/sys/links/backlinks/{message.page_title}\"\n                    body: \"{{globals.message}}\"\n\n              page_move:\n                topic: mediawiki.page-move\n                match_not:\n                  - meta:\n                      domain: /\\.wikidata\\.org$/\n                    page_namespace: 0\n                  - meta:\n                      domain: /\\.wikidata\\.org$/\n                    page_namespace: 120\n                exec:\n                  - method: get\n                    uri: \"https://{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}\"\n                    headers:\n                      cache-control: no-cache\n                      if-unmodified-since: \"{{date(message.meta.dt)}}\"\n                    query:\n                      redirect: false\n                  - method: get\n                    uri: \"https://{{message.meta.domain}}/api/rest_v1/page/title/{message.prior_state.page_title}\"\n                    headers:\n                      cache-control: no-cache\n                    query:\n                      redirect: false\n\n              on_transclusion_update:\n                topic: change-prop.transcludes.resource-change\n                limiters:\n                  blacklist: \"html:{message.meta.uri}\"\n                cases:\n                  - match:\n                      $schema: '/^\\/resource_change\\/.*/'\n                      meta:\n                        uri: '/https?:\\/\\/[^\\/]+\\/wiki\\/(?<title>.+)/'\n                      tags: [ transcludes ]\n                    exec:\n                      method: get\n                      uri: \"https://{{message.meta.domain}}/api/rest_v1/page/html/{{match.meta.uri.title}}\"\n                      headers:\n                        cache-control: no-cache\n                        if-unmodified-since: \"{{date(message.root_event.dt)}}\"\n                        x-restbase-mode: \"{{message.tags[1]}}\"\n                      query:\n                        redirect: false\n                  - match:\n                      $schema: '/^\\/change-prop\\/continue\\/.*/'\n                    exec:\n                      method: post\n                      uri: \"/sys/links/transcludes/{message.original_event.page_title}\"\n                      body: \"{{globals.message}}\"\n\n              page_create:\n                topic: mediawiki.page-create\n                retry_on:\n                  status:\n                    - 5xx\n                    - 404 # Sometimes occasional 404s happen because of the mysql replication lag, so retry\n                match_not:\n                  - meta:\n                      domain: /\\.wikidata\\.org$/\n                    page_namespace: 0\n                  - meta:\n                      domain: /\\.wikidata\\.org$/\n                    page_namespace: 120\n                exec:\n                  - method: post\n                    uri: \"/sys/links/backlinks/{message.page_title}\"\n                    body: \"{{globals.message}}\"\n\n              on_backlinks_update:\n                topic: change-prop.backlinks.resource-change\n                limiters:\n                  blacklist: \"html:{message.meta.uri}\"\n                cases:\n                  - match:\n                      $schema: '/^\\/resource_change\\/.*/'\n                      meta:\n                        uri: '/https?:\\/\\/[^\\/]+\\/wiki\\/(?<title>.+)/'\n                      tags: [ backlinks ]\n                    exec:\n                      method: get\n                      uri: \"https://{{message.meta.domain}}/api/rest_v1/page/html/{{match.meta.uri.title}}\"\n                      headers:\n                        cache-control: no-cache\n                        if-unmodified-since: \"{{date(message.root_event.dt)}}\"\n                        x-restbase-mode: \"{{message.tags[1]}}\"\n                      query:\n                        redirect: false\n                  - match:\n                      $schema: '/^\\/change-prop\\/continue\\/.*/'\n                    exec:\n                      method: post\n                      uri: \"/sys/links/backlinks/{message.original_event.page_title}\"\n                      body: \"{{globals.message}}\"\n\n              # ORES caching updates\n              ores_cache:\n                topic: mediawiki.revision-create\n                concurrency: 10\n                ignore:\n                  status:\n                    - 503\n                exec:\n                  method: post\n                  uri: /sys/ores/\n                  query:\n                    postevent: true\n                  body: \"{{globals.message}}\"\n\n              wikidata_description_on_edit:\n                topic: mediawiki.revision-create\n                match:\n                  meta:\n                    domain: www.wikidata.org\n                  page_namespace: 0\n                  # It's impossible to modify a comment in wikidata while editing the entity.\n                  # TODO: This is a temp solution until we get a more general fragment support T148079\n                  comment: \"/wbeditentity|wbsetdescription|undo|restore/\"\n                  rev_content_changed: true\n                exec:\n                  method: post\n                  uri: /sys/links/wikidata_descriptions\n                  body: \"{{globals.message}}\"\n\n              wikidata_description_on_undelete:\n                topic: mediawiki.page-undelete\n                match:\n                  meta:\n                    domain: www.wikidata.org\n                  page_namespace: 0\n                exec:\n                  method: post\n                  uri: /sys/links/wikidata_descriptions\n                  body: \"{{globals.message}}\"\n\n              on_wikidata_description_change:\n                topic: change-prop.wikidata.resource-change\n                cases:\n                  - match:\n                      meta:\n                        uri: '/https:\\/\\/[^\\/]+\\/wiki\\/(?<title>.+)/'\n                        domain: '/.*\\.wikipedia.org$/'\n                      tags: [ wikidata ]\n                    exec:\n                      - method: get\n                        uri: \"https://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}\"\n                        headers:\n                          cache-control: no-cache\n                        query:\n                          redirect: false\n                      - method: get\n                        uri: \"https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{{match.meta.uri.title}}\"\n                        headers:\n                          cache-control: no-cache\n                        query:\n                          redirect: false\n                  - match:\n                      meta:\n                        uri: '/https:\\/\\/[^\\/]+\\/wiki\\/(?<title>.+)/'\n                      tags: [ wikidata ]\n                    match_not: *others_match_not\n                    exec:\n                      - method: get\n                        uri: \"https://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}\"\n                        headers:\n                          cache-control: no-cache\n                        query:\n                          redirect: false\n\n              page_images:\n                topic: mediawiki.page-properties-change\n                # We don't support 'OR' in the match section, so workaround it by 2 cases with identical exec\n                cases:\n                  - match:\n                      meta:\n                        domain: '/.*\\.wikipedia.org$/'\n                      added_properties:\n                        page_image: \"/.+/\"\n                    exec: &page_images_wikipedia_rerender\n                      - method: get\n                        uri: \"https://{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}\"\n                        headers:\n                          cache-control: no-cache\n                        query:\n                          redirect: false\n                      - method: get\n                        uri: \"https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}\"\n                        headers:\n                          cache-control: no-cache\n                        query:\n                          redirect: false\n                  - match:\n                      added_properties:\n                        page_image: \"/.+/\"\n                    match_not: *others_match_not\n                    exec: &page_images_others_rerender\n                      - method: get\n                        uri: \"https://{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}\"\n                        headers:\n                          cache-control: no-cache\n                        query:\n                          redirect: false\n                  - match:\n                      meta:\n                        domain: '/.*\\.wikipedia.org$/'\n                      removed_properties:\n                        page_image: \"/.+/\"\n                    exec: *page_images_wikipedia_rerender\n                  - match:\n                      removed_properties:\n                        page_image: \"/.+/\"\n                    match_not: *others_match_not\n                    exec: *page_images_others_rerender\n\n              # Map tile cache invalidation\n              purge_map_tile:\n                topic: resource_change\n                match:\n                  tags:\n                    - tilerator\n                exec:\n                  method: post\n                  uri: /sys/purge/\n                  body:\n                    - meta:\n                        uri: \"{{message.meta.uri}}\"\n\nnum_workers: 0\nlogging:\n  name: changeprop\n  level: fatal\n  streams:\n    - type: stdout\nservices:\n  - name: changeprop\n    module: hyperswitch\n    conf:\n      port: 7272\n      user_agent: SampleChangePropInstance\n      spec: *spec\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/config.example.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/config.jobqueue.wikimedia.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/config.test.yaml","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/base_executor.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/kafka_factory.js","messages":[],"suppressedMessages":[{"ruleId":"security/detect-non-literal-regexp","severity":1,"message":"Found non-literal argument to RegExp Constructor","line":148,"column":31,"nodeType":"NewExpression","endLine":148,"endColumn":69,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/mixins.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/retry_executor.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/rule.js","messages":[],"suppressedMessages":[{"ruleId":"no-new-func","severity":2,"message":"The Function constructor is eval.","line":79,"column":12,"nodeType":"NewExpression","messageId":"noFunctionConstructor","endLine":79,"endColumn":50,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"security/detect-non-literal-regexp","severity":1,"message":"Found non-literal argument to RegExp Constructor","line":99,"column":24,"nodeType":"NewExpression","endLine":99,"endColumn":66,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-new-func","severity":2,"message":"The Function constructor is eval.","line":347,"column":23,"nodeType":"NewExpression","messageId":"noFunctionConstructor","endLine":347,"endColumn":66,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-new-func","severity":2,"message":"The Function constructor is eval.","line":349,"column":25,"nodeType":"NewExpression","messageId":"noFunctionConstructor","endLine":349,"endColumn":85,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/rule_executor.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/rule_subscriber.js","messages":[],"suppressedMessages":[{"ruleId":"security/detect-non-literal-regexp","severity":1,"message":"Found non-literal argument to RegExp Constructor","line":61,"column":24,"nodeType":"NewExpression","endLine":61,"endColumn":68,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/sampler.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/lib/utils.js","messages":[],"suppressedMessages":[{"ruleId":"security/detect-non-literal-regexp","severity":1,"message":"Found non-literal argument to RegExp Constructor","line":61,"column":12,"nodeType":"NewExpression","endLine":61,"endColumn":29,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/package-lock.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/package.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/server.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/sys/deduplicator.js","messages":[{"ruleId":"es-x/no-array-prototype-with","severity":2,"message":"ES2023 'Array.prototype.with' method is forbidden.","line":9,"column":28,"nodeType":"MemberExpression","messageId":"forbidden","endLine":9,"endColumn":51}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use strict';\n\nconst mixins = require('../lib/mixins');\nconst utils = require('../lib/utils');\n\nconst DUPLICATE = { status: 200, body: true };\nconst NOT_DUPLICATE = { status: 200, body: false };\n\nclass Deduplicator extends mixins.mix(Object).with(mixins.Redis) {\n    constructor(options) {\n        super(options);\n\n        this._options = options || {};\n        this._expire_timeout = options.window || 86400;\n        this._prefix = this._options.redis_prefix || 'CP';\n    }\n\n    /**\n     * Checks whether the message is a duplicate\n     *\n     * @param {HyperSwitch} hyper\n     * @param {Object} req\n     * @return {Promise} response status shows whether it's a duplicate or not.\n     */\n    checkDuplicate(hyper, req) {\n        const name = req.params.name;\n        const message = req.body;\n        const prefix = `${ this._prefix }_dedupe_${ name }`;\n\n        // First, look at the individual event duplication based on ID\n        // This happens when we restart ChangeProp and reread some of the\n        // exact same events which were executed but was not committed.\n        const messageKeyWithId = `${ prefix }_${ message.meta.domain }_${ message.meta.id }`;\n        return this._redis.setnxAsync(messageKeyWithId, '1')\n        // Expire the key or renew the expiration timestamp if the key existed\n        .tap(() => this._redis.expireAsync(messageKeyWithId, Math.ceil(this._expire_timeout / 24)))\n        // If that key already existed - that means it's a duplicate\n        .then((setResult) => {\n            if (setResult) {\n                return NOT_DUPLICATE;\n            }\n            hyper.metrics.increment(`${ name }_dedupe`);\n            hyper.logger.log('trace/dedupe', () => ({\n                message: 'Event was deduplicated based on id',\n                event_str: utils.stringify(message)\n            }));\n            return DUPLICATE;\n        })\n        .then((individualDuplicate) => {\n            if (individualDuplicate.body || !message.sha1) {\n                // If the message was deduped based on its event ID or if it has no SHA-1 hash,\n                // don't try to deduplicate by SHA-1\n                return individualDuplicate;\n            }\n            const messageKeyWithSha = `${ prefix }_${ message.meta.domain }_${ message.sha1 }`;\n            return this._redis.getAsync(messageKeyWithSha)\n            .then((previousExecutionTime) => {\n                // If the same event (by sha1) was created before the previous execution\n                // time, the changes that caused it were already in the database, so it\n                // will be a no-op and can be deduplicated.\n                if (previousExecutionTime &&\n                        // Give that the resolution of the event dt is 1 second, this could\n                        // be false-positive when the job queue is so quick that it executes\n                        // two jobs with the same SHA1 within a single second. To be on the safe\n                        // side - subtract 1 second from the previous execution time to allow for\n                        // some lag.\n                        new Date(previousExecutionTime) - 1000 > new Date(message.meta.dt)) {\n                    hyper.metrics.increment(`${ name }_dedupe`);\n                    hyper.logger.log('trace/dedupe', () => ({\n                        message: 'Event was deduplicated based on sha1',\n                        event_str: utils.stringify(message),\n                        newer_dt: previousExecutionTime\n                    }));\n                    return DUPLICATE;\n                }\n                // If the root event was created before the previous exec time for the same\n                // leaf event - we can deduplicate cause by the time of the prev execution\n                // the template (root_event source) changes were already in the database.\n                if (previousExecutionTime &&\n                        message.root_event &&\n                        new Date(previousExecutionTime) - 1000 >\n                            new Date(message.root_event.dt)) {\n                    hyper.metrics.increment(`${ name }_dedupe`);\n                    hyper.logger.log('trace/dedupe', () => ({\n                        message: 'Event was deduplicated based on sha1 and root_event dt',\n                        event_str: utils.stringify(message),\n                        newer_dt: previousExecutionTime\n                    }));\n                    return DUPLICATE;\n                }\n                return this._redis.setAsync(messageKeyWithSha, new Date().toISOString())\n                .then(() => this._redis.expireAsync(messageKeyWithSha,\n                    Math.ceil(this._expire_timeout / 24)))\n                .thenReturn(NOT_DUPLICATE);\n            });\n        })\n        .then((sha1Duplicate) => {\n            if (sha1Duplicate.body || !message.root_event) {\n                // If the message was sha1-deduped or if it has no root event info,\n                // don't use deduplication by the root event\n                return sha1Duplicate;\n            }\n\n            const rootEventKey = `${ prefix }_${ message.root_event.signature }`;\n            return this._redis.getAsync(rootEventKey)\n            .then((oldEventTimestamp) => {\n                // If this event was caused by root event and there was a leaf event executed\n                // already that belonged to a later root_event we can cut off this chain.\n                if (oldEventTimestamp &&\n                        new Date(oldEventTimestamp) > new Date(message.root_event.dt)) {\n                    hyper.metrics.increment(`${ name }_dedupe`);\n                    hyper.logger.log('trace/dedupe', () => ({\n                        message: 'Event was deduplicated based on root event',\n                        event_str: utils.stringify(message),\n                        signature: message.root_event.signature,\n                        newer_dt: oldEventTimestamp\n                    }));\n                    return DUPLICATE;\n                }\n                return this._redis.setAsync(rootEventKey, message.root_event.dt)\n                .then(() => this._redis.expireAsync(rootEventKey, this._expire_timeout))\n                .thenReturn(NOT_DUPLICATE);\n            });\n        })\n        .catch((e) => {\n            hyper.logger.log('error/dedupe', {\n                message: 'Error during deduplication',\n                err_str: e.toString()\n            });\n            return NOT_DUPLICATE;\n        });\n    }\n}\n\nmodule.exports = (options) => {\n    const ps = new Deduplicator(options);\n\n    return {\n        spec: {\n            paths: {\n                '/{name}': {\n                    post: {\n                        operationId: 'checkDuplicate'\n                    }\n                }\n            }\n        },\n        operations: {\n            checkDuplicate: ps.checkDuplicate.bind(ps)\n        }\n    };\n};\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/sys/dep_updates.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/sys/kafka.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/sys/ores_updates.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/sys/partitioner.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/sys/purge.js","messages":[],"suppressedMessages":[{"ruleId":"security/detect-unsafe-regex","severity":1,"message":"Unsafe Regular Expression","line":39,"column":52,"nodeType":"Literal","endLine":39,"endColumn":69,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/sys/rate_limiter.js","messages":[{"ruleId":"es-x/no-array-prototype-with","severity":2,"message":"ES2023 'Array.prototype.with' method is forbidden.","line":9,"column":27,"nodeType":"MemberExpression","messageId":"forbidden","endLine":9,"endColumn":50}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use strict';\n\nconst Limiter = require('ratelimit.js').RateLimit;\nconst P = require('bluebird');\nconst HyperSwitch = require('hyperswitch');\nconst HTTPError = HyperSwitch.HTTPError;\nconst mixins = require('../lib/mixins');\n\nclass RateLimiter extends mixins.mix(Object).with(mixins.Redis) {\n    constructor(options) {\n        super(options);\n\n        this._options = options;\n\n        this._LIMITERS = new Map();\n        Object.keys(this._options.limiters).forEach((type) => {\n            let limiterOpts = this._options.limiters[type];\n\n            if (!Array.isArray(limiterOpts)) {\n                limiterOpts = [ limiterOpts ];\n            }\n\n            limiterOpts.forEach((opt) => {\n                if (!opt.interval || !opt.limit) {\n                    throw new Error(`Limiter ${ type } is miconfigured`);\n                }\n            });\n\n            this._LIMITERS.set(type, new Limiter(this._redis, limiterOpts,\n                { prefix: `CPLimiter_${ type }` }));\n        });\n    }\n\n    _execLimiterFun(fun, hyper, type, key) {\n        const limiter = this._LIMITERS.get(type);\n\n        if (!limiter) {\n            hyper.logger.log('warn/ratelimit', {\n                message: 'Unconfigured rate-limiter is used',\n                limiter_type: type\n            });\n            return { status: 204 };\n        }\n\n        const startTime = Date.now();\n\n        return new P((resolve, reject) => {\n            limiter[fun](key, (err, isRateLimited) => {\n                if (err) {\n                    hyper.logger.log('error/ratelimit', err);\n                    hyper.metrics.endTiming(`ratelimit.${ fun }.err`, startTime);\n                    // In case we've got problems with limiting just allow everything\n                    return resolve({ status: 200 });\n                }\n\n                if (isRateLimited) {\n                    hyper.metrics.endTiming(`ratelimit.${ fun }.block`, startTime);\n                    return reject(new HTTPError({\n                        status: 429,\n                        body: {\n                            type: 'rate_limit',\n                            message: `Message rejected by limiter ${ type }`,\n                            key\n                        }\n                    }));\n                }\n\n                hyper.metrics.endTiming(`ratelimit.${ fun }.allow`, startTime);\n                return resolve({ status: 201 });\n            });\n        });\n    }\n\n    increment(hyper, req) {\n        return this._execLimiterFun('incr', hyper, req.params.type, req.params.key);\n    }\n\n    check(hyper, req) {\n        return this._execLimiterFun('check', hyper, req.params.type, req.params.key);\n    }\n}\n\nmodule.exports = (options) => {\n    const ps = new RateLimiter(options);\n\n    return {\n        spec: {\n            paths: {\n                '/{type}/{key}': {\n                    post: {\n                        operationId: 'incrementAndCheck'\n                    },\n                    get: {\n                        operationId: 'check',\n                        // XXX: Ugly hack below so that the automatic monitoring\n                        // script does not complain about it correctly returning 403\n                        'x-monitor': false\n                    }\n                }\n            }\n        },\n        operations: {\n            incrementAndCheck: ps.increment.bind(ps),\n            check: ps.check.bind(ps)\n        }\n    };\n};\n","usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-len","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/.eslintrc.json","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"no-extra-parens","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/feature/job_rules.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/feature/rule.js","messages":[],"suppressedMessages":[{"ruleId":"no-unused-vars","severity":2,"message":"'r' is assigned a value but never used.","line":10,"column":19,"nodeType":"Identifier","messageId":"unusedVar","endLine":10,"endColumn":20,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'r' is assigned a value but never used.","line":118,"column":27,"nodeType":"Identifier","messageId":"unusedVar","endLine":118,"endColumn":28,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-unused-vars","severity":2,"message":"'r' is assigned a value but never used.","line":250,"column":23,"nodeType":"Identifier","messageId":"unusedVar","endLine":250,"endColumn":24,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-useless-escape","severity":2,"message":"Unnecessary escape character: \\w.","line":254,"column":49,"nodeType":"Literal","messageId":"unnecessaryEscape","endLine":254,"endColumn":50,"suggestions":[{"messageId":"removeEscape","fix":{"range":[9246,9247],"text":""},"desc":"Remove the `\\`. This maintains the current functionality."},{"messageId":"escapeBackslash","fix":{"range":[9246,9246],"text":"\\"},"desc":"Replace the `\\` with `\\\\` to include the actual backslash character."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/feature/sampler.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/feature/static_rules.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/feature/update_rules.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/utils/changeProp.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/utils/common.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]},{"filePath":"/src/repo/test/utils/mock_kafka_factory.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[{"ruleId":"space-in-parens","replacedBy":[]},{"ruleId":"arrow-spacing","replacedBy":[]},{"ruleId":"lines-between-class-members","replacedBy":[]},{"ruleId":"no-new-require","replacedBy":[]},{"ruleId":"template-curly-spacing","replacedBy":[]},{"ruleId":"block-spacing","replacedBy":[]},{"ruleId":"brace-style","replacedBy":[]},{"ruleId":"comma-dangle","replacedBy":[]},{"ruleId":"comma-spacing","replacedBy":[]},{"ruleId":"comma-style","replacedBy":[]},{"ruleId":"dot-location","replacedBy":[]},{"ruleId":"eol-last","replacedBy":[]},{"ruleId":"func-call-spacing","replacedBy":[]},{"ruleId":"key-spacing","replacedBy":[]},{"ruleId":"keyword-spacing","replacedBy":[]},{"ruleId":"linebreak-style","replacedBy":[]},{"ruleId":"max-statements-per-line","replacedBy":[]},{"ruleId":"new-parens","replacedBy":[]},{"ruleId":"no-floating-decimal","replacedBy":[]},{"ruleId":"no-multiple-empty-lines","replacedBy":[]},{"ruleId":"no-new-object","replacedBy":["no-object-constructor"]},{"ruleId":"no-tabs","replacedBy":[]},{"ruleId":"no-trailing-spaces","replacedBy":[]},{"ruleId":"no-whitespace-before-property","replacedBy":[]},{"ruleId":"object-curly-spacing","replacedBy":[]},{"ruleId":"operator-linebreak","replacedBy":[]},{"ruleId":"quote-props","replacedBy":[]},{"ruleId":"quotes","replacedBy":[]},{"ruleId":"semi","replacedBy":[]},{"ruleId":"semi-spacing","replacedBy":[]},{"ruleId":"semi-style","replacedBy":[]},{"ruleId":"space-before-blocks","replacedBy":[]},{"ruleId":"space-before-function-paren","replacedBy":[]},{"ruleId":"space-infix-ops","replacedBy":[]},{"ruleId":"space-unary-ops","replacedBy":[]},{"ruleId":"spaced-comment","replacedBy":[]},{"ruleId":"switch-colon-spacing","replacedBy":[]},{"ruleId":"wrap-iife","replacedBy":[]},{"ruleId":"no-extra-semi","replacedBy":[]},{"ruleId":"no-mixed-spaces-and-tabs","replacedBy":[]}]}]

--- end ---
$ /usr/bin/npm ci
--- stderr ---
npm WARN skipping integrity check for git dependency ssh://git@github.com/wikimedia/kad.git 
npm WARN deprecated kad-fs@0.0.4: This package is no longer maintained.
npm WARN deprecated @hapi/bourne@1.3.2: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated kad-memstore@0.0.1: This package is no longer maintained.
npm WARN deprecated debug@4.2.0: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated json-schema-ref-parser@7.1.4: Please switch to @apidevtools/json-schema-ref-parser
--- stdout ---

added 595 packages, and audited 662 packages in 2m

65 packages are looking for funding
  run `npm fund` for details

32 vulnerabilities (1 low, 10 moderate, 16 high, 5 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues possible (including breaking changes), run:
  npm audit fix --force

Some issues need review, and may require choosing
a different dependency.

Run `npm audit` for details.

--- end ---
$ /usr/bin/npm test
--- stdout ---

> change-propagation@0.12.0 test
> export MOCK_SERVICES=true && npm run lint && mocha --recursive


> change-propagation@0.12.0 lint
> eslint --cache --ext .js .


/src/repo/sys/deduplicator.js
  9:28  warning  ES2023 'Array.prototype.with' method is forbidden  es-x/no-array-prototype-with

/src/repo/sys/rate_limiter.js
  9:27  warning  ES2023 'Array.prototype.with' method is forbidden  es-x/no-array-prototype-with

✖ 2 problems (0 errors, 2 warnings)



  JobQueue rules
    ✓ Should propagate updateBetaFeaturesUserCounts job (503ms)
    ✓ Should propagate cdnPurge job (3506ms)
    ✓ Should support partitioned refreshLinks (503ms)
    ✓ Should deduplicate based on ID (2003ms)
    ✓ Should deduplicate based on SHA1 (4002ms)
    ✓ Should deduplicate based on SHA1 and root job combination (4005ms)
    ✓ Should deduplicate base on root job (4004ms)
    ✓ Should support delayed jobs with re-enqueue (13014ms)

  Rule
    ✓ topic required
    ✓ no-op rule
    ✓ simple rule - one request
    ✓ simple rule - multiple requests
    Matching
      ✓ all
      ✓ simple value match
      ✓ simple value mismatch
      ✓ regex match
      ✓ regex match with undefined
      ✓ regex mismatch
      ✓ array match
      ✓ malformed match
      ✓ match_not
      ✓ match_not array
      ✓ matches match and match_not
      ✓ matches match but not match_not
      ✓ matches match_not but not match
      ✓ matches match but is canary event and should_discard_canary_events is true
      ✓ matches match and is canary event and should_discard_canary_events is false
      ✓ expansion
      ✓ expansion with named groups
      ✓ checks for named and unnamed groups mixing

  Sampler
    ✓ Should accept the correct number of values (62ms)

  Basic rule management
    ✓ Should call simple executor (501ms)
    ✓ Should retry simple executor (503ms)
    ✓ Should retry simple executor no more than limit (2002ms)
    ✓ Should emit valid retry message (2681ms)
    ✓ Should not retry if retry_on not matched (2002ms)
    ✓ Should not follow redirects (2002ms)
    ✓ Should not crash with unparsable JSON (502ms)
    ✓ Should support producing to topics on exec (501ms)
    ✓ Should emit valid messages to error topic (147ms)
    ✓ Sampling should only propagate a stable subset (2002ms)
    ✓ Should support array topics (502ms)
    ✓ Should support exclude_topics stanza (2002ms)

  update rules
    ✓ Should update summary endpoint (503ms)
    ✓ Should update summary endpoint, transcludes topic (502ms)
    ✓ Should update summary endpoint on page images change (505ms)
    ✓ Should not update summary for a blacklisted title (2003ms)
    ✓ Should update definition endpoint (502ms)
    ✓ Should not react to revision change event from restbase for definition endpoint (2002ms)
    ✓ Should update mobile apps endpoint (502ms)
    ✓ Should not update definition endpoint for non-main namespace (2002ms)
    ✓ Should update RESTBase on resource_change from MW (501ms)
    ✓ Should update RESTBase on revision create (503ms)
    ✓ Should not update RESTBase on revision create for a blacklisted title (2002ms)
    ✓ Should not update RESTBase on revision create for wikidata (2002ms)
    ✓ Should update RESTBase on page delete (502ms)
    ✓ Should update RESTBase on page undelete (502ms)
    ✓ Should update RESTBase on page move (502ms)
    ✓ Should update RESTBase on revision visibility change (502ms)
    ✓ Should update ORES on revision-create (656ms)
    ✓ Should update ORES on revision-create, error (502ms)
    ✓ Should update RESTBase summary and mobile-sections on wikidata description change (3003ms)
    ✓ Should update RESTBase summary and mobile-sections on wikidata description revert (3002ms)
    ✓ Should update RESTBase summary and mobile-sections on wikidata undelete (3002ms)
    ✓ Should not ask Wikidata for info for non-main namespace titles (5002ms)
    ✓ Should not crash if wikidata description can not be found (3003ms)
    ✓ Should rerender image usages on file update (507ms)
    ✓ Should rerender transclusions on page update (512ms)
    ✓ Should process backlinks, on create (507ms)
    ✓ Should process backlinks, on delete (504ms)
    ✓ Should process backlinks, on undelete (503ms)
    ✓ Should purge caches on resource_change coming from RESTBase (93ms)
    ✓ Should purge caches on resource_change coming from Tilerator (100ms)


  73 passing (1m)


--- end ---
$ /usr/bin/npm audit --json
--- stdout ---
{
  "auditReportVersion": 2,
  "vulnerabilities": {
    "@babel/traverse": {
      "name": "@babel/traverse",
      "severity": "critical",
      "isDirect": false,
      "via": [
        {
          "source": 1096886,
          "name": "@babel/traverse",
          "dependency": "@babel/traverse",
          "title": "Babel vulnerable to arbitrary code execution when compiling specifically crafted malicious code",
          "url": "https://github.com/advisories/GHSA-67hx-6x53-jw92",
          "severity": "critical",
          "cwe": [
            "CWE-184",
            "CWE-697"
          ],
          "cvss": {
            "score": 9.4,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H"
          },
          "range": "<7.23.2"
        }
      ],
      "effects": [],
      "range": "<7.23.2",
      "nodes": [
        "node_modules/@babel/traverse"
      ],
      "fixAvailable": true
    },
    "ansi-regex": {
      "name": "ansi-regex",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1094090,
          "name": "ansi-regex",
          "dependency": "ansi-regex",
          "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex",
          "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw",
          "severity": "high",
          "cwe": [
            "CWE-697",
            "CWE-1333"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": ">=3.0.0 <3.0.1"
        },
        {
          "source": 1094091,
          "name": "ansi-regex",
          "dependency": "ansi-regex",
          "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex",
          "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw",
          "severity": "high",
          "cwe": [
            "CWE-697",
            "CWE-1333"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": ">=4.0.0 <4.1.1"
        },
        {
          "source": 1094092,
          "name": "ansi-regex",
          "dependency": "ansi-regex",
          "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex",
          "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw",
          "severity": "high",
          "cwe": [
            "CWE-697",
            "CWE-1333"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": ">=5.0.0 <5.0.1"
        }
      ],
      "effects": [],
      "range": "3.0.0 || 4.0.0 - 4.1.0 || 5.0.0",
      "nodes": [
        "node_modules/ansi-regex",
        "node_modules/nyc/node_modules/ansi-regex",
        "node_modules/wide-align/node_modules/ansi-regex"
      ],
      "fixAvailable": true
    },
    "busboy": {
      "name": "busboy",
      "severity": "high",
      "isDirect": false,
      "via": [
        "dicer"
      ],
      "effects": [
        "hyperswitch"
      ],
      "range": "<=0.3.1",
      "nodes": [
        "node_modules/busboy"
      ],
      "fixAvailable": {
        "name": "hyperswitch",
        "version": "0.10.5",
        "isSemVerMajor": true
      }
    },
    "coveralls": {
      "name": "coveralls",
      "severity": "moderate",
      "isDirect": true,
      "via": [
        "request"
      ],
      "effects": [],
      "range": "*",
      "nodes": [
        "node_modules/coveralls"
      ],
      "fixAvailable": false
    },
    "debug": {
      "name": "debug",
      "severity": "low",
      "isDirect": false,
      "via": [
        {
          "source": 1096792,
          "name": "debug",
          "dependency": "debug",
          "title": "Regular Expression Denial of Service in debug",
          "url": "https://github.com/advisories/GHSA-gxpj-cx7g-858c",
          "severity": "low",
          "cwe": [
            "CWE-400"
          ],
          "cvss": {
            "score": 3.7,
            "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L"
          },
          "range": ">=4.0.0 <4.3.1"
        }
      ],
      "effects": [
        "mocha"
      ],
      "range": "4.0.0 - 4.3.0",
      "nodes": [
        "node_modules/gc-stats/node_modules/debug",
        "node_modules/mocha/node_modules/debug"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "dicer": {
      "name": "dicer",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1093150,
          "name": "dicer",
          "dependency": "dicer",
          "title": "Crash in HeaderParser in dicer",
          "url": "https://github.com/advisories/GHSA-wm7h-9275-46v2",
          "severity": "high",
          "cwe": [
            "CWE-248"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": "<=0.3.1"
        }
      ],
      "effects": [
        "busboy"
      ],
      "range": "*",
      "nodes": [
        "node_modules/dicer"
      ],
      "fixAvailable": {
        "name": "hyperswitch",
        "version": "0.10.5",
        "isSemVerMajor": true
      }
    },
    "hyperswitch": {
      "name": "hyperswitch",
      "severity": "high",
      "isDirect": true,
      "via": [
        "busboy",
        "preq",
        "swagger-ui-dist"
      ],
      "effects": [],
      "range": ">=0.1.0",
      "nodes": [
        "node_modules/hyperswitch"
      ],
      "fixAvailable": {
        "name": "hyperswitch",
        "version": "0.10.5",
        "isSemVerMajor": true
      }
    },
    "ini": {
      "name": "ini",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1093224,
          "name": "ini",
          "dependency": "ini",
          "title": "ini before 1.3.6 vulnerable to Prototype Pollution via ini.parse",
          "url": "https://github.com/advisories/GHSA-qqgx-2p2h-9c37",
          "severity": "high",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 7.3,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L"
          },
          "range": "<1.3.6"
        }
      ],
      "effects": [],
      "range": "<1.3.6",
      "nodes": [
        "node_modules/gc-stats/node_modules/ini"
      ],
      "fixAvailable": true
    },
    "json-schema": {
      "name": "json-schema",
      "severity": "critical",
      "isDirect": false,
      "via": [
        {
          "source": 1095057,
          "name": "json-schema",
          "dependency": "json-schema",
          "title": "json-schema is vulnerable to Prototype Pollution",
          "url": "https://github.com/advisories/GHSA-896r-f27r-55mw",
          "severity": "critical",
          "cwe": [
            "CWE-915",
            "CWE-1321"
          ],
          "cvss": {
            "score": 9.8,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
          },
          "range": "<0.4.0"
        }
      ],
      "effects": [
        "jsprim"
      ],
      "range": "<0.4.0",
      "nodes": [
        "node_modules/json-schema"
      ],
      "fixAvailable": true
    },
    "json5": {
      "name": "json5",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1096544,
          "name": "json5",
          "dependency": "json5",
          "title": "Prototype Pollution in JSON5 via Parse Method",
          "url": "https://github.com/advisories/GHSA-9c47-m6qq-7p4h",
          "severity": "high",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 7.1,
            "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:L/A:H"
          },
          "range": ">=2.0.0 <2.2.2"
        }
      ],
      "effects": [],
      "range": "2.0.0 - 2.2.1",
      "nodes": [
        "node_modules/json5"
      ],
      "fixAvailable": true
    },
    "jsprim": {
      "name": "jsprim",
      "severity": "critical",
      "isDirect": false,
      "via": [
        "json-schema"
      ],
      "effects": [],
      "range": "0.3.0 - 1.4.1 || 2.0.0 - 2.0.1",
      "nodes": [
        "node_modules/jsprim"
      ],
      "fixAvailable": true
    },
    "kad": {
      "name": "kad",
      "severity": "high",
      "isDirect": false,
      "via": [
        "merge",
        "ms"
      ],
      "effects": [
        "limitation"
      ],
      "range": "*",
      "nodes": [
        "node_modules/kad"
      ],
      "fixAvailable": true
    },
    "limitation": {
      "name": "limitation",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        "kad"
      ],
      "effects": [],
      "range": "<=0.2.2",
      "nodes": [
        "node_modules/limitation"
      ],
      "fixAvailable": true
    },
    "merge": {
      "name": "merge",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1096479,
          "name": "merge",
          "dependency": "merge",
          "title": "Prototype Pollution in merge",
          "url": "https://github.com/advisories/GHSA-7wpw-2hjm-89gp",
          "severity": "high",
          "cwe": [
            "CWE-915"
          ],
          "cvss": {
            "score": 7.3,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L"
          },
          "range": "<2.1.1"
        }
      ],
      "effects": [
        "kad"
      ],
      "range": "<2.1.1",
      "nodes": [
        "node_modules/merge"
      ],
      "fixAvailable": true
    },
    "minimatch": {
      "name": "minimatch",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1096485,
          "name": "minimatch",
          "dependency": "minimatch",
          "title": "minimatch ReDoS vulnerability",
          "url": "https://github.com/advisories/GHSA-f8q6-p94x-37v3",
          "severity": "high",
          "cwe": [
            "CWE-400",
            "CWE-1333"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": "<3.0.5"
        }
      ],
      "effects": [
        "mocha"
      ],
      "range": "<3.0.5",
      "nodes": [
        "node_modules/gc-stats/node_modules/minimatch",
        "node_modules/minimatch"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "minimist": {
      "name": "minimist",
      "severity": "critical",
      "isDirect": false,
      "via": [
        {
          "source": 1096465,
          "name": "minimist",
          "dependency": "minimist",
          "title": "Prototype Pollution in minimist",
          "url": "https://github.com/advisories/GHSA-vh95-rmgr-6w4m",
          "severity": "moderate",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 5.6,
            "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"
          },
          "range": ">=1.0.0 <1.2.3"
        },
        {
          "source": 1096466,
          "name": "minimist",
          "dependency": "minimist",
          "title": "Prototype Pollution in minimist",
          "url": "https://github.com/advisories/GHSA-vh95-rmgr-6w4m",
          "severity": "moderate",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 5.6,
            "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"
          },
          "range": "<0.2.1"
        },
        {
          "source": 1096548,
          "name": "minimist",
          "dependency": "minimist",
          "title": "Prototype Pollution in minimist",
          "url": "https://github.com/advisories/GHSA-xvch-5gv4-984h",
          "severity": "critical",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 9.8,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
          },
          "range": "<0.2.4"
        },
        {
          "source": 1096549,
          "name": "minimist",
          "dependency": "minimist",
          "title": "Prototype Pollution in minimist",
          "url": "https://github.com/advisories/GHSA-xvch-5gv4-984h",
          "severity": "critical",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 9.8,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
          },
          "range": ">=1.0.0 <1.2.6"
        }
      ],
      "effects": [
        "mkdirp"
      ],
      "range": "<=0.2.3 || 1.0.0 - 1.2.5",
      "nodes": [
        "node_modules/gc-stats/node_modules/minimist",
        "node_modules/gc-stats/node_modules/rc/node_modules/minimist",
        "node_modules/minimist"
      ],
      "fixAvailable": true
    },
    "mkdirp": {
      "name": "mkdirp",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        "minimist"
      ],
      "effects": [],
      "range": "0.4.1 - 0.5.1",
      "nodes": [
        "node_modules/gc-stats/node_modules/mkdirp"
      ],
      "fixAvailable": true
    },
    "mocha": {
      "name": "mocha",
      "severity": "high",
      "isDirect": true,
      "via": [
        "debug",
        "minimatch",
        "nanoid"
      ],
      "effects": [],
      "range": "5.1.0 - 9.2.1",
      "nodes": [
        "node_modules/mocha"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "moment": {
      "name": "moment",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1095072,
          "name": "moment",
          "dependency": "moment",
          "title": "Moment.js vulnerable to Inefficient Regular Expression Complexity",
          "url": "https://github.com/advisories/GHSA-wc69-rhjr-hc9g",
          "severity": "high",
          "cwe": [
            "CWE-400",
            "CWE-1333"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": ">=2.18.0 <2.29.4"
        },
        {
          "source": 1095083,
          "name": "moment",
          "dependency": "moment",
          "title": "Path Traversal: 'dir/../../filename' in moment.locale",
          "url": "https://github.com/advisories/GHSA-8hfj-j24r-96c4",
          "severity": "high",
          "cwe": [
            "CWE-22",
            "CWE-27"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N"
          },
          "range": "<2.29.2"
        }
      ],
      "effects": [],
      "range": "<=2.29.3",
      "nodes": [
        "node_modules/moment"
      ],
      "fixAvailable": true
    },
    "ms": {
      "name": "ms",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1094419,
          "name": "ms",
          "dependency": "ms",
          "title": "Vercel ms Inefficient Regular Expression Complexity vulnerability",
          "url": "https://github.com/advisories/GHSA-w9mr-4mfr-499f",
          "severity": "moderate",
          "cwe": [
            "CWE-1333"
          ],
          "cvss": {
            "score": 5.3,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"
          },
          "range": "<2.0.0"
        }
      ],
      "effects": [
        "kad"
      ],
      "range": "<2.0.0",
      "nodes": [
        "node_modules/ms"
      ],
      "fixAvailable": true
    },
    "msgpack5": {
      "name": "msgpack5",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1089202,
          "name": "msgpack5",
          "dependency": "msgpack5",
          "title": "Prototype poisoning",
          "url": "https://github.com/advisories/GHSA-gmjw-49p4-pcfm",
          "severity": "moderate",
          "cwe": [
            "CWE-915",
            "CWE-1321"
          ],
          "cvss": {
            "score": 6.7,
            "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:H/A:H"
          },
          "range": "<3.6.1"
        }
      ],
      "effects": [],
      "range": "<3.6.1",
      "nodes": [
        "node_modules/msgpack5"
      ],
      "fixAvailable": true
    },
    "nanoid": {
      "name": "nanoid",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1089011,
          "name": "nanoid",
          "dependency": "nanoid",
          "title": "Exposure of Sensitive Information to an Unauthorized Actor in nanoid",
          "url": "https://github.com/advisories/GHSA-qrpm-p2h7-hrv2",
          "severity": "moderate",
          "cwe": [
            "CWE-200"
          ],
          "cvss": {
            "score": 5.5,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N"
          },
          "range": ">=3.0.0 <3.1.31"
        }
      ],
      "effects": [
        "mocha"
      ],
      "range": "3.0.0 - 3.1.30",
      "nodes": [
        "node_modules/nanoid"
      ],
      "fixAvailable": {
        "name": "mocha",
        "version": "10.4.0",
        "isSemVerMajor": true
      }
    },
    "preq": {
      "name": "preq",
      "severity": "high",
      "isDirect": true,
      "via": [
        "request",
        "requestretry"
      ],
      "effects": [],
      "range": "*",
      "nodes": [
        "node_modules/preq"
      ],
      "fixAvailable": false
    },
    "qs": {
      "name": "qs",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1096470,
          "name": "qs",
          "dependency": "qs",
          "title": "qs vulnerable to Prototype Pollution",
          "url": "https://github.com/advisories/GHSA-hrpp-h998-j3pp",
          "severity": "high",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": ">=6.5.0 <6.5.3"
        }
      ],
      "effects": [],
      "range": "6.5.0 - 6.5.2",
      "nodes": [
        "node_modules/qs"
      ],
      "fixAvailable": true
    },
    "redis": {
      "name": "redis",
      "severity": "high",
      "isDirect": true,
      "via": [
        {
          "source": 1089196,
          "name": "redis",
          "dependency": "redis",
          "title": "Node-Redis potential exponential regex in monitor mode",
          "url": "https://github.com/advisories/GHSA-35q2-47q7-3pc3",
          "severity": "high",
          "cwe": [
            "CWE-400"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
          },
          "range": ">=2.6.0 <3.1.1"
        }
      ],
      "effects": [],
      "range": "2.6.0 - 3.1.0",
      "nodes": [
        "node_modules/redis"
      ],
      "fixAvailable": true
    },
    "request": {
      "name": "request",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1096727,
          "name": "request",
          "dependency": "request",
          "title": "Server-Side Request Forgery in Request",
          "url": "https://github.com/advisories/GHSA-p8p7-x288-28g6",
          "severity": "moderate",
          "cwe": [
            "CWE-918"
          ],
          "cvss": {
            "score": 6.1,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
          },
          "range": "<=2.88.2"
        },
        "tough-cookie"
      ],
      "effects": [
        "coveralls",
        "preq",
        "requestretry"
      ],
      "range": "*",
      "nodes": [
        "node_modules/request"
      ],
      "fixAvailable": false
    },
    "requestretry": {
      "name": "requestretry",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1090420,
          "name": "requestretry",
          "dependency": "requestretry",
          "title": "Cookie exposure in requestretry",
          "url": "https://github.com/advisories/GHSA-hjp8-2cm3-cc45",
          "severity": "high",
          "cwe": [
            "CWE-200"
          ],
          "cvss": {
            "score": 7.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"
          },
          "range": "<7.0.0"
        },
        "request"
      ],
      "effects": [
        "preq"
      ],
      "range": "*",
      "nodes": [
        "node_modules/requestretry"
      ],
      "fixAvailable": false
    },
    "semver": {
      "name": "semver",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1096483,
          "name": "semver",
          "dependency": "semver",
          "title": "semver vulnerable to Regular Expression Denial of Service",
          "url": "https://github.com/advisories/GHSA-c2qf-rxjj-qqgw",
          "severity": "moderate",
          "cwe": [
            "CWE-1333"
          ],
          "cvss": {
            "score": 5.3,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"
          },
          "range": "<5.7.2"
        },
        {
          "source": 1096484,
          "name": "semver",
          "dependency": "semver",
          "title": "semver vulnerable to Regular Expression Denial of Service",
          "url": "https://github.com/advisories/GHSA-c2qf-rxjj-qqgw",
          "severity": "moderate",
          "cwe": [
            "CWE-1333"
          ],
          "cvss": {
            "score": 5.3,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"
          },
          "range": ">=6.0.0 <6.3.1"
        }
      ],
      "effects": [],
      "range": "<5.7.2 || >=6.0.0 <6.3.1",
      "nodes": [
        "node_modules/@babel/core/node_modules/semver",
        "node_modules/@wikimedia/jsonschema-tools/node_modules/semver",
        "node_modules/gc-stats/node_modules/semver",
        "node_modules/istanbul-lib-instrument/node_modules/semver",
        "node_modules/make-dir/node_modules/semver"
      ],
      "fixAvailable": true
    },
    "swagger-ui-dist": {
      "name": "swagger-ui-dist",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1088759,
          "name": "swagger-ui-dist",
          "dependency": "swagger-ui-dist",
          "title": "Spoofing attack in swagger-ui-dist",
          "url": "https://github.com/advisories/GHSA-6c9x-mj3g-h47x",
          "severity": "moderate",
          "cwe": [
            "CWE-1021"
          ],
          "cvss": {
            "score": 6.1,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
          },
          "range": "<4.1.3"
        },
        {
          "source": 1092160,
          "name": "swagger-ui-dist",
          "dependency": "swagger-ui-dist",
          "title": "Server side request forgery in SwaggerUI",
          "url": "https://github.com/advisories/GHSA-qrmm-w75w-3wpx",
          "severity": "moderate",
          "cwe": [
            "CWE-918"
          ],
          "cvss": {
            "score": 0,
            "vectorString": null
          },
          "range": "<4.1.3"
        }
      ],
      "effects": [
        "hyperswitch"
      ],
      "range": "<=4.1.2",
      "nodes": [
        "node_modules/swagger-ui-dist"
      ],
      "fixAvailable": {
        "name": "hyperswitch",
        "version": "0.10.5",
        "isSemVerMajor": true
      }
    },
    "tar": {
      "name": "tar",
      "severity": "high",
      "isDirect": false,
      "via": [
        {
          "source": 1089684,
          "name": "tar",
          "dependency": "tar",
          "title": "Arbitrary File Creation/Overwrite due to insufficient absolute path sanitization",
          "url": "https://github.com/advisories/GHSA-3jfq-g458-7qm9",
          "severity": "high",
          "cwe": [
            "CWE-22"
          ],
          "cvss": {
            "score": 8.2,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
          },
          "range": ">=4.0.0 <4.4.14"
        },
        {
          "source": 1095117,
          "name": "tar",
          "dependency": "tar",
          "title": "Arbitrary File Creation/Overwrite on Windows via insufficient relative path sanitization",
          "url": "https://github.com/advisories/GHSA-5955-9wpr-37jh",
          "severity": "high",
          "cwe": [
            "CWE-22"
          ],
          "cvss": {
            "score": 8.2,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
          },
          "range": "<4.4.18"
        },
        {
          "source": 1096309,
          "name": "tar",
          "dependency": "tar",
          "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning",
          "url": "https://github.com/advisories/GHSA-r628-mhmh-qjhw",
          "severity": "high",
          "cwe": [
            "CWE-22",
            "CWE-23",
            "CWE-59"
          ],
          "cvss": {
            "score": 8.2,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
          },
          "range": ">=4.0.0 <4.4.15"
        },
        {
          "source": 1096376,
          "name": "tar",
          "dependency": "tar",
          "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning using symbolic links",
          "url": "https://github.com/advisories/GHSA-9r2w-394v-53qc",
          "severity": "high",
          "cwe": [
            "CWE-22",
            "CWE-59"
          ],
          "cvss": {
            "score": 8.2,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
          },
          "range": ">=3.0.0 <4.4.16"
        },
        {
          "source": 1096411,
          "name": "tar",
          "dependency": "tar",
          "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning using symbolic links",
          "url": "https://github.com/advisories/GHSA-qq89-hq3f-393p",
          "severity": "high",
          "cwe": [
            "CWE-22",
            "CWE-59"
          ],
          "cvss": {
            "score": 8.2,
            "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
          },
          "range": ">=3.0.0 <4.4.18"
        },
        {
          "source": 1096915,
          "name": "tar",
          "dependency": "tar",
          "title": "Denial of service while parsing a tar file due to lack of folders count validation",
          "url": "https://github.com/advisories/GHSA-f5x3-32g6-xq36",
          "severity": "moderate",
          "cwe": [
            "CWE-400"
          ],
          "cvss": {
            "score": 6.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H"
          },
          "range": "<6.2.1"
        }
      ],
      "effects": [],
      "range": "<=6.2.0",
      "nodes": [
        "node_modules/gc-stats/node_modules/tar"
      ],
      "fixAvailable": true
    },
    "tough-cookie": {
      "name": "tough-cookie",
      "severity": "moderate",
      "isDirect": false,
      "via": [
        {
          "source": 1096643,
          "name": "tough-cookie",
          "dependency": "tough-cookie",
          "title": "tough-cookie Prototype Pollution vulnerability",
          "url": "https://github.com/advisories/GHSA-72xf-g2v4-qvf3",
          "severity": "moderate",
          "cwe": [
            "CWE-1321"
          ],
          "cvss": {
            "score": 6.5,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N"
          },
          "range": "<4.1.3"
        }
      ],
      "effects": [
        "request"
      ],
      "range": "<4.1.3",
      "nodes": [
        "node_modules/tough-cookie"
      ],
      "fixAvailable": false
    },
    "underscore": {
      "name": "underscore",
      "severity": "critical",
      "isDirect": false,
      "via": [
        {
          "source": 1095097,
          "name": "underscore",
          "dependency": "underscore",
          "title": "Arbitrary Code Execution in underscore",
          "url": "https://github.com/advisories/GHSA-cf4h-3jhx-xvhq",
          "severity": "critical",
          "cwe": [
            "CWE-94"
          ],
          "cvss": {
            "score": 9.8,
            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
          },
          "range": ">=1.3.2 <1.12.1"
        }
      ],
      "effects": [],
      "range": "1.3.2 - 1.12.0",
      "nodes": [
        "node_modules/underscore"
      ],
      "fixAvailable": true
    }
  },
  "metadata": {
    "vulnerabilities": {
      "info": 0,
      "low": 1,
      "moderate": 10,
      "high": 16,
      "critical": 5,
      "total": 32
    },
    "dependencies": {
      "prod": 157,
      "dev": 429,
      "optional": 78,
      "peer": 1,
      "peerOptional": 0,
      "total": 662
    }
  }
}

--- end ---
Attempting to npm audit fix
$ /usr/bin/npm audit fix --dry-run --only=dev --json
--- stderr ---
npm WARN invalid config only="dev" set in command line options
npm WARN invalid config Must be one of: null, prod, production
npm WARN audit fix semver@5.7.0 node_modules/gc-stats/node_modules/semver
npm WARN audit fix semver@5.7.0 is a bundled dependency of
npm WARN audit fix semver@5.7.0 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix semver@5.7.0 It cannot be fixed automatically.
npm WARN audit fix semver@5.7.0 Check for updates to the gc-stats package.
npm WARN audit fix minimatch@3.0.4 node_modules/gc-stats/node_modules/minimatch
npm WARN audit fix minimatch@3.0.4 is a bundled dependency of
npm WARN audit fix minimatch@3.0.4 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix minimatch@3.0.4 It cannot be fixed automatically.
npm WARN audit fix minimatch@3.0.4 Check for updates to the gc-stats package.
npm WARN audit fix debug@4.1.1 node_modules/gc-stats/node_modules/debug
npm WARN audit fix debug@4.1.1 is a bundled dependency of
npm WARN audit fix debug@4.1.1 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix debug@4.1.1 It cannot be fixed automatically.
npm WARN audit fix debug@4.1.1 Check for updates to the gc-stats package.
npm WARN audit fix ini@1.3.5 node_modules/gc-stats/node_modules/ini
npm WARN audit fix ini@1.3.5 is a bundled dependency of
npm WARN audit fix ini@1.3.5 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix ini@1.3.5 It cannot be fixed automatically.
npm WARN audit fix ini@1.3.5 Check for updates to the gc-stats package.
npm WARN audit fix minimist@1.2.0 node_modules/gc-stats/node_modules/rc/node_modules/minimist
npm WARN audit fix minimist@1.2.0 is a bundled dependency of
npm WARN audit fix minimist@1.2.0 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix minimist@1.2.0 It cannot be fixed automatically.
npm WARN audit fix minimist@1.2.0 Check for updates to the gc-stats package.
npm WARN audit fix minimist@0.0.8 node_modules/gc-stats/node_modules/minimist
npm WARN audit fix minimist@0.0.8 is a bundled dependency of
npm WARN audit fix minimist@0.0.8 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix minimist@0.0.8 It cannot be fixed automatically.
npm WARN audit fix minimist@0.0.8 Check for updates to the gc-stats package.
npm WARN audit fix tar@4.4.8 node_modules/gc-stats/node_modules/tar
npm WARN audit fix tar@4.4.8 is a bundled dependency of
npm WARN audit fix tar@4.4.8 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix tar@4.4.8 It cannot be fixed automatically.
npm WARN audit fix tar@4.4.8 Check for updates to the gc-stats package.
npm WARN audit fix mkdirp@0.5.1 node_modules/gc-stats/node_modules/mkdirp
npm WARN audit fix mkdirp@0.5.1 is a bundled dependency of
npm WARN audit fix mkdirp@0.5.1 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix mkdirp@0.5.1 It cannot be fixed automatically.
npm WARN audit fix mkdirp@0.5.1 Check for updates to the gc-stats package.
--- stdout ---
{
  "added": 24,
  "removed": 8,
  "changed": 51,
  "audited": 678,
  "funding": 69,
  "audit": {
    "auditReportVersion": 2,
    "vulnerabilities": {
      "@babel/traverse": {
        "name": "@babel/traverse",
        "severity": "critical",
        "isDirect": false,
        "via": [
          {
            "source": 1096886,
            "name": "@babel/traverse",
            "dependency": "@babel/traverse",
            "title": "Babel vulnerable to arbitrary code execution when compiling specifically crafted malicious code",
            "url": "https://github.com/advisories/GHSA-67hx-6x53-jw92",
            "severity": "critical",
            "cwe": [
              "CWE-184",
              "CWE-697"
            ],
            "cvss": {
              "score": 9.4,
              "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H"
            },
            "range": "<7.23.2"
          }
        ],
        "effects": [],
        "range": "<7.23.2",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "ansi-regex": {
        "name": "ansi-regex",
        "severity": "high",
        "isDirect": false,
        "via": [
          {
            "source": 1094090,
            "name": "ansi-regex",
            "dependency": "ansi-regex",
            "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex",
            "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw",
            "severity": "high",
            "cwe": [
              "CWE-697",
              "CWE-1333"
            ],
            "cvss": {
              "score": 7.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
            },
            "range": ">=3.0.0 <3.0.1"
          },
          {
            "source": 1094091,
            "name": "ansi-regex",
            "dependency": "ansi-regex",
            "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex",
            "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw",
            "severity": "high",
            "cwe": [
              "CWE-697",
              "CWE-1333"
            ],
            "cvss": {
              "score": 7.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
            },
            "range": ">=4.0.0 <4.1.1"
          },
          {
            "source": 1094092,
            "name": "ansi-regex",
            "dependency": "ansi-regex",
            "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex",
            "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw",
            "severity": "high",
            "cwe": [
              "CWE-697",
              "CWE-1333"
            ],
            "cvss": {
              "score": 7.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
            },
            "range": ">=5.0.0 <5.0.1"
          }
        ],
        "effects": [],
        "range": "3.0.0 || 4.0.0 - 4.1.0 || 5.0.0",
        "nodes": [
          "",
          "",
          ""
        ],
        "fixAvailable": true
      },
      "busboy": {
        "name": "busboy",
        "severity": "high",
        "isDirect": false,
        "via": [
          "dicer"
        ],
        "effects": [
          "hyperswitch"
        ],
        "range": "<=0.3.1",
        "nodes": [
          "node_modules/busboy"
        ],
        "fixAvailable": {
          "name": "hyperswitch",
          "version": "0.10.5",
          "isSemVerMajor": true
        }
      },
      "coveralls": {
        "name": "coveralls",
        "severity": "moderate",
        "isDirect": false,
        "via": [
          "request"
        ],
        "effects": [],
        "range": "*",
        "nodes": [
          ""
        ],
        "fixAvailable": false
      },
      "debug": {
        "name": "debug",
        "severity": "low",
        "isDirect": false,
        "via": [
          {
            "source": 1096792,
            "name": "debug",
            "dependency": "debug",
            "title": "Regular Expression Denial of Service in debug",
            "url": "https://github.com/advisories/GHSA-gxpj-cx7g-858c",
            "severity": "low",
            "cwe": [
              "CWE-400"
            ],
            "cvss": {
              "score": 3.7,
              "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L"
            },
            "range": ">=4.0.0 <4.3.1"
          }
        ],
        "effects": [
          "mocha"
        ],
        "range": "4.0.0 - 4.3.0",
        "nodes": [
          "",
          ""
        ],
        "fixAvailable": {
          "name": "mocha",
          "version": "10.4.0",
          "isSemVerMajor": true
        }
      },
      "dicer": {
        "name": "dicer",
        "severity": "high",
        "isDirect": false,
        "via": [
          {
            "source": 1093150,
            "name": "dicer",
            "dependency": "dicer",
            "title": "Crash in HeaderParser in dicer",
            "url": "https://github.com/advisories/GHSA-wm7h-9275-46v2",
            "severity": "high",
            "cwe": [
              "CWE-248"
            ],
            "cvss": {
              "score": 7.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
            },
            "range": "<=0.3.1"
          }
        ],
        "effects": [
          "busboy"
        ],
        "range": "*",
        "nodes": [
          "node_modules/dicer"
        ],
        "fixAvailable": {
          "name": "hyperswitch",
          "version": "0.10.5",
          "isSemVerMajor": true
        }
      },
      "hyperswitch": {
        "name": "hyperswitch",
        "severity": "high",
        "isDirect": true,
        "via": [
          "busboy",
          "preq",
          "swagger-ui-dist"
        ],
        "effects": [],
        "range": ">=0.1.0",
        "nodes": [
          "node_modules/hyperswitch"
        ],
        "fixAvailable": {
          "name": "hyperswitch",
          "version": "0.10.5",
          "isSemVerMajor": true
        }
      },
      "ini": {
        "name": "ini",
        "severity": "high",
        "isDirect": false,
        "via": [
          {
            "source": 1093224,
            "name": "ini",
            "dependency": "ini",
            "title": "ini before 1.3.6 vulnerable to Prototype Pollution via ini.parse",
            "url": "https://github.com/advisories/GHSA-qqgx-2p2h-9c37",
            "severity": "high",
            "cwe": [
              "CWE-1321"
            ],
            "cvss": {
              "score": 7.3,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L"
            },
            "range": "<1.3.6"
          }
        ],
        "effects": [],
        "range": "<1.3.6",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "json-schema": {
        "name": "json-schema",
        "severity": "critical",
        "isDirect": false,
        "via": [
          {
            "source": 1095057,
            "name": "json-schema",
            "dependency": "json-schema",
            "title": "json-schema is vulnerable to Prototype Pollution",
            "url": "https://github.com/advisories/GHSA-896r-f27r-55mw",
            "severity": "critical",
            "cwe": [
              "CWE-915",
              "CWE-1321"
            ],
            "cvss": {
              "score": 9.8,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
            },
            "range": "<0.4.0"
          }
        ],
        "effects": [
          "jsprim"
        ],
        "range": "<0.4.0",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "json5": {
        "name": "json5",
        "severity": "high",
        "isDirect": false,
        "via": [
          {
            "source": 1096544,
            "name": "json5",
            "dependency": "json5",
            "title": "Prototype Pollution in JSON5 via Parse Method",
            "url": "https://github.com/advisories/GHSA-9c47-m6qq-7p4h",
            "severity": "high",
            "cwe": [
              "CWE-1321"
            ],
            "cvss": {
              "score": 7.1,
              "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:L/A:H"
            },
            "range": ">=2.0.0 <2.2.2"
          }
        ],
        "effects": [],
        "range": "2.0.0 - 2.2.1",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "jsprim": {
        "name": "jsprim",
        "severity": "critical",
        "isDirect": false,
        "via": [
          "json-schema"
        ],
        "effects": [],
        "range": "0.3.0 - 1.4.1 || 2.0.0 - 2.0.1",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "kad": {
        "name": "kad",
        "severity": "high",
        "isDirect": false,
        "via": [
          "merge",
          "ms"
        ],
        "effects": [
          "limitation"
        ],
        "range": "*",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "limitation": {
        "name": "limitation",
        "severity": "moderate",
        "isDirect": false,
        "via": [
          "kad"
        ],
        "effects": [],
        "range": "<=0.2.2",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "merge": {
        "name": "merge",
        "severity": "high",
        "isDirect": false,
        "via": [
          {
            "source": 1096479,
            "name": "merge",
            "dependency": "merge",
            "title": "Prototype Pollution in merge",
            "url": "https://github.com/advisories/GHSA-7wpw-2hjm-89gp",
            "severity": "high",
            "cwe": [
              "CWE-915"
            ],
            "cvss": {
              "score": 7.3,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L"
            },
            "range": "<2.1.1"
          }
        ],
        "effects": [
          "kad"
        ],
        "range": "<2.1.1",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "minimatch": {
        "name": "minimatch",
        "severity": "high",
        "isDirect": false,
        "via": [
          {
            "source": 1096485,
            "name": "minimatch",
            "dependency": "minimatch",
            "title": "minimatch ReDoS vulnerability",
            "url": "https://github.com/advisories/GHSA-f8q6-p94x-37v3",
            "severity": "high",
            "cwe": [
              "CWE-400",
              "CWE-1333"
            ],
            "cvss": {
              "score": 7.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
            },
            "range": "<3.0.5"
          }
        ],
        "effects": [
          "mocha"
        ],
        "range": "<3.0.5",
        "nodes": [
          "",
          "node_modules/minimatch"
        ],
        "fixAvailable": {
          "name": "mocha",
          "version": "10.4.0",
          "isSemVerMajor": true
        }
      },
      "minimist": {
        "name": "minimist",
        "severity": "critical",
        "isDirect": true,
        "via": [
          {
            "source": 1096465,
            "name": "minimist",
            "dependency": "minimist",
            "title": "Prototype Pollution in minimist",
            "url": "https://github.com/advisories/GHSA-vh95-rmgr-6w4m",
            "severity": "moderate",
            "cwe": [
              "CWE-1321"
            ],
            "cvss": {
              "score": 5.6,
              "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"
            },
            "range": ">=1.0.0 <1.2.3"
          },
          {
            "source": 1096466,
            "name": "minimist",
            "dependency": "minimist",
            "title": "Prototype Pollution in minimist",
            "url": "https://github.com/advisories/GHSA-vh95-rmgr-6w4m",
            "severity": "moderate",
            "cwe": [
              "CWE-1321"
            ],
            "cvss": {
              "score": 5.6,
              "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"
            },
            "range": "<0.2.1"
          },
          {
            "source": 1096548,
            "name": "minimist",
            "dependency": "minimist",
            "title": "Prototype Pollution in minimist",
            "url": "https://github.com/advisories/GHSA-xvch-5gv4-984h",
            "severity": "critical",
            "cwe": [
              "CWE-1321"
            ],
            "cvss": {
              "score": 9.8,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
            },
            "range": "<0.2.4"
          },
          {
            "source": 1096549,
            "name": "minimist",
            "dependency": "minimist",
            "title": "Prototype Pollution in minimist",
            "url": "https://github.com/advisories/GHSA-xvch-5gv4-984h",
            "severity": "critical",
            "cwe": [
              "CWE-1321"
            ],
            "cvss": {
              "score": 9.8,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
            },
            "range": ">=1.0.0 <1.2.6"
          }
        ],
        "effects": [
          "mkdirp"
        ],
        "range": "<=0.2.3 || 1.0.0 - 1.2.5",
        "nodes": [
          "",
          "",
          "node_modules/minimist"
        ],
        "fixAvailable": true
      },
      "mkdirp": {
        "name": "mkdirp",
        "severity": "moderate",
        "isDirect": false,
        "via": [
          "minimist"
        ],
        "effects": [],
        "range": "0.4.1 - 0.5.1",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "mocha": {
        "name": "mocha",
        "severity": "high",
        "isDirect": false,
        "via": [
          "debug",
          "minimatch",
          "nanoid"
        ],
        "effects": [],
        "range": "5.1.0 - 9.2.1",
        "nodes": [
          ""
        ],
        "fixAvailable": {
          "name": "mocha",
          "version": "10.4.0",
          "isSemVerMajor": true
        }
      },
      "moment": {
        "name": "moment",
        "severity": "high",
        "isDirect": false,
        "via": [
          {
            "source": 1095072,
            "name": "moment",
            "dependency": "moment",
            "title": "Moment.js vulnerable to Inefficient Regular Expression Complexity",
            "url": "https://github.com/advisories/GHSA-wc69-rhjr-hc9g",
            "severity": "high",
            "cwe": [
              "CWE-400",
              "CWE-1333"
            ],
            "cvss": {
              "score": 7.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
            },
            "range": ">=2.18.0 <2.29.4"
          },
          {
            "source": 1095083,
            "name": "moment",
            "dependency": "moment",
            "title": "Path Traversal: 'dir/../../filename' in moment.locale",
            "url": "https://github.com/advisories/GHSA-8hfj-j24r-96c4",
            "severity": "high",
            "cwe": [
              "CWE-22",
              "CWE-27"
            ],
            "cvss": {
              "score": 7.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N"
            },
            "range": "<2.29.2"
          }
        ],
        "effects": [],
        "range": "<=2.29.3",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "ms": {
        "name": "ms",
        "severity": "moderate",
        "isDirect": false,
        "via": [
          {
            "source": 1094419,
            "name": "ms",
            "dependency": "ms",
            "title": "Vercel ms Inefficient Regular Expression Complexity vulnerability",
            "url": "https://github.com/advisories/GHSA-w9mr-4mfr-499f",
            "severity": "moderate",
            "cwe": [
              "CWE-1333"
            ],
            "cvss": {
              "score": 5.3,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"
            },
            "range": "<2.0.0"
          }
        ],
        "effects": [
          "kad"
        ],
        "range": "<2.0.0",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "msgpack5": {
        "name": "msgpack5",
        "severity": "moderate",
        "isDirect": false,
        "via": [
          {
            "source": 1089202,
            "name": "msgpack5",
            "dependency": "msgpack5",
            "title": "Prototype poisoning",
            "url": "https://github.com/advisories/GHSA-gmjw-49p4-pcfm",
            "severity": "moderate",
            "cwe": [
              "CWE-915",
              "CWE-1321"
            ],
            "cvss": {
              "score": 6.7,
              "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:H/A:H"
            },
            "range": "<3.6.1"
          }
        ],
        "effects": [],
        "range": "<3.6.1",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "nanoid": {
        "name": "nanoid",
        "severity": "moderate",
        "isDirect": false,
        "via": [
          {
            "source": 1089011,
            "name": "nanoid",
            "dependency": "nanoid",
            "title": "Exposure of Sensitive Information to an Unauthorized Actor in nanoid",
            "url": "https://github.com/advisories/GHSA-qrpm-p2h7-hrv2",
            "severity": "moderate",
            "cwe": [
              "CWE-200"
            ],
            "cvss": {
              "score": 5.5,
              "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N"
            },
            "range": ">=3.0.0 <3.1.31"
          }
        ],
        "effects": [
          "mocha"
        ],
        "range": "3.0.0 - 3.1.30",
        "nodes": [
          ""
        ],
        "fixAvailable": {
          "name": "mocha",
          "version": "10.4.0",
          "isSemVerMajor": true
        }
      },
      "preq": {
        "name": "preq",
        "severity": "high",
        "isDirect": true,
        "via": [
          "request",
          "requestretry"
        ],
        "effects": [],
        "range": "*",
        "nodes": [
          "node_modules/preq"
        ],
        "fixAvailable": false
      },
      "qs": {
        "name": "qs",
        "severity": "high",
        "isDirect": false,
        "via": [
          {
            "source": 1096470,
            "name": "qs",
            "dependency": "qs",
            "title": "qs vulnerable to Prototype Pollution",
            "url": "https://github.com/advisories/GHSA-hrpp-h998-j3pp",
            "severity": "high",
            "cwe": [
              "CWE-1321"
            ],
            "cvss": {
              "score": 7.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
            },
            "range": ">=6.5.0 <6.5.3"
          }
        ],
        "effects": [],
        "range": "6.5.0 - 6.5.2",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "redis": {
        "name": "redis",
        "severity": "high",
        "isDirect": false,
        "via": [
          {
            "source": 1089196,
            "name": "redis",
            "dependency": "redis",
            "title": "Node-Redis potential exponential regex in monitor mode",
            "url": "https://github.com/advisories/GHSA-35q2-47q7-3pc3",
            "severity": "high",
            "cwe": [
              "CWE-400"
            ],
            "cvss": {
              "score": 7.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
            },
            "range": ">=2.6.0 <3.1.1"
          }
        ],
        "effects": [],
        "range": "2.6.0 - 3.1.0",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "request": {
        "name": "request",
        "severity": "moderate",
        "isDirect": false,
        "via": [
          {
            "source": 1096727,
            "name": "request",
            "dependency": "request",
            "title": "Server-Side Request Forgery in Request",
            "url": "https://github.com/advisories/GHSA-p8p7-x288-28g6",
            "severity": "moderate",
            "cwe": [
              "CWE-918"
            ],
            "cvss": {
              "score": 6.1,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
            },
            "range": "<=2.88.2"
          },
          "tough-cookie"
        ],
        "effects": [
          "coveralls",
          "preq",
          "requestretry"
        ],
        "range": "*",
        "nodes": [
          "node_modules/request"
        ],
        "fixAvailable": false
      },
      "requestretry": {
        "name": "requestretry",
        "severity": "high",
        "isDirect": false,
        "via": [
          {
            "source": 1090420,
            "name": "requestretry",
            "dependency": "requestretry",
            "title": "Cookie exposure in requestretry",
            "url": "https://github.com/advisories/GHSA-hjp8-2cm3-cc45",
            "severity": "high",
            "cwe": [
              "CWE-200"
            ],
            "cvss": {
              "score": 7.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"
            },
            "range": "<7.0.0"
          },
          "request"
        ],
        "effects": [
          "preq"
        ],
        "range": "*",
        "nodes": [
          "node_modules/requestretry"
        ],
        "fixAvailable": false
      },
      "semver": {
        "name": "semver",
        "severity": "moderate",
        "isDirect": false,
        "via": [
          {
            "source": 1096483,
            "name": "semver",
            "dependency": "semver",
            "title": "semver vulnerable to Regular Expression Denial of Service",
            "url": "https://github.com/advisories/GHSA-c2qf-rxjj-qqgw",
            "severity": "moderate",
            "cwe": [
              "CWE-1333"
            ],
            "cvss": {
              "score": 5.3,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"
            },
            "range": "<5.7.2"
          },
          {
            "source": 1096484,
            "name": "semver",
            "dependency": "semver",
            "title": "semver vulnerable to Regular Expression Denial of Service",
            "url": "https://github.com/advisories/GHSA-c2qf-rxjj-qqgw",
            "severity": "moderate",
            "cwe": [
              "CWE-1333"
            ],
            "cvss": {
              "score": 5.3,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"
            },
            "range": ">=6.0.0 <6.3.1"
          }
        ],
        "effects": [],
        "range": "<5.7.2 || >=6.0.0 <6.3.1",
        "nodes": [
          "",
          "",
          "",
          "",
          ""
        ],
        "fixAvailable": true
      },
      "swagger-ui-dist": {
        "name": "swagger-ui-dist",
        "severity": "moderate",
        "isDirect": false,
        "via": [
          {
            "source": 1088759,
            "name": "swagger-ui-dist",
            "dependency": "swagger-ui-dist",
            "title": "Spoofing attack in swagger-ui-dist",
            "url": "https://github.com/advisories/GHSA-6c9x-mj3g-h47x",
            "severity": "moderate",
            "cwe": [
              "CWE-1021"
            ],
            "cvss": {
              "score": 6.1,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"
            },
            "range": "<4.1.3"
          },
          {
            "source": 1092160,
            "name": "swagger-ui-dist",
            "dependency": "swagger-ui-dist",
            "title": "Server side request forgery in SwaggerUI",
            "url": "https://github.com/advisories/GHSA-qrmm-w75w-3wpx",
            "severity": "moderate",
            "cwe": [
              "CWE-918"
            ],
            "cvss": {
              "score": 0,
              "vectorString": null
            },
            "range": "<4.1.3"
          }
        ],
        "effects": [
          "hyperswitch"
        ],
        "range": "<=4.1.2",
        "nodes": [
          ""
        ],
        "fixAvailable": {
          "name": "hyperswitch",
          "version": "0.10.5",
          "isSemVerMajor": true
        }
      },
      "tar": {
        "name": "tar",
        "severity": "high",
        "isDirect": false,
        "via": [
          {
            "source": 1089684,
            "name": "tar",
            "dependency": "tar",
            "title": "Arbitrary File Creation/Overwrite due to insufficient absolute path sanitization",
            "url": "https://github.com/advisories/GHSA-3jfq-g458-7qm9",
            "severity": "high",
            "cwe": [
              "CWE-22"
            ],
            "cvss": {
              "score": 8.2,
              "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
            },
            "range": ">=4.0.0 <4.4.14"
          },
          {
            "source": 1095117,
            "name": "tar",
            "dependency": "tar",
            "title": "Arbitrary File Creation/Overwrite on Windows via insufficient relative path sanitization",
            "url": "https://github.com/advisories/GHSA-5955-9wpr-37jh",
            "severity": "high",
            "cwe": [
              "CWE-22"
            ],
            "cvss": {
              "score": 8.2,
              "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
            },
            "range": "<4.4.18"
          },
          {
            "source": 1096309,
            "name": "tar",
            "dependency": "tar",
            "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning",
            "url": "https://github.com/advisories/GHSA-r628-mhmh-qjhw",
            "severity": "high",
            "cwe": [
              "CWE-22",
              "CWE-23",
              "CWE-59"
            ],
            "cvss": {
              "score": 8.2,
              "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
            },
            "range": ">=4.0.0 <4.4.15"
          },
          {
            "source": 1096376,
            "name": "tar",
            "dependency": "tar",
            "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning using symbolic links",
            "url": "https://github.com/advisories/GHSA-9r2w-394v-53qc",
            "severity": "high",
            "cwe": [
              "CWE-22",
              "CWE-59"
            ],
            "cvss": {
              "score": 8.2,
              "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
            },
            "range": ">=3.0.0 <4.4.16"
          },
          {
            "source": 1096411,
            "name": "tar",
            "dependency": "tar",
            "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning using symbolic links",
            "url": "https://github.com/advisories/GHSA-qq89-hq3f-393p",
            "severity": "high",
            "cwe": [
              "CWE-22",
              "CWE-59"
            ],
            "cvss": {
              "score": 8.2,
              "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"
            },
            "range": ">=3.0.0 <4.4.18"
          },
          {
            "source": 1096915,
            "name": "tar",
            "dependency": "tar",
            "title": "Denial of service while parsing a tar file due to lack of folders count validation",
            "url": "https://github.com/advisories/GHSA-f5x3-32g6-xq36",
            "severity": "moderate",
            "cwe": [
              "CWE-400"
            ],
            "cvss": {
              "score": 6.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H"
            },
            "range": "<6.2.1"
          }
        ],
        "effects": [],
        "range": "<=6.2.0",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      },
      "tough-cookie": {
        "name": "tough-cookie",
        "severity": "moderate",
        "isDirect": false,
        "via": [
          {
            "source": 1096643,
            "name": "tough-cookie",
            "dependency": "tough-cookie",
            "title": "tough-cookie Prototype Pollution vulnerability",
            "url": "https://github.com/advisories/GHSA-72xf-g2v4-qvf3",
            "severity": "moderate",
            "cwe": [
              "CWE-1321"
            ],
            "cvss": {
              "score": 6.5,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N"
            },
            "range": "<4.1.3"
          }
        ],
        "effects": [
          "request"
        ],
        "range": "<4.1.3",
        "nodes": [
          "node_modules/tough-cookie"
        ],
        "fixAvailable": false
      },
      "underscore": {
        "name": "underscore",
        "severity": "critical",
        "isDirect": false,
        "via": [
          {
            "source": 1095097,
            "name": "underscore",
            "dependency": "underscore",
            "title": "Arbitrary Code Execution in underscore",
            "url": "https://github.com/advisories/GHSA-cf4h-3jhx-xvhq",
            "severity": "critical",
            "cwe": [
              "CWE-94"
            ],
            "cvss": {
              "score": 9.8,
              "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"
            },
            "range": ">=1.3.2 <1.12.1"
          }
        ],
        "effects": [],
        "range": "1.3.2 - 1.12.0",
        "nodes": [
          ""
        ],
        "fixAvailable": true
      }
    },
    "metadata": {
      "vulnerabilities": {
        "info": 0,
        "low": 1,
        "moderate": 10,
        "high": 16,
        "critical": 5,
        "total": 32
      },
      "dependencies": {
        "prod": 156,
        "dev": 445,
        "optional": 78,
        "peer": 1,
        "peerOptional": 0,
        "total": 677
      }
    }
  }
}

--- end ---
{"added": 24, "removed": 8, "changed": 51, "audited": 678, "funding": 69, "audit": {"auditReportVersion": 2, "vulnerabilities": {"@babel/traverse": {"name": "@babel/traverse", "severity": "critical", "isDirect": false, "via": [{"source": 1096886, "name": "@babel/traverse", "dependency": "@babel/traverse", "title": "Babel vulnerable to arbitrary code execution when compiling specifically crafted malicious code", "url": "https://github.com/advisories/GHSA-67hx-6x53-jw92", "severity": "critical", "cwe": ["CWE-184", "CWE-697"], "cvss": {"score": 9.4, "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H"}, "range": "<7.23.2"}], "effects": [], "range": "<7.23.2", "nodes": [""], "fixAvailable": true}, "ansi-regex": {"name": "ansi-regex", "severity": "high", "isDirect": false, "via": [{"source": 1094090, "name": "ansi-regex", "dependency": "ansi-regex", "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex", "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw", "severity": "high", "cwe": ["CWE-697", "CWE-1333"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=3.0.0 <3.0.1"}, {"source": 1094091, "name": "ansi-regex", "dependency": "ansi-regex", "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex", "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw", "severity": "high", "cwe": ["CWE-697", "CWE-1333"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=4.0.0 <4.1.1"}, {"source": 1094092, "name": "ansi-regex", "dependency": "ansi-regex", "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex", "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw", "severity": "high", "cwe": ["CWE-697", "CWE-1333"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=5.0.0 <5.0.1"}], "effects": [], "range": "3.0.0 || 4.0.0 - 4.1.0 || 5.0.0", "nodes": ["", "", ""], "fixAvailable": true}, "busboy": {"name": "busboy", "severity": "high", "isDirect": false, "via": ["dicer"], "effects": ["hyperswitch"], "range": "<=0.3.1", "nodes": ["node_modules/busboy"], "fixAvailable": {"name": "hyperswitch", "version": "0.10.5", "isSemVerMajor": true}}, "coveralls": {"name": "coveralls", "severity": "moderate", "isDirect": false, "via": ["request"], "effects": [], "range": "*", "nodes": [""], "fixAvailable": false}, "debug": {"name": "debug", "severity": "low", "isDirect": false, "via": [{"source": 1096792, "name": "debug", "dependency": "debug", "title": "Regular Expression Denial of Service in debug", "url": "https://github.com/advisories/GHSA-gxpj-cx7g-858c", "severity": "low", "cwe": ["CWE-400"], "cvss": {"score": 3.7, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:L"}, "range": ">=4.0.0 <4.3.1"}], "effects": ["mocha"], "range": "4.0.0 - 4.3.0", "nodes": ["", ""], "fixAvailable": {"name": "mocha", "version": "10.4.0", "isSemVerMajor": true}}, "dicer": {"name": "dicer", "severity": "high", "isDirect": false, "via": [{"source": 1093150, "name": "dicer", "dependency": "dicer", "title": "Crash in HeaderParser in dicer", "url": "https://github.com/advisories/GHSA-wm7h-9275-46v2", "severity": "high", "cwe": ["CWE-248"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": "<=0.3.1"}], "effects": ["busboy"], "range": "*", "nodes": ["node_modules/dicer"], "fixAvailable": {"name": "hyperswitch", "version": "0.10.5", "isSemVerMajor": true}}, "hyperswitch": {"name": "hyperswitch", "severity": "high", "isDirect": true, "via": ["busboy", "preq", "swagger-ui-dist"], "effects": [], "range": ">=0.1.0", "nodes": ["node_modules/hyperswitch"], "fixAvailable": {"name": "hyperswitch", "version": "0.10.5", "isSemVerMajor": true}}, "ini": {"name": "ini", "severity": "high", "isDirect": false, "via": [{"source": 1093224, "name": "ini", "dependency": "ini", "title": "ini before 1.3.6 vulnerable to Prototype Pollution via ini.parse", "url": "https://github.com/advisories/GHSA-qqgx-2p2h-9c37", "severity": "high", "cwe": ["CWE-1321"], "cvss": {"score": 7.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L"}, "range": "<1.3.6"}], "effects": [], "range": "<1.3.6", "nodes": [""], "fixAvailable": true}, "json-schema": {"name": "json-schema", "severity": "critical", "isDirect": false, "via": [{"source": 1095057, "name": "json-schema", "dependency": "json-schema", "title": "json-schema is vulnerable to Prototype Pollution", "url": "https://github.com/advisories/GHSA-896r-f27r-55mw", "severity": "critical", "cwe": ["CWE-915", "CWE-1321"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": "<0.4.0"}], "effects": ["jsprim"], "range": "<0.4.0", "nodes": [""], "fixAvailable": true}, "json5": {"name": "json5", "severity": "high", "isDirect": false, "via": [{"source": 1096544, "name": "json5", "dependency": "json5", "title": "Prototype Pollution in JSON5 via Parse Method", "url": "https://github.com/advisories/GHSA-9c47-m6qq-7p4h", "severity": "high", "cwe": ["CWE-1321"], "cvss": {"score": 7.1, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:L/A:H"}, "range": ">=2.0.0 <2.2.2"}], "effects": [], "range": "2.0.0 - 2.2.1", "nodes": [""], "fixAvailable": true}, "jsprim": {"name": "jsprim", "severity": "critical", "isDirect": false, "via": ["json-schema"], "effects": [], "range": "0.3.0 - 1.4.1 || 2.0.0 - 2.0.1", "nodes": [""], "fixAvailable": true}, "kad": {"name": "kad", "severity": "high", "isDirect": false, "via": ["merge", "ms"], "effects": ["limitation"], "range": "*", "nodes": [""], "fixAvailable": true}, "limitation": {"name": "limitation", "severity": "moderate", "isDirect": false, "via": ["kad"], "effects": [], "range": "<=0.2.2", "nodes": [""], "fixAvailable": true}, "merge": {"name": "merge", "severity": "high", "isDirect": false, "via": [{"source": 1096479, "name": "merge", "dependency": "merge", "title": "Prototype Pollution in merge", "url": "https://github.com/advisories/GHSA-7wpw-2hjm-89gp", "severity": "high", "cwe": ["CWE-915"], "cvss": {"score": 7.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L"}, "range": "<2.1.1"}], "effects": ["kad"], "range": "<2.1.1", "nodes": [""], "fixAvailable": true}, "minimatch": {"name": "minimatch", "severity": "high", "isDirect": false, "via": [{"source": 1096485, "name": "minimatch", "dependency": "minimatch", "title": "minimatch ReDoS vulnerability", "url": "https://github.com/advisories/GHSA-f8q6-p94x-37v3", "severity": "high", "cwe": ["CWE-400", "CWE-1333"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": "<3.0.5"}], "effects": ["mocha"], "range": "<3.0.5", "nodes": ["", "node_modules/minimatch"], "fixAvailable": {"name": "mocha", "version": "10.4.0", "isSemVerMajor": true}}, "minimist": {"name": "minimist", "severity": "critical", "isDirect": true, "via": [{"source": 1096465, "name": "minimist", "dependency": "minimist", "title": "Prototype Pollution in minimist", "url": "https://github.com/advisories/GHSA-vh95-rmgr-6w4m", "severity": "moderate", "cwe": ["CWE-1321"], "cvss": {"score": 5.6, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"}, "range": ">=1.0.0 <1.2.3"}, {"source": 1096466, "name": "minimist", "dependency": "minimist", "title": "Prototype Pollution in minimist", "url": "https://github.com/advisories/GHSA-vh95-rmgr-6w4m", "severity": "moderate", "cwe": ["CWE-1321"], "cvss": {"score": 5.6, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"}, "range": "<0.2.1"}, {"source": 1096548, "name": "minimist", "dependency": "minimist", "title": "Prototype Pollution in minimist", "url": "https://github.com/advisories/GHSA-xvch-5gv4-984h", "severity": "critical", "cwe": ["CWE-1321"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": "<0.2.4"}, {"source": 1096549, "name": "minimist", "dependency": "minimist", "title": "Prototype Pollution in minimist", "url": "https://github.com/advisories/GHSA-xvch-5gv4-984h", "severity": "critical", "cwe": ["CWE-1321"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": ">=1.0.0 <1.2.6"}], "effects": ["mkdirp"], "range": "<=0.2.3 || 1.0.0 - 1.2.5", "nodes": ["", "", "node_modules/minimist"], "fixAvailable": true}, "mkdirp": {"name": "mkdirp", "severity": "moderate", "isDirect": false, "via": ["minimist"], "effects": [], "range": "0.4.1 - 0.5.1", "nodes": [""], "fixAvailable": true}, "mocha": {"name": "mocha", "severity": "high", "isDirect": false, "via": ["debug", "minimatch", "nanoid"], "effects": [], "range": "5.1.0 - 9.2.1", "nodes": [""], "fixAvailable": {"name": "mocha", "version": "10.4.0", "isSemVerMajor": true}}, "moment": {"name": "moment", "severity": "high", "isDirect": false, "via": [{"source": 1095072, "name": "moment", "dependency": "moment", "title": "Moment.js vulnerable to Inefficient Regular Expression Complexity", "url": "https://github.com/advisories/GHSA-wc69-rhjr-hc9g", "severity": "high", "cwe": ["CWE-400", "CWE-1333"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=2.18.0 <2.29.4"}, {"source": 1095083, "name": "moment", "dependency": "moment", "title": "Path Traversal: 'dir/../../filename' in moment.locale", "url": "https://github.com/advisories/GHSA-8hfj-j24r-96c4", "severity": "high", "cwe": ["CWE-22", "CWE-27"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N"}, "range": "<2.29.2"}], "effects": [], "range": "<=2.29.3", "nodes": [""], "fixAvailable": true}, "ms": {"name": "ms", "severity": "moderate", "isDirect": false, "via": [{"source": 1094419, "name": "ms", "dependency": "ms", "title": "Vercel ms Inefficient Regular Expression Complexity vulnerability", "url": "https://github.com/advisories/GHSA-w9mr-4mfr-499f", "severity": "moderate", "cwe": ["CWE-1333"], "cvss": {"score": 5.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"}, "range": "<2.0.0"}], "effects": ["kad"], "range": "<2.0.0", "nodes": [""], "fixAvailable": true}, "msgpack5": {"name": "msgpack5", "severity": "moderate", "isDirect": false, "via": [{"source": 1089202, "name": "msgpack5", "dependency": "msgpack5", "title": "Prototype poisoning", "url": "https://github.com/advisories/GHSA-gmjw-49p4-pcfm", "severity": "moderate", "cwe": ["CWE-915", "CWE-1321"], "cvss": {"score": 6.7, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:H/A:H"}, "range": "<3.6.1"}], "effects": [], "range": "<3.6.1", "nodes": [""], "fixAvailable": true}, "nanoid": {"name": "nanoid", "severity": "moderate", "isDirect": false, "via": [{"source": 1089011, "name": "nanoid", "dependency": "nanoid", "title": "Exposure of Sensitive Information to an Unauthorized Actor in nanoid", "url": "https://github.com/advisories/GHSA-qrpm-p2h7-hrv2", "severity": "moderate", "cwe": ["CWE-200"], "cvss": {"score": 5.5, "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N"}, "range": ">=3.0.0 <3.1.31"}], "effects": ["mocha"], "range": "3.0.0 - 3.1.30", "nodes": [""], "fixAvailable": {"name": "mocha", "version": "10.4.0", "isSemVerMajor": true}}, "preq": {"name": "preq", "severity": "high", "isDirect": true, "via": ["request", "requestretry"], "effects": [], "range": "*", "nodes": ["node_modules/preq"], "fixAvailable": false}, "qs": {"name": "qs", "severity": "high", "isDirect": false, "via": [{"source": 1096470, "name": "qs", "dependency": "qs", "title": "qs vulnerable to Prototype Pollution", "url": "https://github.com/advisories/GHSA-hrpp-h998-j3pp", "severity": "high", "cwe": ["CWE-1321"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=6.5.0 <6.5.3"}], "effects": [], "range": "6.5.0 - 6.5.2", "nodes": [""], "fixAvailable": true}, "redis": {"name": "redis", "severity": "high", "isDirect": false, "via": [{"source": 1089196, "name": "redis", "dependency": "redis", "title": "Node-Redis potential exponential regex in monitor mode", "url": "https://github.com/advisories/GHSA-35q2-47q7-3pc3", "severity": "high", "cwe": ["CWE-400"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=2.6.0 <3.1.1"}], "effects": [], "range": "2.6.0 - 3.1.0", "nodes": [""], "fixAvailable": true}, "request": {"name": "request", "severity": "moderate", "isDirect": false, "via": [{"source": 1096727, "name": "request", "dependency": "request", "title": "Server-Side Request Forgery in Request", "url": "https://github.com/advisories/GHSA-p8p7-x288-28g6", "severity": "moderate", "cwe": ["CWE-918"], "cvss": {"score": 6.1, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"}, "range": "<=2.88.2"}, "tough-cookie"], "effects": ["coveralls", "preq", "requestretry"], "range": "*", "nodes": ["node_modules/request"], "fixAvailable": false}, "requestretry": {"name": "requestretry", "severity": "high", "isDirect": false, "via": [{"source": 1090420, "name": "requestretry", "dependency": "requestretry", "title": "Cookie exposure in requestretry", "url": "https://github.com/advisories/GHSA-hjp8-2cm3-cc45", "severity": "high", "cwe": ["CWE-200"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"}, "range": "<7.0.0"}, "request"], "effects": ["preq"], "range": "*", "nodes": ["node_modules/requestretry"], "fixAvailable": false}, "semver": {"name": "semver", "severity": "moderate", "isDirect": false, "via": [{"source": 1096483, "name": "semver", "dependency": "semver", "title": "semver vulnerable to Regular Expression Denial of Service", "url": "https://github.com/advisories/GHSA-c2qf-rxjj-qqgw", "severity": "moderate", "cwe": ["CWE-1333"], "cvss": {"score": 5.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"}, "range": "<5.7.2"}, {"source": 1096484, "name": "semver", "dependency": "semver", "title": "semver vulnerable to Regular Expression Denial of Service", "url": "https://github.com/advisories/GHSA-c2qf-rxjj-qqgw", "severity": "moderate", "cwe": ["CWE-1333"], "cvss": {"score": 5.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"}, "range": ">=6.0.0 <6.3.1"}], "effects": [], "range": "<5.7.2 || >=6.0.0 <6.3.1", "nodes": ["", "", "", "", ""], "fixAvailable": true}, "swagger-ui-dist": {"name": "swagger-ui-dist", "severity": "moderate", "isDirect": false, "via": [{"source": 1088759, "name": "swagger-ui-dist", "dependency": "swagger-ui-dist", "title": "Spoofing attack in swagger-ui-dist", "url": "https://github.com/advisories/GHSA-6c9x-mj3g-h47x", "severity": "moderate", "cwe": ["CWE-1021"], "cvss": {"score": 6.1, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"}, "range": "<4.1.3"}, {"source": 1092160, "name": "swagger-ui-dist", "dependency": "swagger-ui-dist", "title": "Server side request forgery in SwaggerUI", "url": "https://github.com/advisories/GHSA-qrmm-w75w-3wpx", "severity": "moderate", "cwe": ["CWE-918"], "cvss": {"score": 0, "vectorString": null}, "range": "<4.1.3"}], "effects": ["hyperswitch"], "range": "<=4.1.2", "nodes": [""], "fixAvailable": {"name": "hyperswitch", "version": "0.10.5", "isSemVerMajor": true}}, "tar": {"name": "tar", "severity": "high", "isDirect": false, "via": [{"source": 1089684, "name": "tar", "dependency": "tar", "title": "Arbitrary File Creation/Overwrite due to insufficient absolute path sanitization", "url": "https://github.com/advisories/GHSA-3jfq-g458-7qm9", "severity": "high", "cwe": ["CWE-22"], "cvss": {"score": 8.2, "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"}, "range": ">=4.0.0 <4.4.14"}, {"source": 1095117, "name": "tar", "dependency": "tar", "title": "Arbitrary File Creation/Overwrite on Windows via insufficient relative path sanitization", "url": "https://github.com/advisories/GHSA-5955-9wpr-37jh", "severity": "high", "cwe": ["CWE-22"], "cvss": {"score": 8.2, "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"}, "range": "<4.4.18"}, {"source": 1096309, "name": "tar", "dependency": "tar", "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning", "url": "https://github.com/advisories/GHSA-r628-mhmh-qjhw", "severity": "high", "cwe": ["CWE-22", "CWE-23", "CWE-59"], "cvss": {"score": 8.2, "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"}, "range": ">=4.0.0 <4.4.15"}, {"source": 1096376, "name": "tar", "dependency": "tar", "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning using symbolic links", "url": "https://github.com/advisories/GHSA-9r2w-394v-53qc", "severity": "high", "cwe": ["CWE-22", "CWE-59"], "cvss": {"score": 8.2, "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"}, "range": ">=3.0.0 <4.4.16"}, {"source": 1096411, "name": "tar", "dependency": "tar", "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning using symbolic links", "url": "https://github.com/advisories/GHSA-qq89-hq3f-393p", "severity": "high", "cwe": ["CWE-22", "CWE-59"], "cvss": {"score": 8.2, "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"}, "range": ">=3.0.0 <4.4.18"}, {"source": 1096915, "name": "tar", "dependency": "tar", "title": "Denial of service while parsing a tar file due to lack of folders count validation", "url": "https://github.com/advisories/GHSA-f5x3-32g6-xq36", "severity": "moderate", "cwe": ["CWE-400"], "cvss": {"score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H"}, "range": "<6.2.1"}], "effects": [], "range": "<=6.2.0", "nodes": [""], "fixAvailable": true}, "tough-cookie": {"name": "tough-cookie", "severity": "moderate", "isDirect": false, "via": [{"source": 1096643, "name": "tough-cookie", "dependency": "tough-cookie", "title": "tough-cookie Prototype Pollution vulnerability", "url": "https://github.com/advisories/GHSA-72xf-g2v4-qvf3", "severity": "moderate", "cwe": ["CWE-1321"], "cvss": {"score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N"}, "range": "<4.1.3"}], "effects": ["request"], "range": "<4.1.3", "nodes": ["node_modules/tough-cookie"], "fixAvailable": false}, "underscore": {"name": "underscore", "severity": "critical", "isDirect": false, "via": [{"source": 1095097, "name": "underscore", "dependency": "underscore", "title": "Arbitrary Code Execution in underscore", "url": "https://github.com/advisories/GHSA-cf4h-3jhx-xvhq", "severity": "critical", "cwe": ["CWE-94"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": ">=1.3.2 <1.12.1"}], "effects": [], "range": "1.3.2 - 1.12.0", "nodes": [""], "fixAvailable": true}}, "metadata": {"vulnerabilities": {"info": 0, "low": 1, "moderate": 10, "high": 16, "critical": 5, "total": 32}, "dependencies": {"prod": 156, "dev": 445, "optional": 78, "peer": 1, "peerOptional": 0, "total": 677}}}}
$ /usr/bin/npm audit fix --only=dev
--- stderr ---
npm WARN invalid config only="dev" set in command line options
npm WARN invalid config Must be one of: null, prod, production
npm WARN audit fix semver@5.7.0 node_modules/gc-stats/node_modules/semver
npm WARN audit fix semver@5.7.0 is a bundled dependency of
npm WARN audit fix semver@5.7.0 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix semver@5.7.0 It cannot be fixed automatically.
npm WARN audit fix semver@5.7.0 Check for updates to the gc-stats package.
npm WARN audit fix minimatch@3.0.4 node_modules/gc-stats/node_modules/minimatch
npm WARN audit fix minimatch@3.0.4 is a bundled dependency of
npm WARN audit fix minimatch@3.0.4 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix minimatch@3.0.4 It cannot be fixed automatically.
npm WARN audit fix minimatch@3.0.4 Check for updates to the gc-stats package.
npm WARN audit fix debug@4.1.1 node_modules/gc-stats/node_modules/debug
npm WARN audit fix debug@4.1.1 is a bundled dependency of
npm WARN audit fix debug@4.1.1 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix debug@4.1.1 It cannot be fixed automatically.
npm WARN audit fix debug@4.1.1 Check for updates to the gc-stats package.
npm WARN audit fix ini@1.3.5 node_modules/gc-stats/node_modules/ini
npm WARN audit fix ini@1.3.5 is a bundled dependency of
npm WARN audit fix ini@1.3.5 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix ini@1.3.5 It cannot be fixed automatically.
npm WARN audit fix ini@1.3.5 Check for updates to the gc-stats package.
npm WARN audit fix minimist@1.2.0 node_modules/gc-stats/node_modules/rc/node_modules/minimist
npm WARN audit fix minimist@1.2.0 is a bundled dependency of
npm WARN audit fix minimist@1.2.0 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix minimist@1.2.0 It cannot be fixed automatically.
npm WARN audit fix minimist@1.2.0 Check for updates to the gc-stats package.
npm WARN audit fix minimist@0.0.8 node_modules/gc-stats/node_modules/minimist
npm WARN audit fix minimist@0.0.8 is a bundled dependency of
npm WARN audit fix minimist@0.0.8 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix minimist@0.0.8 It cannot be fixed automatically.
npm WARN audit fix minimist@0.0.8 Check for updates to the gc-stats package.
npm WARN audit fix tar@4.4.8 node_modules/gc-stats/node_modules/tar
npm WARN audit fix tar@4.4.8 is a bundled dependency of
npm WARN audit fix tar@4.4.8 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix tar@4.4.8 It cannot be fixed automatically.
npm WARN audit fix tar@4.4.8 Check for updates to the gc-stats package.
npm WARN audit fix mkdirp@0.5.1 node_modules/gc-stats/node_modules/mkdirp
npm WARN audit fix mkdirp@0.5.1 is a bundled dependency of
npm WARN audit fix mkdirp@0.5.1 gc-stats@1.4.0 at node_modules/gc-stats
npm WARN audit fix mkdirp@0.5.1 It cannot be fixed automatically.
npm WARN audit fix mkdirp@0.5.1 Check for updates to the gc-stats package.
npm WARN deprecated kad-fs@0.0.4: This package is no longer maintained.
npm WARN deprecated kad-memstore@0.0.1: This package is no longer maintained.
--- stdout ---

added 23 packages, removed 8 packages, changed 52 packages, and audited 677 packages in 2m

69 packages are looking for funding
  run `npm fund` for details

# npm audit report

debug  4.0.0 - 4.3.0
Regular Expression Denial of Service in debug - https://github.com/advisories/GHSA-gxpj-cx7g-858c
fix available via `npm audit fix`
node_modules/gc-stats/node_modules/debug

dicer  *
Severity: high
Crash in HeaderParser in dicer - https://github.com/advisories/GHSA-wm7h-9275-46v2
fix available via `npm audit fix --force`
Will install hyperswitch@0.10.5, which is a breaking change
node_modules/dicer
  busboy  <=0.3.1
  Depends on vulnerable versions of dicer
  node_modules/busboy
    hyperswitch  >=0.1.0
    Depends on vulnerable versions of busboy
    Depends on vulnerable versions of preq
    Depends on vulnerable versions of swagger-ui-dist
    node_modules/hyperswitch

ini  <1.3.6
Severity: high
ini before 1.3.6 vulnerable to Prototype Pollution via ini.parse - https://github.com/advisories/GHSA-qqgx-2p2h-9c37
fix available via `npm audit fix`
node_modules/gc-stats/node_modules/ini

minimatch  <3.0.5
Severity: high
minimatch ReDoS vulnerability - https://github.com/advisories/GHSA-f8q6-p94x-37v3
fix available via `npm audit fix --force`
Will install mocha@10.4.0, which is a breaking change
node_modules/gc-stats/node_modules/minimatch
node_modules/minimatch
  mocha  5.1.0 - 9.2.1
  Depends on vulnerable versions of minimatch
  Depends on vulnerable versions of nanoid
  node_modules/mocha

minimist  <=0.2.3 || 1.0.0 - 1.2.5
Severity: critical
Prototype Pollution in minimist - https://github.com/advisories/GHSA-vh95-rmgr-6w4m
Prototype Pollution in minimist - https://github.com/advisories/GHSA-vh95-rmgr-6w4m
Prototype Pollution in minimist - https://github.com/advisories/GHSA-xvch-5gv4-984h
Prototype Pollution in minimist - https://github.com/advisories/GHSA-xvch-5gv4-984h
fix available via `npm audit fix`
node_modules/gc-stats/node_modules/minimist
node_modules/gc-stats/node_modules/rc/node_modules/minimist
  mkdirp  0.4.1 - 0.5.1
  Depends on vulnerable versions of minimist
  node_modules/gc-stats/node_modules/mkdirp

ms  <2.0.0
Severity: moderate
Vercel ms Inefficient Regular Expression Complexity vulnerability - https://github.com/advisories/GHSA-w9mr-4mfr-499f
fix available via `npm audit fix`
node_modules/ms
  wikimedia-kad-fork  *
  Depends on vulnerable versions of ms
  node_modules/wikimedia-kad-fork
    limitation  >=0.2.3
    Depends on vulnerable versions of wikimedia-kad-fork
    node_modules/limitation

nanoid  3.0.0 - 3.1.30
Severity: moderate
Exposure of Sensitive Information to an Unauthorized Actor in nanoid - https://github.com/advisories/GHSA-qrpm-p2h7-hrv2
fix available via `npm audit fix --force`
Will install mocha@10.4.0, which is a breaking change
node_modules/nanoid

request  *
Severity: moderate
Server-Side Request Forgery in Request - https://github.com/advisories/GHSA-p8p7-x288-28g6
Depends on vulnerable versions of tough-cookie
No fix available
node_modules/request
  coveralls  *
  Depends on vulnerable versions of request
  node_modules/coveralls
  preq  *
  Depends on vulnerable versions of request
  Depends on vulnerable versions of requestretry
  node_modules/preq
  requestretry  *
  Depends on vulnerable versions of request
  node_modules/requestretry


semver  <5.7.2
Severity: moderate
semver vulnerable to Regular Expression Denial of Service - https://github.com/advisories/GHSA-c2qf-rxjj-qqgw
fix available via `npm audit fix`
node_modules/gc-stats/node_modules/semver

swagger-ui-dist  <=4.1.2
Severity: moderate
Spoofing attack in swagger-ui-dist - https://github.com/advisories/GHSA-6c9x-mj3g-h47x
Server side request forgery in SwaggerUI - https://github.com/advisories/GHSA-qrmm-w75w-3wpx
fix available via `npm audit fix --force`
Will install hyperswitch@0.10.5, which is a breaking change
node_modules/swagger-ui-dist

tar  <=6.2.0
Severity: high
Arbitrary File Creation/Overwrite due to insufficient absolute path sanitization - https://github.com/advisories/GHSA-3jfq-g458-7qm9
Arbitrary File Creation/Overwrite on Windows via insufficient relative path sanitization - https://github.com/advisories/GHSA-5955-9wpr-37jh
Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning - https://github.com/advisories/GHSA-r628-mhmh-qjhw
Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning using symbolic links - https://github.com/advisories/GHSA-9r2w-394v-53qc
Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning using symbolic links - https://github.com/advisories/GHSA-qq89-hq3f-393p
Denial of service while parsing a tar file due to lack of folders count validation - https://github.com/advisories/GHSA-f5x3-32g6-xq36
fix available via `npm audit fix`
node_modules/gc-stats/node_modules/tar

tough-cookie  <4.1.3
Severity: moderate
tough-cookie Prototype Pollution vulnerability - https://github.com/advisories/GHSA-72xf-g2v4-qvf3
No fix available
node_modules/tough-cookie

21 vulnerabilities (1 low, 10 moderate, 9 high, 1 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues possible (including breaking changes), run:
  npm audit fix --force

Some issues need review, and may require choosing
a different dependency.

--- end ---
$ package-lock-lint package-lock.json
--- stdout ---
Checking package-lock.json

--- end ---
Verifying that tests still pass
$ /usr/bin/npm ci
--- stderr ---
npm WARN deprecated kad-fs@0.0.4: This package is no longer maintained.
npm WARN deprecated @hapi/bourne@1.3.2: This version has been deprecated and is no longer supported or maintained
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated kad-memstore@0.0.1: This package is no longer maintained.
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated json-schema-ref-parser@7.1.4: Please switch to @apidevtools/json-schema-ref-parser
--- stdout ---

added 610 packages, and audited 677 packages in 2m

69 packages are looking for funding
  run `npm fund` for details

21 vulnerabilities (1 low, 10 moderate, 9 high, 1 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues possible (including breaking changes), run:
  npm audit fix --force

Some issues need review, and may require choosing
a different dependency.

Run `npm audit` for details.

--- end ---
$ /usr/bin/npm test
--- stdout ---

> change-propagation@0.12.0 test
> export MOCK_SERVICES=true && npm run lint && mocha --recursive


> change-propagation@0.12.0 lint
> eslint --cache --ext .js .


/src/repo/sys/deduplicator.js
  9:28  warning  ES2023 'Array.prototype.with' method is forbidden  es-x/no-array-prototype-with

/src/repo/sys/rate_limiter.js
  9:27  warning  ES2023 'Array.prototype.with' method is forbidden  es-x/no-array-prototype-with

✖ 2 problems (0 errors, 2 warnings)



  JobQueue rules
    ✓ Should propagate updateBetaFeaturesUserCounts job (503ms)
    ✓ Should propagate cdnPurge job (3505ms)
    ✓ Should support partitioned refreshLinks (502ms)
    ✓ Should deduplicate based on ID (2003ms)
    ✓ Should deduplicate based on SHA1 (4003ms)
    ✓ Should deduplicate based on SHA1 and root job combination (4005ms)
    ✓ Should deduplicate base on root job (4004ms)
    ✓ Should support delayed jobs with re-enqueue (13012ms)

  Rule
    ✓ topic required
    ✓ no-op rule
    ✓ simple rule - one request
    ✓ simple rule - multiple requests
    Matching
      ✓ all
      ✓ simple value match
      ✓ simple value mismatch
      ✓ regex match
      ✓ regex match with undefined
      ✓ regex mismatch
      ✓ array match
      ✓ malformed match
      ✓ match_not
      ✓ match_not array
      ✓ matches match and match_not
      ✓ matches match but not match_not
      ✓ matches match_not but not match
      ✓ matches match but is canary event and should_discard_canary_events is true
      ✓ matches match and is canary event and should_discard_canary_events is false
      ✓ expansion
      ✓ expansion with named groups
      ✓ checks for named and unnamed groups mixing

  Sampler
    ✓ Should accept the correct number of values (75ms)

  Basic rule management
    ✓ Should call simple executor (502ms)
    ✓ Should retry simple executor (503ms)
    ✓ Should retry simple executor no more than limit (2004ms)
    ✓ Should emit valid retry message (2681ms)
    ✓ Should not retry if retry_on not matched (2002ms)
    ✓ Should not follow redirects (2002ms)
    ✓ Should not crash with unparsable JSON (502ms)
    ✓ Should support producing to topics on exec (502ms)
    ✓ Should emit valid messages to error topic (156ms)
    ✓ Sampling should only propagate a stable subset (2002ms)
    ✓ Should support array topics (502ms)
    ✓ Should support exclude_topics stanza (2002ms)

  update rules
    ✓ Should update summary endpoint (503ms)
    ✓ Should update summary endpoint, transcludes topic (501ms)
    ✓ Should update summary endpoint on page images change (503ms)
    ✓ Should not update summary for a blacklisted title (2002ms)
    ✓ Should update definition endpoint (502ms)
    ✓ Should not react to revision change event from restbase for definition endpoint (2001ms)
    ✓ Should update mobile apps endpoint (502ms)
    ✓ Should not update definition endpoint for non-main namespace (2002ms)
    ✓ Should update RESTBase on resource_change from MW (502ms)
    ✓ Should update RESTBase on revision create (502ms)
    ✓ Should not update RESTBase on revision create for a blacklisted title (2002ms)
    ✓ Should not update RESTBase on revision create for wikidata (2002ms)
    ✓ Should update RESTBase on page delete (502ms)
    ✓ Should update RESTBase on page undelete (503ms)
    ✓ Should update RESTBase on page move (505ms)
    ✓ Should update RESTBase on revision visibility change (502ms)
    ✓ Should update ORES on revision-create (670ms)
    ✓ Should update ORES on revision-create, error (502ms)
    ✓ Should update RESTBase summary and mobile-sections on wikidata description change (3004ms)
    ✓ Should update RESTBase summary and mobile-sections on wikidata description revert (3002ms)
    ✓ Should update RESTBase summary and mobile-sections on wikidata undelete (3002ms)
    ✓ Should not ask Wikidata for info for non-main namespace titles (5003ms)
    ✓ Should not crash if wikidata description can not be found (3002ms)
    ✓ Should rerender image usages on file update (507ms)
    ✓ Should rerender transclusions on page update (508ms)
    ✓ Should process backlinks, on create (510ms)
    ✓ Should process backlinks, on delete (503ms)
    ✓ Should process backlinks, on undelete (504ms)
    ✓ Should purge caches on resource_change coming from RESTBase
    ✓ Should purge caches on resource_change coming from Tilerator (99ms)


  73 passing (1m)


--- end ---
{"1096886": {"source": 1096886, "name": "@babel/traverse", "dependency": "@babel/traverse", "title": "Babel vulnerable to arbitrary code execution when compiling specifically crafted malicious code", "url": "https://github.com/advisories/GHSA-67hx-6x53-jw92", "severity": "critical", "cwe": ["CWE-184", "CWE-697"], "cvss": {"score": 9.4, "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H"}, "range": "<7.23.2"}}
Upgrading n:@babel/traverse from 7.12.12 -> 7.24.5
{"1094090": {"source": 1094090, "name": "ansi-regex", "dependency": "ansi-regex", "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex", "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw", "severity": "high", "cwe": ["CWE-697", "CWE-1333"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=3.0.0 <3.0.1"}, "1094091": {"source": 1094091, "name": "ansi-regex", "dependency": "ansi-regex", "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex", "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw", "severity": "high", "cwe": ["CWE-697", "CWE-1333"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=4.0.0 <4.1.1"}, "1094092": {"source": 1094092, "name": "ansi-regex", "dependency": "ansi-regex", "title": "Inefficient Regular Expression Complexity in chalk/ansi-regex", "url": "https://github.com/advisories/GHSA-93q8-gq69-wqmw", "severity": "high", "cwe": ["CWE-697", "CWE-1333"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=5.0.0 <5.0.1"}}
Upgrading n:ansi-regex from 2.1.1, 3.0.0, 4.1.0, 5.0.0, 5.0.1 -> 2.1.1, 3.0.1, 4.1.1, 5.0.1
{"1093224": {"source": 1093224, "name": "ini", "dependency": "ini", "title": "ini before 1.3.6 vulnerable to Prototype Pollution via ini.parse", "url": "https://github.com/advisories/GHSA-qqgx-2p2h-9c37", "severity": "high", "cwe": ["CWE-1321"], "cvss": {"score": 7.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L"}, "range": "<1.3.6"}}
{"1095057": {"source": 1095057, "name": "json-schema", "dependency": "json-schema", "title": "json-schema is vulnerable to Prototype Pollution", "url": "https://github.com/advisories/GHSA-896r-f27r-55mw", "severity": "critical", "cwe": ["CWE-915", "CWE-1321"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": "<0.4.0"}}
Upgrading n:json-schema from 0.2.3 -> 0.4.0
{"1096544": {"source": 1096544, "name": "json5", "dependency": "json5", "title": "Prototype Pollution in JSON5 via Parse Method", "url": "https://github.com/advisories/GHSA-9c47-m6qq-7p4h", "severity": "high", "cwe": ["CWE-1321"], "cvss": {"score": 7.1, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:L/A:H"}, "range": ">=2.0.0 <2.2.2"}}
Upgrading n:json5 from 2.1.3 -> 2.2.3
{"1095057": {"source": 1095057, "name": "json-schema", "dependency": "json-schema", "title": "json-schema is vulnerable to Prototype Pollution", "url": "https://github.com/advisories/GHSA-896r-f27r-55mw", "severity": "critical", "cwe": ["CWE-915", "CWE-1321"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": "<0.4.0"}}
Upgrading n:jsprim from 1.4.1 -> 1.4.2
{"1096479": {"source": 1096479, "name": "merge", "dependency": "merge", "title": "Prototype Pollution in merge", "url": "https://github.com/advisories/GHSA-7wpw-2hjm-89gp", "severity": "high", "cwe": ["CWE-915"], "cvss": {"score": 7.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L"}, "range": "<2.1.1"}, "1094419": {"source": 1094419, "name": "ms", "dependency": "ms", "title": "Vercel ms Inefficient Regular Expression Complexity vulnerability", "url": "https://github.com/advisories/GHSA-w9mr-4mfr-499f", "severity": "moderate", "cwe": ["CWE-1333"], "cvss": {"score": 5.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"}, "range": "<2.0.0"}}
Upgrading n:kad from 1.3.6 -> 
{"1096479": {"source": 1096479, "name": "merge", "dependency": "merge", "title": "Prototype Pollution in merge", "url": "https://github.com/advisories/GHSA-7wpw-2hjm-89gp", "severity": "high", "cwe": ["CWE-915"], "cvss": {"score": 7.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L"}, "range": "<2.1.1"}, "1094419": {"source": 1094419, "name": "ms", "dependency": "ms", "title": "Vercel ms Inefficient Regular Expression Complexity vulnerability", "url": "https://github.com/advisories/GHSA-w9mr-4mfr-499f", "severity": "moderate", "cwe": ["CWE-1333"], "cvss": {"score": 5.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"}, "range": "<2.0.0"}}
Upgrading n:limitation from 0.2.1 -> 0.2.3
{"1096479": {"source": 1096479, "name": "merge", "dependency": "merge", "title": "Prototype Pollution in merge", "url": "https://github.com/advisories/GHSA-7wpw-2hjm-89gp", "severity": "high", "cwe": ["CWE-915"], "cvss": {"score": 7.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:L"}, "range": "<2.1.1"}}
Upgrading n:merge from 1.2.1 -> 
{"1096465": {"source": 1096465, "name": "minimist", "dependency": "minimist", "title": "Prototype Pollution in minimist", "url": "https://github.com/advisories/GHSA-vh95-rmgr-6w4m", "severity": "moderate", "cwe": ["CWE-1321"], "cvss": {"score": 5.6, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"}, "range": ">=1.0.0 <1.2.3"}, "1096466": {"source": 1096466, "name": "minimist", "dependency": "minimist", "title": "Prototype Pollution in minimist", "url": "https://github.com/advisories/GHSA-vh95-rmgr-6w4m", "severity": "moderate", "cwe": ["CWE-1321"], "cvss": {"score": 5.6, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"}, "range": "<0.2.1"}, "1096548": {"source": 1096548, "name": "minimist", "dependency": "minimist", "title": "Prototype Pollution in minimist", "url": "https://github.com/advisories/GHSA-xvch-5gv4-984h", "severity": "critical", "cwe": ["CWE-1321"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": "<0.2.4"}, "1096549": {"source": 1096549, "name": "minimist", "dependency": "minimist", "title": "Prototype Pollution in minimist", "url": "https://github.com/advisories/GHSA-xvch-5gv4-984h", "severity": "critical", "cwe": ["CWE-1321"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": ">=1.0.0 <1.2.6"}}
Upgrading n:minimist from 0.0.8, 1.2.0, 1.2.5 -> 0.0.8, 1.2.0, 1.2.8
{"1096465": {"source": 1096465, "name": "minimist", "dependency": "minimist", "title": "Prototype Pollution in minimist", "url": "https://github.com/advisories/GHSA-vh95-rmgr-6w4m", "severity": "moderate", "cwe": ["CWE-1321"], "cvss": {"score": 5.6, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"}, "range": ">=1.0.0 <1.2.3"}, "1096466": {"source": 1096466, "name": "minimist", "dependency": "minimist", "title": "Prototype Pollution in minimist", "url": "https://github.com/advisories/GHSA-vh95-rmgr-6w4m", "severity": "moderate", "cwe": ["CWE-1321"], "cvss": {"score": 5.6, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:L"}, "range": "<0.2.1"}, "1096548": {"source": 1096548, "name": "minimist", "dependency": "minimist", "title": "Prototype Pollution in minimist", "url": "https://github.com/advisories/GHSA-xvch-5gv4-984h", "severity": "critical", "cwe": ["CWE-1321"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": "<0.2.4"}, "1096549": {"source": 1096549, "name": "minimist", "dependency": "minimist", "title": "Prototype Pollution in minimist", "url": "https://github.com/advisories/GHSA-xvch-5gv4-984h", "severity": "critical", "cwe": ["CWE-1321"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": ">=1.0.0 <1.2.6"}}
{"1095072": {"source": 1095072, "name": "moment", "dependency": "moment", "title": "Moment.js vulnerable to Inefficient Regular Expression Complexity", "url": "https://github.com/advisories/GHSA-wc69-rhjr-hc9g", "severity": "high", "cwe": ["CWE-400", "CWE-1333"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=2.18.0 <2.29.4"}, "1095083": {"source": 1095083, "name": "moment", "dependency": "moment", "title": "Path Traversal: 'dir/../../filename' in moment.locale", "url": "https://github.com/advisories/GHSA-8hfj-j24r-96c4", "severity": "high", "cwe": ["CWE-22", "CWE-27"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N"}, "range": "<2.29.2"}}
Upgrading n:moment from 2.29.1 -> 2.30.1
{"1094419": {"source": 1094419, "name": "ms", "dependency": "ms", "title": "Vercel ms Inefficient Regular Expression Complexity vulnerability", "url": "https://github.com/advisories/GHSA-w9mr-4mfr-499f", "severity": "moderate", "cwe": ["CWE-1333"], "cvss": {"score": 5.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"}, "range": "<2.0.0"}}
Upgrading n:ms from 0.7.3, 2.1.1, 2.1.2 -> 0.7.3, 2.1.1, 2.1.2, 2.1.3
{"1089202": {"source": 1089202, "name": "msgpack5", "dependency": "msgpack5", "title": "Prototype poisoning", "url": "https://github.com/advisories/GHSA-gmjw-49p4-pcfm", "severity": "moderate", "cwe": ["CWE-915", "CWE-1321"], "cvss": {"score": 6.7, "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:U/C:L/I:H/A:H"}, "range": "<3.6.1"}}
Upgrading n:msgpack5 from 3.6.0 -> 3.6.1
{"1096470": {"source": 1096470, "name": "qs", "dependency": "qs", "title": "qs vulnerable to Prototype Pollution", "url": "https://github.com/advisories/GHSA-hrpp-h998-j3pp", "severity": "high", "cwe": ["CWE-1321"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=6.5.0 <6.5.3"}}
Upgrading n:qs from 6.5.2 -> 6.5.3
{"1089196": {"source": 1089196, "name": "redis", "dependency": "redis", "title": "Node-Redis potential exponential regex in monitor mode", "url": "https://github.com/advisories/GHSA-35q2-47q7-3pc3", "severity": "high", "cwe": ["CWE-400"], "cvss": {"score": 7.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"}, "range": ">=2.6.0 <3.1.1"}}
Upgrading n:redis from 3.0.2 -> 3.1.2
{"1096483": {"source": 1096483, "name": "semver", "dependency": "semver", "title": "semver vulnerable to Regular Expression Denial of Service", "url": "https://github.com/advisories/GHSA-c2qf-rxjj-qqgw", "severity": "moderate", "cwe": ["CWE-1333"], "cvss": {"score": 5.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"}, "range": "<5.7.2"}, "1096484": {"source": 1096484, "name": "semver", "dependency": "semver", "title": "semver vulnerable to Regular Expression Denial of Service", "url": "https://github.com/advisories/GHSA-c2qf-rxjj-qqgw", "severity": "moderate", "cwe": ["CWE-1333"], "cvss": {"score": 5.3, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"}, "range": ">=6.0.0 <6.3.1"}}
Upgrading n:semver from 5.7.0, 5.7.1, 5.7.2, 6.3.0, 7.6.0 -> 5.7.0, 5.7.2, 6.3.1, 7.6.0
{"1089684": {"source": 1089684, "name": "tar", "dependency": "tar", "title": "Arbitrary File Creation/Overwrite due to insufficient absolute path sanitization", "url": "https://github.com/advisories/GHSA-3jfq-g458-7qm9", "severity": "high", "cwe": ["CWE-22"], "cvss": {"score": 8.2, "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"}, "range": ">=4.0.0 <4.4.14"}, "1095117": {"source": 1095117, "name": "tar", "dependency": "tar", "title": "Arbitrary File Creation/Overwrite on Windows via insufficient relative path sanitization", "url": "https://github.com/advisories/GHSA-5955-9wpr-37jh", "severity": "high", "cwe": ["CWE-22"], "cvss": {"score": 8.2, "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"}, "range": "<4.4.18"}, "1096309": {"source": 1096309, "name": "tar", "dependency": "tar", "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning", "url": "https://github.com/advisories/GHSA-r628-mhmh-qjhw", "severity": "high", "cwe": ["CWE-22", "CWE-23", "CWE-59"], "cvss": {"score": 8.2, "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"}, "range": ">=4.0.0 <4.4.15"}, "1096376": {"source": 1096376, "name": "tar", "dependency": "tar", "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning using symbolic links", "url": "https://github.com/advisories/GHSA-9r2w-394v-53qc", "severity": "high", "cwe": ["CWE-22", "CWE-59"], "cvss": {"score": 8.2, "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"}, "range": ">=3.0.0 <4.4.16"}, "1096411": {"source": 1096411, "name": "tar", "dependency": "tar", "title": "Arbitrary File Creation/Overwrite via insufficient symlink protection due to directory cache poisoning using symbolic links", "url": "https://github.com/advisories/GHSA-qq89-hq3f-393p", "severity": "high", "cwe": ["CWE-22", "CWE-59"], "cvss": {"score": 8.2, "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N"}, "range": ">=3.0.0 <4.4.18"}, "1096915": {"source": 1096915, "name": "tar", "dependency": "tar", "title": "Denial of service while parsing a tar file due to lack of folders count validation", "url": "https://github.com/advisories/GHSA-f5x3-32g6-xq36", "severity": "moderate", "cwe": ["CWE-400"], "cvss": {"score": 6.5, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H"}, "range": "<6.2.1"}}
{"1095097": {"source": 1095097, "name": "underscore", "dependency": "underscore", "title": "Arbitrary Code Execution in underscore", "url": "https://github.com/advisories/GHSA-cf4h-3jhx-xvhq", "severity": "critical", "cwe": ["CWE-94"], "cvss": {"score": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"}, "range": ">=1.3.2 <1.12.1"}}
Upgrading n:underscore from 1.12.0 -> 1.13.6
$ package-lock-lint package-lock.json
--- stdout ---
Checking package-lock.json

--- end ---
build: Updating npm dependencies

* eslint-config-wikimedia: 0.25.1 → 0.27.0
  The following rules are failing and were disabled:
  * es-x/no-array-prototype-with


* @babel/traverse: 7.12.12 → 7.24.5
  * https://github.com/advisories/GHSA-67hx-6x53-jw92
* ansi-regex: 2.1.1, 3.0.0, 4.1.0, 5.0.0, 5.0.1 → 2.1.1, 3.0.1, 4.1.1, 5.0.1
  * https://github.com/advisories/GHSA-93q8-gq69-wqmw
* json-schema: 0.2.3 → 0.4.0
  * https://github.com/advisories/GHSA-896r-f27r-55mw
* json5: 2.1.3 → 2.2.3
  * https://github.com/advisories/GHSA-9c47-m6qq-7p4h
* jsprim: 1.4.1 → 1.4.2
  * https://github.com/advisories/GHSA-896r-f27r-55mw
* kad: 1.3.6 → 
  * https://github.com/advisories/GHSA-7wpw-2hjm-89gp
  * https://github.com/advisories/GHSA-w9mr-4mfr-499f
* limitation: 0.2.1 → 0.2.3
  * https://github.com/advisories/GHSA-7wpw-2hjm-89gp
  * https://github.com/advisories/GHSA-w9mr-4mfr-499f
* merge: 1.2.1 → 
  * https://github.com/advisories/GHSA-7wpw-2hjm-89gp
* minimist: 0.0.8, 1.2.0, 1.2.5 → 0.0.8, 1.2.0, 1.2.8
  * https://github.com/advisories/GHSA-vh95-rmgr-6w4m
  * https://github.com/advisories/GHSA-xvch-5gv4-984h
* moment: 2.29.1 → 2.30.1
  * https://github.com/advisories/GHSA-8hfj-j24r-96c4
  * https://github.com/advisories/GHSA-wc69-rhjr-hc9g
* ms: 0.7.3, 2.1.1, 2.1.2 → 0.7.3, 2.1.1, 2.1.2, 2.1.3
  * https://github.com/advisories/GHSA-w9mr-4mfr-499f
* msgpack5: 3.6.0 → 3.6.1
  * https://github.com/advisories/GHSA-gmjw-49p4-pcfm
* qs: 6.5.2 → 6.5.3
  * https://github.com/advisories/GHSA-hrpp-h998-j3pp
* redis: 3.0.2 → 3.1.2
  * https://github.com/advisories/GHSA-35q2-47q7-3pc3
* semver: 5.7.0, 5.7.1, 5.7.2, 6.3.0, 7.6.0 → 5.7.0, 5.7.2, 6.3.1, 7.6.0
  * https://github.com/advisories/GHSA-c2qf-rxjj-qqgw
* underscore: 1.12.0 → 1.13.6
  * https://github.com/advisories/GHSA-cf4h-3jhx-xvhq

$ git add .
--- stdout ---

--- end ---
$ git commit -F /tmp/tmpn58_y8hi
--- stdout ---
[master 905aabe] build: Updating npm dependencies
 27 files changed, 1501 insertions(+), 974 deletions(-)

--- end ---
$ git format-patch HEAD~1 --stdout
--- stdout ---
From 905aabe4a4c47dd8d17c48ae339b0a51d7e4f18e Mon Sep 17 00:00:00 2001
From: libraryupgrader <tools.libraryupgrader@tools.wmflabs.org>
Date: Mon, 29 Apr 2024 19:24:31 +0000
Subject: [PATCH] build: Updating npm dependencies
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* eslint-config-wikimedia: 0.25.1 → 0.27.0
  The following rules are failing and were disabled:
  * es-x/no-array-prototype-with

* @babel/traverse: 7.12.12 → 7.24.5
  * https://github.com/advisories/GHSA-67hx-6x53-jw92
* ansi-regex: 2.1.1, 3.0.0, 4.1.0, 5.0.0, 5.0.1 → 2.1.1, 3.0.1, 4.1.1, 5.0.1
  * https://github.com/advisories/GHSA-93q8-gq69-wqmw
* json-schema: 0.2.3 → 0.4.0
  * https://github.com/advisories/GHSA-896r-f27r-55mw
* json5: 2.1.3 → 2.2.3
  * https://github.com/advisories/GHSA-9c47-m6qq-7p4h
* jsprim: 1.4.1 → 1.4.2
  * https://github.com/advisories/GHSA-896r-f27r-55mw
* kad: 1.3.6 →
  * https://github.com/advisories/GHSA-7wpw-2hjm-89gp
  * https://github.com/advisories/GHSA-w9mr-4mfr-499f
* limitation: 0.2.1 → 0.2.3
  * https://github.com/advisories/GHSA-7wpw-2hjm-89gp
  * https://github.com/advisories/GHSA-w9mr-4mfr-499f
* merge: 1.2.1 →
  * https://github.com/advisories/GHSA-7wpw-2hjm-89gp
* minimist: 0.0.8, 1.2.0, 1.2.5 → 0.0.8, 1.2.0, 1.2.8
  * https://github.com/advisories/GHSA-vh95-rmgr-6w4m
  * https://github.com/advisories/GHSA-xvch-5gv4-984h
* moment: 2.29.1 → 2.30.1
  * https://github.com/advisories/GHSA-8hfj-j24r-96c4
  * https://github.com/advisories/GHSA-wc69-rhjr-hc9g
* ms: 0.7.3, 2.1.1, 2.1.2 → 0.7.3, 2.1.1, 2.1.2, 2.1.3
  * https://github.com/advisories/GHSA-w9mr-4mfr-499f
* msgpack5: 3.6.0 → 3.6.1
  * https://github.com/advisories/GHSA-gmjw-49p4-pcfm
* qs: 6.5.2 → 6.5.3
  * https://github.com/advisories/GHSA-hrpp-h998-j3pp
* redis: 3.0.2 → 3.1.2
  * https://github.com/advisories/GHSA-35q2-47q7-3pc3
* semver: 5.7.0, 5.7.1, 5.7.2, 6.3.0, 7.6.0 → 5.7.0, 5.7.2, 6.3.1, 7.6.0
  * https://github.com/advisories/GHSA-c2qf-rxjj-qqgw
* underscore: 1.12.0 → 1.13.6
  * https://github.com/advisories/GHSA-cf4h-3jhx-xvhq

Change-Id: Iebb4320518a1e7b9fc0197b6f64e553f243a9742
---
 .eslintrc.json                   |    3 +-
 .travis.yml                      |    4 +-
 config.example.wikimedia.yaml    |  224 ++--
 config.example.yaml              |    2 +-
 config.jobqueue.wikimedia.yaml   |   46 +-
 config.test.yaml                 |   54 +-
 lib/base_executor.js             |   32 +-
 lib/kafka_factory.js             |    6 +-
 lib/retry_executor.js            |    4 +-
 lib/rule.js                      |   60 +-
 lib/rule_executor.js             |    8 +-
 lib/utils.js                     |   10 +-
 package-lock.json                | 1837 +++++++++++++++++++-----------
 package.json                     |    2 +-
 sys/deduplicator.js              |   16 +-
 sys/dep_updates.js               |    4 +-
 sys/kafka.js                     |    4 +-
 sys/ores_updates.js              |    4 +-
 sys/partitioner.js               |    2 +-
 sys/purge.js                     |    2 +-
 sys/rate_limiter.js              |   12 +-
 test/feature/job_rules.js        |   10 +-
 test/feature/static_rules.js     |   22 +-
 test/feature/update_rules.js     |   88 +-
 test/utils/changeProp.js         |    2 +-
 test/utils/common.js             |    8 +-
 test/utils/mock_kafka_factory.js |    9 +-
 27 files changed, 1501 insertions(+), 974 deletions(-)

diff --git a/.eslintrc.json b/.eslintrc.json
index 78d1a0d..86f22c4 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -33,6 +33,7 @@
 		"arrow-parens": "off",
 		"no-multi-spaces": "off",
 		"jsdoc/no-undefined-types": "off",
-		"no-shadow": "warn"
+		"no-shadow": "warn",
+		"es-x/no-array-prototype-with": "warn"
 	}
 }
diff --git a/.travis.yml b/.travis.yml
index 74da3eb..7b3f6e3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,8 +19,8 @@ addons:
       - openjdk-8-jre-headless
 
 before_script:
-- export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
-- npm run install-kafka
+  - export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
+  - npm run install-kafka
 
 script: npm test && npm run start-kafka && npm run coverage && (npm run coveralls || exit 0)
 
diff --git a/config.example.wikimedia.yaml b/config.example.wikimedia.yaml
index 5b2b015..444112d 100644
--- a/config.example.wikimedia.yaml
+++ b/config.example.wikimedia.yaml
@@ -14,8 +14,8 @@ spec: &spec
         - path: sys/ores_updates.js
           options:
             ores_precache_uris:
-              - 'https://ores.wikimedia.org/v3/precache'
-            event_service_uri: 'https://eventgate.stubfortests.org/v1/events'
+              - "https://ores.wikimedia.org/v3/precache"
+            event_service_uri: "https://eventgate.stubfortests.org/v1/events"
     /sys/limit:
       x-modules:
         - path: sys/rate_limiter.js
@@ -52,11 +52,11 @@ spec: &spec
           options:
             templates:
               mw_api:
-                  uri: 'https://{{message.meta.domain}}/w/api.php'
-                  headers:
-                    host: '{{message.meta.domain}}'
-                  body:
-                    formatversion: 2
+                uri: "https://{{message.meta.domain}}/w/api.php"
+                headers:
+                  host: "{{message.meta.domain}}"
+                body:
+                  formatversion: 2
     /sys/queue:
       x-modules:
         - path: sys/kafka.js
@@ -76,22 +76,22 @@ spec: &spec
               compression.codec: snappy
             concurrency: 250
             # Redis-mock does not support evalsha that rate limiting depend on.
-            disable_ratelimit: '{env(MOCK_SERVICES)}'
+            disable_ratelimit: "{env(MOCK_SERVICES)}"
             blacklist:
               en.wikipedia.org:
-                - 'User:Nolelover'
+                - "User:Nolelover"
                 - '/User:Cyberbot_I\//'
             templates:
 
               summary_definition_rerender: &summary_definition_rerender_spec
-                topic: 'resource_change'
+                topic: resource_change
                 retry_limit: 2
                 retry_delay: 500
                 retry_on:
                   status:
-                    - '5xx'
+                    - 5xx
                 limiters:
-                  blacklist: 'summary:{message.meta.uri}'
+                  blacklist: "summary:{message.meta.uri}"
                 cases: # Non wiktionary domains - rerender summary
                   - match:
                       meta:
@@ -100,13 +100,13 @@ spec: &spec
                         - restbase
                     match_not:
                       - meta:
-                          domain: '/wiktionary.org$/'
+                          domain: /wiktionary.org$/
                       - meta:
                           domain: /\.wikidata\.org$/
                     exec:
                       method: get
                       # Don't encode title since it should be already encoded
-                      uri: '{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}'
+                      uri: "{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}"
                       query:
                         redirect: false
                       headers:
@@ -122,7 +122,7 @@ spec: &spec
                     exec:
                       method: get
                       # Don't encode title since it should be already encoded
-                      uri: '{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/definition/{{match.meta.uri.title}}'
+                      uri: "{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/definition/{{match.meta.uri.title}}"
                       query:
                         redirect: false
                       headers:
@@ -130,17 +130,17 @@ spec: &spec
 
               summary_definition_rerender_transcludes: &summary_definition_rerender_transcludes_spec
                 <<: *summary_definition_rerender_spec
-                topic: 'change-prop.transcludes.resource-change'
+                topic: change-prop.transcludes.resource-change
 
               mobile_rerender: &mobile_rerender_spec
-                topic: 'resource_change'
+                topic: resource_change
                 retry_limit: 2
                 retry_delay: 500
                 retry_on:
                   status:
-                    - '5xx'
+                    - 5xx
                 limiters:
-                  blacklist: 'mobile:{message.meta.uri}'
+                  blacklist: "mobile:{message.meta.uri}"
                 match:
                   meta:
                     uri: '/^(?<proto>https?):\/\/[^\/]+\/api\/rest_v1\/page\/html\/(?<title>[^/]+)$/'
@@ -149,24 +149,24 @@ spec: &spec
                     - restbase
                 exec:
                   - method: get
-                    uri: '{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{{match.meta.uri.title}}'
+                    uri: "{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{{match.meta.uri.title}}"
                     query:
                       redirect: false
                     headers:
                       cache-control: no-cache
                     # Until we start storing and actively rerendering PCS endpoints we still need to purge it from Varnish
                   - method: post
-                    uri: '/sys/purge/'
+                    uri: /sys/purge/
                     body:
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/media-list/{{match.meta.uri.title}}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/media-list/{{match.meta.uri.title}}"
 
               mobile_rerender_transcludes: &mobile_rerender_transcludes_spec
                 <<: *mobile_rerender_spec
-                topic: 'change-prop.transcludes.resource-change'
+                topic: change-prop.transcludes.resource-change
 
               purge_varnish: &purge_varnish_spec
-                topic: 'resource_change'
+                topic: resource_change
                 match:
                   meta:
                     uri: '/^https?:\/\/[^\/]+\/api\/rest_v1\/(?<title>.+)$/'
@@ -174,20 +174,20 @@ spec: &spec
                     - restbase
                 exec:
                   method: post
-                  uri: '/sys/purge/'
+                  uri: /sys/purge/
                   body:
                     - meta:
-                        uri: '//{{message.meta.domain}}/api/rest_v1/{{match.meta.uri.title}}'
+                        uri: "//{{message.meta.domain}}/api/rest_v1/{{match.meta.uri.title}}"
 
               purge_varnish_transcludes: &purge_varnish_transcludes_spec
                 <<: *purge_varnish_spec
-                topic: 'change-prop.transcludes.resource-change'
+                topic: change-prop.transcludes.resource-change
 
               # RESTBase update jobs
               mw_purge:
                 topic: resource_change
                 limiters:
-                  blacklist: 'html:{message.meta.uri}'
+                  blacklist: "html:{message.meta.uri}"
                 cases:
                   - match:
                       meta:
@@ -199,22 +199,22 @@ spec: &spec
                       - method: get
                         # This even comes directly from MediaWiki, so title is encoded in MW-specific way.
                         # Re-encode the title in standard `encodeURIComponent` encoding.
-                        uri: '{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}'
+                        uri: "{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
-                          if-unmodified-since: '{{date(message.meta.dt)}}'
+                          if-unmodified-since: "{{date(message.meta.dt)}}"
                         query:
                           redirect: false
                         # The HTML might not change but sometimes editors use a purge to drop incorrectly rendered summary/MCS
                         # content, so let's purge them as well just in case. The rate is low.
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/summary/{decode(match.meta.uri.title)}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/summary/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
                         query:
                           redirect: false
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{decode(match.meta.uri.title)}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
                         query:
@@ -229,16 +229,16 @@ spec: &spec
                       - method: get
                         # This even comes directly from MediaWiki, so title is encoded in MW-specific way.
                         # Re-encode the title in standard `encodeURIComponent` encoding.
-                        uri: '{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}'
+                        uri: "{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
-                          if-unmodified-since: '{{date(message.meta.dt)}}'
+                          if-unmodified-since: "{{date(message.meta.dt)}}"
                         query:
                           redirect: false
                         # The HTML might not change but sometimes editors use a purge to drop incorrectly rendered summary/MCS
                         # content, so let's purge them as well just in case. The rate is low.
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/definition/{decode(match.meta.uri.title)}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/definition/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
                         query:
@@ -263,16 +263,16 @@ spec: &spec
                       - method: get
                         # This even comes directly from MediaWiki, so title is encoded in MW-specific way.
                         # Re-encode the title in standard `encodeURIComponent` encoding.
-                        uri: '{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}'
+                        uri: "{{match.meta.uri.proto}}://{{message.meta.domain}}/api/rest_v1/page/html/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
-                          if-unmodified-since: '{{date(message.meta.dt)}}'
+                          if-unmodified-since: "{{date(message.meta.dt)}}"
                         query:
                           redirect: false
                         # The HTML might not change but sometimes editors use a purge to drop incorrectly rendered summary/MCS
                         # content, so let's purge them as well just in case. The rate is low.
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/summary/{decode(match.meta.uri.title)}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/summary/{decode(match.meta.uri.title)}"
                         headers:
                           cache-control: no-cache
                         query:
@@ -285,7 +285,7 @@ spec: &spec
                     - 403 # Ignoring 403 since some of the pages with high number of null_edit events are blacklisted
                     - 412
                 limiters:
-                  blacklist: 'html:{message.meta.uri}'
+                  blacklist: "html:{message.meta.uri}"
                 cases:
                   - match:
                       meta:
@@ -312,18 +312,18 @@ spec: &spec
               page_edit:
                 topic: mediawiki.revision-create
                 limiters:
-                  blacklist: 'html:{message.meta.uri}'
+                  blacklist: "html:{message.meta.uri}"
                 retry_on:
                   status:
-                    - '5xx'
+                    - 5xx
                     - 404 # Sometimes occasional 404s happen because of the mysql replication lag, so retry
                 match:
                   rev_content_changed: true
                 match_not:
-                # Test-only. We use undefined rev_parent_id to test backlinks so we
-                # don't want transclusions to interfere with backlinks test
+                  # Test-only. We use undefined rev_parent_id to test backlinks so we
+                  # don't want transclusions to interfere with backlinks test
                   - rev_parent_id: undefined
-                # end of test-only config
+                  # end of test-only config
                   - meta:
                       domain: /\.wikidata\.org$/
                     page_namespace: 0
@@ -332,16 +332,16 @@ spec: &spec
                     page_namespace: 120
                 exec:
                   - method: get
-                    uri: 'https://{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}'
+                    uri: "https://{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}"
                     headers:
                       cache-control: no-cache
-                      x-restbase-parentrevision: '{{message.rev_parent_id}}'
-                      if-unmodified-since: '{{date(message.meta.dt)}}'
+                      x-restbase-parentrevision: "{{message.rev_parent_id}}"
+                      if-unmodified-since: "{{date(message.meta.dt)}}"
                     query:
                       redirect: false
                   - method: post
-                    uri: '/sys/links/transcludes/{message.page_title}'
-                    body: '{{globals.message}}'
+                    uri: "/sys/links/transcludes/{message.page_title}"
+                    body: "{{globals.message}}"
 
               revision_visibility_change:
                 topic: mediawiki.revision-visibility-change
@@ -358,7 +358,7 @@ spec: &spec
                     page_namespace: 120
                 exec:
                   - method: get
-                    uri: 'https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}/{{message.rev_id}}'
+                    uri: "https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}/{{message.rev_id}}"
                     headers:
                       cache-control: no-cache
                     query:
@@ -368,16 +368,16 @@ spec: &spec
                   # we need to add many workarounds/shortcurst in RESTBase. So having this list here is an OK compromise.
                   # Only purge the URIs with a rev_id since the latest revision can not be restricted.
                   - method: post
-                    uri: '/sys/purge/'
+                    uri: /sys/purge/
                     body:
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}/{{message.rev_id}}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}/{{message.rev_id}}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-lead/{message.page_title}/{{message.rev_id}}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-lead/{message.page_title}/{{message.rev_id}}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-remaining/{message.page_title}/{{message.rev_id}}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-remaining/{message.page_title}/{{message.rev_id}}"
 
               page_delete:
                 topic: mediawiki.page-delete
@@ -394,37 +394,37 @@ spec: &spec
                     page_namespace: 120
                 exec:
                   - method: get
-                    uri: 'https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}'
+                    uri: "https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}"
                     headers:
                       cache-control: no-cache
                     query:
                       redirect: false
                   # The links to the deleted page should become red again
                   - method: post
-                    uri: '/sys/links/backlinks/{message.page_title}'
-                    body: '{{globals.message}}'
+                    uri: "/sys/links/backlinks/{message.page_title}"
+                    body: "{{globals.message}}"
                   # For page deletion RESTBase doesn't emit resource_change events, and to go through
                   # the normal purge chain (html update -> html resource_change -> summary update -> summary resource_change)
                   # we need to add many workarounds/shortcuts in RESTBase. So having this list here is an OK compromise.
                   - method: post
-                    uri: '/sys/purge/'
+                    uri: /sys/purge/
                     body:
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/definition/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/definition/{message.page_title}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-lead/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-lead/{message.page_title}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-remaining/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/mobile-sections-remaining/{message.page_title}"
                       - meta:
-                          uri: '//{{message.meta.domain}}/api/rest_v1/page/media-list/{message.page_title}'
+                          uri: "//{{message.meta.domain}}/api/rest_v1/page/media-list/{message.page_title}"
 
               page_restore:
                 topic: mediawiki.page-undelete
@@ -437,15 +437,15 @@ spec: &spec
                     page_namespace: 120
                 exec:
                   - method: get
-                    uri: 'https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}'
+                    uri: "https://{{message.meta.domain}}/api/rest_v1/page/title/{message.page_title}"
                     headers:
                       cache-control: no-cache
                     query:
                       redirect: false
                   # The links to the deleted page should become red again
                   - method: post
-                    uri: '/sys/links/backlinks/{message.page_title}'
-                    body: '{{globals.message}}'
+                    uri: "/sys/links/backlinks/{message.page_title}"
+                    body: "{{globals.message}}"
 
               page_move:
                 topic: mediawiki.page-move
@@ -458,14 +458,14 @@ spec: &spec
                     page_namespace: 120
                 exec:
                   - method: get
-                    uri: 'https://{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}'
+                    uri: "https://{{message.meta.domain}}/api/rest_v1/page/html/{message.page_title}/{{message.rev_id}}"
                     headers:
                       cache-control: no-cache
-                      if-unmodified-since: '{{date(message.meta.dt)}}'
+                      if-unmodified-since: "{{date(message.meta.dt)}}"
                     query:
                       redirect: false
                   - method: get
-                    uri: 'https://{{message.meta.domain}}/api/rest_v1/page/title/{message.prior_state.page_title}'
+                    uri: "https://{{message.meta.domain}}/api/rest_v1/page/title/{message.prior_state.page_title}"
                     headers:
                       cache-control: no-cache
                     query:
@@ -474,34 +474,34 @@ spec: &spec
               on_transclusion_update:
                 topic: change-prop.transcludes.resource-change
                 limiters:
-                  blacklist: 'html:{message.meta.uri}'
+                  blacklist: "html:{message.meta.uri}"
                 cases:
                   - match:
                       $schema: '/^\/resource_change\/.*/'
                       meta:
                         uri: '/https?:\/\/[^\/]+\/wiki\/(?<title>.+)/'
-                      tags: [ 'transcludes' ]
+                      tags: [ transcludes ]
                     exec:
                       method: get
-                      uri: 'https://{{message.meta.domain}}/api/rest_v1/page/html/{{match.meta.uri.title}}'
+                      uri: "https://{{message.meta.domain}}/api/rest_v1/page/html/{{match.meta.uri.title}}"
                       headers:
                         cache-control: no-cache
-                        if-unmodified-since: '{{date(message.root_event.dt)}}'
-                        x-restbase-mode: '{{message.tags[1]}}'
+                        if-unmodified-since: "{{date(message.root_event.dt)}}"
+                        x-restbase-mode: "{{message.tags[1]}}"
                       query:
                         redirect: false
                   - match:
                       $schema: '/^\/change-prop\/continue\/.*/'
                     exec:
                       method: post
-                      uri: '/sys/links/transcludes/{message.original_event.page_title}'
-                      body: '{{globals.message}}'
+                      uri: "/sys/links/transcludes/{message.original_event.page_title}"
+                      body: "{{globals.message}}"
 
               page_create:
                 topic: mediawiki.page-create
                 retry_on:
                   status:
-                    - '5xx'
+                    - 5xx
                     - 404 # Sometimes occasional 404s happen because of the mysql replication lag, so retry
                 match_not:
                   - meta:
@@ -512,34 +512,34 @@ spec: &spec
                     page_namespace: 120
                 exec:
                   - method: post
-                    uri: '/sys/links/backlinks/{message.page_title}'
-                    body: '{{globals.message}}'
+                    uri: "/sys/links/backlinks/{message.page_title}"
+                    body: "{{globals.message}}"
 
               on_backlinks_update:
                 topic: change-prop.backlinks.resource-change
                 limiters:
-                  blacklist: 'html:{message.meta.uri}'
+                  blacklist: "html:{message.meta.uri}"
                 cases:
                   - match:
                       $schema: '/^\/resource_change\/.*/'
                       meta:
                         uri: '/https?:\/\/[^\/]+\/wiki\/(?<title>.+)/'
-                      tags: [ 'backlinks' ]
+                      tags: [ backlinks ]
                     exec:
                       method: get
-                      uri: 'https://{{message.meta.domain}}/api/rest_v1/page/html/{{match.meta.uri.title}}'
+                      uri: "https://{{message.meta.domain}}/api/rest_v1/page/html/{{match.meta.uri.title}}"
                       headers:
                         cache-control: no-cache
-                        if-unmodified-since: '{{date(message.root_event.dt)}}'
-                        x-restbase-mode: '{{message.tags[1]}}'
+                        if-unmodified-since: "{{date(message.root_event.dt)}}"
+                        x-restbase-mode: "{{message.tags[1]}}"
                       query:
                         redirect: false
                   - match:
                       $schema: '/^\/change-prop\/continue\/.*/'
                     exec:
                       method: post
-                      uri: '/sys/links/backlinks/{message.original_event.page_title}'
-                      body: '{{globals.message}}'
+                      uri: "/sys/links/backlinks/{message.original_event.page_title}"
+                      body: "{{globals.message}}"
 
               # ORES caching updates
               ores_cache:
@@ -550,10 +550,10 @@ spec: &spec
                     - 503
                 exec:
                   method: post
-                  uri: '/sys/ores/'
+                  uri: /sys/ores/
                   query:
                     postevent: true
-                  body: '{{globals.message}}'
+                  body: "{{globals.message}}"
 
               wikidata_description_on_edit:
                 topic: mediawiki.revision-create
@@ -563,12 +563,12 @@ spec: &spec
                   page_namespace: 0
                   # It's impossible to modify a comment in wikidata while editing the entity.
                   # TODO: This is a temp solution until we get a more general fragment support T148079
-                  comment: '/wbeditentity|wbsetdescription|undo|restore/'
+                  comment: "/wbeditentity|wbsetdescription|undo|restore/"
                   rev_content_changed: true
                 exec:
                   method: post
-                  uri: '/sys/links/wikidata_descriptions'
-                  body: '{{globals.message}}'
+                  uri: /sys/links/wikidata_descriptions
+                  body: "{{globals.message}}"
 
               wikidata_description_on_undelete:
                 topic: mediawiki.page-undelete
@@ -578,8 +578,8 @@ spec: &spec
                   page_namespace: 0
                 exec:
                   method: post
-                  uri: '/sys/links/wikidata_descriptions'
-                  body: '{{globals.message}}'
+                  uri: /sys/links/wikidata_descriptions
+                  body: "{{globals.message}}"
 
               on_wikidata_description_change:
                 topic: change-prop.wikidata.resource-change
@@ -588,16 +588,16 @@ spec: &spec
                       meta:
                         uri: '/https:\/\/[^\/]+\/wiki\/(?<title>.+)/'
                         domain: '/.*\.wikipedia.org$/'
-                      tags: [ 'wikidata' ]
+                      tags: [ wikidata ]
                     exec:
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}"
                         headers:
                           cache-control: no-cache
                         query:
                           redirect: false
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{{match.meta.uri.title}}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{{match.meta.uri.title}}"
                         headers:
                           cache-control: no-cache
                         query:
@@ -605,11 +605,11 @@ spec: &spec
                   - match:
                       meta:
                         uri: '/https:\/\/[^\/]+\/wiki\/(?<title>.+)/'
-                      tags: [ 'wikidata' ]
+                      tags: [ wikidata ]
                     match_not: *others_match_not
                     exec:
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/summary/{{match.meta.uri.title}}"
                         headers:
                           cache-control: no-cache
                         query:
@@ -623,27 +623,27 @@ spec: &spec
                       meta:
                         domain: '/.*\.wikipedia.org$/'
                       added_properties:
-                        page_image: '/.+/'
+                        page_image: "/.+/"
                     exec: &page_images_wikipedia_rerender
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}"
                         headers:
                           cache-control: no-cache
                         query:
                           redirect: false
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/mobile-sections/{message.page_title}"
                         headers:
                           cache-control: no-cache
                         query:
                           redirect: false
                   - match:
                       added_properties:
-                        page_image: '/.+/'
+                        page_image: "/.+/"
                     match_not: *others_match_not
                     exec: &page_images_others_rerender
                       - method: get
-                        uri: 'https://{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}'
+                        uri: "https://{{message.meta.domain}}/api/rest_v1/page/summary/{message.page_title}"
                         headers:
                           cache-control: no-cache
                         query:
@@ -652,26 +652,26 @@ spec: &spec
                       meta:
                         domain: '/.*\.wikipedia.org$/'
                       removed_properties:
-                        page_image: '/.+/'
+                        page_image: "/.+/"
                     exec: *page_images_wikipedia_rerender
                   - match:
                       removed_properties:
-                        page_image: '/.+/'
+                        page_image: "/.+/"
                     match_not: *others_match_not
                     exec: *page_images_others_rerender
 
               # Map tile cache invalidation
               purge_map_tile:
-                topic: 'resource_change'
+                topic: resource_change
                 match:
                   tags:
                     - tilerator
                 exec:
                   method: post
-                  uri: '/sys/purge/'
+                  uri: /sys/purge/
                   body:
                     - meta:
-                        uri: '{{message.meta.uri}}'
+                        uri: "{{message.meta.uri}}"
 
 num_workers: 0
 logging:
diff --git a/config.example.yaml b/config.example.yaml
index e8c1b81..fc78c48 100644
--- a/config.example.yaml
+++ b/config.example.yaml
@@ -28,7 +28,7 @@ services:
       # IP address to bind to, all IPs by default
       # interface: localhost # uncomment to only listen on localhost
       # allow cross-domain requests to the API (default '*')
-      cors: '*'
+      cors: "*"
       # to disable use:
       # cors: false
       # to restrict to a particular domain, use:
diff --git a/config.jobqueue.wikimedia.yaml b/config.jobqueue.wikimedia.yaml
index 4b859e8..2ee0c12 100644
--- a/config.jobqueue.wikimedia.yaml
+++ b/config.jobqueue.wikimedia.yaml
@@ -35,61 +35,61 @@ spec: &spec
               queue.buffering.max.messages: "10"
               compression.codec: snappy
             # Redis-mock does not support evalsha that rate limiting depend on.
-            disable_ratelimit: '{env(MOCK_SERVICES)}'
+            disable_ratelimit: "{env(MOCK_SERVICES)}"
             concurrency: 250
             reenqueue_delay: 5
             templates:
               normal_job_rule:
                 topics:
-                  - 'mediawiki.job.updateBetaFeaturesUserCounts'
-                  - 'mediawiki.job.cdnPurge'
+                  - mediawiki.job.updateBetaFeaturesUserCounts
+                  - mediawiki.job.cdnPurge
                 exec:
                   method: post
-                  uri: 'http://jobrunner.wikipedia.org/wiki/Special:RunSingleJob'
+                  uri: "http://jobrunner.wikipedia.org/wiki/Special:RunSingleJob"
                   headers:
                     content-type: application/json
-                    host: '{{message.meta.domain}}'
-                  body: '{{globals.message}}'
+                    host: "{{message.meta.domain}}"
+                  body: "{{globals.message}}"
               htmlCacheUpdate_partitioner:
-                topic: 'mediawiki.job.htmlCacheUpdate'
+                topic: mediawiki.job.htmlCacheUpdate
                 exec:
-                  method: 'post'
-                  uri: '/sys/partition/'
+                  method: post
+                  uri: /sys/partition/
                   headers:
                     content-type: application/json
-                  body: '{{globals.message}}'
+                  body: "{{globals.message}}"
               htmlCacheUpdate:
-                topic: 'cpjobqueue.partitioned.mediawiki.job.htmlCacheUpdate'
+                topic: cpjobqueue.partitioned.mediawiki.job.htmlCacheUpdate
                 exec:
                   method: post
-                  uri: 'http://jobrunner.wikipedia.org/wiki/Special:RunSingleJob'
+                  uri: "http://jobrunner.wikipedia.org/wiki/Special:RunSingleJob"
                   headers:
                     content-type: application/json
-                    host: '{{message.meta.domain}}'
-                  body: '{{globals.message}}'
+                    host: "{{message.meta.domain}}"
+                  body: "{{globals.message}}"
               refreshLinks_partitioner:
-                topic: 'mediawiki.job.refreshLinks'
+                topic: mediawiki.job.refreshLinks
                 exec:
-                  method: 'post'
-                  uri: '/sys/partition/'
+                  method: post
+                  uri: /sys/partition/
                   headers:
                     content-type: application/json
-                  body: '{{globals.message}}'
+                  body: "{{globals.message}}"
               refreshLinks:
-                topic: 'cpjobqueue.partitioned.mediawiki.job.refreshLinks'
+                topic: cpjobqueue.partitioned.mediawiki.job.refreshLinks
                 exec:
                   method: post
-                  uri: 'http://jobrunner.wikipedia.org/wiki/Special:RunSingleJob'
+                  uri: "http://jobrunner.wikipedia.org/wiki/Special:RunSingleJob"
                   headers:
                     content-type: application/json
-                    host: '{{message.meta.domain}}'
-                  body: '{{globals.message}}'
+                    host: "{{message.meta.domain}}"
+                  body: "{{globals.message}}"
     /sys/partition:
       x-modules:
         - path: sys/partitioner.js
           options:
             templates:
-              partition_stream: 'cpjobqueue.partitioned.{{message.meta.stream}}'
+              partition_stream: "cpjobqueue.partitioned.{{message.meta.stream}}"
             partition_key: database
             partition_default: 2
             partition_map:
diff --git a/config.test.yaml b/config.test.yaml
index 3624b4b..485bb2f 100644
--- a/config.test.yaml
+++ b/config.test.yaml
@@ -36,7 +36,7 @@ spec: &spec
               compression.codec: snappy
             concurrency: 1
             # Redis-mock does not support evalsha that rate limiting depend on.
-            disable_ratelimit: '{env(MOCK_SERVICES)}'
+            disable_ratelimit: "{env(MOCK_SERVICES)}"
             templates:
               simple_test_rule:
                 topic: /^simple_test_rule$/
@@ -44,7 +44,7 @@ spec: &spec
                 retry_delay: 10
                 retry_on:
                   status:
-                    - '50x'
+                    - 50x
                     - 400
                 ignore:
                   status:
@@ -52,59 +52,59 @@ spec: &spec
                     - 412
                 match:
                   meta:
-                    uri: 'https://en.wikipedia.org/wiki/SamplePage'
-                  message: 'test'
+                    uri: "https://en.wikipedia.org/wiki/SamplePage"
+                  message: test
                 limiters:
-                  blacklist: '{{message.message}}'
+                  blacklist: "{{message.message}}"
                 exec:
                   method: post
-                  uri: 'http://mock.com'
+                  uri: "http://mock.com"
                   headers:
                     test_header_name: test_header_value
                     content-type: application/json
                   body:
                     test_field_name: test_field_value
-                    derived_field: '{{message.message}}'
-                    random_field: '{{message.random}}'
+                    derived_field: "{{message.message}}"
+                    random_field: "{{message.random}}"
               redirect_testing_rule:
                 topic: simple_test_rule
                 match:
                   meta:
-                    uri: 'https://en.wikipedia.org/wiki/SamplePage'
-                  message: 'redirect'
+                    uri: "https://en.wikipedia.org/wiki/SamplePage"
+                  message: redirect
                 exec:
                   method: get
-                  uri: 'http://mock.com/will_redirect'
+                  uri: "http://mock.com/will_redirect"
 
               kafka_producing_rule:
                 topic: kafka_producing_rule
                 exec:
-                  method: 'post'
-                  uri: '/sys/queue/events'
+                  method: post
+                  uri: /sys/queue/events
                   body:
                     - meta:
-                        stream: '{{message.produce_to_topic}}'
-                        uri: '{{message.meta.uri}}'
-                      message: 'test'
-                      triggered_by: '{{message.meta.stream}}:{{message.meta.uri}}'
+                        stream: "{{message.produce_to_topic}}"
+                        uri: "{{message.meta.uri}}"
+                      message: test
+                      triggered_by: "{{message.meta.stream}}:{{message.meta.uri}}"
                     - meta:
-                        stream: '{{message.produce_to_topic}}'
-                        uri: '{{message.meta.uri}}'
-                      message: 'test'
-                      triggered_by: '{{message.meta.stream}}:{{message.meta.uri}}'
+                        stream: "{{message.produce_to_topic}}"
+                        uri: "{{message.meta.uri}}"
+                      message: test
+                      triggered_by: "{{message.meta.stream}}:{{message.meta.uri}}"
 
               sample_testing_rule:
                 topic: sample_test_rule
                 sample:
                   rate: 0.5
-                  hash_template: '{{message.meta.domain}}-{{message.page_title}}'
+                  hash_template: "{{message.meta.domain}}-{{message.page_title}}"
                 match:
                   meta:
-                    uri: 'https://en.wikipedia.org/wiki/SamplePage'
-                  message: 'sampled'
+                    uri: "https://en.wikipedia.org/wiki/SamplePage"
+                  message: sampled
                 exec:
                   method: get
-                  uri: 'http://mock.com/{{message.meta.domain}}/{{message.page_title}}'
+                  uri: "http://mock.com/{{message.meta.domain}}/{{message.page_title}}"
 
               array_rule:
                 topics:
@@ -115,9 +115,9 @@ spec: &spec
                   - simple_test_rule3
                 exec:
                   method: post
-                  uri: 'http://mock2.org'
+                  uri: "http://mock2.org"
                   body:
-                    topic: '{{message.meta.stream}}'
+                    topic: "{{message.meta.stream}}"
 num_workers: 0
 logging:
   name: changeprop
diff --git a/lib/base_executor.js b/lib/base_executor.js
index 864fedf..df1774e 100644
--- a/lib/base_executor.js
+++ b/lib/base_executor.js
@@ -131,9 +131,9 @@ class BaseExecutor {
     }
 
     subscribe() {
-        const prefix = this.options.test_mode ? `test-${this._hyper.config.service_name}` : `${this._hyper.config.service_name}`;
+        const prefix = this.options.test_mode ? `test-${ this._hyper.config.service_name }` : `${ this._hyper.config.service_name }`;
         return this.kafkaFactory.createConsumer(
-            `${prefix}-${this.rule.name}`,
+            `${ prefix }-${ this.rule.name }`,
             this.subscribeTopics,
             this._hyper.metrics,
             this._hyper.logger
@@ -183,7 +183,7 @@ class BaseExecutor {
                 }
 
                 this._hyper.metrics.increment(
-                    `${this.statName(message)}_dequeue`,
+                    `${ this.statName(message) }_dequeue`,
                     1,
                     0.1);
 
@@ -257,7 +257,7 @@ class BaseExecutor {
         return P.all(this.rule.getRateLimiterTypes().map((type) => {
             const key = this.rule.getLimiterKey(type, expander);
             return this._hyper.get({
-                uri: new URI(`/sys/limit/${type}/${key}`)
+                uri: new URI(`/sys/limit/${ type }/${ key }`)
             });
         }))
         .thenReturn(false)
@@ -290,7 +290,7 @@ class BaseExecutor {
             if (status >= 500) {
                 const limiterKey = this.rule.getLimiterKey(type, expander);
                 return this._hyper.post({
-                    uri: new URI(`/sys/limit/${type}/${limiterKey}`)
+                    uri: new URI(`/sys/limit/${ type }/${ limiterKey }`)
                 }).catch({ status: 429 }, () => {
                     // No need to react here, we'll reject the next message
                 }).catch({ status: 404 }, () => {
@@ -390,7 +390,7 @@ class BaseExecutor {
                 message: 'Processed event sample',
                 event_str: utils.stringify(event),
                 request: {
-                    uri: `${request.uri}`,
+                    uri: `${ request.uri }`,
                     headers: request.headers,
                     // Don't include the full body in the log
                     body: request.body && utils.stringify(request.body).slice(0, 1024)
@@ -433,7 +433,7 @@ class BaseExecutor {
                 stream: origEvent.meta.stream,
                 uri: origEvent.meta.uri
             });
-            this._hyper.metrics.increment(`${this.statName(origEvent)}_blacklist`);
+            this._hyper.metrics.increment(`${ this.statName(origEvent) }_blacklist`);
             return P.resolve({ status: 200 });
         }
 
@@ -496,7 +496,7 @@ class BaseExecutor {
         // Latency from the event (if it's a retry - an original event)
         // creation time to execution time
         this._hyper.metrics.endTiming(
-            [`${this.statName(origEvent)}_delay`],
+            [`${ this.statName(origEvent) }_delay`],
             metricStartTime
         );
 
@@ -504,7 +504,7 @@ class BaseExecutor {
         if (origEvent.root_event && !retryEvent) {
             // Latency from the beginning of the recursive event chain
             // to the event execution
-            this._hyper.metrics.endTiming([`${this.statName(origEvent)}_totaldelay`],
+            this._hyper.metrics.endTiming([`${ this.statName(origEvent) }_totaldelay`],
                 new Date(origEvent.root_event.dt));
         }
 
@@ -550,7 +550,7 @@ class BaseExecutor {
                 .tap(() => this._updateLimiters(expander, 200))
                 .tapCatch(e => this._updateLimiters(expander, e.status))
                 .finally(() => this._hyper.metrics.endTiming(
-                    [`${this.statName(origEvent)}_exec`],
+                    [`${ this.statName(origEvent) }_exec`],
                     startTime)
                 );
             });
@@ -558,15 +558,15 @@ class BaseExecutor {
     }
 
     retryStreamName(topic) {
-        return `${this._hyper.config.service_name}.retry.${topic}`;
+        return `${ this._hyper.config.service_name }.retry.${ topic }`;
     }
 
     emitterId() {
-        return `${this._hyper.config.service_name}#${this.rule.name}`;
+        return `${ this._hyper.config.service_name }#${ this.rule.name }`;
     }
 
     _errorStreamName() {
-        return `${this._hyper.config.service_name}.error`;
+        return `${ this._hyper.config.service_name }.error`;
     }
 
     _constructRetryMessage(event, errorRes, retriesLeft, retryEvent) {
@@ -627,8 +627,8 @@ class BaseExecutor {
             // We've got an error, but it's not from the update request, it's
             // some bug in change-prop. Log and send a fatal error message.
             this._logger.log('fatal/internal_error', () => ({
-                message: `Internal error in ${this._hyper.config.service_name}`,
-                description: `${e}`,
+                message: `Internal error in ${ this._hyper.config.service_name }`,
+                description: `${ e }`,
                 stack: e.stack,
                 event_str: utils.stringify(message),
                 stream: message.meta.stream
@@ -650,7 +650,7 @@ class BaseExecutor {
 
         if (!this.rule.shouldIgnoreError(e)) {
             this._logger.log('error/exec_error', () => ({
-                message: `Exec error in ${this._hyper.config.service_name}`,
+                message: `Exec error in ${ this._hyper.config.service_name }`,
                 status: e.status,
                 event_str: utils.stringify(message),
                 stream: message.meta.stream,
diff --git a/lib/kafka_factory.js b/lib/kafka_factory.js
index 6d47d2d..02313ff 100644
--- a/lib/kafka_factory.js
+++ b/lib/kafka_factory.js
@@ -145,7 +145,7 @@ class MetadataWatch extends EventEmitter {
 
     getTopics() {
         /* eslint-disable-next-line security/detect-non-literal-regexp */
-        const dcRemoveRegex = new RegExp(`^${this._consumeDC}\\.`);
+        const dcRemoveRegex = new RegExp(`^${ this._consumeDC }\\.`);
         return new P((resolve, reject) => {
             this._consumer.getMetadata(undefined, (err, res) => {
                 if (err) {
@@ -243,7 +243,7 @@ class KafkaFactory {
     createConsumer(groupId, topics, metrics, logger) {
         const conf = Object.assign({}, this._consumerConf);
         conf['group.id'] = groupId;
-        conf['client.id'] = `${Math.floor(Math.random() * 1000000)}`;
+        conf['client.id'] = `${ Math.floor(Math.random() * 1000000) }`;
 
         return new P((resolve, reject) => {
             const consumer = new kafka.KafkaConsumer(conf, this._consumerTopicConf);
@@ -261,7 +261,7 @@ class KafkaFactory {
     createMetadataWatch(groupId) {
         const conf = Object.assign({}, this._consumerConf);
         conf['group.id'] = groupId;
-        conf['client.id'] = `${Math.floor(Math.random() * 1000000)}`;
+        conf['client.id'] = `${ Math.floor(Math.random() * 1000000) }`;
 
         return new P((resolve, reject) => {
             const consumer = new kafka.KafkaConsumer(conf, this._consumerTopicConf);
diff --git a/lib/retry_executor.js b/lib/retry_executor.js
index 44e0e85..b2d5b32 100644
--- a/lib/retry_executor.js
+++ b/lib/retry_executor.js
@@ -10,12 +10,12 @@ const BaseExecutor = require('./base_executor');
 class RetryExecutor extends BaseExecutor {
     get subscribeTopics() {
         return this.rule.topics.map(topic =>
-            `${this.kafkaFactory.consumeDC}.${this.retryStreamName(topic)}`);
+            `${ this.kafkaFactory.consumeDC }.${ this.retryStreamName(topic) }`);
     }
 
     statName(event) {
         return this._hyper.metrics.normalizeName(
-            `${this.rule.name}-${event.meta.stream.replace(/\./g, '_')}_retry`);
+            `${ this.rule.name }-${ event.meta.stream.replace(/\./g, '_') }_retry`);
     }
 
     _delay(message) {
diff --git a/lib/rule.js b/lib/rule.js
index 98b18fc..943b3f9 100644
--- a/lib/rule.js
+++ b/lib/rule.js
@@ -52,14 +52,14 @@ function _compileErrorCheckCondition(retryDefinition) {
         if (retryCond === 'status') {
             const opt = option.toString();
             if (/^[0-9]+$/.test(opt)) {
-                return `(res["${retryCond}"] === ${opt})`;
+                return `(res["${ retryCond }"] === ${ opt })`;
             }
             if (/^[0-9x]+$/.test(opt)) {
-                return `/^${opt.replace(/x/g, '\\d')}$/.test(res["${retryCond}"])`;
+                return `/^${ opt.replace(/x/g, '\\d') }$/.test(res["${ retryCond }"])`;
             }
-            throw new Error(`Invalid retry_on condition ${opt}`);
+            throw new Error(`Invalid retry_on condition ${ opt }`);
         } else {
-            return `(stringify(res["${retryCond}"]) === '${stringify(option)}')`;
+            return `(stringify(res["${ retryCond }"]) === '${ stringify(option) }')`;
         }
     }
 
@@ -68,12 +68,12 @@ function _compileErrorCheckCondition(retryDefinition) {
         if (Array.isArray(retryDefinition[catchCond])) {
             const orCondition = retryDefinition[catchCond].map(option =>
                 createCondition(catchCond, option));
-            condition.push(`(${orCondition.join(' || ')})`);
+            condition.push(`(${ orCondition.join(' || ') })`);
         } else {
             condition.push(createCondition(catchCond, retryDefinition[catchCond]));
         }
     });
-    const code = `return (${condition.join(' && ')});`;
+    const code = `return (${ condition.join(' && ') });`;
     /* jslint evil: true */
     /* eslint-disable no-new-func */
     return new Function('stringify', 'res', code).bind(null, stringify);
@@ -82,9 +82,9 @@ function _compileErrorCheckCondition(retryDefinition) {
 
 function _getMatchObjCode(obj) {
     if (obj.constructor === Object) {
-        return `{${Object.keys(obj).map((key) => {
-            return `${key}: ${_getMatchObjCode(obj[key])}`;
-        }).join(', ')}}`;
+        return `{${ Object.keys(obj).map((key) => {
+            return `${ key }: ${ _getMatchObjCode(obj[key]) }`;
+        }).join(', ') }}`;
     }
     return obj;
 }
@@ -96,32 +96,32 @@ function _compileNamedRegex(obj, result, name, fieldName) {
         return '(';
     });
     /* eslint-disable-next-line security/detect-non-literal-regexp */
-    const numGroups = (new RegExp(`${normalRegex.toString()}|`)).exec('').length - 1;
+    const numGroups = (new RegExp(`${ normalRegex.toString() }|`)).exec('').length - 1;
 
     if (captureNames.length && captureNames.length !== numGroups) {
-        throw new Error(`${'Invalid match regex. ' +
-        'Mixing named and unnamed capture groups are not supported. Regex: '}${obj}`);
+        throw new Error(`${ 'Invalid match regex. ' +
+        'Mixing named and unnamed capture groups are not supported. Regex: ' }${ obj }`);
     }
 
     if (!captureNames.length) {
         // No named captures
-        result[fieldName] = `${normalRegex}.exec(${name})`;
+        result[fieldName] = `${ normalRegex }.exec(${ name })`;
     } else {
-        let code = `(() => { const execRes = ${normalRegex}.exec(${name}); const res = {}; `;
+        let code = `(() => { const execRes = ${ normalRegex }.exec(${ name }); const res = {}; `;
         captureNames.forEach((captureName, index) => {
-            code += `res['${captureName}'] = execRes[${index + 1}]; `;
+            code += `res['${ captureName }'] = execRes[${ index + 1 }]; `;
         });
-        result[fieldName] = `${code}return res; })()`;
+        result[fieldName] = `${ code }return res; })()`;
     }
 
-    return `typeof ${name} === "string" && ${normalRegex}.test(${name})`;
+    return `typeof ${ name } === "string" && ${ normalRegex }.test(${ name })`;
 }
 
 function _compileMatch(obj, result, name, fieldName) {
     function _compileArrayMatch(objToSearch, nameToSearch) {
         const itemsCheck = objToSearch.map((item, index) =>
-            `${nameToSearch}.find((item) => ${_compileMatch(item, {}, 'item', index)})`).join(' && ');
-        return `Array.isArray(${nameToSearch})${itemsCheck.length ? (` && ${itemsCheck}`) : ''}`;
+            `${ nameToSearch }.find((item) => ${ _compileMatch(item, {}, 'item', index) })`).join(' && ');
+        return `Array.isArray(${ nameToSearch })${ itemsCheck.length ? (` && ${ itemsCheck }`) : '' }`;
     }
 
     if (obj.constructor !== Object) {
@@ -129,17 +129,17 @@ function _compileMatch(obj, result, name, fieldName) {
             return _compileArrayMatch(obj, name);
         }
         if (obj === 'undefined') {
-            return `${name} === undefined`;
+            return `${ name } === undefined`;
         }
         if (typeof obj !== 'string') {
             // not a string, so it has to match exactly
             result[fieldName] = obj;
-            return `${name} === ${obj}`;
+            return `${ name } === ${ obj }`;
         }
         if (!/^\/.+\/[gimuy]{0,5}$/.test(obj)) {
             // not a regex, quote the string
-            result[fieldName] = `'${obj}'`;
-            return `${name} === '${obj}'`;
+            result[fieldName] = `'${ obj }'`;
+            return `${ name } === '${ obj }'`;
         }
         // it's a regex, we have to the test the arg
         return _compileNamedRegex(obj, result, name, fieldName);
@@ -149,9 +149,9 @@ function _compileMatch(obj, result, name, fieldName) {
     const subObj = fieldName ? {} : result;
     const test = Object.keys(obj).map(
         (key) => {
-            const propertyName = `${name}['${key}']`;
+            const propertyName = `${ name }['${ key }']`;
             if (obj[key].constructor === Object) {
-                return `${propertyName} && ${_compileMatch(obj[key], subObj, propertyName, key)}`;
+                return `${ propertyName } && ${ _compileMatch(obj[key], subObj, propertyName, key) }`;
             }
             return _compileMatch(obj[key], subObj, propertyName, key);
         })
@@ -169,7 +169,7 @@ class Rule {
 
         const topics = this.spec.topics || (this.spec.topic && [ this.spec.topic ]);
         if (!topics || !Array.isArray(topics) || !topics.length) {
-            throw new Error(`No topics specified for rule ${this.name}`);
+            throw new Error(`No topics specified for rule ${ this.name }`);
         }
         this.topics = topics;
         if (this.spec.exclude_topics) {
@@ -208,7 +208,7 @@ class Rule {
                 try {
                     this._limiterKeyTemplates[type] = new Template(this.spec.limiters[type]);
                 } catch (e) {
-                    throw new Error(`Compilation failed for limiter ${type}. Error: ${e.message}`);
+                    throw new Error(`Compilation failed for limiter ${ type }. Error: ${ e.message }`);
                 }
             });
         }
@@ -344,9 +344,9 @@ class Rule {
             return {
                 /* eslint-disable no-new-func */
                 /* jslint evil: true  */
-                test: new Function('message', `return ${test}`),
+                test: new Function('message', `return ${ test }`),
                 /* jslint evil: true  */
-                expand: new Function('message', `return ${_getMatchObjCode(obj)}`)
+                expand: new Function('message', `return ${ _getMatchObjCode(obj) }`)
                 /* eslint-enable no-new-func */
             };
         } catch (e) {
@@ -369,7 +369,7 @@ class Rule {
         for (let idx = 0; idx < exec.length; idx++) {
             const req = exec[idx];
             if (req.constructor !== Object || !req.uri) {
-                throw new Error(`In rule ${this.name}, request number ${idx}
+                throw new Error(`In rule ${ this.name }, request number ${ idx }
                     must be an object and must have the "uri" property`);
             }
             req.method = req.method || 'get';
diff --git a/lib/rule_executor.js b/lib/rule_executor.js
index c2b277e..7b1a972 100644
--- a/lib/rule_executor.js
+++ b/lib/rule_executor.js
@@ -8,12 +8,12 @@ const URI = require('hyperswitch').URI;
  */
 class RuleExecutor extends BaseExecutor {
     get subscribeTopics() {
-        return this.rule.topics.map(topic => `${this.kafkaFactory.consumeDC}.${topic}`);
+        return this.rule.topics.map(topic => `${ this.kafkaFactory.consumeDC }.${ topic }`);
     }
 
     statName(event) {
         return this._hyper.metrics.normalizeName(
-            `${this.rule.name}-${event.meta.stream.replace(/\./g, '_')}`);
+            `${ this.rule.name }-${ event.meta.stream.replace(/\./g, '_') }`);
     }
 
     /**
@@ -48,10 +48,10 @@ class RuleExecutor extends BaseExecutor {
         if (this.rule.topics.length === 1) {
             dedupeKey = this.rule.name;
         } else {
-            dedupeKey = `${this.rule.name}-${expander.message.meta.stream}`;
+            dedupeKey = `${ this.rule.name }-${ expander.message.meta.stream }`;
         }
         return this._hyper.post({
-            uri: new URI(`/sys/dedupe/${dedupeKey}`),
+            uri: new URI(`/sys/dedupe/${ dedupeKey }`),
             body: expander.message
         })
         .get('body')
diff --git a/lib/utils.js b/lib/utils.js
index e76b34e..d345b05 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -15,9 +15,9 @@ utils.triggeredBy = (event) => {
     if (prevTrigger) {
         prevTrigger += ',';
     } else {
-        prevTrigger = `req:${event.meta.request_id},`;
+        prevTrigger = `req:${ event.meta.request_id },`;
     }
-    return `${prevTrigger + event.meta.stream}:${event.meta.uri}`;
+    return `${ prevTrigger + event.meta.stream }:${ event.meta.uri }`;
 };
 
 utils.requestId = () => uuidv1();
@@ -50,12 +50,12 @@ utils.constructRegex = (list) => {
     const regex = list.map((regexString) => {
         regexString = regexString.trim();
         if (/^\/.+\/$/.test(regexString)) {
-            return `(?:${regexString.slice(1, regexString.length - 1)})`;
+            return `(?:${ regexString.slice(1, regexString.length - 1) })`;
         }
         // Compare strings, instead
         const slash = /^\//.test(regexString) ? '' : '/';
-        return `(?:${slash}${decodeURIComponent(regexString)
-        .replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&')}$)`;
+        return `(?:${ slash }${ decodeURIComponent(regexString)
+        .replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&') }$)`;
     }).join('|');
     /* eslint-disable-next-line security/detect-non-literal-regexp */
     return new RegExp(regex);
diff --git a/package-lock.json b/package-lock.json
index 510da93..3d58699 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
 	"name": "change-propagation",
-	"version": "0.11.0",
+	"version": "0.12.0",
 	"lockfileVersion": 3,
 	"requires": true,
 	"packages": {
 		"": {
 			"name": "change-propagation",
-			"version": "0.11.0",
+			"version": "0.12.0",
 			"license": "Apache-2.0",
 			"dependencies": {
 				"bluebird": "^3.7.2",
@@ -26,7 +26,7 @@
 				"@wikimedia/jsonschema-tools": "^0.7.5",
 				"ajv": "^6.12.2",
 				"coveralls": "^3.1.0",
-				"eslint-config-wikimedia": "0.25.1",
+				"eslint-config-wikimedia": "0.27.0",
 				"js-yaml": "^3.14.0",
 				"kafka-test-tools": "^0.1.13",
 				"mocha": "^8.0.1",
@@ -50,12 +50,16 @@
 			}
 		},
 		"node_modules/@babel/code-frame": {
-			"version": "7.12.11",
-			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
-			"integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
+			"version": "7.24.2",
+			"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
+			"integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
 			"dev": true,
 			"dependencies": {
-				"@babel/highlight": "^7.10.4"
+				"@babel/highlight": "^7.24.2",
+				"picocolors": "^1.0.0"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/core": {
@@ -89,43 +93,61 @@
 			}
 		},
 		"node_modules/@babel/core/node_modules/semver": {
-			"version": "5.7.1",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
-			"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+			"version": "5.7.2",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+			"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
 			"dev": true,
 			"bin": {
 				"semver": "bin/semver"
 			}
 		},
 		"node_modules/@babel/generator": {
-			"version": "7.12.11",
-			"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz",
-			"integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz",
+			"integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==",
 			"dev": true,
 			"dependencies": {
-				"@babel/types": "^7.12.11",
-				"jsesc": "^2.5.1",
-				"source-map": "^0.5.0"
+				"@babel/types": "^7.24.5",
+				"@jridgewell/gen-mapping": "^0.3.5",
+				"@jridgewell/trace-mapping": "^0.3.25",
+				"jsesc": "^2.5.1"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-environment-visitor": {
+			"version": "7.22.20",
+			"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+			"integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+			"dev": true,
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/helper-function-name": {
-			"version": "7.12.11",
-			"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz",
-			"integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==",
+			"version": "7.23.0",
+			"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+			"integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
 			"dev": true,
 			"dependencies": {
-				"@babel/helper-get-function-arity": "^7.12.10",
-				"@babel/template": "^7.12.7",
-				"@babel/types": "^7.12.11"
+				"@babel/template": "^7.22.15",
+				"@babel/types": "^7.23.0"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
-		"node_modules/@babel/helper-get-function-arity": {
-			"version": "7.12.10",
-			"resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz",
-			"integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==",
+		"node_modules/@babel/helper-hoist-variables": {
+			"version": "7.22.5",
+			"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+			"integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
 			"dev": true,
 			"dependencies": {
-				"@babel/types": "^7.12.10"
+				"@babel/types": "^7.22.5"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/helper-member-expression-to-functions": {
@@ -194,18 +216,30 @@
 			}
 		},
 		"node_modules/@babel/helper-split-export-declaration": {
-			"version": "7.12.11",
-			"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz",
-			"integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz",
+			"integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==",
 			"dev": true,
 			"dependencies": {
-				"@babel/types": "^7.12.11"
+				"@babel/types": "^7.24.5"
+			},
+			"engines": {
+				"node": ">=6.9.0"
+			}
+		},
+		"node_modules/@babel/helper-string-parser": {
+			"version": "7.24.1",
+			"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
+			"integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
+			"dev": true,
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/helper-validator-identifier": {
-			"version": "7.22.20",
-			"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
-			"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz",
+			"integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==",
 			"dev": true,
 			"engines": {
 				"node": ">=6.9.0"
@@ -223,20 +257,24 @@
 			}
 		},
 		"node_modules/@babel/highlight": {
-			"version": "7.10.4",
-			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
-			"integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz",
+			"integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==",
 			"dev": true,
 			"dependencies": {
-				"@babel/helper-validator-identifier": "^7.10.4",
-				"chalk": "^2.0.0",
-				"js-tokens": "^4.0.0"
+				"@babel/helper-validator-identifier": "^7.24.5",
+				"chalk": "^2.4.2",
+				"js-tokens": "^4.0.0",
+				"picocolors": "^1.0.0"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/parser": {
-			"version": "7.12.11",
-			"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz",
-			"integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz",
+			"integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==",
 			"dev": true,
 			"bin": {
 				"parser": "bin/babel-parser.js"
@@ -246,31 +284,38 @@
 			}
 		},
 		"node_modules/@babel/template": {
-			"version": "7.12.7",
-			"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz",
-			"integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==",
+			"version": "7.24.0",
+			"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
+			"integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
 			"dev": true,
 			"dependencies": {
-				"@babel/code-frame": "^7.10.4",
-				"@babel/parser": "^7.12.7",
-				"@babel/types": "^7.12.7"
+				"@babel/code-frame": "^7.23.5",
+				"@babel/parser": "^7.24.0",
+				"@babel/types": "^7.24.0"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/traverse": {
-			"version": "7.12.12",
-			"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz",
-			"integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.5.tgz",
+			"integrity": "sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==",
 			"dev": true,
 			"dependencies": {
-				"@babel/code-frame": "^7.12.11",
-				"@babel/generator": "^7.12.11",
-				"@babel/helper-function-name": "^7.12.11",
-				"@babel/helper-split-export-declaration": "^7.12.11",
-				"@babel/parser": "^7.12.11",
-				"@babel/types": "^7.12.12",
-				"debug": "^4.1.0",
-				"globals": "^11.1.0",
-				"lodash": "^4.17.19"
+				"@babel/code-frame": "^7.24.2",
+				"@babel/generator": "^7.24.5",
+				"@babel/helper-environment-visitor": "^7.22.20",
+				"@babel/helper-function-name": "^7.23.0",
+				"@babel/helper-hoist-variables": "^7.22.5",
+				"@babel/helper-split-export-declaration": "^7.24.5",
+				"@babel/parser": "^7.24.5",
+				"@babel/types": "^7.24.5",
+				"debug": "^4.3.1",
+				"globals": "^11.1.0"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@babel/traverse/node_modules/globals": {
@@ -283,28 +328,31 @@
 			}
 		},
 		"node_modules/@babel/types": {
-			"version": "7.12.12",
-			"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz",
-			"integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==",
+			"version": "7.24.5",
+			"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz",
+			"integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==",
 			"dev": true,
 			"dependencies": {
-				"@babel/helper-validator-identifier": "^7.12.11",
-				"lodash": "^4.17.19",
+				"@babel/helper-string-parser": "^7.24.1",
+				"@babel/helper-validator-identifier": "^7.24.5",
 				"to-fast-properties": "^2.0.0"
+			},
+			"engines": {
+				"node": ">=6.9.0"
 			}
 		},
 		"node_modules/@es-joy/jsdoccomment": {
-			"version": "0.23.6",
-			"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.23.6.tgz",
-			"integrity": "sha512-cCtumxG+qrYORGeOkDQ58GtSt/bb2XiP9GC0x2YduoUEX2EmBQ48FtoZMUs+8wiIdTDN1izUiRUD2FDu+p+Lvg==",
+			"version": "0.42.0",
+			"resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.42.0.tgz",
+			"integrity": "sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==",
 			"dev": true,
 			"dependencies": {
-				"comment-parser": "1.3.1",
-				"esquery": "^1.4.0",
-				"jsdoc-type-pratt-parser": "~2.2.5"
+				"comment-parser": "1.4.1",
+				"esquery": "^1.5.0",
+				"jsdoc-type-pratt-parser": "~4.0.0"
 			},
 			"engines": {
-				"node": "^12 || ^14 || ^16 || ^17"
+				"node": ">=16"
 			}
 		},
 		"node_modules/@eslint-community/eslint-utils": {
@@ -332,9 +380,9 @@
 			}
 		},
 		"node_modules/@eslint/eslintrc": {
-			"version": "2.1.2",
-			"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz",
-			"integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==",
+			"version": "2.1.4",
+			"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+			"integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
 			"dev": true,
 			"dependencies": {
 				"ajv": "^6.12.4",
@@ -385,9 +433,9 @@
 			}
 		},
 		"node_modules/@eslint/js": {
-			"version": "8.51.0",
-			"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz",
-			"integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==",
+			"version": "8.57.0",
+			"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
+			"integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
 			"dev": true,
 			"engines": {
 				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -401,13 +449,13 @@
 			"dev": true
 		},
 		"node_modules/@humanwhocodes/config-array": {
-			"version": "0.11.11",
-			"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
-			"integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==",
+			"version": "0.11.14",
+			"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
+			"integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
 			"dev": true,
 			"dependencies": {
-				"@humanwhocodes/object-schema": "^1.2.1",
-				"debug": "^4.1.1",
+				"@humanwhocodes/object-schema": "^2.0.2",
+				"debug": "^4.3.1",
 				"minimatch": "^3.0.5"
 			},
 			"engines": {
@@ -440,9 +488,9 @@
 			}
 		},
 		"node_modules/@humanwhocodes/object-schema": {
-			"version": "1.2.1",
-			"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
-			"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+			"version": "2.0.3",
+			"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+			"integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
 			"dev": true
 		},
 		"node_modules/@istanbuljs/load-nyc-config": {
@@ -525,6 +573,54 @@
 				"node": ">=8"
 			}
 		},
+		"node_modules/@jridgewell/gen-mapping": {
+			"version": "0.3.5",
+			"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+			"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+			"dev": true,
+			"dependencies": {
+				"@jridgewell/set-array": "^1.2.1",
+				"@jridgewell/sourcemap-codec": "^1.4.10",
+				"@jridgewell/trace-mapping": "^0.3.24"
+			},
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
+		"node_modules/@jridgewell/resolve-uri": {
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+			"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+			"dev": true,
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
+		"node_modules/@jridgewell/set-array": {
+			"version": "1.2.1",
+			"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+			"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+			"dev": true,
+			"engines": {
+				"node": ">=6.0.0"
+			}
+		},
+		"node_modules/@jridgewell/sourcemap-codec": {
+			"version": "1.4.15",
+			"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+			"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+			"dev": true
+		},
+		"node_modules/@jridgewell/trace-mapping": {
+			"version": "0.3.25",
+			"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+			"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+			"dev": true,
+			"dependencies": {
+				"@jridgewell/resolve-uri": "^3.1.0",
+				"@jridgewell/sourcemap-codec": "^1.4.14"
+			}
+		},
 		"node_modules/@mdn/browser-compat-data": {
 			"version": "5.3.23",
 			"resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.3.23.tgz",
@@ -566,18 +662,158 @@
 				"node": ">= 8"
 			}
 		},
+		"node_modules/@types/json-schema": {
+			"version": "7.0.15",
+			"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+			"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+			"dev": true
+		},
 		"node_modules/@types/normalize-package-data": {
-			"version": "2.4.2",
-			"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.2.tgz",
-			"integrity": "sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==",
+			"version": "2.4.4",
+			"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
+			"integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
+			"dev": true
+		},
+		"node_modules/@types/semver": {
+			"version": "7.5.8",
+			"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
+			"integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
 			"dev": true
 		},
+		"node_modules/@typescript-eslint/scope-manager": {
+			"version": "5.62.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
+			"integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "5.62.0",
+				"@typescript-eslint/visitor-keys": "5.62.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@typescript-eslint/types": {
+			"version": "5.62.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
+			"integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
+			"dev": true,
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
+		"node_modules/@typescript-eslint/typescript-estree": {
+			"version": "5.62.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz",
+			"integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "5.62.0",
+				"@typescript-eslint/visitor-keys": "5.62.0",
+				"debug": "^4.3.4",
+				"globby": "^11.1.0",
+				"is-glob": "^4.0.3",
+				"semver": "^7.3.7",
+				"tsutils": "^3.21.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependenciesMeta": {
+				"typescript": {
+					"optional": true
+				}
+			}
+		},
+		"node_modules/@typescript-eslint/utils": {
+			"version": "5.62.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz",
+			"integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==",
+			"dev": true,
+			"dependencies": {
+				"@eslint-community/eslint-utils": "^4.2.0",
+				"@types/json-schema": "^7.0.9",
+				"@types/semver": "^7.3.12",
+				"@typescript-eslint/scope-manager": "5.62.0",
+				"@typescript-eslint/types": "5.62.0",
+				"@typescript-eslint/typescript-estree": "5.62.0",
+				"eslint-scope": "^5.1.1",
+				"semver": "^7.3.7"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			},
+			"peerDependencies": {
+				"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+			}
+		},
+		"node_modules/@typescript-eslint/utils/node_modules/eslint-scope": {
+			"version": "5.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+			"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+			"dev": true,
+			"dependencies": {
+				"esrecurse": "^4.3.0",
+				"estraverse": "^4.1.1"
+			},
+			"engines": {
+				"node": ">=8.0.0"
+			}
+		},
+		"node_modules/@typescript-eslint/utils/node_modules/estraverse": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+			"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+			"dev": true,
+			"engines": {
+				"node": ">=4.0"
+			}
+		},
+		"node_modules/@typescript-eslint/visitor-keys": {
+			"version": "5.62.0",
+			"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
+			"integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/types": "5.62.0",
+				"eslint-visitor-keys": "^3.3.0"
+			},
+			"engines": {
+				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/typescript-eslint"
+			}
+		},
 		"node_modules/@ungap/promise-all-settled": {
 			"version": "1.1.2",
 			"resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
 			"integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
 			"dev": true
 		},
+		"node_modules/@ungap/structured-clone": {
+			"version": "1.2.0",
+			"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+			"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
+			"dev": true
+		},
 		"node_modules/@wikimedia/jsonschema-tools": {
 			"version": "0.7.7",
 			"resolved": "https://registry.npmjs.org/@wikimedia/jsonschema-tools/-/jsonschema-tools-0.7.7.tgz",
@@ -602,9 +838,9 @@
 			}
 		},
 		"node_modules/@wikimedia/jsonschema-tools/node_modules/semver": {
-			"version": "6.3.0",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-			"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+			"version": "6.3.1",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+			"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
 			"dev": true,
 			"bin": {
 				"semver": "bin/semver.js"
@@ -669,9 +905,9 @@
 			}
 		},
 		"node_modules/ansi-regex": {
-			"version": "4.1.0",
-			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
-			"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+			"version": "4.1.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
+			"integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==",
 			"engines": {
 				"node": ">=6"
 			}
@@ -688,9 +924,9 @@
 			}
 		},
 		"node_modules/anymatch": {
-			"version": "3.1.1",
-			"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
-			"integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+			"version": "3.1.3",
+			"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+			"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
 			"dev": true,
 			"dependencies": {
 				"normalize-path": "^3.0.0",
@@ -718,6 +954,15 @@
 			"integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
 			"dev": true
 		},
+		"node_modules/are-docs-informative": {
+			"version": "0.0.2",
+			"resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz",
+			"integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==",
+			"dev": true,
+			"engines": {
+				"node": ">=14"
+			}
+		},
 		"node_modules/argparse": {
 			"version": "1.0.10",
 			"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -750,6 +995,15 @@
 				"node": ">=6"
 			}
 		},
+		"node_modules/array-union": {
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+			"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/asap": {
 			"version": "2.0.6",
 			"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
@@ -827,12 +1081,15 @@
 			}
 		},
 		"node_modules/binary-extensions": {
-			"version": "2.2.0",
-			"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
-			"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+			"version": "2.3.0",
+			"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+			"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
 			"dev": true,
 			"engines": {
 				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
 		"node_modules/bindings": {
@@ -897,9 +1154,9 @@
 			"dev": true
 		},
 		"node_modules/browserslist": {
-			"version": "4.22.1",
-			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
-			"integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
+			"version": "4.23.0",
+			"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
+			"integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
 			"dev": true,
 			"funding": [
 				{
@@ -916,9 +1173,9 @@
 				}
 			],
 			"dependencies": {
-				"caniuse-lite": "^1.0.30001541",
-				"electron-to-chromium": "^1.4.535",
-				"node-releases": "^2.0.13",
+				"caniuse-lite": "^1.0.30001587",
+				"electron-to-chromium": "^1.4.668",
+				"node-releases": "^2.0.14",
 				"update-browserslist-db": "^1.0.13"
 			},
 			"bin": {
@@ -929,9 +1186,9 @@
 			}
 		},
 		"node_modules/browserslist-config-wikimedia": {
-			"version": "0.5.1",
-			"resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.5.1.tgz",
-			"integrity": "sha512-jf532fUf/gaxiKdHgGCQUT552P5up3RpG+CzLixOQBJ5FwDmYQSRLYHCFUA9s3KMOHh4P3xVp+NUaGNxvtoT9g==",
+			"version": "0.6.1",
+			"resolved": "https://registry.npmjs.org/browserslist-config-wikimedia/-/browserslist-config-wikimedia-0.6.1.tgz",
+			"integrity": "sha512-F3O+12ud7ZwBaiB/RZIMGDgz3nEuXz8RhtdPB4Lkd/WVP5Vy77EqBWRMz4vJ64x8LTTH3BOaHCD2ZuUcgShqyQ==",
 			"dev": true
 		},
 		"node_modules/builtin-modules": {
@@ -946,6 +1203,15 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
+		"node_modules/builtins": {
+			"version": "5.1.0",
+			"resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz",
+			"integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==",
+			"dev": true,
+			"dependencies": {
+				"semver": "^7.0.0"
+			}
+		},
 		"node_modules/bunyan": {
 			"version": "1.8.15",
 			"resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz",
@@ -1018,9 +1284,9 @@
 			}
 		},
 		"node_modules/caniuse-lite": {
-			"version": "1.0.30001549",
-			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001549.tgz",
-			"integrity": "sha512-qRp48dPYSCYaP+KurZLhDYdVE+yEyht/3NlmcJgVQ2VMGt6JL36ndQ/7rgspdZsJuxDPFIo/OzBT2+GmIJ53BA==",
+			"version": "1.0.30001614",
+			"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001614.tgz",
+			"integrity": "sha512-jmZQ1VpmlRwHgdP1/uiKzgiAuGOfLEJsYFP4+GBou/QQ4U6IOJCB4NP1c+1p9RGLpwObcT94jA5/uO+F1vBbog==",
 			"dev": true,
 			"funding": [
 				{
@@ -1057,9 +1323,9 @@
 			}
 		},
 		"node_modules/chokidar": {
-			"version": "3.4.3",
-			"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz",
-			"integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==",
+			"version": "3.5.1",
+			"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
+			"integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
 			"dev": true,
 			"dependencies": {
 				"anymatch": "~3.1.1",
@@ -1074,13 +1340,13 @@
 				"node": ">= 8.10.0"
 			},
 			"optionalDependencies": {
-				"fsevents": "~2.1.2"
+				"fsevents": "~2.3.1"
 			}
 		},
 		"node_modules/ci-info": {
-			"version": "3.9.0",
-			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
-			"integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz",
+			"integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==",
 			"dev": true,
 			"funding": [
 				{
@@ -1095,7 +1361,7 @@
 		"node_modules/clarinet": {
 			"version": "0.11.0",
 			"resolved": "https://registry.npmjs.org/clarinet/-/clarinet-0.11.0.tgz",
-			"integrity": "sha1-bMkSuTE43IZ/wnPNNOqQ6D4FRxk=",
+			"integrity": "sha512-6hgoCgDgdyEtrXsk1tMomUl+S6wnslv2F1muNTOuhQemOhauR+Q0FtBdrj9k+qyIDLm0TVW0QMZ10aeWwRDgIA==",
 			"engines": {
 				"chrome": ">=16.0.912",
 				"firefox": ">=0.8.0",
@@ -1166,9 +1432,9 @@
 			}
 		},
 		"node_modules/comment-parser": {
-			"version": "1.3.1",
-			"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz",
-			"integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==",
+			"version": "1.4.1",
+			"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
+			"integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==",
 			"dev": true,
 			"engines": {
 				"node": ">= 12.0.0"
@@ -1224,15 +1490,28 @@
 			"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
 			"dev": true
 		},
+		"node_modules/core-js-compat": {
+			"version": "3.37.0",
+			"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.0.tgz",
+			"integrity": "sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==",
+			"dev": true,
+			"dependencies": {
+				"browserslist": "^4.23.0"
+			},
+			"funding": {
+				"type": "opencollective",
+				"url": "https://opencollective.com/core-js"
+			}
+		},
 		"node_modules/core-util-is": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
 			"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
 		},
 		"node_modules/coveralls": {
-			"version": "3.1.0",
-			"resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.0.tgz",
-			"integrity": "sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ==",
+			"version": "3.1.1",
+			"resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz",
+			"integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==",
 			"dev": true,
 			"dependencies": {
 				"js-yaml": "^3.13.1",
@@ -1371,14 +1650,26 @@
 			}
 		},
 		"node_modules/diff": {
-			"version": "4.0.2",
-			"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
-			"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+			"version": "5.0.0",
+			"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
+			"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
 			"dev": true,
 			"engines": {
 				"node": ">=0.3.1"
 			}
 		},
+		"node_modules/dir-glob": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+			"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+			"dev": true,
+			"dependencies": {
+				"path-type": "^4.0.0"
+			},
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/dnscache": {
 			"version": "1.0.2",
 			"resolved": "https://registry.npmjs.org/dnscache/-/dnscache-1.0.2.tgz",
@@ -1431,9 +1722,9 @@
 			}
 		},
 		"node_modules/electron-to-chromium": {
-			"version": "1.4.556",
-			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.556.tgz",
-			"integrity": "sha512-6RPN0hHfzDU8D56E72YkDvnLw5Cj2NMXZGg3UkgyoHxjVhG99KZpsKgBWMmTy0Ei89xwan+rbRsVB9yzATmYzQ==",
+			"version": "1.4.751",
+			"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.751.tgz",
+			"integrity": "sha512-2DEPi++qa89SMGRhufWTiLmzqyuGmNF3SK4+PQetW1JKiZdEpF4XQonJXJCzyuYSA6mauiMhbyVhqYAP45Hvfw==",
 			"dev": true
 		},
 		"node_modules/emoji-regex": {
@@ -1484,18 +1775,19 @@
 			}
 		},
 		"node_modules/eslint": {
-			"version": "8.51.0",
-			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz",
-			"integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==",
+			"version": "8.57.0",
+			"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
+			"integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
 			"dev": true,
 			"dependencies": {
 				"@eslint-community/eslint-utils": "^4.2.0",
 				"@eslint-community/regexpp": "^4.6.1",
-				"@eslint/eslintrc": "^2.1.2",
-				"@eslint/js": "8.51.0",
-				"@humanwhocodes/config-array": "^0.11.11",
+				"@eslint/eslintrc": "^2.1.4",
+				"@eslint/js": "8.57.0",
+				"@humanwhocodes/config-array": "^0.11.14",
 				"@humanwhocodes/module-importer": "^1.0.1",
 				"@nodelib/fs.walk": "^1.2.8",
+				"@ungap/structured-clone": "^1.2.0",
 				"ajv": "^6.12.4",
 				"chalk": "^4.0.0",
 				"cross-spawn": "^7.0.2",
@@ -1537,28 +1829,44 @@
 				"url": "https://opencollective.com/eslint"
 			}
 		},
+		"node_modules/eslint-compat-utils": {
+			"version": "0.5.0",
+			"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz",
+			"integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==",
+			"dev": true,
+			"dependencies": {
+				"semver": "^7.5.4"
+			},
+			"engines": {
+				"node": ">=12"
+			},
+			"peerDependencies": {
+				"eslint": ">=6.0.0"
+			}
+		},
 		"node_modules/eslint-config-wikimedia": {
-			"version": "0.25.1",
-			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.25.1.tgz",
-			"integrity": "sha512-1ppDlbwSSPuMLAIzvTXSDWNOEq3VnRu82jbc1jaG0aCjE3PpBVOEKUh0bbCk/mFVWEocUNeYIYeL9BHADq9ReA==",
+			"version": "0.27.0",
+			"resolved": "https://registry.npmjs.org/eslint-config-wikimedia/-/eslint-config-wikimedia-0.27.0.tgz",
+			"integrity": "sha512-KkZ54+MUnggz17C/RCEMXQSpiiqZRF7p9fjrz4phaaeKlTrjg0B+QbM5zcDWcjGiAWaJUptHaH17+RZldadkUw==",
 			"dev": true,
 			"dependencies": {
-				"browserslist-config-wikimedia": "^0.5.0",
-				"eslint": "^8.31.0",
-				"eslint-plugin-compat": "^4.1.4",
-				"eslint-plugin-es-x": "^5.2.1",
-				"eslint-plugin-jsdoc": "39.2.2",
+				"browserslist-config-wikimedia": "^0.6.1",
+				"eslint": "^8.57.0",
+				"eslint-plugin-compat": "^4.2.0",
+				"eslint-plugin-es-x": "^7.6.0",
+				"eslint-plugin-jest": "^27.9.0",
+				"eslint-plugin-jsdoc": "48.2.1",
 				"eslint-plugin-json-es": "^1.5.7",
-				"eslint-plugin-mediawiki": "^0.5.0",
-				"eslint-plugin-mocha": "^9.0.0",
+				"eslint-plugin-mediawiki": "^0.6.0",
+				"eslint-plugin-mocha": "^10.4.1",
+				"eslint-plugin-n": "^16.6.2",
 				"eslint-plugin-no-jquery": "^2.7.0",
-				"eslint-plugin-node": "^11.1.0",
-				"eslint-plugin-qunit": "^7.3.0",
+				"eslint-plugin-qunit": "^8.1.1",
 				"eslint-plugin-security": "^1.7.1",
-				"eslint-plugin-unicorn": "^42.0.0",
-				"eslint-plugin-vue": "^8.7.1",
-				"eslint-plugin-wdio": "^7.19.4",
-				"eslint-plugin-yml": "^0.14.0"
+				"eslint-plugin-unicorn": "^51.0.1",
+				"eslint-plugin-vue": "^9.23.0",
+				"eslint-plugin-wdio": "^8.24.12",
+				"eslint-plugin-yml": "^1.13.2"
 			}
 		},
 		"node_modules/eslint-plugin-compat": {
@@ -1653,43 +1961,71 @@
 			}
 		},
 		"node_modules/eslint-plugin-es-x": {
-			"version": "5.4.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-5.4.0.tgz",
-			"integrity": "sha512-6Mniw760Nhd6brnDy+rz857LD+icZe5wXmsvXSuJ84svM0Q53ulJxpMhTJmpqHaLzYh7fuGAJ8V62ohbmqF+jA==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.6.0.tgz",
+			"integrity": "sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==",
 			"dev": true,
 			"dependencies": {
-				"eslint-utils": "^2.0.0 || ^3.0.0",
-				"regexpp": "^3.0.0"
+				"@eslint-community/eslint-utils": "^4.1.2",
+				"@eslint-community/regexpp": "^4.6.0",
+				"eslint-compat-utils": "^0.5.0"
 			},
 			"engines": {
-				"node": ">=8.10.0"
+				"node": "^14.18.0 || >=16.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/ota-meshi"
 			},
 			"peerDependencies": {
-				"eslint": ">=4.19.1"
+				"eslint": ">=8"
+			}
+		},
+		"node_modules/eslint-plugin-jest": {
+			"version": "27.9.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.9.0.tgz",
+			"integrity": "sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==",
+			"dev": true,
+			"dependencies": {
+				"@typescript-eslint/utils": "^5.10.0"
+			},
+			"engines": {
+				"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+			},
+			"peerDependencies": {
+				"@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0 || ^7.0.0",
+				"eslint": "^7.0.0 || ^8.0.0",
+				"jest": "*"
+			},
+			"peerDependenciesMeta": {
+				"@typescript-eslint/eslint-plugin": {
+					"optional": true
+				},
+				"jest": {
+					"optional": true
+				}
 			}
 		},
 		"node_modules/eslint-plugin-jsdoc": {
-			"version": "39.2.2",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.2.2.tgz",
-			"integrity": "sha512-ybkvja0p9JRzHEd2ST9h+Z47DLOuPyXpeb6r18/zKHdMmggPU1J0/zl+F0phea8ze9rMxi42MJVmGXi2NZ7PpA==",
+			"version": "48.2.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.1.tgz",
+			"integrity": "sha512-iUvbcyDZSO/9xSuRv2HQBw++8VkV/pt3UWtX9cpPH0l7GKPq78QC/6+PmyQHHvNZaTjAce6QVciEbnc6J/zH5g==",
 			"dev": true,
 			"dependencies": {
-				"@es-joy/jsdoccomment": "~0.23.1",
-				"comment-parser": "1.3.1",
+				"@es-joy/jsdoccomment": "~0.42.0",
+				"are-docs-informative": "^0.0.2",
+				"comment-parser": "1.4.1",
 				"debug": "^4.3.4",
 				"escape-string-regexp": "^4.0.0",
-				"esquery": "^1.4.0",
-				"semver": "^7.3.7",
-				"spdx-expression-parse": "^3.0.1"
+				"esquery": "^1.5.0",
+				"is-builtin-module": "^3.2.1",
+				"semver": "^7.6.0",
+				"spdx-expression-parse": "^4.0.0"
 			},
 			"engines": {
-				"node": "^14 || ^16 || ^17"
+				"node": ">=18"
 			},
 			"peerDependencies": {
-				"eslint": "^7.0.0 || ^8.0.0"
+				"eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
 			}
 		},
 		"node_modules/eslint-plugin-jsdoc/node_modules/escape-string-regexp": {
@@ -1718,12 +2054,12 @@
 			}
 		},
 		"node_modules/eslint-plugin-mediawiki": {
-			"version": "0.5.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.5.0.tgz",
-			"integrity": "sha512-rjkHFyv3VDan/dmu7YpD1Rl9h64NOlz4mqqesRN316R+571+ymmb6lXVOdNMbT8H1iPhmtHc+nijVLVkn7pYDw==",
+			"version": "0.6.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mediawiki/-/eslint-plugin-mediawiki-0.6.0.tgz",
+			"integrity": "sha512-a2Zm18N5nPyflBajM2ZWATxucIpYPEmOSjFzUR1OBH3hAL0GY9fx1mpezEwzqAQ862d+kPkolgQOzktnZe8nKA==",
 			"dev": true,
 			"dependencies": {
-				"eslint-plugin-vue": "^8.7.1",
+				"eslint-plugin-vue": "^9.23.0",
 				"upath": "^2.0.1"
 			},
 			"peerDependencies": {
@@ -1731,143 +2067,82 @@
 			}
 		},
 		"node_modules/eslint-plugin-mocha": {
-			"version": "9.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-9.0.0.tgz",
-			"integrity": "sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg==",
-			"dev": true,
-			"dependencies": {
-				"eslint-utils": "^3.0.0",
-				"ramda": "^0.27.1"
-			},
-			"engines": {
-				"node": ">=12.0.0"
-			},
-			"peerDependencies": {
-				"eslint": ">=7.0.0"
-			}
-		},
-		"node_modules/eslint-plugin-mocha/node_modules/eslint-utils": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-			"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
-			"dev": true,
-			"dependencies": {
-				"eslint-visitor-keys": "^2.0.0"
-			},
-			"engines": {
-				"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/mysticatea"
-			},
-			"peerDependencies": {
-				"eslint": ">=5"
-			}
-		},
-		"node_modules/eslint-plugin-mocha/node_modules/eslint-visitor-keys": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
-			"dev": true,
-			"engines": {
-				"node": ">=10"
-			}
-		},
-		"node_modules/eslint-plugin-no-jquery": {
-			"version": "2.7.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.7.0.tgz",
-			"integrity": "sha512-Aeg7dA6GTH1AcWLlBtWNzOU9efK5KpNi7b0EhBO0o0M+awyzguUUo8gF6hXGjQ9n5h8/uRtYv9zOqQkeC5CG0w==",
-			"dev": true,
-			"peerDependencies": {
-				"eslint": ">=2.3.0"
-			}
-		},
-		"node_modules/eslint-plugin-node": {
-			"version": "11.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
-			"integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==",
-			"dev": true,
-			"dependencies": {
-				"eslint-plugin-es": "^3.0.0",
-				"eslint-utils": "^2.0.0",
-				"ignore": "^5.1.1",
-				"minimatch": "^3.0.4",
-				"resolve": "^1.10.1",
-				"semver": "^6.1.0"
-			},
-			"engines": {
-				"node": ">=8.10.0"
-			},
-			"peerDependencies": {
-				"eslint": ">=5.16.0"
-			}
-		},
-		"node_modules/eslint-plugin-node/node_modules/eslint-plugin-es": {
-			"version": "3.0.1",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz",
-			"integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==",
-			"dev": true,
-			"dependencies": {
-				"eslint-utils": "^2.0.0",
-				"regexpp": "^3.0.0"
-			},
-			"engines": {
-				"node": ">=8.10.0"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/mysticatea"
-			},
-			"peerDependencies": {
-				"eslint": ">=4.19.1"
-			}
-		},
-		"node_modules/eslint-plugin-node/node_modules/semver": {
-			"version": "6.3.0",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-			"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
-			"dev": true,
-			"bin": {
-				"semver": "bin/semver.js"
-			}
-		},
-		"node_modules/eslint-plugin-qunit": {
-			"version": "7.3.4",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-7.3.4.tgz",
-			"integrity": "sha512-EbDM0zJerH9zVdUswMJpcFF7wrrpvsGuYfNexUpa5hZkkdFhaFcX+yD+RSK4Nrauw4psMGlcqeWUMhaVo+Manw==",
+			"version": "10.4.3",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.3.tgz",
+			"integrity": "sha512-emc4TVjq5Ht0/upR+psftuz6IBG5q279p+1dSRDeHf+NS9aaerBi3lXKo1SEzwC29hFIW21gO89CEWSvRsi8IQ==",
 			"dev": true,
 			"dependencies": {
 				"eslint-utils": "^3.0.0",
-				"requireindex": "^1.2.0"
+				"globals": "^13.24.0",
+				"rambda": "^7.4.0"
 			},
 			"engines": {
-				"node": "12.x || 14.x || >=16.0.0"
+				"node": ">=14.0.0"
+			},
+			"peerDependencies": {
+				"eslint": ">=7.0.0"
 			}
 		},
-		"node_modules/eslint-plugin-qunit/node_modules/eslint-utils": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-			"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+		"node_modules/eslint-plugin-n": {
+			"version": "16.6.2",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz",
+			"integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==",
 			"dev": true,
 			"dependencies": {
-				"eslint-visitor-keys": "^2.0.0"
+				"@eslint-community/eslint-utils": "^4.4.0",
+				"builtins": "^5.0.1",
+				"eslint-plugin-es-x": "^7.5.0",
+				"get-tsconfig": "^4.7.0",
+				"globals": "^13.24.0",
+				"ignore": "^5.2.4",
+				"is-builtin-module": "^3.2.1",
+				"is-core-module": "^2.12.1",
+				"minimatch": "^3.1.2",
+				"resolve": "^1.22.2",
+				"semver": "^7.5.3"
 			},
 			"engines": {
-				"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
+				"node": ">=16.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/mysticatea"
 			},
 			"peerDependencies": {
-				"eslint": ">=5"
+				"eslint": ">=7.0.0"
 			}
 		},
-		"node_modules/eslint-plugin-qunit/node_modules/eslint-visitor-keys": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+		"node_modules/eslint-plugin-n/node_modules/minimatch": {
+			"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"
+			},
 			"engines": {
-				"node": ">=10"
+				"node": "*"
+			}
+		},
+		"node_modules/eslint-plugin-no-jquery": {
+			"version": "2.7.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.7.0.tgz",
+			"integrity": "sha512-Aeg7dA6GTH1AcWLlBtWNzOU9efK5KpNi7b0EhBO0o0M+awyzguUUo8gF6hXGjQ9n5h8/uRtYv9zOqQkeC5CG0w==",
+			"dev": true,
+			"peerDependencies": {
+				"eslint": ">=2.3.0"
+			}
+		},
+		"node_modules/eslint-plugin-qunit": {
+			"version": "8.1.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-8.1.1.tgz",
+			"integrity": "sha512-j3xhiAf2Wvr8Dfwl5T6tlJ+F55vqYE9ZdAHUOTzq1lGerYrXzOS46RvK4SSWug2D8sl3ZYr2lA4/hgVXgLloxw==",
+			"dev": true,
+			"dependencies": {
+				"eslint-utils": "^3.0.0",
+				"requireindex": "^1.2.0"
+			},
+			"engines": {
+				"node": "^16.0.0 || ^18.0.0 || >=20.0.0"
 			}
 		},
 		"node_modules/eslint-plugin-security": {
@@ -1880,132 +2155,95 @@
 			}
 		},
 		"node_modules/eslint-plugin-unicorn": {
-			"version": "42.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-42.0.0.tgz",
-			"integrity": "sha512-ixBsbhgWuxVaNlPTT8AyfJMlhyC5flCJFjyK3oKE8TRrwBnaHvUbuIkCM1lqg8ryYrFStL/T557zfKzX4GKSlg==",
+			"version": "51.0.1",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-51.0.1.tgz",
+			"integrity": "sha512-MuR/+9VuB0fydoI0nIn2RDA5WISRn4AsJyNSaNKLVwie9/ONvQhxOBbkfSICBPnzKrB77Fh6CZZXjgTt/4Latw==",
 			"dev": true,
 			"dependencies": {
-				"@babel/helper-validator-identifier": "^7.15.7",
-				"ci-info": "^3.3.0",
+				"@babel/helper-validator-identifier": "^7.22.20",
+				"@eslint-community/eslint-utils": "^4.4.0",
+				"@eslint/eslintrc": "^2.1.4",
+				"ci-info": "^4.0.0",
 				"clean-regexp": "^1.0.0",
-				"eslint-utils": "^3.0.0",
-				"esquery": "^1.4.0",
+				"core-js-compat": "^3.34.0",
+				"esquery": "^1.5.0",
 				"indent-string": "^4.0.0",
-				"is-builtin-module": "^3.1.0",
-				"lodash": "^4.17.21",
+				"is-builtin-module": "^3.2.1",
+				"jsesc": "^3.0.2",
 				"pluralize": "^8.0.0",
 				"read-pkg-up": "^7.0.1",
-				"regexp-tree": "^0.1.24",
-				"safe-regex": "^2.1.1",
-				"semver": "^7.3.5",
+				"regexp-tree": "^0.1.27",
+				"regjsparser": "^0.10.0",
+				"semver": "^7.5.4",
 				"strip-indent": "^3.0.0"
 			},
 			"engines": {
-				"node": ">=12"
+				"node": ">=16"
 			},
 			"funding": {
 				"url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1"
 			},
 			"peerDependencies": {
-				"eslint": ">=8.8.0"
+				"eslint": ">=8.56.0"
 			}
 		},
-		"node_modules/eslint-plugin-unicorn/node_modules/eslint-utils": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-			"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+		"node_modules/eslint-plugin-unicorn/node_modules/jsesc": {
+			"version": "3.0.2",
+			"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+			"integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
 			"dev": true,
-			"dependencies": {
-				"eslint-visitor-keys": "^2.0.0"
-			},
-			"engines": {
-				"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/mysticatea"
+			"bin": {
+				"jsesc": "bin/jsesc"
 			},
-			"peerDependencies": {
-				"eslint": ">=5"
-			}
-		},
-		"node_modules/eslint-plugin-unicorn/node_modules/eslint-visitor-keys": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
-			"dev": true,
 			"engines": {
-				"node": ">=10"
+				"node": ">=6"
 			}
 		},
 		"node_modules/eslint-plugin-vue": {
-			"version": "8.7.1",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-8.7.1.tgz",
-			"integrity": "sha512-28sbtm4l4cOzoO1LtzQPxfxhQABararUb1JtqusQqObJpWX2e/gmVyeYVfepizPFne0Q5cILkYGiBoV36L12Wg==",
+			"version": "9.25.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.25.0.tgz",
+			"integrity": "sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==",
 			"dev": true,
 			"dependencies": {
-				"eslint-utils": "^3.0.0",
+				"@eslint-community/eslint-utils": "^4.4.0",
+				"globals": "^13.24.0",
 				"natural-compare": "^1.4.0",
-				"nth-check": "^2.0.1",
-				"postcss-selector-parser": "^6.0.9",
-				"semver": "^7.3.5",
-				"vue-eslint-parser": "^8.0.1"
-			},
-			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-			},
-			"peerDependencies": {
-				"eslint": "^6.2.0 || ^7.0.0 || ^8.0.0"
-			}
-		},
-		"node_modules/eslint-plugin-vue/node_modules/eslint-utils": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
-			"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
-			"dev": true,
-			"dependencies": {
-				"eslint-visitor-keys": "^2.0.0"
+				"nth-check": "^2.1.1",
+				"postcss-selector-parser": "^6.0.15",
+				"semver": "^7.6.0",
+				"vue-eslint-parser": "^9.4.2",
+				"xml-name-validator": "^4.0.0"
 			},
 			"engines": {
-				"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
-			},
-			"funding": {
-				"url": "https://github.com/sponsors/mysticatea"
+				"node": "^14.17.0 || >=16.0.0"
 			},
 			"peerDependencies": {
-				"eslint": ">=5"
-			}
-		},
-		"node_modules/eslint-plugin-vue/node_modules/eslint-visitor-keys": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
-			"dev": true,
-			"engines": {
-				"node": ">=10"
+				"eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
 			}
 		},
 		"node_modules/eslint-plugin-wdio": {
-			"version": "7.25.3",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-7.25.3.tgz",
-			"integrity": "sha512-2zbYwV14Md9FNlyhaIILVGPB6w4bu2eJdOTywDUs2Qy4ebcQNwrxB0qCaf7Rm4O+T0Ir+tdYHYBBfbDocSLKng==",
+			"version": "8.24.12",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-wdio/-/eslint-plugin-wdio-8.24.12.tgz",
+			"integrity": "sha512-OmzGteXFOQnJDdkTNnTfksaVa18WlFCyeLjZXHvDpkbomLWAg9wc296Pr0wnTCagqNj8qfEHpy+N2XVew5VCMA==",
 			"dev": true,
 			"engines": {
-				"node": ">=12.0.0"
+				"node": "^16.13 || >=18"
 			}
 		},
 		"node_modules/eslint-plugin-yml": {
-			"version": "0.14.0",
-			"resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-0.14.0.tgz",
-			"integrity": "sha512-+0+bBV/07txENbxfrHF9olGoLCHez64vmnOmjWOoLwmXOwfdaSRleBSPIi4nWQs7WwX8lm/fSLadOjbVEcsXQQ==",
+			"version": "1.14.0",
+			"resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.14.0.tgz",
+			"integrity": "sha512-ESUpgYPOcAYQO9czugcX5OqRvn/ydDVwGCPXY4YjPqc09rHaUVUA6IE6HLQys4rXk/S+qx3EwTd1wHCwam/OWQ==",
 			"dev": true,
 			"dependencies": {
 				"debug": "^4.3.2",
+				"eslint-compat-utils": "^0.5.0",
 				"lodash": "^4.17.21",
 				"natural-compare": "^1.4.0",
-				"yaml-eslint-parser": "^0.5.0"
+				"yaml-eslint-parser": "^1.2.1"
 			},
 			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+				"node": "^14.17.0 || >=16.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/ota-meshi"
@@ -2031,27 +2269,30 @@
 			}
 		},
 		"node_modules/eslint-utils": {
-			"version": "2.1.0",
-			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
-			"integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+			"integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
 			"dev": true,
 			"dependencies": {
-				"eslint-visitor-keys": "^1.1.0"
+				"eslint-visitor-keys": "^2.0.0"
 			},
 			"engines": {
-				"node": ">=6"
+				"node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/mysticatea"
+			},
+			"peerDependencies": {
+				"eslint": ">=5"
 			}
 		},
 		"node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
-			"version": "1.3.0",
-			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
-			"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+			"version": "2.1.0",
+			"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+			"integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
 			"dev": true,
 			"engines": {
-				"node": ">=4"
+				"node": ">=10"
 			}
 		},
 		"node_modules/eslint-visitor-keys": {
@@ -2370,6 +2611,22 @@
 			"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
 			"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
 		},
+		"node_modules/fast-glob": {
+			"version": "3.3.2",
+			"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+			"integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+			"dev": true,
+			"dependencies": {
+				"@nodelib/fs.stat": "^2.0.2",
+				"@nodelib/fs.walk": "^1.2.3",
+				"glob-parent": "^5.1.2",
+				"merge2": "^1.3.0",
+				"micromatch": "^4.0.4"
+			},
+			"engines": {
+				"node": ">=8.6.0"
+			}
+		},
 		"node_modules/fast-json-stable-stringify": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
@@ -2606,10 +2863,9 @@
 			"dev": true
 		},
 		"node_modules/fsevents": {
-			"version": "2.1.3",
-			"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
-			"integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
-			"deprecated": "\"Please update to latest v2.3 or v2.2\"",
+			"version": "2.3.3",
+			"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+			"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
 			"dev": true,
 			"hasInstallScript": true,
 			"optional": true,
@@ -2621,10 +2877,13 @@
 			}
 		},
 		"node_modules/function-bind": {
-			"version": "1.1.1",
-			"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-			"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-			"dev": true
+			"version": "1.1.2",
+			"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+			"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+			"dev": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
 		},
 		"node_modules/gc-stats": {
 			"version": "1.4.0",
@@ -3296,6 +3555,18 @@
 				"node": ">=8.0.0"
 			}
 		},
+		"node_modules/get-tsconfig": {
+			"version": "4.7.3",
+			"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz",
+			"integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==",
+			"dev": true,
+			"dependencies": {
+				"resolve-pkg-maps": "^1.0.0"
+			},
+			"funding": {
+				"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+			}
+		},
 		"node_modules/getpass": {
 			"version": "0.1.7",
 			"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@@ -3333,9 +3604,9 @@
 			}
 		},
 		"node_modules/globals": {
-			"version": "13.23.0",
-			"resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
-			"integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
+			"version": "13.24.0",
+			"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+			"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
 			"dev": true,
 			"dependencies": {
 				"type-fest": "^0.20.2"
@@ -3359,6 +3630,26 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
+		"node_modules/globby": {
+			"version": "11.1.0",
+			"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+			"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+			"dev": true,
+			"dependencies": {
+				"array-union": "^2.1.0",
+				"dir-glob": "^3.0.1",
+				"fast-glob": "^3.2.9",
+				"ignore": "^5.2.0",
+				"merge2": "^1.4.1",
+				"slash": "^3.0.0"
+			},
+			"engines": {
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
+			}
+		},
 		"node_modules/graceful-fs": {
 			"version": "4.2.4",
 			"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
@@ -3401,18 +3692,6 @@
 				"node": ">=6"
 			}
 		},
-		"node_modules/has": {
-			"version": "1.0.3",
-			"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-			"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-			"dev": true,
-			"dependencies": {
-				"function-bind": "^1.1.1"
-			},
-			"engines": {
-				"node": ">= 0.4.0"
-			}
-		},
 		"node_modules/has-flag": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@@ -3438,10 +3717,22 @@
 				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
+		"node_modules/hasown": {
+			"version": "2.0.2",
+			"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+			"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+			"dev": true,
+			"dependencies": {
+				"function-bind": "^1.1.2"
+			},
+			"engines": {
+				"node": ">= 0.4"
+			}
+		},
 		"node_modules/hat": {
 			"version": "0.0.3",
 			"resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz",
-			"integrity": "sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo=",
+			"integrity": "sha512-zpImx2GoKXy42fVDSEad2BPKuSQdLcqsCYa48K3zHSzM/ugWuYjLDr8IXxpVuL7uCLHw56eaiLxCRthhOzf5ug==",
 			"engines": {
 				"node": "*"
 			}
@@ -3543,9 +3834,9 @@
 			}
 		},
 		"node_modules/ignore": {
-			"version": "5.2.4",
-			"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
-			"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+			"version": "5.3.1",
+			"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
+			"integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
 			"dev": true,
 			"engines": {
 				"node": ">= 4"
@@ -3634,12 +3925,12 @@
 			}
 		},
 		"node_modules/is-core-module": {
-			"version": "2.2.0",
-			"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
-			"integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
+			"version": "2.13.1",
+			"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
+			"integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
 			"dev": true,
 			"dependencies": {
-				"has": "^1.0.3"
+				"hasown": "^2.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/ljharb"
@@ -3727,7 +4018,7 @@
 		"node_modules/isarray": {
 			"version": "1.0.0",
 			"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-			"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+			"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
 		},
 		"node_modules/isexe": {
 			"version": "2.0.0",
@@ -3777,9 +4068,9 @@
 			}
 		},
 		"node_modules/istanbul-lib-instrument/node_modules/semver": {
-			"version": "6.3.0",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-			"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+			"version": "6.3.1",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+			"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
 			"dev": true,
 			"bin": {
 				"semver": "bin/semver.js"
@@ -3961,9 +4252,9 @@
 			"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
 		},
 		"node_modules/jsdoc-type-pratt-parser": {
-			"version": "2.2.5",
-			"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-2.2.5.tgz",
-			"integrity": "sha512-2a6eRxSxp1BW040hFvaJxhsCMI9lT8QB8t14t+NY5tC5rckIR0U9cr2tjOeaFirmEOy6MHvmJnY7zTBHq431Lw==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz",
+			"integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==",
 			"dev": true,
 			"engines": {
 				"node": ">=12.0.0"
@@ -3988,9 +4279,9 @@
 			"dev": true
 		},
 		"node_modules/json-schema": {
-			"version": "0.2.3",
-			"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-			"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+			"version": "0.4.0",
+			"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+			"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
 		},
 		"node_modules/json-schema-compare": {
 			"version": "0.2.2",
@@ -4041,13 +4332,10 @@
 			"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
 		},
 		"node_modules/json5": {
-			"version": "2.1.3",
-			"resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
-			"integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
+			"version": "2.2.3",
+			"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+			"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
 			"dev": true,
-			"dependencies": {
-				"minimist": "^1.2.5"
-			},
 			"bin": {
 				"json5": "lib/cli.js"
 			},
@@ -4065,42 +4353,23 @@
 			}
 		},
 		"node_modules/jsprim": {
-			"version": "1.4.1",
-			"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-			"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
-			"engines": [
-				"node >=0.6.0"
-			],
+			"version": "1.4.2",
+			"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+			"integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
 			"dependencies": {
 				"assert-plus": "1.0.0",
 				"extsprintf": "1.3.0",
-				"json-schema": "0.2.3",
+				"json-schema": "0.4.0",
 				"verror": "1.10.0"
-			}
-		},
-		"node_modules/kad": {
-			"version": "1.3.6",
-			"resolved": "git+ssh://git@github.com/wikimedia/kad.git#96f8f5c8e5a88f5dffed47abc20756e93e16387e",
-			"integrity": "sha512-vGPFf2DWtyb6DnpVkUKNPKlVyiLOxdAaN3Ubbiz2vu2dhBTgq306Rmw4h30i2cluphBRngTMyHqLwSO50PuPUg==",
-			"license": "GPL-3.0",
-			"dependencies": {
-				"async": "^0.9.0",
-				"clarinet": "^0.11.0",
-				"colors": "^1.0.3",
-				"hat": "0.0.3",
-				"kad-fs": "0.0.4",
-				"kad-localstorage": "0.0.7",
-				"kad-memstore": "0.0.1",
-				"lodash": "^4.17.11",
-				"merge": "^1.2.0",
-				"ms": "^0.7.0",
-				"msgpack5": "^3.3.0"
+			},
+			"engines": {
+				"node": ">=0.6.0"
 			}
 		},
 		"node_modules/kad-fs": {
 			"version": "0.0.4",
 			"resolved": "https://registry.npmjs.org/kad-fs/-/kad-fs-0.0.4.tgz",
-			"integrity": "sha1-Aupapc8iIlclV5YnzP1tJmNyKJo=",
+			"integrity": "sha512-VlLY7MuXy+3Tlqn1NJNgNkta6BRposNsJhqqcLv/M5e/rGBAETU33DhlPwV6/RBZKGzylQFkeYaKaoYin+mGZw==",
 			"deprecated": "This package is no longer maintained.",
 			"dependencies": {
 				"readable-stream": "^2.0.4"
@@ -4109,7 +4378,7 @@
 		"node_modules/kad-localstorage": {
 			"version": "0.0.7",
 			"resolved": "https://registry.npmjs.org/kad-localstorage/-/kad-localstorage-0.0.7.tgz",
-			"integrity": "sha1-96LngNpT+yi5Q8LFqJTCeaqBDxc=",
+			"integrity": "sha512-3BEFBPa9cbPvW7WvZSTQHy6dSgw7ob7yTqT+eORWrxm4f4fE26BUVorg36KRbg/W+YWEnippuM68ybFyF3heiA==",
 			"dependencies": {
 				"dom-storage": "^2.0.1"
 			}
@@ -4117,7 +4386,7 @@
 		"node_modules/kad-memstore": {
 			"version": "0.0.1",
 			"resolved": "https://registry.npmjs.org/kad-memstore/-/kad-memstore-0.0.1.tgz",
-			"integrity": "sha1-g8t0hJasSRxxNRBMvla4jKc5JHc=",
+			"integrity": "sha512-fwGvRXWjaSzMed8iQHkZH41wvaoq+3tIhuIbkqBBYFuuJtWoDWqgCYTADGPqLyaLX4Ct8aP5NtAxCaxk4cfcCg==",
 			"deprecated": "This package is no longer maintained.",
 			"dependencies": {
 				"readable-stream": "^2.0.5"
@@ -4161,13 +4430,13 @@
 			}
 		},
 		"node_modules/limitation": {
-			"version": "0.2.1",
-			"resolved": "https://registry.npmjs.org/limitation/-/limitation-0.2.1.tgz",
-			"integrity": "sha512-5lMmsPc9ZtMjBk8rJ8ADKIj6AOgYvRtAuNfboO2TVPZsmcn6gSRyijUsA8KG6DUcJ89/hyQ3cnVRyzO1hbDavw==",
+			"version": "0.2.3",
+			"resolved": "https://registry.npmjs.org/limitation/-/limitation-0.2.3.tgz",
+			"integrity": "sha512-IpIBG7WniPI1Og0HYxlo8JRD2E2pExwuol7hjobcNZSYBBxAamPJdV91Q47uw5/KiUKA+We8a33sh6vD1PQ+Yw==",
 			"dependencies": {
 				"bluebird": "^3.3.1",
-				"kad": "git+https://github.com/wikimedia/kad.git#master",
-				"readable-stream": "^2.0.5"
+				"readable-stream": "^2.0.5",
+				"wikimedia-kad-fork": "^1.3.6"
 			}
 		},
 		"node_modules/lines-and-columns": {
@@ -4339,9 +4608,9 @@
 			}
 		},
 		"node_modules/make-dir/node_modules/semver": {
-			"version": "6.3.0",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-			"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+			"version": "6.3.1",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+			"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
 			"dev": true,
 			"bin": {
 				"semver": "bin/semver.js"
@@ -4352,10 +4621,27 @@
 			"resolved": "https://registry.npmjs.org/mediawiki-title/-/mediawiki-title-0.7.3.tgz",
 			"integrity": "sha512-WFemxDGfv+XMZuF/D+XR7/wggW7Aen6J0MPeJl+UIIeQIrbvVJmMArKLROCDZ0emqZltBUdaxEar7eQEfJKdZQ=="
 		},
-		"node_modules/merge": {
-			"version": "1.2.1",
-			"resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz",
-			"integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ=="
+		"node_modules/merge2": {
+			"version": "1.4.1",
+			"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+			"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+			"dev": true,
+			"engines": {
+				"node": ">= 8"
+			}
+		},
+		"node_modules/micromatch": {
+			"version": "4.0.5",
+			"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+			"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+			"dev": true,
+			"dependencies": {
+				"braces": "^3.0.2",
+				"picomatch": "^2.3.1"
+			},
+			"engines": {
+				"node": ">=8.6"
+			}
 		},
 		"node_modules/mime-db": {
 			"version": "1.45.0",
@@ -4398,10 +4684,13 @@
 			}
 		},
 		"node_modules/minimist": {
-			"version": "1.2.5",
-			"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-			"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
-			"devOptional": true
+			"version": "1.2.8",
+			"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+			"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+			"devOptional": true,
+			"funding": {
+				"url": "https://github.com/sponsors/ljharb"
+			}
 		},
 		"node_modules/mkdirp": {
 			"version": "0.5.5",
@@ -4416,35 +4705,35 @@
 			}
 		},
 		"node_modules/mocha": {
-			"version": "8.2.1",
-			"resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz",
-			"integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==",
+			"version": "8.4.0",
+			"resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz",
+			"integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==",
 			"dev": true,
 			"dependencies": {
 				"@ungap/promise-all-settled": "1.1.2",
 				"ansi-colors": "4.1.1",
 				"browser-stdout": "1.3.1",
-				"chokidar": "3.4.3",
-				"debug": "4.2.0",
-				"diff": "4.0.2",
+				"chokidar": "3.5.1",
+				"debug": "4.3.1",
+				"diff": "5.0.0",
 				"escape-string-regexp": "4.0.0",
 				"find-up": "5.0.0",
 				"glob": "7.1.6",
 				"growl": "1.10.5",
 				"he": "1.2.0",
-				"js-yaml": "3.14.0",
+				"js-yaml": "4.0.0",
 				"log-symbols": "4.0.0",
 				"minimatch": "3.0.4",
-				"ms": "2.1.2",
-				"nanoid": "3.1.12",
+				"ms": "2.1.3",
+				"nanoid": "3.1.20",
 				"serialize-javascript": "5.0.1",
 				"strip-json-comments": "3.1.1",
-				"supports-color": "7.2.0",
+				"supports-color": "8.1.1",
 				"which": "2.0.2",
 				"wide-align": "1.1.3",
-				"workerpool": "6.0.2",
-				"yargs": "13.3.2",
-				"yargs-parser": "13.1.2",
+				"workerpool": "6.1.0",
+				"yargs": "16.2.0",
+				"yargs-parser": "20.2.4",
 				"yargs-unparser": "2.0.0"
 			},
 			"bin": {
@@ -4459,11 +4748,69 @@
 				"url": "https://opencollective.com/mochajs"
 			}
 		},
+		"node_modules/mocha/node_modules/ansi-regex": {
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+			"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
+		"node_modules/mocha/node_modules/ansi-styles": {
+			"version": "4.3.0",
+			"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+			"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+			"dev": true,
+			"dependencies": {
+				"color-convert": "^2.0.1"
+			},
+			"engines": {
+				"node": ">=8"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/ansi-styles?sponsor=1"
+			}
+		},
+		"node_modules/mocha/node_modules/argparse": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+			"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+			"dev": true
+		},
+		"node_modules/mocha/node_modules/cliui": {
+			"version": "7.0.4",
+			"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+			"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+			"dev": true,
+			"dependencies": {
+				"string-width": "^4.2.0",
+				"strip-ansi": "^6.0.0",
+				"wrap-ansi": "^7.0.0"
+			}
+		},
+		"node_modules/mocha/node_modules/color-convert": {
+			"version": "2.0.1",
+			"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+			"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+			"dev": true,
+			"dependencies": {
+				"color-name": "~1.1.4"
+			},
+			"engines": {
+				"node": ">=7.0.0"
+			}
+		},
+		"node_modules/mocha/node_modules/color-name": {
+			"version": "1.1.4",
+			"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+			"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+			"dev": true
+		},
 		"node_modules/mocha/node_modules/debug": {
-			"version": "4.2.0",
-			"resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
-			"integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
-			"deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
+			"version": "4.3.1",
+			"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+			"integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
 			"dev": true,
 			"dependencies": {
 				"ms": "2.1.2"
@@ -4477,6 +4824,18 @@
 				}
 			}
 		},
+		"node_modules/mocha/node_modules/debug/node_modules/ms": {
+			"version": "2.1.2",
+			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+			"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+			"dev": true
+		},
+		"node_modules/mocha/node_modules/emoji-regex": {
+			"version": "8.0.0",
+			"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+			"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+			"dev": true
+		},
 		"node_modules/mocha/node_modules/escape-string-regexp": {
 			"version": "4.0.0",
 			"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
@@ -4525,6 +4884,18 @@
 				"url": "https://github.com/sponsors/isaacs"
 			}
 		},
+		"node_modules/mocha/node_modules/glob/node_modules/minimatch": {
+			"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"
+			},
+			"engines": {
+				"node": "*"
+			}
+		},
 		"node_modules/mocha/node_modules/has-flag": {
 			"version": "4.0.0",
 			"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -4534,14 +4905,22 @@
 				"node": ">=8"
 			}
 		},
+		"node_modules/mocha/node_modules/is-fullwidth-code-point": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+			"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/mocha/node_modules/js-yaml": {
-			"version": "3.14.0",
-			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
-			"integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
+			"integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
 			"dev": true,
 			"dependencies": {
-				"argparse": "^1.0.7",
-				"esprima": "^4.0.0"
+				"argparse": "^2.0.1"
 			},
 			"bin": {
 				"js-yaml": "bin/js-yaml.js"
@@ -4563,9 +4942,9 @@
 			}
 		},
 		"node_modules/mocha/node_modules/ms": {
-			"version": "2.1.2",
-			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-			"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+			"version": "2.1.3",
+			"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+			"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
 			"dev": true
 		},
 		"node_modules/mocha/node_modules/p-limit": {
@@ -4607,105 +4986,98 @@
 				"node": ">=8"
 			}
 		},
-		"node_modules/mocha/node_modules/supports-color": {
-			"version": "7.2.0",
-			"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-			"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+		"node_modules/mocha/node_modules/string-width": {
+			"version": "4.2.3",
+			"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+			"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
 			"dev": true,
 			"dependencies": {
-				"has-flag": "^4.0.0"
+				"emoji-regex": "^8.0.0",
+				"is-fullwidth-code-point": "^3.0.0",
+				"strip-ansi": "^6.0.1"
 			},
 			"engines": {
 				"node": ">=8"
 			}
 		},
-		"node_modules/mocha/node_modules/yargs": {
-			"version": "13.3.2",
-			"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
-			"integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
-			"dev": true,
-			"dependencies": {
-				"cliui": "^5.0.0",
-				"find-up": "^3.0.0",
-				"get-caller-file": "^2.0.1",
-				"require-directory": "^2.1.1",
-				"require-main-filename": "^2.0.0",
-				"set-blocking": "^2.0.0",
-				"string-width": "^3.0.0",
-				"which-module": "^2.0.0",
-				"y18n": "^4.0.0",
-				"yargs-parser": "^13.1.2"
-			}
-		},
-		"node_modules/mocha/node_modules/yargs-parser": {
-			"version": "13.1.2",
-			"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
-			"integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
-			"dev": true,
-			"dependencies": {
-				"camelcase": "^5.0.0",
-				"decamelize": "^1.2.0"
-			}
-		},
-		"node_modules/mocha/node_modules/yargs/node_modules/find-up": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
-			"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+		"node_modules/mocha/node_modules/strip-ansi": {
+			"version": "6.0.1",
+			"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+			"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
 			"dev": true,
 			"dependencies": {
-				"locate-path": "^3.0.0"
+				"ansi-regex": "^5.0.1"
 			},
 			"engines": {
-				"node": ">=6"
+				"node": ">=8"
 			}
 		},
-		"node_modules/mocha/node_modules/yargs/node_modules/locate-path": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
-			"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+		"node_modules/mocha/node_modules/supports-color": {
+			"version": "8.1.1",
+			"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+			"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
 			"dev": true,
 			"dependencies": {
-				"p-locate": "^3.0.0",
-				"path-exists": "^3.0.0"
+				"has-flag": "^4.0.0"
 			},
 			"engines": {
-				"node": ">=6"
+				"node": ">=10"
+			},
+			"funding": {
+				"url": "https://github.com/chalk/supports-color?sponsor=1"
 			}
 		},
-		"node_modules/mocha/node_modules/yargs/node_modules/p-limit": {
-			"version": "2.3.0",
-			"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
-			"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+		"node_modules/mocha/node_modules/wrap-ansi": {
+			"version": "7.0.0",
+			"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+			"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
 			"dev": true,
 			"dependencies": {
-				"p-try": "^2.0.0"
+				"ansi-styles": "^4.0.0",
+				"string-width": "^4.1.0",
+				"strip-ansi": "^6.0.0"
 			},
 			"engines": {
-				"node": ">=6"
+				"node": ">=10"
 			},
 			"funding": {
-				"url": "https://github.com/sponsors/sindresorhus"
+				"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
 			}
 		},
-		"node_modules/mocha/node_modules/yargs/node_modules/p-locate": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
-			"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+		"node_modules/mocha/node_modules/y18n": {
+			"version": "5.0.8",
+			"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+			"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+			"dev": true,
+			"engines": {
+				"node": ">=10"
+			}
+		},
+		"node_modules/mocha/node_modules/yargs": {
+			"version": "16.2.0",
+			"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+			"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
 			"dev": true,
 			"dependencies": {
-				"p-limit": "^2.0.0"
+				"cliui": "^7.0.2",
+				"escalade": "^3.1.1",
+				"get-caller-file": "^2.0.5",
+				"require-directory": "^2.1.1",
+				"string-width": "^4.2.0",
+				"y18n": "^5.0.5",
+				"yargs-parser": "^20.2.2"
 			},
 			"engines": {
-				"node": ">=6"
+				"node": ">=10"
 			}
 		},
-		"node_modules/mocha/node_modules/yargs/node_modules/path-exists": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-			"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+		"node_modules/mocha/node_modules/yargs-parser": {
+			"version": "20.2.4",
+			"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+			"integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
 			"dev": true,
 			"engines": {
-				"node": ">=4"
+				"node": ">=10"
 			}
 		},
 		"node_modules/mock-require": {
@@ -4740,9 +5112,9 @@
 			}
 		},
 		"node_modules/moment": {
-			"version": "2.29.1",
-			"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
-			"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
+			"version": "2.30.1",
+			"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
+			"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
 			"optional": true,
 			"engines": {
 				"node": "*"
@@ -4760,12 +5132,12 @@
 		"node_modules/ms": {
 			"version": "0.7.3",
 			"resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz",
-			"integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8="
+			"integrity": "sha512-lrKNzMWqQZgwJahtrtrM+9NgOoDUveDrVmm5aGXrf3BdtL0mq7X6IVzoZaw+TfNti29eHd1/8GI+h45K5cQ6/w=="
 		},
 		"node_modules/msgpack5": {
-			"version": "3.6.0",
-			"resolved": "https://registry.npmjs.org/msgpack5/-/msgpack5-3.6.0.tgz",
-			"integrity": "sha512-6HuCZHA57WtNUzrKIvjJ8OMxigzveJ6D5i13y6TsgGu3X3zxABpuBvChpppOoGdB9SyWZcmqUs1fwUV/PpSQ7Q==",
+			"version": "3.6.1",
+			"resolved": "https://registry.npmjs.org/msgpack5/-/msgpack5-3.6.1.tgz",
+			"integrity": "sha512-VoY2AaoowHZLLKyEb5FRzuhdSzXn5quGjcMKJOJHJPxp9baYZx5t6jiHUhp5aNRlqqlt+5GXQGovMLNKsrm1hg==",
 			"dependencies": {
 				"bl": "^1.2.1",
 				"inherits": "^2.0.3",
@@ -4798,15 +5170,15 @@
 			"integrity": "sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w=="
 		},
 		"node_modules/nanoid": {
-			"version": "3.1.12",
-			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz",
-			"integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==",
+			"version": "3.1.20",
+			"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
+			"integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==",
 			"dev": true,
 			"bin": {
 				"nanoid": "bin/nanoid.cjs"
 			},
 			"engines": {
-				"node": "^10 || ^12 || >=13.7"
+				"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
 			}
 		},
 		"node_modules/natural-compare": {
@@ -4865,9 +5237,9 @@
 			}
 		},
 		"node_modules/node-releases": {
-			"version": "2.0.13",
-			"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
-			"integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
+			"version": "2.0.14",
+			"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
+			"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
 			"dev": true
 		},
 		"node_modules/normalize-package-data": {
@@ -4954,9 +5326,9 @@
 			}
 		},
 		"node_modules/nyc/node_modules/ansi-regex": {
-			"version": "5.0.0",
-			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
-			"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+			"version": "5.0.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+			"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
 			"dev": true,
 			"engines": {
 				"node": ">=8"
@@ -5348,6 +5720,15 @@
 			"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
 			"dev": true
 		},
+		"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/performance-now": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -5360,9 +5741,9 @@
 			"dev": true
 		},
 		"node_modules/picomatch": {
-			"version": "2.2.2",
-			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
-			"integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+			"version": "2.3.1",
+			"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+			"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
 			"dev": true,
 			"engines": {
 				"node": ">=8.6"
@@ -5498,9 +5879,9 @@
 			}
 		},
 		"node_modules/postcss-selector-parser": {
-			"version": "6.0.13",
-			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
-			"integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
+			"version": "6.0.16",
+			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz",
+			"integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==",
 			"dev": true,
 			"dependencies": {
 				"cssesc": "^3.0.0",
@@ -5593,9 +5974,9 @@
 			}
 		},
 		"node_modules/qs": {
-			"version": "6.5.2",
-			"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
-			"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+			"version": "6.5.3",
+			"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+			"integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
 			"engines": {
 				"node": ">=0.6"
 			}
@@ -5626,10 +6007,10 @@
 			"integrity": "sha512-dy1yjycmn9blucmJLXOfZDx1ikZJUi6E8bBZLnhPG5gBrVhHXx2xVyqqgKBubVNEXmx51dBACMHpoMQK/N/AXQ==",
 			"dev": true
 		},
-		"node_modules/ramda": {
-			"version": "0.27.2",
-			"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.2.tgz",
-			"integrity": "sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==",
+		"node_modules/rambda": {
+			"version": "7.5.0",
+			"resolved": "https://registry.npmjs.org/rambda/-/rambda-7.5.0.tgz",
+			"integrity": "sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA==",
 			"dev": true
 		},
 		"node_modules/randombytes": {
@@ -5739,9 +6120,9 @@
 			}
 		},
 		"node_modules/readable-stream": {
-			"version": "2.3.7",
-			"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
-			"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+			"version": "2.3.8",
+			"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+			"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
 			"dependencies": {
 				"core-util-is": "~1.0.0",
 				"inherits": "~2.0.3",
@@ -5776,17 +6157,17 @@
 			"dev": true
 		},
 		"node_modules/redis": {
-			"version": "3.0.2",
-			"resolved": "https://registry.npmjs.org/redis/-/redis-3.0.2.tgz",
-			"integrity": "sha512-PNhLCrjU6vKVuMOyFu7oSP296mwBkcE6lrAjruBYG5LgdSqtRBoVQIylrMyVZD/lkF24RSNNatzvYag6HRBHjQ==",
+			"version": "3.1.2",
+			"resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz",
+			"integrity": "sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==",
 			"dependencies": {
-				"denque": "^1.4.1",
-				"redis-commands": "^1.5.0",
+				"denque": "^1.5.0",
+				"redis-commands": "^1.7.0",
 				"redis-errors": "^1.2.0",
 				"redis-parser": "^3.0.0"
 			},
 			"engines": {
-				"node": ">=6"
+				"node": ">=10"
 			},
 			"funding": {
 				"type": "opencollective",
@@ -5794,9 +6175,9 @@
 			}
 		},
 		"node_modules/redis-commands": {
-			"version": "1.6.0",
-			"resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.6.0.tgz",
-			"integrity": "sha512-2jnZ0IkjZxvguITjFTrGiLyzQZcTvaw8DAaCXxZq/dsHXz7KfMQ3OUJy7Tz9vnRtZRVz6VRCPDvruvU8Ts44wQ=="
+			"version": "1.7.0",
+			"resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.7.0.tgz",
+			"integrity": "sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ=="
 		},
 		"node_modules/redis-errors": {
 			"version": "1.2.0",
@@ -5845,16 +6226,25 @@
 			"resolved": "https://registry.npmjs.org/regexp-utils/-/regexp-utils-0.3.2.tgz",
 			"integrity": "sha1-Q3bAMYqioP33v8fRUv0BDzJhcPQ="
 		},
-		"node_modules/regexpp": {
-			"version": "3.1.0",
-			"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
-			"integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
+		"node_modules/regjsparser": {
+			"version": "0.10.0",
+			"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz",
+			"integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==",
 			"dev": true,
-			"engines": {
-				"node": ">=8"
+			"dependencies": {
+				"jsesc": "~0.5.0"
 			},
-			"funding": {
-				"url": "https://github.com/sponsors/mysticatea"
+			"bin": {
+				"regjsparser": "bin/parser"
+			}
+		},
+		"node_modules/regjsparser/node_modules/jsesc": {
+			"version": "0.5.0",
+			"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+			"integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+			"dev": true,
+			"bin": {
+				"jsesc": "bin/jsesc"
 			}
 		},
 		"node_modules/release-zalgo": {
@@ -5951,13 +6341,17 @@
 			}
 		},
 		"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.8",
+			"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+			"integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
 			"dev": true,
 			"dependencies": {
-				"is-core-module": "^2.2.0",
-				"path-parse": "^1.0.6"
+				"is-core-module": "^2.13.0",
+				"path-parse": "^1.0.7",
+				"supports-preserve-symlinks-flag": "^1.0.0"
+			},
+			"bin": {
+				"resolve": "bin/resolve"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/ljharb"
@@ -5972,6 +6366,15 @@
 				"node": ">=4"
 			}
 		},
+		"node_modules/resolve-pkg-maps": {
+			"version": "1.0.0",
+			"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+			"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+			"dev": true,
+			"funding": {
+				"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+			}
+		},
 		"node_modules/reusify": {
 			"version": "1.0.4",
 			"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -6057,9 +6460,9 @@
 			"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
 		},
 		"node_modules/semver": {
-			"version": "7.5.4",
-			"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
-			"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+			"version": "7.6.0",
+			"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+			"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
 			"dependencies": {
 				"lru-cache": "^6.0.0"
 			},
@@ -6140,6 +6543,15 @@
 			"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
 			"dev": true
 		},
+		"node_modules/slash": {
+			"version": "3.0.0",
+			"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+			"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/sonic-boom": {
 			"version": "0.7.7",
 			"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-0.7.7.tgz",
@@ -6221,16 +6633,26 @@
 				"spdx-license-ids": "^3.0.0"
 			}
 		},
+		"node_modules/spdx-correct/node_modules/spdx-expression-parse": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"dev": true,
+			"dependencies": {
+				"spdx-exceptions": "^2.1.0",
+				"spdx-license-ids": "^3.0.0"
+			}
+		},
 		"node_modules/spdx-exceptions": {
-			"version": "2.3.0",
-			"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
-			"integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+			"version": "2.5.0",
+			"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
+			"integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
 			"dev": true
 		},
 		"node_modules/spdx-expression-parse": {
-			"version": "3.0.1",
-			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
-			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz",
+			"integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==",
 			"dev": true,
 			"dependencies": {
 				"spdx-exceptions": "^2.1.0",
@@ -6238,9 +6660,9 @@
 			}
 		},
 		"node_modules/spdx-license-ids": {
-			"version": "3.0.16",
-			"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz",
-			"integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==",
+			"version": "3.0.17",
+			"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz",
+			"integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==",
 			"dev": true
 		},
 		"node_modules/split2": {
@@ -6385,6 +6807,18 @@
 				"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/swagger-router": {
 			"version": "0.7.4",
 			"resolved": "https://registry.npmjs.org/swagger-router/-/swagger-router-0.7.4.tgz",
@@ -6407,9 +6841,9 @@
 			}
 		},
 		"node_modules/swagger-ui-dist": {
-			"version": "3.40.0",
-			"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.40.0.tgz",
-			"integrity": "sha512-R0eaS61/cOE6wiFOY7AtmoTBV5lZqmyosuE14G9nAudp5MNsNfCTdI9MWJLs8iF28HXdtH8EACiFFtUbQomHog=="
+			"version": "3.52.5",
+			"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.52.5.tgz",
+			"integrity": "sha512-8z18eX8G/jbTXYzyNIaobrnD7PSN7yU/YkSasMmajrXtw0FGS64XjrKn5v37d36qmU3o1xLeuYnktshRr7uIFw=="
 		},
 		"node_modules/tassembly": {
 			"version": "0.2.3",
@@ -6502,6 +6936,27 @@
 				"node": ">=0.8"
 			}
 		},
+		"node_modules/tslib": {
+			"version": "1.14.1",
+			"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+			"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+			"dev": true
+		},
+		"node_modules/tsutils": {
+			"version": "3.21.0",
+			"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+			"integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
+			"dev": true,
+			"dependencies": {
+				"tslib": "^1.8.1"
+			},
+			"engines": {
+				"node": ">= 6"
+			},
+			"peerDependencies": {
+				"typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
+			}
+		},
 		"node_modules/tunnel-agent": {
 			"version": "0.6.0",
 			"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
@@ -6548,10 +7003,24 @@
 				"is-typedarray": "^1.0.0"
 			}
 		},
+		"node_modules/typescript": {
+			"version": "5.4.5",
+			"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
+			"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
+			"dev": true,
+			"peer": true,
+			"bin": {
+				"tsc": "bin/tsc",
+				"tsserver": "bin/tsserver"
+			},
+			"engines": {
+				"node": ">=14.17"
+			}
+		},
 		"node_modules/underscore": {
-			"version": "1.12.0",
-			"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.0.tgz",
-			"integrity": "sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ=="
+			"version": "1.13.6",
+			"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
+			"integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A=="
 		},
 		"node_modules/universalify": {
 			"version": "0.1.2",
@@ -6651,6 +7120,16 @@
 				"spdx-expression-parse": "^3.0.0"
 			}
 		},
+		"node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": {
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+			"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+			"dev": true,
+			"dependencies": {
+				"spdx-exceptions": "^2.1.0",
+				"spdx-license-ids": "^3.0.0"
+			}
+		},
 		"node_modules/validate.io-array": {
 			"version": "1.0.6",
 			"resolved": "https://registry.npmjs.org/validate.io-array/-/validate.io-array-1.0.6.tgz",
@@ -6702,21 +7181,21 @@
 			}
 		},
 		"node_modules/vue-eslint-parser": {
-			"version": "8.3.0",
-			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz",
-			"integrity": "sha512-dzHGG3+sYwSf6zFBa0Gi9ZDshD7+ad14DGOdTLjruRVgZXe2J+DcZ9iUhyR48z5g1PqRa20yt3Njna/veLJL/g==",
+			"version": "9.4.2",
+			"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.2.tgz",
+			"integrity": "sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==",
 			"dev": true,
 			"dependencies": {
-				"debug": "^4.3.2",
-				"eslint-scope": "^7.0.0",
-				"eslint-visitor-keys": "^3.1.0",
-				"espree": "^9.0.0",
+				"debug": "^4.3.4",
+				"eslint-scope": "^7.1.1",
+				"eslint-visitor-keys": "^3.3.0",
+				"espree": "^9.3.1",
 				"esquery": "^1.4.0",
 				"lodash": "^4.17.21",
-				"semver": "^7.3.5"
+				"semver": "^7.3.6"
 			},
 			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+				"node": "^14.17.0 || >=16.0.0"
 			},
 			"funding": {
 				"url": "https://github.com/sponsors/mysticatea"
@@ -6760,9 +7239,9 @@
 			}
 		},
 		"node_modules/wide-align/node_modules/ansi-regex": {
-			"version": "3.0.0",
-			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
-			"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+			"version": "3.0.1",
+			"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
+			"integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
 			"dev": true,
 			"engines": {
 				"node": ">=4"
@@ -6793,10 +7272,27 @@
 				"node": ">=4"
 			}
 		},
+		"node_modules/wikimedia-kad-fork": {
+			"version": "1.3.6",
+			"resolved": "https://registry.npmjs.org/wikimedia-kad-fork/-/wikimedia-kad-fork-1.3.6.tgz",
+			"integrity": "sha512-m+IxFN4JatoQPRo0N46xMh7tR6FSznb/ithIchAy7Wg9mrkc4/bE/3BhlJS410quFJFrJp8lJJp93g4uTbj4lA==",
+			"dependencies": {
+				"async": "^0.9.0",
+				"clarinet": "^0.11.0",
+				"colors": "^1.0.3",
+				"hat": "0.0.3",
+				"kad-fs": "0.0.4",
+				"kad-localstorage": "0.0.7",
+				"kad-memstore": "0.0.1",
+				"lodash": "^4.17.11",
+				"ms": "^0.7.0",
+				"msgpack5": "^3.3.0"
+			}
+		},
 		"node_modules/workerpool": {
-			"version": "6.0.2",
-			"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz",
-			"integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==",
+			"version": "6.1.0",
+			"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz",
+			"integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==",
 			"dev": true
 		},
 		"node_modules/wrap-ansi": {
@@ -6830,6 +7326,15 @@
 				"typedarray-to-buffer": "^3.1.5"
 			}
 		},
+		"node_modules/xml-name-validator": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
+			"integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
+			"dev": true,
+			"engines": {
+				"node": ">=12"
+			}
+		},
 		"node_modules/y18n": {
 			"version": "4.0.1",
 			"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
@@ -6841,26 +7346,32 @@
 			"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
 		},
 		"node_modules/yaml": {
-			"version": "1.10.2",
-			"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
-			"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+			"version": "2.4.2",
+			"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz",
+			"integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==",
 			"dev": true,
+			"bin": {
+				"yaml": "bin.mjs"
+			},
 			"engines": {
-				"node": ">= 6"
+				"node": ">= 14"
 			}
 		},
 		"node_modules/yaml-eslint-parser": {
-			"version": "0.5.0",
-			"resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-0.5.0.tgz",
-			"integrity": "sha512-nJeyLA3YHAzhBTZbRAbu3W6xrSCucyxExmA+ZDtEdUFpGllxAZpto2Zxo2IG0r0eiuEiBM4e+wiAdxTziTq94g==",
+			"version": "1.2.2",
+			"resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz",
+			"integrity": "sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==",
 			"dev": true,
 			"dependencies": {
 				"eslint-visitor-keys": "^3.0.0",
 				"lodash": "^4.17.21",
-				"yaml": "^1.10.2"
+				"yaml": "^2.0.0"
 			},
 			"engines": {
-				"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+				"node": "^14.17.0 || >=16.0.0"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/ota-meshi"
 			}
 		},
 		"node_modules/yargs": {
diff --git a/package.json b/package.json
index 97f2c6f..6e15f3b 100644
--- a/package.json
+++ b/package.json
@@ -56,7 +56,7 @@
 		"@wikimedia/jsonschema-tools": "^0.7.5",
 		"ajv": "^6.12.2",
 		"coveralls": "^3.1.0",
-		"eslint-config-wikimedia": "0.25.1",
+		"eslint-config-wikimedia": "0.27.0",
 		"js-yaml": "^3.14.0",
 		"kafka-test-tools": "^0.1.13",
 		"mocha": "^8.0.1",
diff --git a/sys/deduplicator.js b/sys/deduplicator.js
index e34bd53..101d98a 100644
--- a/sys/deduplicator.js
+++ b/sys/deduplicator.js
@@ -25,12 +25,12 @@ class Deduplicator extends mixins.mix(Object).with(mixins.Redis) {
     checkDuplicate(hyper, req) {
         const name = req.params.name;
         const message = req.body;
-        const prefix = `${this._prefix}_dedupe_${name}`;
+        const prefix = `${ this._prefix }_dedupe_${ name }`;
 
         // First, look at the individual event duplication based on ID
         // This happens when we restart ChangeProp and reread some of the
         // exact same events which were executed but was not committed.
-        const messageKeyWithId = `${prefix}_${message.meta.domain}_${message.meta.id}`;
+        const messageKeyWithId = `${ prefix }_${ message.meta.domain }_${ message.meta.id }`;
         return this._redis.setnxAsync(messageKeyWithId, '1')
         // Expire the key or renew the expiration timestamp if the key existed
         .tap(() => this._redis.expireAsync(messageKeyWithId, Math.ceil(this._expire_timeout / 24)))
@@ -39,7 +39,7 @@ class Deduplicator extends mixins.mix(Object).with(mixins.Redis) {
             if (setResult) {
                 return NOT_DUPLICATE;
             }
-            hyper.metrics.increment(`${name}_dedupe`);
+            hyper.metrics.increment(`${ name }_dedupe`);
             hyper.logger.log('trace/dedupe', () => ({
                 message: 'Event was deduplicated based on id',
                 event_str: utils.stringify(message)
@@ -52,7 +52,7 @@ class Deduplicator extends mixins.mix(Object).with(mixins.Redis) {
                 // don't try to deduplicate by SHA-1
                 return individualDuplicate;
             }
-            const messageKeyWithSha = `${prefix}_${message.meta.domain}_${message.sha1}`;
+            const messageKeyWithSha = `${ prefix }_${ message.meta.domain }_${ message.sha1 }`;
             return this._redis.getAsync(messageKeyWithSha)
             .then((previousExecutionTime) => {
                 // If the same event (by sha1) was created before the previous execution
@@ -65,7 +65,7 @@ class Deduplicator extends mixins.mix(Object).with(mixins.Redis) {
                         // side - subtract 1 second from the previous execution time to allow for
                         // some lag.
                         new Date(previousExecutionTime) - 1000 > new Date(message.meta.dt)) {
-                    hyper.metrics.increment(`${name}_dedupe`);
+                    hyper.metrics.increment(`${ name }_dedupe`);
                     hyper.logger.log('trace/dedupe', () => ({
                         message: 'Event was deduplicated based on sha1',
                         event_str: utils.stringify(message),
@@ -80,7 +80,7 @@ class Deduplicator extends mixins.mix(Object).with(mixins.Redis) {
                         message.root_event &&
                         new Date(previousExecutionTime) - 1000 >
                             new Date(message.root_event.dt)) {
-                    hyper.metrics.increment(`${name}_dedupe`);
+                    hyper.metrics.increment(`${ name }_dedupe`);
                     hyper.logger.log('trace/dedupe', () => ({
                         message: 'Event was deduplicated based on sha1 and root_event dt',
                         event_str: utils.stringify(message),
@@ -101,14 +101,14 @@ class Deduplicator extends mixins.mix(Object).with(mixins.Redis) {
                 return sha1Duplicate;
             }
 
-            const rootEventKey = `${prefix}_${message.root_event.signature}`;
+            const rootEventKey = `${ prefix }_${ message.root_event.signature }`;
             return this._redis.getAsync(rootEventKey)
             .then((oldEventTimestamp) => {
                 // If this event was caused by root event and there was a leaf event executed
                 // already that belonged to a later root_event we can cut off this chain.
                 if (oldEventTimestamp &&
                         new Date(oldEventTimestamp) > new Date(message.root_event.dt)) {
-                    hyper.metrics.increment(`${name}_dedupe`);
+                    hyper.metrics.increment(`${ name }_dedupe`);
                     hyper.logger.log('trace/dedupe', () => ({
                         message: 'Event was deduplicated based on root event',
                         event_str: utils.stringify(message),
diff --git a/sys/dep_updates.js b/sys/dep_updates.js
index beee6d6..8f363b8 100644
--- a/sys/dep_updates.js
+++ b/sys/dep_updates.js
@@ -143,7 +143,7 @@ function _sendResourceChanges(hyper, items, originalEvent, tags, streamName) {
         body: items.map((item) => {
             // TODO: need to check whether a wiki is http or https!
             const resourceURI =
-                `https://${item.domain}/wiki/${encodeURIComponent(item.title)}`;
+                `https://${ item.domain }/wiki/${ encodeURIComponent(item.title) }`;
             return {
                 $schema: '/resource_change/1.0.0',
                 meta: {
@@ -275,7 +275,7 @@ class DependencyProcessor {
             }))
             .then((res) => {
                 if (!res || !res.body || !res.body.query || !res.body.query.general) {
-                    throw new Error(`SiteInfo is unavailable for ${message.meta.domain}`);
+                    throw new Error(`SiteInfo is unavailable for ${ message.meta.domain }`);
                 }
                 return {
                     general: {
diff --git a/sys/kafka.js b/sys/kafka.js
index 1578c66..1468bd1 100644
--- a/sys/kafka.js
+++ b/sys/kafka.js
@@ -88,8 +88,8 @@ class Kafka {
                 });
             }
             hyper.metrics.increment(
-                `produce_${hyper.metrics.normalizeName(message.meta.stream.replace(/\./g, '_'))}.${partition}`);
-            return this.producer.produce(`${this.kafkaFactory.produceDC}.${message.meta.stream}`,
+                `produce_${ hyper.metrics.normalizeName(message.meta.stream.replace(/\./g, '_')) }.${ partition }`);
+            return this.producer.produce(`${ this.kafkaFactory.produceDC }.${ message.meta.stream }`,
                 partition,
                 Buffer.from(JSON.stringify(message)));
         }))
diff --git a/sys/ores_updates.js b/sys/ores_updates.js
index e4c930c..594a2f5 100644
--- a/sys/ores_updates.js
+++ b/sys/ores_updates.js
@@ -54,7 +54,7 @@ class OresProcessor {
             // https://phabricator.wikimedia.org/T210465#4797591
 
             const domainScores = res.body[newMessage.database];
-            const revScores = domainScores.scores[`${newMessage.rev_id}`];
+            const revScores = domainScores.scores[`${ newMessage.rev_id }`];
             Object.keys(revScores).forEach((modelName) => {
                 // The example schema for the score object:
                 //   {
@@ -88,7 +88,7 @@ class OresProcessor {
                     if (!Array.isArray(prediction)) {
                         prediction = [ prediction ];
                     }
-                    score[modelName].prediction = prediction.map(p => `${p}`);
+                    score[modelName].prediction = prediction.map(p => `${ p }`);
                     // Convert probabilities to an array of name-value pairs.
                     score[modelName].probability = Object.keys(originalScore.probability)
                         .reduce((obj, probName) => Object.assign(
diff --git a/sys/partitioner.js b/sys/partitioner.js
index 0b11f48..8d72c71 100644
--- a/sys/partitioner.js
+++ b/sys/partitioner.js
@@ -62,7 +62,7 @@ class Partitioner {
             message: event
         });
         return hyper.post({
-            uri: `/sys/queue/events/${partition}`,
+            uri: `/sys/queue/events/${ partition }`,
             body: [ event ]
         });
     }
diff --git a/sys/purge.js b/sys/purge.js
index ee15491..89d8ddb 100644
--- a/sys/purge.js
+++ b/sys/purge.js
@@ -43,7 +43,7 @@ class PurgeService {
                 }));
                 return undefined;
             }
-            return `http:${event.meta.uri.replace(/^https?:/, '')}`;
+            return `http:${ event.meta.uri.replace(/^https?:/, '') }`;
         }).filter(event => !!event))
         .thenReturn({ status: 201 })
         .catch((e) => {
diff --git a/sys/rate_limiter.js b/sys/rate_limiter.js
index 0fd1a8c..c9b45bd 100644
--- a/sys/rate_limiter.js
+++ b/sys/rate_limiter.js
@@ -22,12 +22,12 @@ class RateLimiter extends mixins.mix(Object).with(mixins.Redis) {
 
             limiterOpts.forEach((opt) => {
                 if (!opt.interval || !opt.limit) {
-                    throw new Error(`Limiter ${type} is miconfigured`);
+                    throw new Error(`Limiter ${ type } is miconfigured`);
                 }
             });
 
             this._LIMITERS.set(type, new Limiter(this._redis, limiterOpts,
-                { prefix: `CPLimiter_${type}` }));
+                { prefix: `CPLimiter_${ type }` }));
         });
     }
 
@@ -48,24 +48,24 @@ class RateLimiter extends mixins.mix(Object).with(mixins.Redis) {
             limiter[fun](key, (err, isRateLimited) => {
                 if (err) {
                     hyper.logger.log('error/ratelimit', err);
-                    hyper.metrics.endTiming(`ratelimit.${fun}.err`, startTime);
+                    hyper.metrics.endTiming(`ratelimit.${ fun }.err`, startTime);
                     // In case we've got problems with limiting just allow everything
                     return resolve({ status: 200 });
                 }
 
                 if (isRateLimited) {
-                    hyper.metrics.endTiming(`ratelimit.${fun}.block`, startTime);
+                    hyper.metrics.endTiming(`ratelimit.${ fun }.block`, startTime);
                     return reject(new HTTPError({
                         status: 429,
                         body: {
                             type: 'rate_limit',
-                            message: `Message rejected by limiter ${type}`,
+                            message: `Message rejected by limiter ${ type }`,
                             key
                         }
                     }));
                 }
 
-                hyper.metrics.endTiming(`ratelimit.${fun}.allow`, startTime);
+                hyper.metrics.endTiming(`ratelimit.${ fun }.allow`, startTime);
                 return resolve({ status: 201 });
             });
         });
diff --git a/test/feature/job_rules.js b/test/feature/job_rules.js
index 57a0fce..987f86b 100644
--- a/test/feature/job_rules.js
+++ b/test/feature/job_rules.js
@@ -18,14 +18,16 @@ describe('JobQueue rules', function () {
         this.timeout(50000);
         return changeProp.start()
         .then(() => common.getKafkaFactory().createProducer({ log: console.log.bind(console) }))
-        .then((result) => { producer = result; });
+        .then((result) => {
+ producer = result;
+});
     });
 
     [
         'updateBetaFeaturesUserCounts',
         'cdnPurge'
     ].forEach((jobType) => {
-        it(`Should propagate ${jobType} job`, function () {
+        it(`Should propagate ${ jobType } job`, function () {
             this.timeout(10000);
             const sampleEvent = common.jobs[jobType];
             const service = nock('http://jobrunner.wikipedia.org', {
@@ -36,7 +38,7 @@ describe('JobQueue rules', function () {
             })
             .post('/wiki/Special%3ARunSingleJob', sampleEvent)
             .reply(200, {});
-            return producer.produce(`test_dc.mediawiki.job.${jobType}`, 0, sampleEvent.toBuffer())
+            return producer.produce(`test_dc.mediawiki.job.${ jobType }`, 0, sampleEvent.toBuffer())
             .then(() => common.checkAPIDone(service))
             .finally(() => nock.cleanAll());
         });
@@ -151,7 +153,7 @@ describe('JobQueue rules', function () {
     it('Should support delayed jobs with re-enqueue', () => {
         this.timeout(20000);
         const sampleEvent = common.jobs.cdnPurge;
-        sampleEvent.delay_until = `${new Date(Date.parse(sampleEvent.delay_until) + 10000).toISOString()}`;
+        sampleEvent.delay_until = `${ new Date(Date.parse(sampleEvent.delay_until) + 10000).toISOString() }`;
         const service = nock('http://jobrunner.wikipedia.org', {
             reqheaders: {
                 host: sampleEvent.meta.domain,
diff --git a/test/feature/static_rules.js b/test/feature/static_rules.js
index 1e595dd..d090195 100644
--- a/test/feature/static_rules.js
+++ b/test/feature/static_rules.js
@@ -21,7 +21,9 @@ describe('Basic rule management', function () {
         this.timeout(50000);
         return changeProp.start()
         .then(() => common.getKafkaFactory().createProducer({ log: console.log.bind(console) }))
-        .then((result) => { producer = result; });
+        .then((result) => {
+ producer = result;
+});
     });
 
     it('Should call simple executor', () => {
@@ -30,7 +32,7 @@ describe('Basic rule management', function () {
             reqheaders: {
                 test_header_name: 'test_header_value',
                 'content-type': 'application/json',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`,
                 'user-agent': 'ChangePropTestSuite'
             }
         })
@@ -65,14 +67,14 @@ describe('Basic rule management', function () {
             derived_field: 'test',
             random_field: random
         })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
         .reply(500, {})
         .post('/', {
             test_field_name: 'test_field_value',
             derived_field: 'test',
             random_field: random
         })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
         .reply(200, {});
 
         return P.try(() => producer.produce('test_dc.simple_test_rule', 0,
@@ -95,21 +97,21 @@ describe('Basic rule management', function () {
             derived_field: 'test',
             random_field: random
         })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
         .reply(500, {})
         .post('/', {
             test_field_name: 'test_field_value',
             derived_field: 'test',
             random_field: random
         })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
         .reply(500, {})
         .post('/', {
             test_field_name: 'test_field_value',
             derived_field: 'test',
             random_field: random
         })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage,changeprop.retry.simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`)
         .reply(500, {})
         // Next one must never get called, we verify that by checking pending mocks
         .post('/', {
@@ -176,7 +178,7 @@ describe('Basic rule management', function () {
                             return check();
                         }
 
-                        if (msg.triggered_by !== `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`) {
+                        if (msg.triggered_by !== `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`) {
                             throw new Error('TriggeredBy should be equal to simple_test_rule:https://en.wikipedia.org/wiki/SamplePage');
                         }
                     });
@@ -192,7 +194,7 @@ describe('Basic rule management', function () {
             reqheaders: {
                 test_header_name: 'test_header_value',
                 'content-type': 'application/json',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`,
                 'user-agent': 'ChangePropTestSuite'
             }
         })
@@ -237,7 +239,7 @@ describe('Basic rule management', function () {
             reqheaders: {
                 test_header_name: 'test_header_value',
                 'content-type': 'application/json',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },simple_test_rule:https://en.wikipedia.org/wiki/SamplePage`,
                 'user-agent': 'ChangePropTestSuite'
             }
         })
diff --git a/test/feature/update_rules.js b/test/feature/update_rules.js
index f461be1..e073ddc 100644
--- a/test/feature/update_rules.js
+++ b/test/feature/update_rules.js
@@ -33,9 +33,13 @@ describe('update rules', function () {
                 }
             });
         })
-        .then((res) => { siteInfoResponse = res.body; })
+        .then((res) => {
+ siteInfoResponse = res.body;
+})
         .then(() => common.getKafkaFactory().createProducer({ log: console.log.bind(console) }))
-        .then((result) => { producer = result; });
+        .then((result) => {
+ producer = result;
+});
     });
 
     const nockWithOptionalSiteInfo = () => nock('https://en.wikipedia.org')
@@ -53,7 +57,7 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},${topic}:https://en.wikipedia.org/api/rest_v1/page/html/Main_Page`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },${ topic }:https://en.wikipedia.org/api/rest_v1/page/html/Main_Page`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
@@ -61,7 +65,7 @@ describe('update rules', function () {
         .query({ redirect: false })
         .reply(200, { });
 
-        return P.try(() => producer.produce(`test_dc.${topic}`, 0, common.events.resourceChange(
+        return P.try(() => producer.produce(`test_dc.${ topic }`, 0, common.events.resourceChange(
             'https://en.wikipedia.org/api/rest_v1/page/html/Main_Page', topic
         ).toBuffer()))
         .then(() => common.checkAPIDone(mwAPI))
@@ -114,11 +118,11 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.page-properties-change:${SAMPLE_EVENT.meta.uri}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.page-properties-change:${ SAMPLE_EVENT.meta.uri }`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/summary/${SAMPLE_EVENT.page_title}`)
+        .get(`/api/rest_v1/page/summary/${ SAMPLE_EVENT.page_title }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -131,7 +135,7 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},resource_change:https://en.wikipedia.org/api/rest_v1/page/html/User%3ACyberbot_I%2FTest`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },resource_change:https://en.wikipedia.org/api/rest_v1/page/html/User%3ACyberbot_I%2FTest`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
@@ -150,7 +154,7 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wiktionary.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},resource_change:https://en.wiktionary.org/api/rest_v1/page/html/Main_Page`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },resource_change:https://en.wiktionary.org/api/rest_v1/page/html/Main_Page`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
@@ -182,7 +186,7 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},resource_change:https://en.wikipedia.org/api/rest_v1/page/html/Main_Page`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },resource_change:https://en.wikipedia.org/api/rest_v1/page/html/Main_Page`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
@@ -217,7 +221,7 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},resource_change:https://en.wikipedia.org/wiki/Main_Page`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },resource_change:https://en.wikipedia.org/wiki/Main_Page`,
                 'if-unmodified-since': 'Tue, 20 Feb 1990 19:31:13 +0000',
                 'user-agent': 'SampleChangePropInstance'
             }
@@ -246,13 +250,13 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-create:${SAMPLE_EVENT.meta.uri}`,
-                'x-restbase-parentrevision': `${SAMPLE_EVENT.rev_parent_id}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-create:${ SAMPLE_EVENT.meta.uri }`,
+                'x-restbase-parentrevision': `${ SAMPLE_EVENT.rev_parent_id }`,
                 'if-unmodified-since': SAMPLE_DATE,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/html/${SAMPLE_EVENT.page_title}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/html/${ SAMPLE_EVENT.page_title }/${ SAMPLE_EVENT.rev_id }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -270,13 +274,13 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-create:${SAMPLE_EVENT.meta.uri}`,
-                'x-restbase-parentrevision': `${SAMPLE_EVENT.rev_parent_id}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-create:${ SAMPLE_EVENT.meta.uri }`,
+                'x-restbase-parentrevision': `${ SAMPLE_EVENT.rev_parent_id }`,
                 'if-unmodified-since': SAMPLE_DATE,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/html/${encodeURIComponent(SAMPLE_EVENT.page_title)}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/html/${ encodeURIComponent(SAMPLE_EVENT.page_title) }/${ SAMPLE_EVENT.rev_id }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -288,7 +292,7 @@ describe('update rules', function () {
     it('Should not update RESTBase on revision create for wikidata', () => {
         const SAMPLE_EVENT = common.events.revisionCreate('https://www.wikidata.org/wiki/Q1');
         const mwAPI = nock('https://www.wikidata.org')
-        .get(`/api/rest_v1/page/html/${SAMPLE_EVENT.page_title}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/html/${ SAMPLE_EVENT.page_title }/${ SAMPLE_EVENT.rev_id }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -302,11 +306,11 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.page-delete:${SAMPLE_EVENT.meta.uri}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.page-delete:${ SAMPLE_EVENT.meta.uri }`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/title/${encodeURIComponent(SAMPLE_EVENT.page_title)}`)
+        .get(`/api/rest_v1/page/title/${ encodeURIComponent(SAMPLE_EVENT.page_title) }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -320,11 +324,11 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.page-undelete:${SAMPLE_EVENT.meta.uri}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.page-undelete:${ SAMPLE_EVENT.meta.uri }`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/title/${encodeURIComponent(SAMPLE_EVENT.page_title)}`)
+        .get(`/api/rest_v1/page/title/${ encodeURIComponent(SAMPLE_EVENT.page_title) }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -343,15 +347,15 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.page-move:${SAMPLE_EVENT.meta.uri}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.page-move:${ SAMPLE_EVENT.meta.uri }`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/html/${SAMPLE_EVENT.page_title}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/html/${ SAMPLE_EVENT.page_title }/${ SAMPLE_EVENT.rev_id }`)
         .matchHeader('if-unmodified-since', SAMPLE_DATE)
         .query({ redirect: false })
         .reply(200, { })
-        .get(`/api/rest_v1/page/title/${SAMPLE_EVENT.prior_state.page_title}`)
+        .get(`/api/rest_v1/page/title/${ SAMPLE_EVENT.prior_state.page_title }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -365,11 +369,11 @@ describe('update rules', function () {
         const mwAPI = nock('https://en.wikipedia.org', {
             reqheaders: {
                 'cache-control': 'no-cache',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-visibility-change:${SAMPLE_EVENT.meta.uri}`,
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-visibility-change:${ SAMPLE_EVENT.meta.uri }`,
                 'user-agent': 'SampleChangePropInstance'
             }
         })
-        .get(`/api/rest_v1/page/title/${SAMPLE_EVENT.page_title}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/title/${ SAMPLE_EVENT.page_title }/${ SAMPLE_EVENT.rev_id }`)
         .query({ redirect: false })
         .reply(200, { });
 
@@ -496,7 +500,7 @@ describe('update rules', function () {
                 'cache-control': 'no-cache',
                 'x-request-id': common.SAMPLE_REQUEST_ID,
                 'user-agent': 'SampleChangePropInstance',
-                'x-triggered-by': `req:${common.SAMPLE_REQUEST_ID},${stream}:${SAMPLE_EVENT.meta.uri},change-prop.wikidata.resource-change:https://ru.wikipedia.org/wiki/%D0%9F%D1%91%D1%82%D1%80`
+                'x-triggered-by': `req:${ common.SAMPLE_REQUEST_ID },${ stream }:${ SAMPLE_EVENT.meta.uri },change-prop.wikidata.resource-change:https://ru.wikipedia.org/wiki/%D0%9F%D1%91%D1%82%D1%80`
             }
         })
         .get('/api/rest_v1/page/summary/%D0%9F%D1%91%D1%82%D1%80')
@@ -506,7 +510,7 @@ describe('update rules', function () {
         .query({ redirect: false })
         .reply(200, { });
 
-        return P.try(() => producer.produce(`test_dc.${stream}`, 0, SAMPLE_EVENT.toBuffer()))
+        return P.try(() => producer.produce(`test_dc.${ stream }`, 0, SAMPLE_EVENT.toBuffer()))
         .delay(common.REQUEST_CHECK_DELAY)
         .then(() => common.checkAPIDone(wikidataAPI))
         .then(() => common.checkAPIDone(restbase))
@@ -602,7 +606,7 @@ describe('update rules', function () {
             SAMPLE_DATE
         );
         const mwAPI = nockWithOptionalSiteInfo()
-        .get(`/api/rest_v1/page/html/${encodeURIComponent(SAMPLE_EVENT.page_title)}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/html/${ encodeURIComponent(SAMPLE_EVENT.page_title) }/${ SAMPLE_EVENT.rev_id }`)
         .query({ redirect: false })
         .reply(200)
         .post('/w/api.php', {
@@ -625,7 +629,7 @@ describe('update rules', function () {
         })
         .get('/api/rest_v1/page/html/File_Transcluded_Page')
         .query({ redirect: false })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-create:${SAMPLE_EVENT.meta.uri},change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/File_Transcluded_Page`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-create:${ SAMPLE_EVENT.meta.uri },change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/File_Transcluded_Page`)
         .matchHeader('if-unmodified-since', SAMPLE_DATE)
         .matchHeader('x-restbase-mode', 'files')
         .times(2)
@@ -647,7 +651,7 @@ describe('update rules', function () {
         })
         .get('/api/rest_v1/page/html/File_Transcluded_Page')
         .query({ redirect: false })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-create:${SAMPLE_EVENT.meta.uri},change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/File_Transcluded_Page`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-create:${ SAMPLE_EVENT.meta.uri },change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/File_Transcluded_Page`)
         .matchHeader('if-unmodified-since', SAMPLE_DATE)
         .matchHeader('x-restbase-mode', 'files')
         .reply(200);
@@ -664,7 +668,7 @@ describe('update rules', function () {
             '1990-02-20T19:31:13+00:00'
         );
         const mwAPI = nockWithOptionalSiteInfo()
-        .get(`/api/rest_v1/page/html/${SAMPLE_EVENT.page_title}/${SAMPLE_EVENT.rev_id}`)
+        .get(`/api/rest_v1/page/html/${ SAMPLE_EVENT.page_title }/${ SAMPLE_EVENT.rev_id }`)
         .query({ redirect: false })
         .reply(200)
         .post('/w/api.php', {
@@ -693,7 +697,7 @@ describe('update rules', function () {
         })
         .get('/api/rest_v1/page/html/Transcluded_Here')
         .query({ redirect: false })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-create:https://en.wikipedia.org/wiki/${SAMPLE_EVENT.page_title},change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/Transcluded_Here`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-create:https://en.wikipedia.org/wiki/${ SAMPLE_EVENT.page_title },change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/Transcluded_Here`)
         .matchHeader('if-unmodified-since', SAMPLE_DATE)
         .matchHeader('x-restbase-mode', 'templates')
         .times(2)
@@ -721,7 +725,7 @@ describe('update rules', function () {
         })
         .get('/api/rest_v1/page/html/Transcluded_Here')
         .query({ redirect: false })
-        .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},mediawiki.revision-create:https://en.wikipedia.org/wiki/${SAMPLE_EVENT.page_title},change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/Transcluded_Here`)
+        .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },mediawiki.revision-create:https://en.wikipedia.org/wiki/${ SAMPLE_EVENT.page_title },change-prop.transcludes.resource-change:https://en.wikipedia.org/wiki/Transcluded_Here`)
         .matchHeader('if-unmodified-since', SAMPLE_DATE)
         .matchHeader('x-restbase-mode', 'templates')
         .reply(200);
@@ -732,7 +736,7 @@ describe('update rules', function () {
 
     function backlinksTest(pageTitle, topic) {
         const mwAPI = nockWithOptionalSiteInfo()
-            .get(`/api/rest_v1/page/title/${pageTitle}`)
+            .get(`/api/rest_v1/page/title/${ pageTitle }`)
             .query({ redirect: false })
             .optionally()
             .reply(200)
@@ -752,13 +756,13 @@ describe('update rules', function () {
                     continue: '-||'
                 },
                 query: {
-                    backlinks: common.arrayWithLinks(`Linked_${pageTitle}`, 2)
+                    backlinks: common.arrayWithLinks(`Linked_${ pageTitle }`, 2)
                 }
             })
-            .get(`/api/rest_v1/page/html/Linked_${pageTitle}`)
+            .get(`/api/rest_v1/page/html/Linked_${ pageTitle }`)
             .times(2)
             .query({ redirect: false })
-            .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},${topic}:https://en.wikipedia.org/wiki/SamplePage,change-prop.backlinks.resource-change:https://en.wikipedia.org/wiki/Linked_${pageTitle}`)
+            .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },${ topic }:https://en.wikipedia.org/wiki/SamplePage,change-prop.backlinks.resource-change:https://en.wikipedia.org/wiki/Linked_${ pageTitle }`)
             .reply(200)
             .post('/w/api.php', {
                 format: 'json',
@@ -773,15 +777,15 @@ describe('update rules', function () {
             .reply(200, {
                 batchcomplete: '',
                 query: {
-                    backlinks: common.arrayWithLinks(`Linked_${pageTitle}`, 1)
+                    backlinks: common.arrayWithLinks(`Linked_${ pageTitle }`, 1)
                 }
             })
-            .get(`/api/rest_v1/page/html/Linked_${pageTitle}`)
+            .get(`/api/rest_v1/page/html/Linked_${ pageTitle }`)
             .query({ redirect: false })
-            .matchHeader('x-triggered-by', `req:${common.SAMPLE_REQUEST_ID},${topic}:https://en.wikipedia.org/wiki/SamplePage,change-prop.backlinks.resource-change:https://en.wikipedia.org/wiki/Linked_${pageTitle}`)
+            .matchHeader('x-triggered-by', `req:${ common.SAMPLE_REQUEST_ID },${ topic }:https://en.wikipedia.org/wiki/SamplePage,change-prop.backlinks.resource-change:https://en.wikipedia.org/wiki/Linked_${ pageTitle }`)
             .reply(200);
 
-        return P.try(() => producer.produce(`test_dc.${topic}`, 0,
+        return P.try(() => producer.produce(`test_dc.${ topic }`, 0,
             Buffer.from(JSON.stringify(common.eventWithProperties(topic,
                 {
                     page_title: pageTitle
diff --git a/test/utils/changeProp.js b/test/utils/changeProp.js
index 6a99c18..713b3fc 100644
--- a/test/utils/changeProp.js
+++ b/test/utils/changeProp.js
@@ -8,7 +8,7 @@ const CHANGE_PROP_STOP_DELAY = 1000;
 const CHANGE_PROP_START_DELAY = 30000;
 
 class ChangePropServer extends TestServer {
-    constructor(configPath = `${__dirname}/../../config.test.yaml`) {
+    constructor(configPath = `${ __dirname }/../../config.test.yaml`) {
         super(configPath);
     }
 
diff --git a/test/utils/common.js b/test/utils/common.js
index 519dd67..edf31c0 100644
--- a/test/utils/common.js
+++ b/test/utils/common.js
@@ -117,7 +117,7 @@ const ajv = new Ajv({
     loadSchema: (uri) => preq.get({ uri })
     .then((content) => {
         if (content.status !== 200) {
-            throw new Error(`Failed to load meta schema at ${uri}`);
+            throw new Error(`Failed to load meta schema at ${ uri }`);
         }
         const metaSchema = content.body;
         // Need to reassign the ID cause we're using https in the meta-schema URIs
@@ -127,7 +127,7 @@ const ajv = new Ajv({
 });
 
 common.fetchEventValidator = (schemaUri, version = 1) => {
-    const schemaPath = `${schemaUri}/${version}.yaml`;
+    const schemaPath = `${ schemaUri }/${ version }.yaml`;
     if (validatorCache.has(schemaPath)) {
         return P.resolve(validatorCache.get(schemaPath));
     }
@@ -149,7 +149,7 @@ common.fetchEventValidator = (schemaUri, version = 1) => {
         });
     } catch (e) {
         return preq.get({
-            uri: `https://raw.githubusercontent.com/wikimedia/mediawiki-event-schemas/master/jsonschema/${schemaPath}`
+            uri: `https://raw.githubusercontent.com/wikimedia/mediawiki-event-schemas/master/jsonschema/${ schemaPath }`
         })
         .then((res) => ajv.compileAsync(yaml.safeLoad(res.body)))
         .then((validator) => {
@@ -409,7 +409,7 @@ common.jobs = {
             __proto__: eventMethods,
             $schema: 'mediawiki/job/1.0.0',
             database: 'commonswiki',
-            delay_until: `${releaseTimestamp}`,
+            delay_until: `${ releaseTimestamp }`,
             mediawiki_signature: 'e6ff5af8f89ac6441c6ad7b34bdcf44fb1746c1ef6e07d8b9653c75d0005193e',
             meta: {
                 domain: 'commons.wikimedia.org',
diff --git a/test/utils/mock_kafka_factory.js b/test/utils/mock_kafka_factory.js
index 071b0c2..7335a38 100644
--- a/test/utils/mock_kafka_factory.js
+++ b/test/utils/mock_kafka_factory.js
@@ -4,7 +4,7 @@ const P = require('bluebird');
 const EventEmitter = require('events').EventEmitter;
 const fs = require('fs');
 
-const fixtureTopics = fs.readFileSync(`${__dirname}/test_topics`, 'utf8')
+const fixtureTopics = fs.readFileSync(`${ __dirname }/test_topics`, 'utf8')
     .split('\n')
     .map((line) => line.split(' ')[0].replace(/^test_dc\./, ''))
     .filter((line) => line.length);
@@ -13,6 +13,7 @@ class MockMetadataWatch extends EventEmitter {
     getTopics() {
         return P.resolve(fixtureTopics);
     }
+
     disconnect() {}
 }
 
@@ -20,6 +21,7 @@ class MockProducer {
     constructor(messages) {
         this._messages = messages;
     }
+
     produce(topic, partition, message) {
         if (!this._messages.has(topic)) {
             this._messages.set(topic, []);
@@ -31,6 +33,7 @@ class MockProducer {
         });
         return P.resolve();
     }
+
     disconnect() {}
 }
 
@@ -41,13 +44,16 @@ class MockConsumer extends EventEmitter {
         this._messages = messages;
         this._currentTopicOffsets = new Map();
     }
+
     _getCurrentOffset(topic) {
         if (this._currentTopicOffsets.has(topic)) {
             return this._currentTopicOffsets.get(topic);
         }
         return 0;
     }
+
     disconnect() {}
+
     disconnectAsync() {}
 
     consumeAsync() {
@@ -68,6 +74,7 @@ class MockConsumer extends EventEmitter {
         }
         return P.resolve([]);
     }
+
     commitMessageAsync() {
         return P.resolve();
     }
-- 
2.39.2


--- end ---

npm dependencies

Dependencies
Development dependencies

Logs

Source code is licensed under the AGPL.