Repository: kiali/kiali

Issue:
Automate the generation of the Istio model in the frontend code
The frontend layer maintains an IstioObjects.ts file to map the Istio backend with the model used in the frontend (mainly wizards and Istio Config editor).

As we moved to the istio.io/api in the backend, all these types have a formal proto buffer definition; it could be nice to perform a minimal refactoring here, then every time that we change the istio.io/api, we could recreate this mapping automatically.

What this issue expects is a helper hack script that could parse the types and generate the *.ts files in the frontend used for the IstioObject.ts. Perhaps that would trigger a minimal reorganization of those files.

Related to https://github.com/kiali/kiali/issues/5159


Hints from issue comments:
@jshaughn: This has never gained enough priority to get done. Closing.

Solution patch:
diff --git a/.github/workflows/integration-tests-frontend.yml b/.github/workflows/integration-tests-frontend.yml
index 9582c8c00..ab405a043 100644
--- a/.github/workflows/integration-tests-frontend.yml
+++ b/.github/workflows/integration-tests-frontend.yml
@@ -71,7 +71,7 @@ jobs:
       - name: Get debug info when integration tests fail
         if: failure()
         run: |
-          kubectl logs -l app.kubernetes.io/name=kiali -n istio-system
+          kubectl logs -l app.kubernetes.io/name=kiali --tail=-1 --all-containers -n istio-system
           kubectl describe nodes
           kubectl get pods -l app.kubernetes.io/name=kiali -n istio-system -o yaml
 
@@ -80,4 +80,4 @@ jobs:
         if: failure()
         with:
           name: cypress-screenshots
-          path: frontend/cypress/screenshots
+          path: frontend/cypress/screenshots
\ No newline at end of file
diff --git a/business/istio_config.go b/business/istio_config.go
index c2c48dd07..3622ce755 100644
--- a/business/istio_config.go
+++ b/business/istio_config.go
@@ -816,7 +816,7 @@ func (in *IstioConfigService) DeleteIstioConfigDetail(namespace, resourceType, n
 
 	// Cache is stopped after a Create/Update/Delete operation to force a refresh
 	if kialiCache != nil && err == nil {
-		kialiCache.RefreshNamespace(namespace)
+		kialiCache.Refresh(namespace)
 	}
 	return err
 }
@@ -878,7 +878,7 @@ func (in *IstioConfigService) UpdateIstioConfigDetail(namespace, resourceType, n
 
 	// Cache is stopped after a Create/Update/Delete operation to force a refresh
 	if kialiCache != nil && err == nil {
-		kialiCache.RefreshNamespace(namespace)
+		kialiCache.Refresh(namespace)
 	}
 	return istioConfigDetail, err
 }
@@ -989,7 +989,7 @@ func (in *IstioConfigService) CreateIstioConfigDetail(namespace, resourceType st
 	}
 	// Cache is stopped after a Create/Update/Delete operation to force a refresh
 	if kialiCache != nil && err == nil {
-		kialiCache.RefreshNamespace(namespace)
+		kialiCache.Refresh(namespace)
 	}
 	return istioConfigDetail, err
 }
diff --git a/business/layer.go b/business/layer.go
index 14b47fce3..7567e8086 100644
--- a/business/layer.go
+++ b/business/layer.go
@@ -38,35 +38,63 @@ type Layer struct {
 
 // Global clientfactory and prometheus clients.
 var clientFactory kubernetes.ClientFactory
-var jaegerClient jaeger.ClientInterface
-var prometheusClient prometheus.ClientInterface
-var once sync.Once
-var kialiCache cache.KialiCache
 
+var (
+	jaegerClient     jaeger.ClientInterface
+	kialiCache       cache.KialiCache
+	once             sync.Once
+	prometheusClient prometheus.ClientInterface
+)
+
+// sets the global kiali cache var.
 func initKialiCache() {
+	if excludedWorkloads == nil {
+		excludedWorkloads = make(map[string]bool)
+		for _, w := range config.Get().KubernetesConfig.ExcludeWorkloads {
+			excludedWorkloads[w] = true
+		}
+	}
+
 	if config.Get().KubernetesConfig.CacheEnabled {
 		log.Infof("Initializing Kiali Cache")
-		if cache, err := cache.NewKialiCache(); err != nil {
-			log.Errorf("Error initializing Kiali Cache. Details: %s", err)
-		} else {
-			// Temporal NamespaceService to initialize the cache informers
-			initK8sClient := cache.GetClient()
-			initNamespaceService := NewNamespaceService(initK8sClient)
-			if nss, err := initNamespaceService.GetNamespaces(context.Background()); err != nil {
+
+		// Initial list of namespaces to seed the cache with.
+		// This is only necessary if the cache is namespace-scoped.
+		// For a cluster-scoped cache, all namespaces are accessible.
+		// TODO: This is leaking cluster-scoped vs. namespace-scoped in a way.
+		var namespaceSeedList []string
+		if !config.Get().AllNamespacesAccessible() {
+			cfg, err := kubernetes.ConfigClient()
+			if err != nil {
+				log.Errorf("Failed to initialize Kiali Cache. Unable to create Kube rest config. Err: %s", err)
+				return
+			}
+
+			kubeClient, err := kubernetes.NewClientFromConfig(cfg)
+			if err != nil {
+				log.Errorf("Failed to initialize Kiali Cache. Unable to create Kube client. Err: %s", err)
+				return
+			}
+
+			initNamespaceService := NewNamespaceService(kubeClient)
+			nss, err := initNamespaceService.GetNamespaces(context.Background())
+			if err != nil {
 				log.Errorf("Error fetching initial namespaces for populating the Kiali Cache. Details: %s", err)
-			} else {
-				for _, ns := range nss {
-					cache.CheckNamespace(ns.Name)
-				}
+				return
+			}
+
+			for _, ns := range nss {
+				namespaceSeedList = append(namespaceSeedList, ns.Name)
 			}
-			kialiCache = cache
 		}
-	}
-	if excludedWorkloads == nil {
-		excludedWorkloads = make(map[string]bool)
-		for _, w := range config.Get().KubernetesConfig.ExcludeWorkloads {
-			excludedWorkloads[w] = true
+
+		cache, err := cache.NewKialiCache(namespaceSeedList...)
+		if err != nil {
+			log.Errorf("Error initializing Kiali Cache. Details: %s", err)
+			return
 		}
+
+		kialiCache = cache
 	}
 }
 
diff --git a/business/namespaces.go b/business/namespaces.go
index 87cfe739d..b717e70da 100644
--- a/business/namespaces.go
+++ b/business/namespaces.go
@@ -251,7 +251,7 @@ func (in *NamespaceService) UpdateNamespace(ctx context.Context, namespace strin
 
 	// Cache is stopped after a Create/Update/Delete operation to force a refresh
 	if kialiCache != nil && err == nil {
-		kialiCache.RefreshNamespace(namespace)
+		kialiCache.Refresh(namespace)
 		kialiCache.RefreshTokenNamespaces()
 	}
 	// Call GetNamespace to update the caching
diff --git a/business/services.go b/business/services.go
index a64488f1b..e774e4a98 100644
--- a/business/services.go
+++ b/business/services.go
@@ -592,7 +592,7 @@ func (in *SvcService) UpdateService(ctx context.Context, namespace, service stri
 
 	// Cache is stopped after a Create/Update/Delete operation to force a refresh
 	if kialiCache != nil && err == nil {
-		kialiCache.RefreshNamespace(namespace)
+		kialiCache.Refresh(namespace)
 	}
 
 	// After the update we fetch the whole workload
diff --git a/business/workloads.go b/business/workloads.go
index a38820aae..94e5f459d 100644
--- a/business/workloads.go
+++ b/business/workloads.go
@@ -363,7 +363,7 @@ func (in *WorkloadService) UpdateWorkload(ctx context.Context, namespace string,
 
 	// Cache is stopped after a Create/Update/Delete operation to force a refresh
 	if kialiCache != nil && err == nil {
-		kialiCache.RefreshNamespace(namespace)
+		kialiCache.Refresh(namespace)
 	}
 
 	// After the update we fetch the whole workload
@@ -419,7 +419,6 @@ func (in *WorkloadService) BuildLogOptionsCriteria(container, duration, isProxy,
 
 	if duration != "" {
 		duration, err := time.ParseDuration(duration)
-
 		if err != nil {
 			return nil, fmt.Errorf("Invalid duration [%s]: %v", duration, err)
 		}
@@ -431,7 +430,6 @@ func (in *WorkloadService) BuildLogOptionsCriteria(container, duration, isProxy,
 
 	if sinceTime != "" {
 		numTime, err := strconv.ParseInt(sinceTime, 10, 64)
-
 		if err != nil {
 			return nil, fmt.Errorf("Invalid sinceTime [%s]: %v", sinceTime, err)
 		}
diff --git a/config/config.go b/config/config.go
index 402389d9b..1119c653c 100644
--- a/config/config.go
+++ b/config/config.go
@@ -459,7 +459,6 @@ type CompatibilityMatrix []struct {
 
 // NewCompatibilityMatrix return compatible kiali versions for mesh
 func NewCompatibilityMatrix() (CompatibilityMatrix, error) {
-
 	in, err := fs.ReadFile(compatibilityMatrixFile, "version-compatibility-matrix.yaml")
 	if err != nil {
 		log.Warningf("Can not load compatibility matrix file. Error: %v", err)
@@ -777,6 +776,18 @@ func (conf *Config) AddHealthDefault() {
 	conf.HealthConfig.Rate = append(conf.HealthConfig.Rate, healthConfig.Rate...)
 }
 
+// AllNamespacesAccessible determines if kiali has access to all namespaces.
+// When using the operator, the operator will grant the kiali service account
+// cluster role permissions when '**' is provided as a namespace.
+func (conf *Config) AllNamespacesAccessible() bool {
+	for _, ns := range conf.Deployment.AccessibleNamespaces {
+		if ns == "**" {
+			return true
+		}
+	}
+	return false
+}
+
 // Get the global Config
 func Get() (conf *Config) {
 	rwMutex.RLock()
@@ -943,7 +954,7 @@ func SaveToFile(filename string, conf *Config) (err error) {
 	}
 
 	log.Debugf("Writing YAML config to [%s]", filename)
-	err = ioutil.WriteFile(filename, []byte(fileContent), 0640)
+	err = ioutil.WriteFile(filename, []byte(fileContent), 0o640)
 	return
 }
 
diff --git a/frontend/cypress-perf.config.ts b/frontend/cypress-perf.config.ts
new file mode 100644
index 000000000..1c4b38d3d
--- /dev/null
+++ b/frontend/cypress-perf.config.ts
@@ -0,0 +1,24 @@
+import { defineConfig } from 'cypress';
+import { getAuthStrategy } from './cypress/plugins/setup';
+
+export default defineConfig({
+  fixturesFolder: 'cypress/fixtures',
+  env: {
+    timeout: 10000,
+    threshold: 100000
+  },
+  e2e: {
+    baseUrl: 'http://localhost:3000',
+    async setupNodeEvents(on, config) {
+      config.env.cookie = false;
+      // This name is non-standard and might change based on your environment hence the separate
+      // env variable.
+      config.env.AUTH_PROVIDER = config.env.AUTH_PROVIDER || 'my_htpasswd_provider';
+      config.env.AUTH_STRATEGY = await getAuthStrategy(config.baseUrl!);
+
+      return config;
+    },
+    specPattern: '**/*.spec.ts',
+    supportFile: 'cypress/support/index.ts'
+  }
+});
diff --git a/frontend/cypress-perf.json b/frontend/cypress-perf.json
deleted file mode 100644
index 618831237..000000000
--- a/frontend/cypress-perf.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "baseUrl": "http://localhost:3000",
-  "env": {
-    "timeout": 10000,
-    "threshold": 100000
-  },
-  "integrationFolder": "cypress/perf",
-  "fixturesFolder": "cypress/fixtures/perf",
-  "testFiles": "**/*.spec.ts"
-}
diff --git a/frontend/cypress.config.ts b/frontend/cypress.config.ts
new file mode 100644
index 000000000..03252819e
--- /dev/null
+++ b/frontend/cypress.config.ts
@@ -0,0 +1,45 @@
+import { defineConfig } from 'cypress';
+import { getAuthStrategy } from './cypress/plugins/setup';
+import { addCucumberPreprocessorPlugin } from '@badeball/cypress-cucumber-preprocessor';
+import browserify from '@badeball/cypress-cucumber-preprocessor/browserify';
+
+export default defineConfig({
+  viewportWidth: 1920,
+  viewportHeight: 1080,
+  defaultCommandTimeout: 40000,
+  animationDistanceThreshold: 20,
+  execTimeout: 150000,
+  pageLoadTimeout: 90000,
+  requestTimeout: 15000,
+  responseTimeout: 15000,
+  fixturesFolder: 'cypress/fixtures',
+  env: {
+    'cypress-react-selector': {
+      root: '#root'
+    }
+  },
+  e2e: {
+    baseUrl: 'http://localhost:3000',
+    async setupNodeEvents(on, config) {
+      // This is required for the preprocessor to be able to generate JSON reports after each run, and more,
+      await addCucumberPreprocessorPlugin(on, config);
+
+      on(
+        'file:preprocessor',
+        browserify(config, {
+          typescript: require.resolve('typescript')
+        })
+      );
+
+      config.env.cookie = false;
+      // This name is non-standard and might change based on your environment hence the separate
+      // env variable.
+      config.env.AUTH_PROVIDER = config.env.AUTH_PROVIDER || 'my_htpasswd_provider';
+      config.env.AUTH_STRATEGY = await getAuthStrategy(config.baseUrl!);
+
+      return config;
+    },
+    specPattern: '**/*.feature',
+    supportFile: 'cypress/support/index.ts'
+  }
+});
diff --git a/frontend/cypress.json b/frontend/cypress.json
deleted file mode 100644
index c25057f7d..000000000
--- a/frontend/cypress.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "baseUrl": "http://localhost:3000",
-  "viewportWidth": 1920,
-  "viewportHeight": 1080,
-  "integrationFolder": "cypress/integration",
-  "testFiles": "**/*.feature",
-  "defaultCommandTimeout": 40000,
-  "animationDistanceThreshold": 20,
-  "execTimeout": 150000,
-  "pageLoadTimeout": 90000,
-  "requestTimeout": 15000,
-  "responseTimeout": 15000,
-  "supportFile": "cypress/support/index.ts",
-  "pluginsFile": "cypress/plugins/bdd.ts",
-  "fixturesFolder": "cypress/fixtures",
-  "env": {
-    "cypress-react-selector": {
-      "root": "#root"
-    }
-  }
-}
diff --git a/frontend/cypress/integration/common/app_details.ts b/frontend/cypress/integration/common/app_details.ts
index 4c2c9de90..f92e0dc76 100644
--- a/frontend/cypress/integration/common/app_details.ts
+++ b/frontend/cypress/integration/common/app_details.ts
@@ -1,5 +1,6 @@
-import { And, Then } from 'cypress-cucumber-preprocessor/steps';
+import { And, Then } from '@badeball/cypress-cucumber-preprocessor';
 import { getCellsForCol } from './table';
+import { openTab } from './transition';
 
 const APP = 'details';
 const NAMESPACE = 'bookinfo';
@@ -12,14 +13,6 @@ Then('user sees details information for app', () => {
   });
 });
 
-Then('user sees a minigraph', () => {
-  cy.getBySel('mini-graph');
-});
-
-function openTab(tab: string) {
-  cy.get('#basic-tabs').should('be.visible').contains(tab).click();
-}
-
 Then('user sees inbound and outbound traffic information', () => {
   openTab('Traffic');
   cy.contains('Inbound Traffic');
diff --git a/frontend/cypress/integration/common/apps.ts b/frontend/cypress/integration/common/apps.ts
index 3b1363f6d..e30a122df 100644
--- a/frontend/cypress/integration/common/apps.ts
+++ b/frontend/cypress/integration/common/apps.ts
@@ -1,4 +1,4 @@
-import { And, Then, When } from 'cypress-cucumber-preprocessor/steps';
+import { And, Then, When } from '@badeball/cypress-cucumber-preprocessor';
 import { getColWithRowText, ensureObjectsInTable, checkHealthIndicatorInTable, checkHealthStatusInTable } from './table';
 
 // Choosing a random bookinfo app to test with.
diff --git a/frontend/cypress/integration/common/graph.ts b/frontend/cypress/integration/common/graph.ts
new file mode 100644
index 000000000..f07a363c0
--- /dev/null
+++ b/frontend/cypress/integration/common/graph.ts
@@ -0,0 +1,13 @@
+/*
+  This file contains graph related step definitions
+  that are common to multiple features.
+*/
+
+import { Then } from '@badeball/cypress-cucumber-preprocessor';
+
+Then('user sees a minigraph', () => {
+  cy.getBySel('mini-graph').within(() => {
+    cy.get('#cytoscape-graph').should('be.visible');
+    cy.get('#cy').should('be.visible');
+  });
+});
diff --git a/frontend/cypress/integration/common/graph_context_menu.ts b/frontend/cypress/integration/common/graph_context_menu.ts
index 2491bdab4..8d59f6d74 100644
--- a/frontend/cypress/integration/common/graph_context_menu.ts
+++ b/frontend/cypress/integration/common/graph_context_menu.ts
@@ -1,4 +1,4 @@
-import { Then, When } from 'cypress-cucumber-preprocessor/steps';
+import { Then, When } from '@badeball/cypress-cucumber-preprocessor';
 
 When('user opens the context menu of the {string} service node', function (svcName: string) {
   cy.waitForReact();
diff --git a/frontend/cypress/integration/common/graph_display.ts b/frontend/cypress/integration/common/graph_display.ts
index 46427f94e..981ea2795 100644
--- a/frontend/cypress/integration/common/graph_display.ts
+++ b/frontend/cypress/integration/common/graph_display.ts
@@ -1,4 +1,4 @@
-import { Before, Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
+import { Before, Then, When } from '@badeball/cypress-cucumber-preprocessor';
 import { ensureKialiFinishedLoading } from './transition';
 
 const url = '/console';
diff --git a/frontend/cypress/integration/common/graph_find_hide.ts b/frontend/cypress/integration/common/graph_find_hide.ts
index b8ae648b6..4cb7d993b 100644
--- a/frontend/cypress/integration/common/graph_find_hide.ts
+++ b/frontend/cypress/integration/common/graph_find_hide.ts
@@ -1,4 +1,4 @@
-import { And, Then, When } from 'cypress-cucumber-preprocessor/steps';
+import { And, Then, When } from '@badeball/cypress-cucumber-preprocessor';
 
 function clearFindAndHide() {
   cy.get('#graph_hide').clear();
@@ -104,7 +104,7 @@ Then('user sees no healthy workloads on the graph', () => {
 });
 
 When('user seeks help for find and hide', () => {
-  cy.getBySel('graph-find-hide-help-button').click();
+  cy.getBySel('graph-find-hide-help-button').should('be.visible').click();
 });
 
 Then('user sees the help menu', () => {
@@ -112,13 +112,13 @@ Then('user sees the help menu', () => {
 });
 
 And('the help menu has info on {string}', (helpMenuItem: string) => {
-  cy.get('#graph_find_help_tabs').contains(helpMenuItem).should('be.visible').click();
+  cy.get('#graph_find_help_tabs').contains(helpMenuItem).should('be.visible');
 });
 
-When("user fills {string} in find and submits", (input: string) => {
-  cy.get('#graph_find').type(input+'{enter}')
-})
+When('user fills {string} in find and submits', (input: string) => {
+  cy.get('#graph_find').type(input + '{enter}');
+});
 
-Then("user sees the {string} message",(error: string)=> {
-  cy.get('[aria-label="graph settings"]').should("contain.text", error)
-})
+Then('user sees the {string} message', (error: string) => {
+  cy.get('[aria-label="graph settings"]').should('contain.text', error);
+});
diff --git a/frontend/cypress/integration/common/graph_replay.ts b/frontend/cypress/integration/common/graph_replay.ts
index 8d162c11a..f024041bd 100644
--- a/frontend/cypress/integration/common/graph_replay.ts
+++ b/frontend/cypress/integration/common/graph_replay.ts
@@ -1,4 +1,4 @@
-import { Before, Then, When } from 'cypress-cucumber-preprocessor/steps';
+import { Before, Then, When } from '@badeball/cypress-cucumber-preprocessor';
 
 const url = '/console';
 
diff --git a/frontend/cypress/integration/common/graph_side_panel.ts b/frontend/cypress/integration/common/graph_side_panel.ts
index 3d1e2a328..4e4570518 100644
--- a/frontend/cypress/integration/common/graph_side_panel.ts
+++ b/frontend/cypress/integration/common/graph_side_panel.ts
@@ -1,4 +1,4 @@
-import { When } from 'cypress-cucumber-preprocessor/steps';
+import { When } from '@badeball/cypress-cucumber-preprocessor';
 
 When('user clicks the {string} service node', function (svcName: string) {
   cy.waitForReact();
diff --git a/frontend/cypress/integration/common/graph_toolbar.ts b/frontend/cypress/integration/common/graph_toolbar.ts
index e62a85e3e..4fdbeaa50 100644
--- a/frontend/cypress/integration/common/graph_toolbar.ts
+++ b/frontend/cypress/integration/common/graph_toolbar.ts
@@ -1,4 +1,4 @@
-import { Before, Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
+import { Before, Given, Then, When } from '@badeball/cypress-cucumber-preprocessor';
 import { CytoscapeGlobalScratchData, CytoscapeGlobalScratchNamespace } from '../../../src/types/Graph';
 
 const url = '/console';
diff --git a/frontend/cypress/integration/common/graph_toolbar_legend.ts b/frontend/cypress/integration/common/graph_toolbar_legend.ts
index 2ea738417..cbdb67771 100644
--- a/frontend/cypress/integration/common/graph_toolbar_legend.ts
+++ b/frontend/cypress/integration/common/graph_toolbar_legend.ts
@@ -1,69 +1,65 @@
-import { Then, And, When } from "cypress-cucumber-preprocessor/steps";
+import { Then, And, When } from '@badeball/cypress-cucumber-preprocessor';
 
-function buttonClick(label:string){
-    cy.get(`button[aria-label="${label}"]`).click();
-};
+function buttonClick(label: string) {
+  cy.get(`button[aria-label="${label}"]`).click();
+}
 
-function buttonPrepare(label:string, active:boolean){
-    cy.waitForReact();
-    cy.getReact("Button",{ props: { 'aria-label': `${label}`}})
+function buttonPrepare(label: string, active: boolean) {
+  cy.waitForReact();
+  cy.getReact('Button', { props: { 'aria-label': `${label}` } })
     .should('have.length', '1')
     .getProps()
-    .then((props => {
-        if (props.isActive !== active){
-            buttonClick(label);
-        }
-    }));
-};
+    .then(props => {
+      if (props.isActive !== active) {
+        buttonClick(label);
+      }
+    });
+}
 
-function buttonState(label:string, active:boolean){
-    cy.waitForReact();
-    cy.getReact("Button",{ props: { 'aria-label': `${label}`}})
+function buttonState(label: string, active: boolean) {
+  cy.waitForReact();
+  cy.getReact('Button', { props: { 'aria-label': `${label}` } })
     .should('have.length', '1')
     .getProps('isActive')
     .should('eq', active);
 }
 
-Then("the toggle button {string} is enabled", (label: string) => {
-    cy.get(`button[aria-label="${label}"]`).should('have.attr', 'aria-disabled', 'false');
-});
-
-And("the toggle button {string} is enabled", (label: string) => {
-    cy.get(`button[aria-label="${label}"]`).should('have.attr', 'aria-disabled', 'false');
+And('the toggle button {string} is enabled', (label: string) => {
+  cy.get(`button[aria-label="${label}"]`).should('have.attr', 'aria-disabled', 'false');
 });
 
-And("the button {string} is clicked", (label: string) => {
-    buttonClick(label);
+And('the button {string} is clicked', (label: string) => {
+  buttonClick(label);
 });
 
-Then("the button {string} is active", (label: string) => {
-   buttonState(label, true); 
+Then('the button {string} is active', (label: string) => {
+  buttonState(label, true);
 });
 
-Then("the button {string} is not active", (label: string) => {
-   buttonState(label, false); 
+Then('the button {string} is not active', (label: string) => {
+  buttonState(label, false);
 });
 
-And("the {string} is turned on", (label: string) => {
-   buttonPrepare(label, true); 
+And('the {string} is turned on', (label: string) => {
+  buttonPrepare(label, true);
 });
 
-And("the {string} is turned off", (label: string) => {
-   buttonPrepare(label, false); 
+And('the {string} is turned off', (label: string) => {
+  buttonPrepare(label, false);
 });
 
-Then("user can see the legend section", () => {
-    cy.get("[data-test='graph-legend']").should("be.visible");
+Then('user can see the legend section', () => {
+  cy.get("[data-test='graph-legend']").should('be.visible');
 });
 
-When("the Legend section is visible", () => {
-    buttonClick("Show Legend");
+When('the Legend section is visible', () => {
+  buttonClick('Show Legend');
 });
 
-And ("the cross is clicked", () => {
-    cy.get("#legend_close").click()
+And('the cross is clicked', () => {
+  cy.get('#legend_close').click();
 });
 
-Then("user cannot see the legend section", () => {
-    cy.get("[data-test='graph-legend']").should("not.exist");
+Then('user cannot see the legend section', () => {
+  cy.get("[data-test='graph-legend']").should('not.exist');
 });
diff --git a/frontend/cypress/integration/common/istio_config.ts b/frontend/cypress/integration/common/istio_config.ts
index 4f5bc05c6..db504f415 100644
--- a/frontend/cypress/integration/common/istio_config.ts
+++ b/frontend/cypress/integration/common/istio_config.ts
@@ -1,4 +1,4 @@
-import { After, And, Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
+import { After, And, Given, Then, When } from '@badeball/cypress-cucumber-preprocessor';
 import { getColWithRowText } from './table';
 import { ensureKialiFinishedLoading } from "./transition";
 
diff --git a/frontend/cypress/integration/common/istio_config_editor.ts b/frontend/cypress/integration/common/istio_config_editor.ts
index 8b2b517f8..4daeb6348 100644
--- a/frontend/cypress/integration/common/istio_config_editor.ts
+++ b/frontend/cypress/integration/common/istio_config_editor.ts
@@ -1,4 +1,4 @@
-import { Then } from 'cypress-cucumber-preprocessor/steps';
+import { Then } from '@badeball/cypress-cucumber-preprocessor';
 
 Then('user can see istio config editor', () => {
 	cy.get('#ace-editor').should('be.visible');
diff --git a/frontend/cypress/integration/common/kiali_about.ts b/frontend/cypress/integration/common/kiali_about.ts
index aff640797..329f46bf4 100644
--- a/frontend/cypress/integration/common/kiali_about.ts
+++ b/frontend/cypress/integration/common/kiali_about.ts
@@ -1,4 +1,4 @@
-import { And, Then } from "cypress-cucumber-preprocessor/steps";
+import { And, Then } from "@badeball/cypress-cucumber-preprocessor";
 
 
 And('user clicks on Help Button', () => {
diff --git a/frontend/cypress/integration/common/kiali_cookie.ts b/frontend/cypress/integration/common/kiali_cookie.ts
index ec9b3c2fd..8166c9df6 100644
--- a/frontend/cypress/integration/common/kiali_cookie.ts
+++ b/frontend/cypress/integration/common/kiali_cookie.ts
@@ -1,4 +1,4 @@
-import { And, Given } from "cypress-cucumber-preprocessor/steps";
+import { And, Given } from "@badeball/cypress-cucumber-preprocessor";
 
 const USERNAME = Cypress.env('USERNAME') || 'jenkins';
 const PASSWD = Cypress.env('PASSWD')
diff --git a/frontend/cypress/integration/common/kiali_help.ts b/frontend/cypress/integration/common/kiali_help.ts
index d167f6cf0..12f14a236 100644
--- a/frontend/cypress/integration/common/kiali_help.ts
+++ b/frontend/cypress/integration/common/kiali_help.ts
@@ -1,26 +1,20 @@
-import { When, Then, And } from "cypress-cucumber-preprocessor/steps";
-import { TableDefinition } from 'cypress-cucumber-preprocessor';
+import { When, Then, And, DataTable } from '@badeball/cypress-cucumber-preprocessor';
 
-
-When('user clicks on Help Button', () => {
-    cy.getBySel('about-help-button').click();
-});
-
-Then("user can see all of the Help dropdown options", (options: TableDefinition) => {
+Then('user can see all of the Help dropdown options', (options: DataTable) => {
   const names = options.raw()[0];
   names.forEach(function (value) {
     cy.get('li[role="menuitem"]').contains(value).should('be.visible');
-  });  
+  });
 });
 
-And("the {string} button has a link", (title:string) => {
+And('the {string} button has a link', (title: string) => {
   cy.get('li[role="menuitem"]').contains(title).should('have.attr', 'href');
 });
 
-When('user clicks on the {string} button', (title:string) => {
+When('user clicks on the {string} button', (title: string) => {
   cy.get('li[role="menuitem"]').contains(title).click();
 });
 
-Then('user sees the {string} modal', (title:string) => {
-  cy.get('h1.pf-c-modal-box__title').contains(title).should('be.visible')  
+Then('user sees the {string} modal', (title: string) => {
+  cy.get('h1.pf-c-modal-box__title').contains(title).should('be.visible');
 });
diff --git a/frontend/cypress/integration/common/kiali_homepage.ts b/frontend/cypress/integration/common/kiali_homepage.ts
index be03606a5..bd96ba7b7 100644
--- a/frontend/cypress/integration/common/kiali_homepage.ts
+++ b/frontend/cypress/integration/common/kiali_homepage.ts
@@ -1,5 +1,5 @@
-import { Given } from 'cypress-cucumber-preprocessor/steps';
-import { Then } from 'cypress-cucumber-preprocessor/steps';
+import { Given } from '@badeball/cypress-cucumber-preprocessor';
+import { Then } from '@badeball/cypress-cucumber-preprocessor';
 
 const url = '/';
 
diff --git a/frontend/cypress/integration/common/kiali_login.ts b/frontend/cypress/integration/common/kiali_login.ts
index fef4c9daa..9f4bdcf2f 100644
--- a/frontend/cypress/integration/common/kiali_login.ts
+++ b/frontend/cypress/integration/common/kiali_login.ts
@@ -1,4 +1,4 @@
-import { Given, And, Then } from "cypress-cucumber-preprocessor/steps";
+import { Given, And, Then } from "@badeball/cypress-cucumber-preprocessor";
 
 const USERNAME = Cypress.env('USERNAME') || 'jenkins'; // CYPRESS_USERNAME to the user
 const PASSWD = Cypress.env('PASSWD'); // CYPRESS_PASSWD to the user
diff --git a/frontend/cypress/integration/common/kiali_logout.ts b/frontend/cypress/integration/common/kiali_logout.ts
index 10fbeda83..cc6a822fa 100644
--- a/frontend/cypress/integration/common/kiali_logout.ts
+++ b/frontend/cypress/integration/common/kiali_logout.ts
@@ -1,4 +1,4 @@
-import { And, Then } from "cypress-cucumber-preprocessor/steps";
+import { And, Then } from "@badeball/cypress-cucumber-preprocessor";
 
 const auth_strategy = Cypress.env('auth_strategy')
 
diff --git a/frontend/cypress/integration/common/kiali_sidebar_toggle.ts b/frontend/cypress/integration/common/kiali_sidebar_toggle.ts
index 4bc4aab39..7b1b24213 100644
--- a/frontend/cypress/integration/common/kiali_sidebar_toggle.ts
+++ b/frontend/cypress/integration/common/kiali_sidebar_toggle.ts
@@ -1,4 +1,4 @@
-import {And, When, Then} from "cypress-cucumber-preprocessor/steps";
+import {And, When, Then} from "@badeball/cypress-cucumber-preprocessor";
 
 When('the sidebar is open', () => {
   cy.get('#page-sidebar').should('be.visible').then(($sidebar) => {
diff --git a/frontend/cypress/integration/common/namespace.ts b/frontend/cypress/integration/common/namespace.ts
index 782dcc262..c6d588630 100644
--- a/frontend/cypress/integration/common/namespace.ts
+++ b/frontend/cypress/integration/common/namespace.ts
@@ -1,4 +1,4 @@
-import { And } from 'cypress-cucumber-preprocessor/steps';
+import { And } from '@badeball/cypress-cucumber-preprocessor';
 import { ensureKialiFinishedLoading } from './transition';
 
 And('user selects the {string} namespace', (namespace: string) => {
diff --git a/frontend/cypress/integration/common/navigation.ts b/frontend/cypress/integration/common/navigation.ts
index c018ff5f6..a3713decb 100644
--- a/frontend/cypress/integration/common/navigation.ts
+++ b/frontend/cypress/integration/common/navigation.ts
@@ -1,4 +1,4 @@
-import { And, Given } from 'cypress-cucumber-preprocessor/steps';
+import { And, Given } from '@badeball/cypress-cucumber-preprocessor';
 import { ensureKialiFinishedLoading } from './transition';
 
 enum detailType {
diff --git a/frontend/cypress/integration/common/overview.ts b/frontend/cypress/integration/common/overview.ts
index 5b78dac8c..ce13273d6 100644
--- a/frontend/cypress/integration/common/overview.ts
+++ b/frontend/cypress/integration/common/overview.ts
@@ -1,4 +1,4 @@
-import { Before, Given, Then, When } from "cypress-cucumber-preprocessor/steps";
+import { Before, Given, Then, When } from "@badeball/cypress-cucumber-preprocessor";
 
 const url = "/console";
 
diff --git a/frontend/cypress/integration/common/service_details.ts b/frontend/cypress/integration/common/service_details.ts
index ddffe9a7a..7508ffdbe 100644
--- a/frontend/cypress/integration/common/service_details.ts
+++ b/frontend/cypress/integration/common/service_details.ts
@@ -1,103 +1,127 @@
-import { And, Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
-import {checkHealthIndicatorInTable, checkHealthStatusInTable, getCellsForCol, getColWithRowText} from './table';
-import { ensureKialiFinishedLoading } from './transition';
+import { And, Then } from '@badeball/cypress-cucumber-preprocessor';
 
-const NAMESPACE = 'bookinfo';
-const SERVICE = 'productpage';
-const URL = '/console/namespaces/'+NAMESPACE+'/services/'+SERVICE+'?refresh=0';
 const tracingDotQuery = '[style*="fill: var(--pf-global--palette--blue-200)"][style*="stroke: transparent"]';
 
 function openTab(tab: string) {
-    cy.get('.pf-c-tabs__list').should('be.visible').contains(tab).click();
+  cy.get('.pf-c-tabs__list').should('be.visible').contains(tab).click();
 }
 
-Given('a service in the cluster with a healthy amount of traffic', function () {
-    this.targetNamespace = NAMESPACE;
-    this.targetService = SERVICE;
+Then('sd::user sees a list with content {string}', (tab: string) => {
+  cy.get('.pf-c-tabs__list').contains(tab);
 });
 
-Then('user sees a list with content {string}', (tab: string) => {
-    cy.get('.pf-c-tabs__list').contains(tab);
+Then('sd::user sees the actions button', () => {
+  cy.getBySel('wizard-actions').should('be.visible').click();
+  cy.getBySel('wizard-actions').siblings().contains('Request Routing');
 });
 
-Then('user sees the actions button', () => {
-    cy.getBySel('wizard-actions').should('be.visible').click();
-    cy.getBySel('wizard-actions').siblings().contains("Request Routing");
+Then('sd::user sees {string} details information for service {string}', (name: string, version: string) => {
+  cy.get('#ServiceDescriptionCard').within(() => {
+    cy.get('#pfbadge-S').parent().parent().contains(name); // Service
+    cy.get('#pfbadge-A').parent().parent().contains(name); // App
+    cy.get('#pfbadge-W')
+      .parent()
+      .parent()
+      .contains(name + '-' + version); // Workload
+  });
 });
 
-Then('user sees {string} details information for service {string}', (name: string, version: string) => {
-    cy.get('#ServiceDescriptionCard').within(() => {
-        cy.get('#pfbadge-S').parent().parent().contains(name); // Service
-        cy.get('#pfbadge-A').parent().parent().contains(name); // App
-        cy.get('#pfbadge-W').parent().parent().contains(name + '-' + version); // Workload
-    });
+Then('sd::user sees Network card', (name: string) => {
+  cy.get('#ServiceNetworkCard').within(() => {
+    cy.get('.pf-c-card__body').contains('Service IP');
+    cy.get('.pf-c-card__body').contains('Hostnames');
+  });
 });
 
-Then('user sees Network card', (name: string) => {
-    cy.get('#ServiceNetworkCard').within(() => {
-        cy.get('.pf-c-card__body').contains("Service IP");
-        cy.get('.pf-c-card__body').contains("Hostnames");
-    });
-});
-
-Then('user sees Istio Config', (name: string) => {
-    cy.get('#IstioConfigCard').within(() => {
-        cy.get('#pfbadge-G').should("be.visible");
-        cy.get('#pfbadge-VS').should("be.visible");
-    });
+Then('sd::user sees Istio Config', (name: string) => {
+  cy.get('#IstioConfigCard').within(() => {
+    cy.get('#pfbadge-G').should('be.visible');
+    cy.get('#pfbadge-VS').should('be.visible');
+  });
 });
 
-Then('user sees a minigraph', () => {
-    cy.getBySel('mini-graph').within(() => {
-        cy.get('#cytoscape-graph').should("be.visible");
-        cy.get('#cy').should("be.visible");
-    });
+Then('sd::user sees a minigraph', () => {
+  cy.getBySel('mini-graph').within(() => {
+    cy.get('#cytoscape-graph').should('be.visible');
+    cy.get('#cy').should('be.visible');
+  });
 });
 
-Then('user sees inbound and outbound traffic information', () => {
-    openTab('Traffic');
+Then('sd::user sees inbound and outbound traffic information', () => {
+  openTab('Traffic');
+  cy.get('.pf-c-card__body').within(() => {
     cy.contains('Inbound Traffic');
     cy.contains('No Inbound Traffic').should('not.exist');
     cy.contains('Outbound Traffic');
     cy.contains('No Inbound Traffic').should('not.exist');
-    cy.contains('.pf-c-card__body').within(() => {
-        cy.get('table.pf-c-table.pf-m-grid-md').should('exist');
-        cy.contains('istio-ingressgateway');
-    });
+    cy.get('table.pf-c-table.pf-m-grid-md').should('exist');
+    cy.contains('istio-ingressgateway');
+  });
 });
 
-Then('the user sees {string} graph', (graph: string) => {
-    openTab('Inbound Metrics');
-    cy.get('.pf-l-grid__item').children().children().children().contains(graph);
+Then('sd::user sees {string} graph', (graph: string) => {
+  openTab('Inbound Metrics');
+  cy.get('.pf-l-grid__item').children().children().children().contains(graph);
 });
 
-Then('the user does not see No data message in the {string} graph', (graph: string) => {
-    openTab('Inbound Metrics');
-    cy.get('.pf-l-grid__item').children().children().children().contains(graph).should('not.contain', 'No data available');
+Then('sd::user does not see No data message in the {string} graph', (graph: string) => {
+  openTab('Inbound Metrics');
+  cy.get('.pf-l-grid__item')
+    .children()
+    .children()
+    .children()
+    .contains(graph)
+    .should('not.contain', 'No data available');
 });
 
-Then('user sees graph with traces information', (graph: string) => {
-    openTab('Traces');
-    cy.getBySel('jaeger-scatterplot');
+Then('sd::user sees graph with traces information', (graph: string) => {
+  openTab('Traces');
+  cy.getBySel('jaeger-scatterplot');
+  cy.getBySel('trace-details-tabs').should('not.exist');
+  cy.getBySel('jaeger-scatterplot').contains('Traces');
+  cy.getBySel('jaeger-scatterplot').find(`path${tracingDotQuery}`).first().should('be.visible').click({ force: true });
 });
 
-And('And user sees trace details after selecting a trace', () => {
-    cy.getBySel('trace-details-tabs').should('not.exist');
-    cy.getBySel('jaeger-scatterplot').contains('Traces');
-    cy.getBySel('jaeger-scatterplot').find(`path${tracingDotQuery}`).first().should('be.visible').click({ force: true });
-    cy.getBySel('trace-details-tabs').should('be.visible').contains("Trace Details");
-    cy.getBySel('.pf-l-grid').should('be.visible').get(".pf-c-label__content").should('be.visible');
-    cy.getBySel('trace-details-kebab').click().contains('View on Graph');
+And('sd::user sees trace details after selecting a trace', () => {
+  cy.getBySel('trace-details-tabs').should('be.visible').contains('Trace Details');
+  cy.getBySel('trace-details-kebab').click().contains('View on Graph');
 });
 
-And('user sees table details after selecting a trace', () => {
-    cy.getBySel('trace-details-tabs').should('not.exist');
-    cy.getBySel('jaeger-scatterplot').contains('Traces');
-    cy.getBySel('jaeger-scatterplot').find(`path${tracingDotQuery}`).first().should('be.visible').click({ force: true });
-    cy.getBySel('trace-details-tabs').should('be.visible').contains("Span Details").click();
-    cy.get('table').should('be.visible').contains('th', 'Timeline');
-    cy.get('#pf-tab-section-1-trace-details').within(() => {
-        cy.get('.pf-c-dropdown__toggle.pf-m-plain').first().click();
-        cy.get('ul.pf-c-dropdown__menu').should('be.visible').contains('Inbound Metrics');
+And('sd::user sees table details after selecting a trace', () => {
+  cy.getBySel('trace-details-tabs').should('be.visible').contains('Span Details').click();
+
+  // The traces tab fetches metrics in the background on a loop.
+  // Unforunately new data causes a re-render which
+  // makes clicking and testing for menus to open
+  // unreliable since re-renders cause the menus to close.
+  // We're delaying the response until after the test has finished so that
+  // we can test the menu opening without it closing prematurely.
+  // TODO: Fix whatever is causing new metrics data to undo click actions.
+  let dropdownVisible = false;
+  cy.intercept(`${Cypress.config('baseUrl')}/api/stats/metrics`, req => {
+    req.continue(res => {
+      let timer = 0;
+      const timeout = 30000;
+      while (!dropdownVisible && timer < timeout) {
+        setTimeout(() => {
+          timer += 50;
+        }, 50);
+      }
+    });
+  });
+
+  cy.get('table')
+    .should('be.visible')
+    .find('tbody tr') // ignore thead rows
+    .should('have.length.above', 1) // retries above cy.find() until we have a non head-row
+    .eq(1) // take 1st  row
+    .find('td')
+    .eq(4) // take 5th cell (kebab)
+    .click();
+  cy.get('ul.pf-c-dropdown__menu')
+    .should('be.visible')
+    .contains('Inbound Metrics')
+    .then(() => {
+      dropdownVisible = true;
     });
 });
diff --git a/frontend/cypress/integration/common/services.ts b/frontend/cypress/integration/common/services.ts
index 3b2bc22ce..dc261b3ca 100644
--- a/frontend/cypress/integration/common/services.ts
+++ b/frontend/cypress/integration/common/services.ts
@@ -1,4 +1,4 @@
-import { And, Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
+import { And, Given, Then, When } from '@badeball/cypress-cucumber-preprocessor';
 import { checkHealthIndicatorInTable, checkHealthStatusInTable, getColWithRowText } from './table';
 import { ensureKialiFinishedLoading } from './transition';
 
diff --git a/frontend/cypress/integration/common/sidecar_injection.ts b/frontend/cypress/integration/common/sidecar_injection.ts
index 0b51c2d62..9e72f5a80 100644
--- a/frontend/cypress/integration/common/sidecar_injection.ts
+++ b/frontend/cypress/integration/common/sidecar_injection.ts
@@ -1,4 +1,4 @@
-import { Given, Then, When } from "cypress-cucumber-preprocessor/steps";
+import { Given, Then, When } from "@badeball/cypress-cucumber-preprocessor";
 import { ensureKialiFinishedLoading } from "./transition";
 
 // Most of these "Given" implementations are directly using the Kiali API
diff --git a/frontend/cypress/integration/common/table.ts b/frontend/cypress/integration/common/table.ts
index d91768196..0d3f474d8 100644
--- a/frontend/cypress/integration/common/table.ts
+++ b/frontend/cypress/integration/common/table.ts
@@ -1,4 +1,4 @@
-import { And, Then, When } from 'cypress-cucumber-preprocessor/steps';
+import { And, Then, When } from '@badeball/cypress-cucumber-preprocessor';
 import { TableDefinition } from 'cypress-cucumber-preprocessor';
 
 Then(`user sees a table with headings`, (tableHeadings: TableDefinition) => {
diff --git a/frontend/cypress/integration/common/transition.ts b/frontend/cypress/integration/common/transition.ts
index fb3bb3fd4..bbb27b255 100644
--- a/frontend/cypress/integration/common/transition.ts
+++ b/frontend/cypress/integration/common/transition.ts
@@ -2,3 +2,7 @@ export function ensureKialiFinishedLoading() {
   cy.get('#loading_kiali_spinner').should('not.exist');
   cy.getBySel('loading-screen').should('not.exist');
 }
+
+export function openTab(tab: string) {
+  cy.get('#basic-tabs').should('be.visible').contains(tab).click();
+}
diff --git a/frontend/cypress/integration/common/wizard_request_routing.ts b/frontend/cypress/integration/common/wizard_request_routing.ts
index f531f93ac..e4f20343f 100644
--- a/frontend/cypress/integration/common/wizard_request_routing.ts
+++ b/frontend/cypress/integration/common/wizard_request_routing.ts
@@ -1,4 +1,4 @@
-import {And, Before, Given, Then, When} from "cypress-cucumber-preprocessor/steps";
+import {And, Before, Given, Then, When} from "@badeball/cypress-cucumber-preprocessor";
 
 const url = "/console";
 
diff --git a/frontend/cypress/integration/common/workload_logs.ts b/frontend/cypress/integration/common/workload_logs.ts
index 677f462ab..c88b9a40c 100644
--- a/frontend/cypress/integration/common/workload_logs.ts
+++ b/frontend/cypress/integration/common/workload_logs.ts
@@ -1,4 +1,4 @@
-import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
+import { Given, Then, When } from '@badeball/cypress-cucumber-preprocessor';
 
 Given('I am on the {string} workload detail page of the {string} namespace', (workload, namespace) => {
   cy.visit(`/console/namespaces/${namespace}/workloads/${workload}?refresh=0`);
diff --git a/frontend/cypress/integration/common/workloads.ts b/frontend/cypress/integration/common/workloads.ts
index d2f3a5528..385f2b9cf 100644
--- a/frontend/cypress/integration/common/workloads.ts
+++ b/frontend/cypress/integration/common/workloads.ts
@@ -1,4 +1,4 @@
-import { And, Given, Then } from 'cypress-cucumber-preprocessor/steps';
+import { And, Given, Then } from '@badeball/cypress-cucumber-preprocessor';
 import { checkHealthIndicatorInTable, checkHealthStatusInTable } from "./table";
 
 Given('a healthy workload in the cluster', function () {
diff --git a/frontend/cypress/integration/common/workloads_details.ts b/frontend/cypress/integration/common/workloads_details.ts
index 231b7ac19..150f61ade 100644
--- a/frontend/cypress/integration/common/workloads_details.ts
+++ b/frontend/cypress/integration/common/workloads_details.ts
@@ -1,6 +1,8 @@
-import { When, And, Then } from 'cypress-cucumber-preprocessor/steps';
+import { When, And, Then } from '@badeball/cypress-cucumber-preprocessor';
 import { getCellsForCol } from './table';
 
+const tracingDotQuery = '[style*="fill: var(--pf-global--palette--blue-200)"][style*="stroke: transparent;"]';
+
 function openTab(tab: string) {
   cy.get('#basic-tabs').should('be.visible').contains(tab).click();
 }
@@ -9,7 +11,6 @@ function openEnvoyTab(tab: string) {
   cy.get('#envoy-details').should('be.visible').contains(tab).click();
 }
 
-
 Then('user sees details information for workload', () => {
   cy.getBySel('workload-description-card').within(() => {
     cy.get('#pfbadge-A').parent().parent().contains('details'); // App
@@ -18,10 +19,6 @@ Then('user sees details information for workload', () => {
   });
 });
 
-Then('user sees a minigraph for workload', () => {
-  cy.getBySel('mini-graph');
-});
-
 Then('user sees workload inbound and outbound traffic information', () => {
   openTab('Traffic');
   cy.contains('Inbound Traffic');
@@ -30,7 +27,9 @@ Then('user sees workload inbound and outbound traffic information', () => {
 });
 
 Then('user sees workload inbound metrics information', () => {
-  cy.intercept(Cypress.config('baseUrl') + `/api/namespaces/bookinfo/workloads/details-v1/dashboard*`).as('fetchMetrics');
+  cy.intercept(Cypress.config('baseUrl') + `/api/namespaces/bookinfo/workloads/details-v1/dashboard*`).as(
+    'fetchMetrics'
+  );
   openTab('Inbound Metrics');
   cy.wait('@fetchMetrics');
   cy.waitForReact(1000, '#root');
@@ -44,7 +43,9 @@ Then('user sees workload inbound metrics information', () => {
 });
 
 Then('user sees workload outbound metrics information', () => {
-  cy.intercept(Cypress.config('baseUrl') + `/api/namespaces/bookinfo/workloads/details-v1/dashboard*`).as('fetchMetrics');
+  cy.intercept(Cypress.config('baseUrl') + `/api/namespaces/bookinfo/workloads/details-v1/dashboard*`).as(
+    'fetchMetrics'
+  );
   openTab('Outbound Metrics');
   cy.wait('@fetchMetrics');
   cy.waitForReact(1000, '#root');
@@ -58,19 +59,11 @@ Then('user sees workload outbound metrics information', () => {
 });
 
 Then('user sees workload trace information', () => {
-  cy.intercept(Cypress.config('baseUrl') + `/api/namespaces/bookinfo/workloads/details-v1/traces*`).as('fetchTraces');
   openTab('Traces');
-  cy.wait('@fetchTraces');
-  cy.waitForReact(1000, '#root');
   cy.getBySel('jaeger-scatterplot');
-  cy.contains('No traces').should('not.exist');
-  cy.getReact('TracesComponent')
-    .nthNode(1)
-    .getCurrentState()
-    .then(state => {
-      cy.wrap(state.traces).should('not.be.empty');
-      cy.wrap(state.jaegerErrors).should('be.undefined');
-    });
+  cy.getBySel('trace-details-tabs').should('not.exist');
+  cy.getBySel('jaeger-scatterplot').contains('Traces');
+  cy.getBySel('jaeger-scatterplot').find(`path${tracingDotQuery}`).first().should('be.visible').click({ force: true });
 });
 
 And('user sees workload trace details after selecting a trace', () => {
@@ -79,7 +72,6 @@ And('user sees workload trace details after selecting a trace', () => {
   // The traces component has fully loaded once 'Traces' is visible.
   cy.getBySel('jaeger-scatterplot').contains('Traces');
   // Blue dot on scatterplot is a trace so find one and click on it.
-  const tracingDotQuery = '[style*="fill: var(--pf-global--palette--blue-200)"][style*="stroke: transparent;"]';
   cy.getBySel('jaeger-scatterplot').find(`path${tracingDotQuery}`).first().should('be.visible').click({ force: true });
   cy.getBySel('trace-details-tabs').should('be.visible');
   cy.getBySel('trace-details-kebab').click().contains('View on Graph');
@@ -91,7 +83,6 @@ And('user sees workload span details after selecting a trace', () => {
   // The traces component has fully loaded once 'Traces' is visible.
   cy.getBySel('jaeger-scatterplot').contains('Traces');
   // Blue dot on scatterplot is a trace so find one and click on it.
-  const tracingDotQuery = '[style*="fill: var(--pf-global--palette--blue-200)"][style*="stroke: transparent"]';
   cy.getBySel('jaeger-scatterplot').find(`path${tracingDotQuery}`).first().should('be.visible').click({ force: true });
   cy.getBySel('trace-details-tabs').should('be.visible').contains('Span Details').click();
 });
@@ -107,13 +98,16 @@ And('user can filter spans by workload', () => {
   getCellsForCol(4).first().click();
 });
 
-When('the user filters by {string} with value {string} on the {string} tab', (filter: string, value: string, tab: string) => {
-  openTab('Envoy');
-  openEnvoyTab(tab);
-  cy.waitForReact(1000, '#root');
-  cy.get('select[aria-label="filter_select_type"]').select(filter);
-  cy.get('input[aria-label="filter_input_value"]').type(`${value}{enter}`);
-});
+When(
+  'the user filters by {string} with value {string} on the {string} tab',
+  (filter: string, value: string, tab: string) => {
+    openTab('Envoy');
+    openEnvoyTab(tab);
+    cy.waitForReact(1000, '#root');
+    cy.get('select[aria-label="filter_select_type"]').select(filter);
+    cy.get('input[aria-label="filter_input_value"]').type(`${value}{enter}`);
+  }
+);
 
 Then('the user sees clusters expected information', () => {
   cy.get('tbody').within(() => {
diff --git a/frontend/cypress/integration/featureFiles/service_details.feature b/frontend/cypress/integration/featureFiles/service_details.feature
index 6dc885ae4..7c3b3ce51 100644
--- a/frontend/cypress/integration/featureFiles/service_details.feature
+++ b/frontend/cypress/integration/featureFiles/service_details.feature
@@ -9,51 +9,51 @@ Feature: Kiali Service Details page
 
   @service-details-page
   Scenario: See details for productpage
-    Then user sees a list with content "Overview"
-    Then user sees a list with content "Traffic"
-    Then user sees a list with content "Inbound Metrics"
-    Then user sees a list with content "Traces"
-    Then user sees the actions button
+    Then sd::user sees a list with content "Overview"
+    Then sd::user sees a list with content "Traffic"
+    Then sd::user sees a list with content "Inbound Metrics"
+    Then sd::user sees a list with content "Traces"
+    Then sd::user sees the actions button
 
   @service-details-page
   Scenario: See details for service
-    Then user sees "productpage" details information for service "v1"
-    Then user sees Network card
-    Then user sees Istio Config
+    Then sd::user sees "productpage" details information for service "v1"
+    Then sd::user sees Network card
+    Then sd::user sees Istio Config
 
   @service-details-page
   Scenario: See minigraph for details app.
-    Then user sees a minigraph
+    Then sd::user sees a minigraph
 
   @service-details-page
   Scenario: See Traffic information
-    Then user sees inbound and outbound traffic information
+    Then sd::user sees inbound and outbound traffic information
 
   @service-details-page
   Scenario: See Inbound Metrics for productspage service details
-    Then the user sees "Request volume" graph
-    Then the user sees "Request duration" graph
-    Then the user sees "Request size" graph
-    Then the user sees "Response size" graph
-    Then the user sees "Request throughput" graph
-    Then the user sees "Response throughput" graph
-    Then the user sees "gRPC received" graph
-    Then the user sees "gRPC sent" graph
-    Then the user sees "TCP opened" graph
-    Then the user sees "TCP closed" graph
-    Then the user sees "TCP received" graph
-    Then the user sees "TCP sent" graph
+    Then sd::user sees "Request volume" graph
+    Then sd::user sees "Request duration" graph
+    Then sd::user sees "Request size" graph
+    Then sd::user sees "Response size" graph
+    Then sd::user sees "Request throughput" graph
+    Then sd::user sees "Response throughput" graph
+    Then sd::user sees "gRPC received" graph
+    Then sd::user sees "gRPC sent" graph
+    Then sd::user sees "TCP opened" graph
+    Then sd::user sees "TCP closed" graph
+    Then sd::user sees "TCP received" graph
+    Then sd::user sees "TCP sent" graph
 
   @service-details-page
   Scenario: See Graph data for productspage service details Inbound Metrics graphs
-    Then the user does not see No data message in the "Request volume" graph
+    Then sd::user does not see No data message in the "Request volume" graph
 
   @service-details-page
   Scenario: See graph traces for productspage service details
-    Then user sees graph with traces information
-    And user sees trace details after selecting a trace
+    Then sd::user sees graph with traces information
+    And sd::user sees trace details after selecting a trace
 
   @service-details-page
   Scenario: See span info after selecting a span
-    Then user sees graph with traces information
-    And user sees table details after selecting a trace
\ No newline at end of file
+    Then sd::user sees graph with traces information
+    And sd::user sees table details after selecting a trace
\ No newline at end of file
diff --git a/frontend/cypress/plugins/bdd.ts b/frontend/cypress/plugins/bdd.ts
deleted file mode 100644
index 2c0b74214..000000000
--- a/frontend/cypress/plugins/bdd.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-const browserify = require('@cypress/browserify-preprocessor');
-const cucumber = require('cypress-cucumber-preprocessor').default;
-const path = require('path');
-const plugin = require('./index');
-
-module.exports = (on, config) => {
-  config = plugin(on, config);
-  const options = {
-    ...browserify.defaultOptions,
-    typescript: path.join(path.resolve('..'), 'frontend/node_modules/typescript')
-  };
-
-  on('file:preprocessor', cucumber(options));
-
-  return config;
-};
diff --git a/frontend/cypress/plugins/index.ts b/frontend/cypress/plugins/index.ts
deleted file mode 100644
index e79ff2d70..000000000
--- a/frontend/cypress/plugins/index.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-/// <reference types="cypress" />
-// ***********************************************************
-// This example plugins/index.js can be used to load plugins
-//
-// You can change the location of this file or turn off loading
-// the plugins file with the 'pluginsFile' configuration option.
-//
-// You can read more here:
-// https://on.cypress.io/plugins-guide
-// ***********************************************************
-
-// This function is called when a project is opened or re-opened (e.g. due to
-// the project's config changing)
-const axios = require('axios');
-
-/**
- * @type {Cypress.PluginConfig}
- */
-// eslint-disable-next-line no-unused-vars
-module.exports = (on, config) => {
-  config.env.cookie = false;
-  // This name is non-standard and might change based on your environment hence the separate
-  // env variable.
-  config.env.AUTH_PROVIDER = config.env.AUTH_PROVIDER || 'my_htpasswd_provider';
-
-  async function exportConfig() {
-    const getAuthStrategy = async (url: string) => {
-      try {
-        const resp = await axios.get(url + '/api/auth/info');
-        return resp.data.strategy;
-      } catch (err) {
-        console.error(`ERROR: Kiali API is not reachable at ${JSON.stringify(err.config.url)}`);
-        throw new Error(`Kiali API is not reachable at ${JSON.stringify(err.config.url)}`);
-      }
-    };
-
-    config.env.AUTH_STRATEGY = await getAuthStrategy(config.baseUrl);
-    return await config;
-  }
-
-  return exportConfig();
-};
diff --git a/frontend/cypress/plugins/setup.ts b/frontend/cypress/plugins/setup.ts
new file mode 100644
index 000000000..6be5244ac
--- /dev/null
+++ b/frontend/cypress/plugins/setup.ts
@@ -0,0 +1,15 @@
+/*
+  This file contains helper functions for the *setup* of cypress itself.
+  It contains shared functionality used by the cypress config files.
+*/
+import get from 'axios';
+
+export async function getAuthStrategy(url: string) {
+  try {
+    const resp = await get(url + '/api/auth/info');
+    return resp.data.strategy;
+  } catch (err) {
+    console.error(`ERROR: Kiali API is not reachable at ${JSON.stringify(err.config.url)}`);
+    throw new Error(`Kiali API is not reachable at ${JSON.stringify(err.config.url)}`);
+  }
+}
diff --git a/frontend/package.json b/frontend/package.json
index 6fec487d9..522143a73 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -104,7 +104,6 @@
     "visibilityjs": "2.0.2"
   },
   "devDependencies": {
-    "@types/cypress-cucumber-preprocessor": "^4.0.1",
     "@types/cytoscape": "3.14.0",
     "@types/enzyme": "3.10.5",
     "@types/jest": "23.3.10",
@@ -116,8 +115,9 @@
     "@types/react-router-dom": "5.1.5",
     "@wojtekmaj/enzyme-adapter-react-17": "^0.6.7",
     "axios-mock-adapter": "1.16.0",
-    "cypress": "^9.2.1",
-    "cypress-cucumber-preprocessor": "^4.3.1",
+    "cypress": "^10.7.0",
+    "@badeball/cypress-cucumber-preprocessor": "^12.2.0",
+    "@cypress/browserify-preprocessor": "3.0.2",
     "cypress-multi-reporters": "^1.6.0",
     "cypress-react-selector": "^2.3.17",
     "enzyme": "3.11.0",
@@ -160,6 +160,6 @@
     "not ie <= 11"
   ],
   "cypress-cucumber-preprocessor": {
-    "nonGlobalStepDefinitions": true
+    "stepDefinitions": "cypress/integration/**/*.{js,ts}"
   }
 }
diff --git a/frontend/src/components/Details/DetailDescription.tsx b/frontend/src/components/Details/DetailDescription.tsx
index ea71e16f8..9fdcd5797 100644
--- a/frontend/src/components/Details/DetailDescription.tsx
+++ b/frontend/src/components/Details/DetailDescription.tsx
@@ -66,8 +66,8 @@ class DetailDescription extends React.Component<Props> {
       <Link to={href}>{appName}</Link>
     );
     return (
-      <li key={`App_${appName}`}>
-        <div key="service-icon" className={iconStyle}>
+      <li key={`App_${namespace}_${appName}`}>
+        <div className={iconStyle}>
           <PFBadge badge={PFBadges.App} position={TooltipPosition.top} />
         </div>
         <span>
@@ -91,7 +91,7 @@ class DetailDescription extends React.Component<Props> {
     );
     return (
       <li key={`Service_${serviceName}`}>
-        <div key="service-icon" className={iconStyle}>
+        <div className={iconStyle}>
           <PFBadge badge={PFBadges.Service} position={TooltipPosition.top} />
         </div>
         <span>
@@ -115,7 +115,7 @@ class DetailDescription extends React.Component<Props> {
         : this.renderEmptyItem('applications');
 
     return [
-      <div className={resourceListStyle}>
+      <div key="app-list" className={resourceListStyle}>
         <ul id="app-list" style={{ listStyleType: 'none' }}>
           {applicationList}
         </ul>
@@ -183,8 +183,8 @@ class DetailDescription extends React.Component<Props> {
         </Link>
       );
       return (
-        <span key={'WorkloadItem_' + workload.workloadName}>
-          <div key="service-icon" className={iconStyle}>
+        <span key={`WorkloadItem_${workload.workloadName}`}>
+          <div className={iconStyle}>
             <PFBadge badge={PFBadges.Workload} position={TooltipPosition.top} />
           </div>
           {link}
@@ -206,7 +206,7 @@ class DetailDescription extends React.Component<Props> {
       );
     } else {
       return (
-        <span key={'WorkloadItem_' + sub.text}>
+        <span key={`WorkloadItem_${sub.text}`}>
           <span style={{ marginRight: '10px' }}>{createIcon(sub.status)}</span>
           {sub.text}
         </span>
@@ -221,8 +221,8 @@ class DetailDescription extends React.Component<Props> {
           <div key="properties-list" className={resourceListStyle}>
             <span>Service accounts</span>
             <ul>
-              {workload.serviceAccountNames.map(serviceAccount => (
-                <li>{serviceAccount}</li>
+              {workload.serviceAccountNames.map((serviceAccount, i) => (
+                <li key={i}>{serviceAccount}</li>
               ))}
             </ul>
           </div>
@@ -281,7 +281,7 @@ class DetailDescription extends React.Component<Props> {
         : this.renderEmptyItem('services');
 
     return [
-      <div className={resourceListStyle}>
+      <div key="service-list" className={resourceListStyle}>
         <ul id="service-list" style={{ listStyleType: 'none' }}>
           {serviceList}
         </ul>
diff --git a/frontend/src/components/HeatMap/HeatMap.tsx b/frontend/src/components/HeatMap/HeatMap.tsx
index 76982ff48..133bd29c4 100644
--- a/frontend/src/components/HeatMap/HeatMap.tsx
+++ b/frontend/src/components/HeatMap/HeatMap.tsx
@@ -21,25 +21,19 @@ type Props = {
   displayMode?: 'compact' | 'normal' | 'large';
 };
 
-
 const baseStyle = {
-    alignItems: 'center',
-    borderRadius: 3,
-    display: 'flex',
-    fontSize: '.7rem',
-    justifyContent: 'center',
-    overflow: 'hidden',
-    textOverflow: 'clip'
+  alignItems: 'center',
+  borderRadius: 3,
+  display: 'flex',
+  fontSize: '.7rem',
+  justifyContent: 'center',
+  overflow: 'hidden',
+  textOverflow: 'clip'
 };
 
-const labelStyle = style(
-  baseStyle
-);
+const labelStyle = style(baseStyle);
 
-const cellStyle = style(
-  baseStyle,
-  { whiteSpace: 'nowrap'}
-);
+const cellStyle = style(baseStyle, { whiteSpace: 'nowrap' });
 
 export class HeatMap extends React.Component<Props> {
   static HealthColorMap: ColorMap = [
@@ -96,14 +90,14 @@ export class HeatMap extends React.Component<Props> {
       <div style={this.getGridStyle()}>
         <div></div>
         {this.props.xLabels.map((xLabel, x) => (
-          <div key={'xlabel_' + x} className={labelStyle}>
+          <div key={`xlabel_${x}`} className={labelStyle}>
             {isCompact ? '' : xLabel}
           </div>
         ))}
         {this.props.yLabels.map((yLabel, y) => {
           return (
-            <>
-              <div key={'ylabel_' + y} className={labelStyle}>
+            <React.Fragment key={`ylabel_${y}`}>
+              <div className={labelStyle}>
                 {isCompact ? '' : yLabel}
               </div>
               {this.props.xLabels.map((_, x) => {
@@ -131,7 +125,7 @@ export class HeatMap extends React.Component<Props> {
                   </div>
                 );
               })}
-            </>
+            </React.Fragment>
           );
         })}
       </div>
diff --git a/frontend/src/components/IstioWizards/ConfirmDeleteTrafficRoutingModal.tsx b/frontend/src/components/IstioWizards/ConfirmDeleteTrafficRoutingModal.tsx
index 1473e65be..08d1231ca 100644
--- a/frontend/src/components/IstioWizards/ConfirmDeleteTrafficRoutingModal.tsx
+++ b/frontend/src/components/IstioWizards/ConfirmDeleteTrafficRoutingModal.tsx
@@ -1,14 +1,14 @@
-import React from "react";
-import {Button, ButtonVariant, Modal, ModalVariant} from "@patternfly/react-core";
-import {DestinationRuleC, VirtualService} from "../../types/IstioObjects";
+import React from 'react';
+import { Button, ButtonVariant, Modal, ModalVariant } from '@patternfly/react-core';
+import { DestinationRuleC, VirtualService } from '../../types/IstioObjects';
 
 type Props = {
   destinationRules: DestinationRuleC[];
   virtualServices: VirtualService[];
-  isOpen: boolean
+  isOpen: boolean;
   onCancel: () => void;
   onConfirm: () => void;
-}
+};
 
 const ConfirmDeleteTrafficRoutingModal: React.FunctionComponent<Props> = props => {
   function hasAnyPeerAuthn(drs: DestinationRuleC[]): boolean {
@@ -19,33 +19,36 @@ const ConfirmDeleteTrafficRoutingModal: React.FunctionComponent<Props> = props =
     const deleteMessage = 'Are you sure you want to delete ?';
     const deleteItems: JSX.Element[] = [];
 
+    let i = 0;
     let vsMessage =
       props.virtualServices.length > 0
         ? `VirtualService${props.virtualServices.length > 1 ? 's' : ''}: '${props.virtualServices.map(
-          vs => vs.metadata.name
-        )}'`
+            vs => vs.metadata.name
+          )}'`
         : '';
-    deleteItems.push(<div>{vsMessage}</div>);
+    deleteItems.push(<div key={`delete_item_${++i}`}>{vsMessage}</div>);
 
     let drMessage =
       props.destinationRules.length > 0
         ? `DestinationRule${props.destinationRules.length > 1 ? 's' : ''}: '${props.destinationRules.map(
-          dr => dr.metadata.name
-        )}'`
+            dr => dr.metadata.name
+          )}'`
         : '';
-    deleteItems.push(<div>{drMessage}</div>);
+    deleteItems.push(<div key={`delete_item_${++i}`}>{drMessage}</div>);
 
     let paMessage =
       props.destinationRules.length > 0 && hasAnyPeerAuthn(props.destinationRules)
-        ? `PeerAuthentication${
-          props.destinationRules.length > 1 ? 's' : ''
-        }: '${props.destinationRules.map(dr => dr.metadata.name)}'`
+        ? `PeerAuthentication${props.destinationRules.length > 1 ? 's' : ''}: '${props.destinationRules.map(
+            dr => dr.metadata.name
+          )}'`
         : '';
-    deleteItems.push(<div>{paMessage}</div>);
+    deleteItems.push(<div key={`delete_item_${++i}`}>{paMessage}</div>);
 
     return (
       <>
-        <div style={{ marginBottom: 5 }}>{deleteMessage}</div>
+        <div key="delete_items" style={{ marginBottom: 5 }}>
+          {deleteMessage}
+        </div>
         {deleteItems}
       </>
     );
@@ -70,6 +73,6 @@ const ConfirmDeleteTrafficRoutingModal: React.FunctionComponent<Props> = props =
       {getDeleteMessage()}
     </Modal>
   );
-}
+};
 
 export default ConfirmDeleteTrafficRoutingModal;
diff --git a/frontend/src/components/IstioWizards/ServiceWizardActionsDropdownGroup.tsx b/frontend/src/components/IstioWizards/ServiceWizardActionsDropdownGroup.tsx
index eebd1066b..ac069edcf 100644
--- a/frontend/src/components/IstioWizards/ServiceWizardActionsDropdownGroup.tsx
+++ b/frontend/src/components/IstioWizards/ServiceWizardActionsDropdownGroup.tsx
@@ -87,11 +87,11 @@ const ServiceWizardActionsDropdownGroup: React.FunctionComponent<Props> = props
   }
 
   actionItems.push(deleteDropdownItem);
-
+  const label = updateLabel === '' ? 'Create' : 'Update';
   return (
     <DropdownGroup
-      key={'group_create'}
-      label={updateLabel === '' ? 'Create' : 'Update'}
+      key={`group_${label}`}
+      label={label}
       className="kiali-group-menu"
       children={actionItems}
     />
diff --git a/frontend/src/components/IstioWizards/ServiceWizardDropdown.tsx b/frontend/src/components/IstioWizards/ServiceWizardDropdown.tsx
index 7fa87a054..daffac7d5 100644
--- a/frontend/src/components/IstioWizards/ServiceWizardDropdown.tsx
+++ b/frontend/src/components/IstioWizards/ServiceWizardDropdown.tsx
@@ -168,6 +168,7 @@ class ServiceWizardDropdown extends React.Component<Props, State> {
   renderDropdownItems = () => {
     return [
       <ServiceWizardActionsDropdownGroup
+        key="service_wizard_actions_dropdown_group"
         isDisabled={this.state.isDeleting}
         virtualServices={this.props.virtualServices}
         destinationRules={this.props.destinationRules}
diff --git a/frontend/src/components/IstioWizards/WorkloadWizard.tsx b/frontend/src/components/IstioWizards/WorkloadWizard.tsx
index d37f73830..6ae17dd38 100644
--- a/frontend/src/components/IstioWizards/WorkloadWizard.tsx
+++ b/frontend/src/components/IstioWizards/WorkloadWizard.tsx
@@ -45,6 +45,7 @@ class WorkloadWizard extends React.Component<WorkloadWizardProps, WorkloadWizard
         <Modal
           width={'75%'}
           title={this.props.type.length > 0 ? WIZARD_TITLES[this.props.type] : ''}
+          aria-label="workload wizard"
           isOpen={this.state.showWizard}
           onClose={() => this.onClose(false)}
           actions={[
diff --git a/frontend/src/components/JaegerIntegration/JaegerResults/JaegerTraceTitle.tsx b/frontend/src/components/JaegerIntegration/JaegerResults/JaegerTraceTitle.tsx
index 986f1ebdd..1adcb7d7d 100644
--- a/frontend/src/components/JaegerIntegration/JaegerResults/JaegerTraceTitle.tsx
+++ b/frontend/src/components/JaegerIntegration/JaegerResults/JaegerTraceTitle.tsx
@@ -1,33 +1,27 @@
 import * as React from 'react';
-import {
-  CardActions,
-  CardHeader,
-  CardTitle,
-  Dropdown,
-  DropdownItem,
-  KebabToggle,
-} from '@patternfly/react-core';
+import { CardActions, CardHeader, CardTitle, Dropdown, DropdownItem, KebabToggle } from '@patternfly/react-core';
 import { ExternalLinkAltIcon } from '@patternfly/react-icons';
 import { FormattedTraceInfo, fullIDStyle } from './FormattedTraceInfo';
 import history from 'app/History';
-import {KialiAppState} from "../../../store/Store";
-import {connect} from "react-redux";
-import {isParentKiosk, kioskContextMenuAction} from "../../Kiosk/KioskActions";
+import { KialiAppState } from '../../../store/Store';
+import { connect } from 'react-redux';
+import { isParentKiosk, kioskContextMenuAction } from '../../Kiosk/KioskActions';
 
 type ReduxProps = {
   kiosk: string;
-}
+};
 
 type Props = ReduxProps & {
   formattedTrace: FormattedTraceInfo;
   externalURL?: string;
   graphURL: string;
   comparisonURL?: string;
-}
+};
 
 const JaegerTraceTitle = (props: Props) => {
   const links = [
     <DropdownItem
+      key="view_on_graph"
       onClick={() => {
         if (isParentKiosk(props.kiosk)) {
           kioskContextMenuAction(props.graphURL);
@@ -35,19 +29,20 @@ const JaegerTraceTitle = (props: Props) => {
           history.push(props.graphURL);
         }
       }}
-    >View on Graph
+    >
+      View on Graph
     </DropdownItem>
   ];
   if (props.externalURL) {
     links.push(
-      <DropdownItem onClick={() => window.open(props.externalURL, '_blank')}>
+      <DropdownItem key="view_in_tracing" onClick={() => window.open(props.externalURL, '_blank')}>
         View in Tracing <ExternalLinkAltIcon />
       </DropdownItem>
     );
   }
   if (props.comparisonURL) {
     links.push(
-      <DropdownItem onClick={() => window.open(props.comparisonURL, '_blank')}>
+      <DropdownItem key="compare_with_similar_traces" onClick={() => window.open(props.comparisonURL, '_blank')}>
         Compare with similar traces <ExternalLinkAltIcon />
       </DropdownItem>
     );
@@ -80,8 +75,8 @@ const JaegerTraceTitle = (props: Props) => {
 
 const mapStateToProps = (state: KialiAppState) => {
   return {
-    kiosk: state.globalState.kiosk,
-  }
+    kiosk: state.globalState.kiosk
+  };
 };
 
 const JaegerTraceTitleContainer = connect(mapStateToProps)(JaegerTraceTitle);
diff --git a/frontend/src/components/JaegerIntegration/JaegerResults/SpanTable.tsx b/frontend/src/components/JaegerIntegration/JaegerResults/SpanTable.tsx
index 96a58181e..ed789926b 100644
--- a/frontend/src/components/JaegerIntegration/JaegerResults/SpanTable.tsx
+++ b/frontend/src/components/JaegerIntegration/JaegerResults/SpanTable.tsx
@@ -44,7 +44,7 @@ import responseFlags from 'utils/ResponseFlags';
 import { renderMetricsComparison } from './StatsComparison';
 import history from 'app/History';
 import { AngleDownIcon, AngleRightIcon, ExternalLinkAltIcon } from '@patternfly/react-icons';
-import {isParentKiosk, kioskContextMenuAction} from "../../Kiosk/KioskActions";
+import { isParentKiosk, kioskContextMenuAction } from '../../Kiosk/KioskActions';
 
 type ReduxProps = {
   kiosk: string;
@@ -196,8 +196,9 @@ class SpanTable extends React.Component<Props, State> {
 
     return {
       cells: [
-        <div key={`${item.spanID}-duration`}>
+        <>
           <Button
+            key={`${item.spanID}-duration`}
             style={{ padding: '6px 4px 6px 0' }}
             variant={ButtonVariant.link}
             onClick={() => this.toggleExpanded(item.spanID)}
@@ -205,7 +206,7 @@ class SpanTable extends React.Component<Props, State> {
             {isExpanded ? <AngleDownIcon /> : <AngleRightIcon />}
           </Button>
           {formatDuration(item.relativeStartTime)}
-        </div>,
+        </>,
         this.OriginCell(item),
         this.SummaryCell(item),
         this.StatsCell(item)
@@ -324,7 +325,9 @@ class SpanTable extends React.Component<Props, State> {
 
     // Parent Kiosk won't have links to the app details
     // as most of the kubernetes consoles don't have an unified "app" entity
-    return parentKiosk ? [...workloadActions, ...tracingActions] : [...appActions, ...workloadActions, ...tracingActions];
+    return parentKiosk
+      ? [...workloadActions, ...tracingActions]
+      : [...appActions, ...workloadActions, ...tracingActions];
   };
 
   private isExpanded = (spanID: string): boolean => {
@@ -339,72 +342,90 @@ class SpanTable extends React.Component<Props, State> {
 
   private OriginCell = (item: RichSpanData): React.ReactNode => {
     const parentKiosk = isParentKiosk(this.props.kiosk);
+    const key = `${item.spanID}-origin`;
     return (
-      <div key={`${item.spanID}-origin`}>
-        <strong>Application: </strong>
-        {(item.linkToApp && (parentKiosk ?
-          <Link
-            to={''}
-            onClick={() => {
-              if (item.linkToApp) {
-                kioskContextMenuAction(item.linkToApp);
-              }
-            }}>{item.app}</Link> :
-          <Link to={item.linkToApp}>{item.app}</Link>
-        )) || item.app}
-        <br />
-        <strong>Workload: </strong>
-        {(item.linkToWorkload && (parentKiosk ?
-          <Link
-            to={''}
-            onClick={() => {
-              if (item.linkToWorkload) {
-                kioskContextMenuAction(item.linkToWorkload);
-              }
-            }}
-          >{item.workload}</Link> :
-            <Link to={item.linkToWorkload}>{item.workload}</Link>
-        )) || 'unknown'}
+      <>
+        <strong key={`${key}-app`}>Application: </strong>
+        {(item.linkToApp &&
+          (parentKiosk ? (
+            <Link
+              key={`${key}-link-app`}
+              to={''}
+              onClick={() => {
+                if (item.linkToApp) {
+                  kioskContextMenuAction(item.linkToApp);
+                }
+              }}
+            >
+              {item.app}
+            </Link>
+          ) : (
+            <Link key={`${key}-link-app`} to={item.linkToApp}>
+              {item.app}
+            </Link>
+          ))) ||
+          item.app}
+        <br key={`${key}-br`} />
+        <strong key={`${key}-wl`}>Workload: </strong>
+        {(item.linkToWorkload &&
+          (parentKiosk ? (
+            <Link
+              key={`${key}-link-wl`}
+              to={''}
+              onClick={() => {
+                if (item.linkToWorkload) {
+                  kioskContextMenuAction(item.linkToWorkload);
+                }
+              }}
+            >
+              {item.workload}
+            </Link>
+          ) : (
+            <Link key={`${key}-link-wl`} to={item.linkToWorkload}>
+              {item.workload}
+            </Link>
+          ))) ||
+          'unknown'}
         {this.isExpanded(item.spanID) && (
-          <>
-            <br />
-            <strong>Pod: </strong>
+          <div key={`${key}-expanded-br-1`}>
+            <strong key={`${key}-expanded-pod`}>Pod: </strong>
             {item.pod || 'unknown'}
-            <br />
-          </>
+          </div>
         )}
-      </div>
+      </>
     );
   };
 
   private SummaryCell = (item: RichSpanData): React.ReactNode => {
     const flag = (item.info as EnvoySpanInfo).responseFlags;
+    const key = `${item.spanID}-summary`;
     return (
-      <div key={`${item.spanID}-summary`}>
+      <>
         {item.info.hasError && (
-          <div>
-            <ExclamationCircleIcon color={PFColors.Danger} /> <strong>This span reported an error</strong>
+          <div key={`${key}-err`}>
+            <ExclamationCircleIcon key={`${key}-err-ic`} color={PFColors.Danger} />{' '}
+            <strong key={`${key}-err-msg`}>This span reported an error</strong>
           </div>
         )}
-        <div>
-          <strong>Operation: </strong>
+        <div key={`${key}-op`}>
+          <strong key={`${key}-op-title`}>Operation: </strong>
           {flag ? (
-            <>
-              {item.operationName} ({flag} <ExclamationCircleIcon color={PFColors.Danger} />)
-            </>
+            <span key={`${key}-op-name`}>
+              {item.operationName} ({flag} <ExclamationCircleIcon key={`${key}-dan-ic`} color={PFColors.Danger} />)
+            </span>
           ) : (
-            <>{item.operationName}</>
+            <span key={`${key}-op-name`}>{item.operationName}</span>
           )}
         </div>
-        <div>
-          <strong>Component: </strong>
+        <div key={`${key}-comp`}>
+          <strong key={`${key}-comp=-title`}>Component: </strong>
           {item.component}
         </div>
         {this.isExpanded(item.spanID) &&
           ((item.type === 'envoy' && this.renderEnvoySummary(item)) ||
             (item.type === 'http' && this.renderHTTPSummary(item)) ||
             (item.type === 'tcp' && this.renderTCPSummary(item)))}
-      </div>
+      </>
     );
   };
 
@@ -413,6 +434,7 @@ class SpanTable extends React.Component<Props, State> {
     const info = item.info as EnvoySpanInfo;
     let rqLabel = 'Request';
     let peerLink: JSX.Element | undefined = undefined;
+    const key = `${item.spanID}-summary-envoy`;
     if (info.direction === 'inbound') {
       rqLabel = 'Received request';
       if (info.peer) {
@@ -427,7 +449,9 @@ class SpanTable extends React.Component<Props, State> {
                     kioskContextMenuAction('/namespaces/' + info.peer.namespace + '/workloads/' + info.peer.name);
                   }
                 }}
-              >{info.peer.name}</Link>
+              >
+                {info.peer.name}
+              </Link>
             ) : (
               <Link to={'/namespaces/' + info.peer.namespace + '/workloads/' + info.peer.name}>{info.peer.name}</Link>
             )}
@@ -438,21 +462,26 @@ class SpanTable extends React.Component<Props, State> {
       rqLabel = 'Sent request';
       if (info.peer) {
         peerLink = (
-          <>
-            {' to '}
+          <React.Fragment key={`${key}-out`}>
+            <span key={`${key}-out-to`}>{' to '}</span>
             {parentKiosk ? (
               <Link
+                key={`${key}-out-link`}
                 to={''}
                 onClick={() => {
                   if (info.peer) {
                     kioskContextMenuAction('/namespaces/' + info.peer.namespace + '/services/' + info.peer.name);
                   }
                 }}
-              >{info.peer.name}</Link>
+              >
+                {info.peer.name}
+              </Link>
             ) : (
-              <Link to={'/namespaces/' + info.peer.namespace + '/services/' + info.peer.name}>{info.peer.name}</Link>
+              <Link key={`${key}-out-link`} to={'/namespaces/' + info.peer.namespace + '/services/' + info.peer.name}>
+                {info.peer.name}
+              </Link>
             )}
-          </>
+          </React.Fragment>
         );
       }
     }
@@ -467,20 +496,22 @@ class SpanTable extends React.Component<Props, State> {
     }
 
     return (
-      <>
-        <div>
-          <strong>
+      <React.Fragment key={`${key}`}>
+        <div key={`${key}-req`}>
+          <strong key={`${key}-req-title`}>
             {rqLabel}
             {peerLink}:{' '}
           </strong>
-          {info.method} {info.url}
+          <span key={`${key}-req-val`}>
+            {info.method} {info.url}
+          </span>
         </div>
-        <div>
-          <strong>Response status: </strong>
-          {rsDetails.join(', ')}
+        <div key={`${key}-status`}>
+          <strong key={`${key}-status-title`}>Response status: </strong>
+          <span key={`${key}-status-val`}>{rsDetails.join(', ')}</span>
         </div>
-        {flagInfo}
-      </>
+        <span key={`${key}-flag`}>{flagInfo}</span>
+      </React.Fragment>
     );
   };
 
@@ -488,41 +519,46 @@ class SpanTable extends React.Component<Props, State> {
     const info = item.info as OpenTracingHTTPInfo;
     const rqLabel =
       info.direction === 'inbound' ? 'Received request' : info.direction === 'outbound' ? 'Sent request' : 'Request';
+    const key = `${item.spanID}-summary-http`;
     return (
-      <>
-        <div>
-          <strong>{rqLabel}: </strong>
-          {info.method} {info.url}
+      <React.Fragment key={key}>
+        <div key={`${key}-req`}>
+          <strong key={`${key}-req-title`}>{rqLabel}: </strong>
+          <span key={`${key}-req-val`}>
+            {info.method} {info.url}
+          </span>
         </div>
         {info.statusCode && (
-          <div>
-            <strong>Response status: </strong>
-            {info.statusCode}
+          <div key={`${key}-code`}>
+            <strong key={`${key}-code-title`}>Response status: </strong>
+            <span key={`${key}-code-val`}>{info.statusCode}</span>
           </div>
         )}
-      </>
+      </React.Fragment>
     );
   };
 
   private renderTCPSummary = (item: RichSpanData) => {
     const info = item.info as OpenTracingTCPInfo;
+    const key = `${item.spanID}-summary-tcp`;
     return (
-      <>
+      <React.Fragment key={key}>
         {info.topic && (
-          <div>
-            <strong>Topic: </strong>
-            {info.topic}
+          <div key={`${key}-topic`}>
+            <strong key={`${key}-topic-title`}>Topic: </strong>
+            <span key={`${key}-topic-val`}>{info.topic}</span>
           </div>
         )}
-      </>
+      </React.Fragment>
     );
   };
 
   private StatsCell = (item: RichSpanData): React.ReactNode => {
+    const key = `${item.spanID}-stats`;
     return (
-      <div key={`${item.spanID}-stats`}>
-        <div>
-          <strong>Duration: </strong>
+      <div key={key}>
+        <div key={`${key}-dur-div`}>
+          <strong key={`${key}-dur-title`}>Duration: </strong>
           {formatDuration(item.duration)}
         </div>
         {item.type === 'envoy' &&
@@ -536,7 +572,7 @@ class SpanTable extends React.Component<Props, State> {
 
 const mapStateToProps = (state: KialiAppState) => ({
   kiosk: state.globalState.kiosk,
-  metricsStats: state.metricsStats.data,
+  metricsStats: state.metricsStats.data
 });
 
 const mapDispatchToProps = (dispatch: KialiDispatch) => ({
diff --git a/frontend/src/components/JaegerIntegration/JaegerResults/StatsComparison.tsx b/frontend/src/components/JaegerIntegration/JaegerResults/StatsComparison.tsx
index 41ffa4316..14ed4d193 100644
--- a/frontend/src/components/JaegerIntegration/JaegerResults/StatsComparison.tsx
+++ b/frontend/src/components/JaegerIntegration/JaegerResults/StatsComparison.tsx
@@ -35,8 +35,10 @@ const renderHeatMap = (
   intervals: string[],
   compactMode: boolean
 ) => {
+  const key = `${item.spanID}-hm`;
   return (
     <HeatMap
+      key={key}
       xLabels={statsAvgWithQuantiles.map(s => statToText[s]?.short || s)}
       yLabels={intervals}
       data={statsToMatrix(stats, intervals)}
@@ -75,24 +77,28 @@ export const renderMetricsComparison = (
 ) => {
   const intervals = compactMode ? compactStatsIntervals : allStatsIntervals;
   const itemStats = getSpanStats(item, intervals, metricsStats);
+  const key = `${item.spanID}-metcomp`;
   if (itemStats.length > 0) {
     return (
-      <>
+      <React.Fragment key={key}>
         {!compactMode && (
-          <Tooltip content="This heatmap is a comparison matrix of this request duration against duration statistics aggregated over time. Move the pointer over cells to get more details.">
+          <Tooltip
+            key={`${key}-tt`}
+            content="This heatmap is a comparison matrix of this request duration against duration statistics aggregated over time. Move the pointer over cells to get more details."
+          >
             <>
-              <InfoAltIcon /> <strong>Comparison map: </strong>
+              <InfoAltIcon key={`${key}-ic`} /> <strong key={`${key}-ic-title`}>Comparison map: </strong>
             </>
           </Tooltip>
         )}
         {renderHeatMap(item, itemStats, intervals, compactMode)}
-      </>
+      </React.Fragment>
     );
   }
   return (
-    <Tooltip content="Click to load more statistics for this request">
-      <Button onClick={load} variant={ButtonVariant.link}>
-        <strong>Load statistics</strong>
+    <Tooltip key={`${key}-tt`} content="Click to load more statistics for this request">
+      <Button key={`${key}-load`} onClick={load} variant={ButtonVariant.link}>
+        <strong key={`${key}-load-title`}>Load statistics</strong>
       </Button>
     </Tooltip>
   );
diff --git a/frontend/src/components/Time/TimeDurationModal.tsx b/frontend/src/components/Time/TimeDurationModal.tsx
index 94a8dafd9..133dad402 100644
--- a/frontend/src/components/Time/TimeDurationModal.tsx
+++ b/frontend/src/components/Time/TimeDurationModal.tsx
@@ -65,6 +65,7 @@ export function TimeDurationModal(props: Props) {
 
   return (
     <Modal
+      aria-label="time-duration"
       variant={ModalVariant.small}
       width={700}
       isOpen={props.isOpen}
diff --git a/frontend/src/components/VirtualList/Renderers.tsx b/frontend/src/components/VirtualList/Renderers.tsx
index c2ddc590c..74e8daf49 100644
--- a/frontend/src/components/VirtualList/Renderers.tsx
+++ b/frontend/src/components/VirtualList/Renderers.tsx
@@ -93,7 +93,7 @@ export const details: Renderer<AppListItem | WorkloadListItem | ServiceListItem>
         {item.istioReferences &&
           item.istioReferences.length > 0 &&
           item.istioReferences.map(ir => (
-            <li key={ir.namespace ? `${ir.name}_${ir.namespace}` : ir.name}>
+            <li key={ir.namespace ? `${ir.objectType}_${ir.name}_${ir.namespace}` : ir.name}>
               <PFBadge badge={PFBadges[ir.objectType]} position={TooltipPosition.top} />
               <IstioObjectLink name={ir.name} namespace={ir.namespace || ''} type={ir.objectType.toLowerCase()}>
                 {ir.name}
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 8983e5688..2be777661 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -32,6 +32,13 @@
   dependencies:
     "@babel/highlight" "^7.16.7"
 
+"@babel/code-frame@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a"
+  integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==
+  dependencies:
+    "@babel/highlight" "^7.18.6"
+
 "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.4":
   version "7.14.4"
   resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.4.tgz#45720fe0cecf3fd42019e1d12cc3d27fadc98d58"
@@ -47,6 +54,11 @@
   resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2"
   integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==
 
+"@babel/compat-data@^7.18.8", "@babel/compat-data@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.0.tgz#2a592fd89bacb1fcde68de31bee4f2f2dacb0e86"
+  integrity sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==
+
 "@babel/core@^7.1.0":
   version "7.14.3"
   resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.3.tgz#5395e30405f0776067fbd9cf0884f15bfb770a38"
@@ -146,6 +158,15 @@
     jsesc "^2.5.1"
     source-map "^0.5.0"
 
+"@babel/generator@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.0.tgz#785596c06425e59334df2ccee63ab166b738419a"
+  integrity sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==
+  dependencies:
+    "@babel/types" "^7.19.0"
+    "@jridgewell/gen-mapping" "^0.3.2"
+    jsesc "^2.5.1"
+
 "@babel/helper-annotate-as-pure@^7.12.13":
   version "7.12.13"
   resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab"
@@ -160,6 +181,13 @@
   dependencies:
     "@babel/types" "^7.16.7"
 
+"@babel/helper-annotate-as-pure@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb"
+  integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==
+  dependencies:
+    "@babel/types" "^7.18.6"
+
 "@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b"
@@ -168,6 +196,14 @@
     "@babel/helper-explode-assignable-expression" "^7.16.7"
     "@babel/types" "^7.16.7"
 
+"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz#acd4edfd7a566d1d51ea975dff38fd52906981bb"
+  integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==
+  dependencies:
+    "@babel/helper-explode-assignable-expression" "^7.18.6"
+    "@babel/types" "^7.18.9"
+
 "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.16":
   version "7.14.4"
   resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.4.tgz#33ebd0ffc34248051ee2089350a929ab02f2a516"
@@ -198,6 +234,16 @@
     browserslist "^4.17.5"
     semver "^6.3.0"
 
+"@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.0.tgz#537ec8339d53e806ed422f1e06c8f17d55b96bb0"
+  integrity sha512-Ai5bNWXIvwDvWM7njqsG3feMlL9hCVQsPYXodsZyLwshYkZVJt59Gftau4VrE8S9IT9asd2uSP1hG6wCNw+sXA==
+  dependencies:
+    "@babel/compat-data" "^7.19.0"
+    "@babel/helper-validator-option" "^7.18.6"
+    browserslist "^4.20.2"
+    semver "^6.3.0"
+
 "@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7", "@babel/helper-create-class-features-plugin@^7.17.6":
   version "7.17.6"
   resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz#3778c1ed09a7f3e65e6d6e0f6fbfcc53809d92c9"
@@ -211,6 +257,19 @@
     "@babel/helper-replace-supers" "^7.16.7"
     "@babel/helper-split-export-declaration" "^7.16.7"
 
+"@babel/helper-create-class-features-plugin@^7.18.6":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz#bfd6904620df4e46470bae4850d66be1054c404b"
+  integrity sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==
+  dependencies:
+    "@babel/helper-annotate-as-pure" "^7.18.6"
+    "@babel/helper-environment-visitor" "^7.18.9"
+    "@babel/helper-function-name" "^7.19.0"
+    "@babel/helper-member-expression-to-functions" "^7.18.9"
+    "@babel/helper-optimise-call-expression" "^7.18.6"
+    "@babel/helper-replace-supers" "^7.18.9"
+    "@babel/helper-split-export-declaration" "^7.18.6"
+
 "@babel/helper-create-regexp-features-plugin@^7.12.13":
   version "7.14.3"
   resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.3.tgz#149aa6d78c016e318c43e2409a0ae9c136a86688"
@@ -227,6 +286,14 @@
     "@babel/helper-annotate-as-pure" "^7.16.7"
     regexpu-core "^5.0.1"
 
+"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b"
+  integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==
+  dependencies:
+    "@babel/helper-annotate-as-pure" "^7.18.6"
+    regexpu-core "^5.1.0"
+
 "@babel/helper-define-polyfill-provider@^0.3.1":
   version "0.3.1"
   resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665"
@@ -241,6 +308,18 @@
     resolve "^1.14.2"
     semver "^6.1.2"
 
+"@babel/helper-define-polyfill-provider@^0.3.2", "@babel/helper-define-polyfill-provider@^0.3.3":
+  version "0.3.3"
+  resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a"
+  integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==
+  dependencies:
+    "@babel/helper-compilation-targets" "^7.17.7"
+    "@babel/helper-plugin-utils" "^7.16.7"
+    debug "^4.1.1"
+    lodash.debounce "^4.0.8"
+    resolve "^1.14.2"
+    semver "^6.1.2"
+
 "@babel/helper-environment-visitor@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7"
@@ -248,6 +327,11 @@
   dependencies:
     "@babel/types" "^7.16.7"
 
+"@babel/helper-environment-visitor@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"
+  integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
+
 "@babel/helper-explode-assignable-expression@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a"
@@ -255,6 +339,13 @@
   dependencies:
     "@babel/types" "^7.16.7"
 
+"@babel/helper-explode-assignable-expression@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096"
+  integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==
+  dependencies:
+    "@babel/types" "^7.18.6"
+
 "@babel/helper-function-name@^7.14.2":
   version "7.14.2"
   resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz#397688b590760b6ef7725b5f0860c82427ebaac2"
@@ -273,6 +364,14 @@
     "@babel/template" "^7.16.7"
     "@babel/types" "^7.16.7"
 
+"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c"
+  integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==
+  dependencies:
+    "@babel/template" "^7.18.10"
+    "@babel/types" "^7.19.0"
+
 "@babel/helper-get-function-arity@^7.12.13":
   version "7.12.13"
   resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583"
@@ -294,6 +393,13 @@
   dependencies:
     "@babel/types" "^7.16.7"
 
+"@babel/helper-hoist-variables@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678"
+  integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==
+  dependencies:
+    "@babel/types" "^7.18.6"
+
 "@babel/helper-member-expression-to-functions@^7.13.12":
   version "7.13.12"
   resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72"
@@ -308,6 +414,13 @@
   dependencies:
     "@babel/types" "^7.16.7"
 
+"@babel/helper-member-expression-to-functions@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815"
+  integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==
+  dependencies:
+    "@babel/types" "^7.18.9"
+
 "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437"
@@ -322,6 +435,13 @@
   dependencies:
     "@babel/types" "^7.13.12"
 
+"@babel/helper-module-imports@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e"
+  integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==
+  dependencies:
+    "@babel/types" "^7.18.6"
+
 "@babel/helper-module-transforms@^7.14.2":
   version "7.14.2"
   resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz#ac1cc30ee47b945e3e0c4db12fa0c5389509dfe5"
@@ -364,6 +484,20 @@
     "@babel/traverse" "^7.17.3"
     "@babel/types" "^7.17.0"
 
+"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30"
+  integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==
+  dependencies:
+    "@babel/helper-environment-visitor" "^7.18.9"
+    "@babel/helper-module-imports" "^7.18.6"
+    "@babel/helper-simple-access" "^7.18.6"
+    "@babel/helper-split-export-declaration" "^7.18.6"
+    "@babel/helper-validator-identifier" "^7.18.6"
+    "@babel/template" "^7.18.10"
+    "@babel/traverse" "^7.19.0"
+    "@babel/types" "^7.19.0"
+
 "@babel/helper-optimise-call-expression@^7.12.13":
   version "7.12.13"
   resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea"
@@ -378,6 +512,13 @@
   dependencies:
     "@babel/types" "^7.16.7"
 
+"@babel/helper-optimise-call-expression@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe"
+  integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==
+  dependencies:
+    "@babel/types" "^7.18.6"
+
 "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
   version "7.13.0"
   resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af"
@@ -388,6 +529,11 @@
   resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5"
   integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==
 
+"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf"
+  integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==
+
 "@babel/helper-remap-async-to-generator@^7.16.8":
   version "7.16.8"
   resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3"
@@ -397,6 +543,16 @@
     "@babel/helper-wrap-function" "^7.16.8"
     "@babel/types" "^7.16.8"
 
+"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519"
+  integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==
+  dependencies:
+    "@babel/helper-annotate-as-pure" "^7.18.6"
+    "@babel/helper-environment-visitor" "^7.18.9"
+    "@babel/helper-wrap-function" "^7.18.9"
+    "@babel/types" "^7.18.9"
+
 "@babel/helper-replace-supers@^7.13.12":
   version "7.14.4"
   resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz#b2ab16875deecfff3ddfcd539bc315f72998d836"
@@ -418,6 +574,17 @@
     "@babel/traverse" "^7.16.7"
     "@babel/types" "^7.16.7"
 
+"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz#1092e002feca980fbbb0bd4d51b74a65c6a500e6"
+  integrity sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ==
+  dependencies:
+    "@babel/helper-environment-visitor" "^7.18.9"
+    "@babel/helper-member-expression-to-functions" "^7.18.9"
+    "@babel/helper-optimise-call-expression" "^7.18.6"
+    "@babel/traverse" "^7.18.9"
+    "@babel/types" "^7.18.9"
+
 "@babel/helper-simple-access@^7.13.12":
   version "7.13.12"
   resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6"
@@ -439,6 +606,13 @@
   dependencies:
     "@babel/types" "^7.17.0"
 
+"@babel/helper-simple-access@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea"
+  integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==
+  dependencies:
+    "@babel/types" "^7.18.6"
+
 "@babel/helper-skip-transparent-expression-wrappers@^7.16.0":
   version "7.16.0"
   resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09"
@@ -446,6 +620,13 @@
   dependencies:
     "@babel/types" "^7.16.0"
 
+"@babel/helper-skip-transparent-expression-wrappers@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818"
+  integrity sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==
+  dependencies:
+    "@babel/types" "^7.18.9"
+
 "@babel/helper-split-export-declaration@^7.12.13":
   version "7.12.13"
   resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05"
@@ -460,6 +641,18 @@
   dependencies:
     "@babel/types" "^7.16.7"
 
+"@babel/helper-split-export-declaration@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075"
+  integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==
+  dependencies:
+    "@babel/types" "^7.18.6"
+
+"@babel/helper-string-parser@^7.18.10":
+  version "7.18.10"
+  resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56"
+  integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==
+
 "@babel/helper-validator-identifier@^7.14.0":
   version "7.14.0"
   resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288"
@@ -470,6 +663,11 @@
   resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad"
   integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==
 
+"@babel/helper-validator-identifier@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076"
+  integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==
+
 "@babel/helper-validator-option@^7.12.17":
   version "7.12.17"
   resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831"
@@ -480,6 +678,11 @@
   resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23"
   integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==
 
+"@babel/helper-validator-option@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
+  integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==
+
 "@babel/helper-wrap-function@^7.16.8":
   version "7.16.8"
   resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200"
@@ -490,6 +693,16 @@
     "@babel/traverse" "^7.16.8"
     "@babel/types" "^7.16.8"
 
+"@babel/helper-wrap-function@^7.18.9":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz#89f18335cff1152373222f76a4b37799636ae8b1"
+  integrity sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==
+  dependencies:
+    "@babel/helper-function-name" "^7.19.0"
+    "@babel/template" "^7.18.10"
+    "@babel/traverse" "^7.19.0"
+    "@babel/types" "^7.19.0"
+
 "@babel/helpers@^7.14.0":
   version "7.14.0"
   resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.0.tgz#ea9b6be9478a13d6f961dbb5f36bf75e2f3b8f62"
@@ -535,6 +748,15 @@
     chalk "^2.0.0"
     js-tokens "^4.0.0"
 
+"@babel/highlight@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf"
+  integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==
+  dependencies:
+    "@babel/helper-validator-identifier" "^7.18.6"
+    chalk "^2.0.0"
+    js-tokens "^4.0.0"
+
 "@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.14.2", "@babel/parser@^7.14.3":
   version "7.14.4"
   resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.4.tgz#a5c560d6db6cd8e6ed342368dea8039232cbab18"
@@ -550,6 +772,11 @@
   resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.3.tgz#b07702b982990bf6fdc1da5049a23fece4c5c3d0"
   integrity sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==
 
+"@babel/parser@^7.18.10", "@babel/parser@^7.18.8", "@babel/parser@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.0.tgz#497fcafb1d5b61376959c1c338745ef0577aa02c"
+  integrity sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==
+
 "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz#4eda6d6c2a0aa79c70fa7b6da67763dfe2141050"
@@ -557,6 +784,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2"
+  integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz#cc001234dfc139ac45f6bcf801866198c8c72ff9"
@@ -566,6 +800,15 @@
     "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0"
     "@babel/plugin-proposal-optional-chaining" "^7.16.7"
 
+"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz#a11af19aa373d68d561f08e0a57242350ed0ec50"
+  integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.9"
+    "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9"
+    "@babel/plugin-proposal-optional-chaining" "^7.18.9"
+
 "@babel/plugin-proposal-async-generator-functions@^7.16.8":
   version "7.16.8"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8"
@@ -575,6 +818,16 @@
     "@babel/helper-remap-async-to-generator" "^7.16.8"
     "@babel/plugin-syntax-async-generators" "^7.8.4"
 
+"@babel/plugin-proposal-async-generator-functions@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.0.tgz#cf5740194f170467df20581712400487efc79ff1"
+  integrity sha512-nhEByMUTx3uZueJ/QkJuSlCfN4FGg+xy+vRsfGQGzSauq5ks2Deid2+05Q3KhfaUjvec1IGhw/Zm3cFm8JigTQ==
+  dependencies:
+    "@babel/helper-environment-visitor" "^7.18.9"
+    "@babel/helper-plugin-utils" "^7.19.0"
+    "@babel/helper-remap-async-to-generator" "^7.18.9"
+    "@babel/plugin-syntax-async-generators" "^7.8.4"
+
 "@babel/plugin-proposal-class-properties@^7.16.0", "@babel/plugin-proposal-class-properties@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0"
@@ -583,6 +836,14 @@
     "@babel/helper-create-class-features-plugin" "^7.16.7"
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-proposal-class-properties@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3"
+  integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==
+  dependencies:
+    "@babel/helper-create-class-features-plugin" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-proposal-class-static-block@^7.16.7":
   version "7.17.6"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.17.6.tgz#164e8fd25f0d80fa48c5a4d1438a6629325ad83c"
@@ -592,6 +853,15 @@
     "@babel/helper-plugin-utils" "^7.16.7"
     "@babel/plugin-syntax-class-static-block" "^7.14.5"
 
+"@babel/plugin-proposal-class-static-block@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020"
+  integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==
+  dependencies:
+    "@babel/helper-create-class-features-plugin" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/plugin-syntax-class-static-block" "^7.14.5"
+
 "@babel/plugin-proposal-decorators@^7.16.4":
   version "7.17.8"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.17.8.tgz#4f0444e896bee85d35cf714a006fc5418f87ff00"
@@ -611,6 +881,14 @@
     "@babel/helper-plugin-utils" "^7.16.7"
     "@babel/plugin-syntax-dynamic-import" "^7.8.3"
 
+"@babel/plugin-proposal-dynamic-import@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94"
+  integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/plugin-syntax-dynamic-import" "^7.8.3"
+
 "@babel/plugin-proposal-export-namespace-from@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163"
@@ -619,6 +897,14 @@
     "@babel/helper-plugin-utils" "^7.16.7"
     "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
 
+"@babel/plugin-proposal-export-namespace-from@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203"
+  integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.9"
+    "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
+
 "@babel/plugin-proposal-json-strings@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8"
@@ -627,6 +913,14 @@
     "@babel/helper-plugin-utils" "^7.16.7"
     "@babel/plugin-syntax-json-strings" "^7.8.3"
 
+"@babel/plugin-proposal-json-strings@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b"
+  integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/plugin-syntax-json-strings" "^7.8.3"
+
 "@babel/plugin-proposal-logical-assignment-operators@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea"
@@ -635,6 +929,14 @@
     "@babel/helper-plugin-utils" "^7.16.7"
     "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
 
+"@babel/plugin-proposal-logical-assignment-operators@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz#8148cbb350483bf6220af06fa6db3690e14b2e23"
+  integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.9"
+    "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
+
 "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99"
@@ -643,6 +945,14 @@
     "@babel/helper-plugin-utils" "^7.16.7"
     "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
 
+"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1"
+  integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
+
 "@babel/plugin-proposal-numeric-separator@^7.16.0", "@babel/plugin-proposal-numeric-separator@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9"
@@ -651,7 +961,26 @@
     "@babel/helper-plugin-utils" "^7.16.7"
     "@babel/plugin-syntax-numeric-separator" "^7.10.4"
 
-"@babel/plugin-proposal-object-rest-spread@^7.16.0", "@babel/plugin-proposal-object-rest-spread@^7.16.7":
+"@babel/plugin-proposal-numeric-separator@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75"
+  integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/plugin-syntax-numeric-separator" "^7.10.4"
+
+"@babel/plugin-proposal-object-rest-spread@^7.16.0", "@babel/plugin-proposal-object-rest-spread@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz#f9434f6beb2c8cae9dfcf97d2a5941bbbf9ad4e7"
+  integrity sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==
+  dependencies:
+    "@babel/compat-data" "^7.18.8"
+    "@babel/helper-compilation-targets" "^7.18.9"
+    "@babel/helper-plugin-utils" "^7.18.9"
+    "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
+    "@babel/plugin-transform-parameters" "^7.18.8"
+
+"@babel/plugin-proposal-object-rest-spread@^7.16.7":
   version "7.17.3"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.17.3.tgz#d9eb649a54628a51701aef7e0ea3d17e2b9dd390"
   integrity sha512-yuL5iQA/TbZn+RGAfxQXfi7CNLmKi1f8zInn4IgobuCWcAb7i+zj4TYzQ9l8cEzVyJ89PDGuqxK1xZpUDISesw==
@@ -670,6 +999,14 @@
     "@babel/helper-plugin-utils" "^7.16.7"
     "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
 
+"@babel/plugin-proposal-optional-catch-binding@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb"
+  integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
+
 "@babel/plugin-proposal-optional-chaining@^7.16.0", "@babel/plugin-proposal-optional-chaining@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a"
@@ -679,6 +1016,15 @@
     "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0"
     "@babel/plugin-syntax-optional-chaining" "^7.8.3"
 
+"@babel/plugin-proposal-optional-chaining@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993"
+  integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.9"
+    "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9"
+    "@babel/plugin-syntax-optional-chaining" "^7.8.3"
+
 "@babel/plugin-proposal-private-methods@^7.16.0", "@babel/plugin-proposal-private-methods@^7.16.11":
   version "7.16.11"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50"
@@ -687,6 +1033,14 @@
     "@babel/helper-create-class-features-plugin" "^7.16.10"
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-proposal-private-methods@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea"
+  integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==
+  dependencies:
+    "@babel/helper-create-class-features-plugin" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-proposal-private-property-in-object@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz#b0b8cef543c2c3d57e59e2c611994861d46a3fce"
@@ -697,6 +1051,16 @@
     "@babel/helper-plugin-utils" "^7.16.7"
     "@babel/plugin-syntax-private-property-in-object" "^7.14.5"
 
+"@babel/plugin-proposal-private-property-in-object@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz#a64137b232f0aca3733a67eb1a144c192389c503"
+  integrity sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==
+  dependencies:
+    "@babel/helper-annotate-as-pure" "^7.18.6"
+    "@babel/helper-create-class-features-plugin" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/plugin-syntax-private-property-in-object" "^7.14.5"
+
 "@babel/plugin-proposal-unicode-property-regex@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2"
@@ -705,6 +1069,14 @@
     "@babel/helper-create-regexp-features-plugin" "^7.16.7"
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-proposal-unicode-property-regex@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e"
+  integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==
+  dependencies:
+    "@babel/helper-create-regexp-features-plugin" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-proposal-unicode-property-regex@^7.4.4":
   version "7.12.13"
   resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba"
@@ -769,6 +1141,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-syntax-import-assertions@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz#cd6190500a4fa2fe31990a963ffab4b63e4505e4"
+  integrity sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-syntax-import-meta@^7.8.3":
   version "7.10.4"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51"
@@ -860,6 +1239,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-arrow-functions@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe"
+  integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-transform-async-to-generator@^7.16.8":
   version "7.16.8"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808"
@@ -869,6 +1255,15 @@
     "@babel/helper-plugin-utils" "^7.16.7"
     "@babel/helper-remap-async-to-generator" "^7.16.8"
 
+"@babel/plugin-transform-async-to-generator@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615"
+  integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==
+  dependencies:
+    "@babel/helper-module-imports" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/helper-remap-async-to-generator" "^7.18.6"
+
 "@babel/plugin-transform-block-scoped-functions@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620"
@@ -876,6 +1271,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-block-scoped-functions@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8"
+  integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-transform-block-scoping@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87"
@@ -883,6 +1285,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-block-scoping@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz#f9b7e018ac3f373c81452d6ada8bd5a18928926d"
+  integrity sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.9"
+
 "@babel/plugin-transform-classes@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00"
@@ -897,6 +1306,21 @@
     "@babel/helper-split-export-declaration" "^7.16.7"
     globals "^11.1.0"
 
+"@babel/plugin-transform-classes@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz#0e61ec257fba409c41372175e7c1e606dc79bb20"
+  integrity sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==
+  dependencies:
+    "@babel/helper-annotate-as-pure" "^7.18.6"
+    "@babel/helper-compilation-targets" "^7.19.0"
+    "@babel/helper-environment-visitor" "^7.18.9"
+    "@babel/helper-function-name" "^7.19.0"
+    "@babel/helper-optimise-call-expression" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.19.0"
+    "@babel/helper-replace-supers" "^7.18.9"
+    "@babel/helper-split-export-declaration" "^7.18.6"
+    globals "^11.1.0"
+
 "@babel/plugin-transform-computed-properties@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470"
@@ -904,6 +1328,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-computed-properties@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e"
+  integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.9"
+
 "@babel/plugin-transform-destructuring@^7.16.7":
   version "7.17.3"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.17.3.tgz#c445f75819641788a27a0a3a759d9df911df6abc"
@@ -911,6 +1342,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-destructuring@^7.18.13":
+  version "7.18.13"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz#9e03bc4a94475d62b7f4114938e6c5c33372cbf5"
+  integrity sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.9"
+
 "@babel/plugin-transform-dotall-regex@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241"
@@ -919,6 +1357,14 @@
     "@babel/helper-create-regexp-features-plugin" "^7.16.7"
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-dotall-regex@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8"
+  integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==
+  dependencies:
+    "@babel/helper-create-regexp-features-plugin" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-transform-dotall-regex@^7.4.4":
   version "7.12.13"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad"
@@ -934,6 +1380,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-duplicate-keys@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e"
+  integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.9"
+
 "@babel/plugin-transform-exponentiation-operator@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b"
@@ -942,6 +1395,14 @@
     "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7"
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-exponentiation-operator@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd"
+  integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==
+  dependencies:
+    "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-transform-flow-strip-types@^7.16.0":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.16.7.tgz#291fb140c78dabbf87f2427e7c7c332b126964b8"
@@ -957,6 +1418,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-for-of@^7.18.8":
+  version "7.18.8"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1"
+  integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-transform-function-name@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf"
@@ -966,6 +1434,15 @@
     "@babel/helper-function-name" "^7.16.7"
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-function-name@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0"
+  integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==
+  dependencies:
+    "@babel/helper-compilation-targets" "^7.18.9"
+    "@babel/helper-function-name" "^7.18.9"
+    "@babel/helper-plugin-utils" "^7.18.9"
+
 "@babel/plugin-transform-literals@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1"
@@ -973,6 +1450,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-literals@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc"
+  integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.9"
+
 "@babel/plugin-transform-member-expression-literals@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384"
@@ -980,6 +1464,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-member-expression-literals@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e"
+  integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-transform-modules-amd@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186"
@@ -989,6 +1480,15 @@
     "@babel/helper-plugin-utils" "^7.16.7"
     babel-plugin-dynamic-import-node "^2.3.3"
 
+"@babel/plugin-transform-modules-amd@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz#8c91f8c5115d2202f277549848874027d7172d21"
+  integrity sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==
+  dependencies:
+    "@babel/helper-module-transforms" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.6"
+    babel-plugin-dynamic-import-node "^2.3.3"
+
 "@babel/plugin-transform-modules-commonjs@^7.16.8":
   version "7.16.8"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe"
@@ -999,6 +1499,16 @@
     "@babel/helper-simple-access" "^7.16.7"
     babel-plugin-dynamic-import-node "^2.3.3"
 
+"@babel/plugin-transform-modules-commonjs@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz#afd243afba166cca69892e24a8fd8c9f2ca87883"
+  integrity sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==
+  dependencies:
+    "@babel/helper-module-transforms" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/helper-simple-access" "^7.18.6"
+    babel-plugin-dynamic-import-node "^2.3.3"
+
 "@babel/plugin-transform-modules-systemjs@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz#887cefaef88e684d29558c2b13ee0563e287c2d7"
@@ -1010,6 +1520,17 @@
     "@babel/helper-validator-identifier" "^7.16.7"
     babel-plugin-dynamic-import-node "^2.3.3"
 
+"@babel/plugin-transform-modules-systemjs@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz#5f20b471284430f02d9c5059d9b9a16d4b085a1f"
+  integrity sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==
+  dependencies:
+    "@babel/helper-hoist-variables" "^7.18.6"
+    "@babel/helper-module-transforms" "^7.19.0"
+    "@babel/helper-plugin-utils" "^7.19.0"
+    "@babel/helper-validator-identifier" "^7.18.6"
+    babel-plugin-dynamic-import-node "^2.3.3"
+
 "@babel/plugin-transform-modules-umd@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618"
@@ -1018,6 +1539,14 @@
     "@babel/helper-module-transforms" "^7.16.7"
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-modules-umd@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9"
+  integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==
+  dependencies:
+    "@babel/helper-module-transforms" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-transform-named-capturing-groups-regex@^7.16.8":
   version "7.16.8"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252"
@@ -1025,6 +1554,14 @@
   dependencies:
     "@babel/helper-create-regexp-features-plugin" "^7.16.7"
 
+"@babel/plugin-transform-named-capturing-groups-regex@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.0.tgz#58c52422e4f91a381727faed7d513c89d7f41ada"
+  integrity sha512-HDSuqOQzkU//kfGdiHBt71/hkDTApw4U/cMVgKgX7PqfB3LOaK+2GtCEsBu1dL9CkswDm0Gwehht1dCr421ULQ==
+  dependencies:
+    "@babel/helper-create-regexp-features-plugin" "^7.19.0"
+    "@babel/helper-plugin-utils" "^7.19.0"
+
 "@babel/plugin-transform-new-target@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244"
@@ -1032,6 +1569,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-new-target@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8"
+  integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-transform-object-super@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94"
@@ -1040,6 +1584,14 @@
     "@babel/helper-plugin-utils" "^7.16.7"
     "@babel/helper-replace-supers" "^7.16.7"
 
+"@babel/plugin-transform-object-super@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c"
+  integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+    "@babel/helper-replace-supers" "^7.18.6"
+
 "@babel/plugin-transform-parameters@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f"
@@ -1047,6 +1599,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-parameters@^7.18.8":
+  version "7.18.8"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz#ee9f1a0ce6d78af58d0956a9378ea3427cccb48a"
+  integrity sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-transform-property-literals@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55"
@@ -1054,6 +1613,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-property-literals@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3"
+  integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-transform-react-constant-elements@^7.12.1":
   version "7.17.6"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.17.6.tgz#6cc273c2f612a6a50cb657e63ee1303e5e68d10a"
@@ -1101,6 +1667,14 @@
   dependencies:
     regenerator-transform "^0.14.2"
 
+"@babel/plugin-transform-regenerator@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz#585c66cb84d4b4bf72519a34cfce761b8676ca73"
+  integrity sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+    regenerator-transform "^0.15.0"
+
 "@babel/plugin-transform-reserved-words@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586"
@@ -1108,7 +1682,26 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
-"@babel/plugin-transform-runtime@^7.16.0", "@babel/plugin-transform-runtime@^7.16.4":
+"@babel/plugin-transform-reserved-words@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a"
+  integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/plugin-transform-runtime@^7.16.0":
+  version "7.18.10"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.10.tgz#37d14d1fa810a368fd635d4d1476c0154144a96f"
+  integrity sha512-q5mMeYAdfEbpBAgzl7tBre/la3LeCxmDO1+wMXRdPWbcoMjR3GiXlCLk7JBZVVye0bqTGNMbt0yYVXX1B1jEWQ==
+  dependencies:
+    "@babel/helper-module-imports" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.9"
+    babel-plugin-polyfill-corejs2 "^0.3.2"
+    babel-plugin-polyfill-corejs3 "^0.5.3"
+    babel-plugin-polyfill-regenerator "^0.4.0"
+    semver "^6.3.0"
+
+"@babel/plugin-transform-runtime@^7.16.4":
   version "7.17.0"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.0.tgz#0a2e08b5e2b2d95c4b1d3b3371a2180617455b70"
   integrity sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A==
@@ -1127,6 +1720,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-shorthand-properties@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9"
+  integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-transform-spread@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44"
@@ -1135,6 +1735,14 @@
     "@babel/helper-plugin-utils" "^7.16.7"
     "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0"
 
+"@babel/plugin-transform-spread@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6"
+  integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.19.0"
+    "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9"
+
 "@babel/plugin-transform-sticky-regex@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660"
@@ -1142,6 +1750,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-sticky-regex@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc"
+  integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.6"
+
 "@babel/plugin-transform-template-literals@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab"
@@ -1149,6 +1764,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-template-literals@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e"
+  integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.9"
+
 "@babel/plugin-transform-typeof-symbol@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e"
@@ -1156,6 +1778,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-typeof-symbol@^7.18.9":
+  version "7.18.9"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0"
+  integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.9"
+
 "@babel/plugin-transform-typescript@^7.16.7":
   version "7.16.8"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz#591ce9b6b83504903fa9dd3652c357c2ba7a1ee0"
@@ -1172,6 +1801,13 @@
   dependencies:
     "@babel/helper-plugin-utils" "^7.16.7"
 
+"@babel/plugin-transform-unicode-escapes@^7.18.10":
+  version "7.18.10"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246"
+  integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==
+  dependencies:
+    "@babel/helper-plugin-utils" "^7.18.9"
+
 "@babel/plugin-transform-unicode-regex@^7.16.7":
   version "7.16.7"
   resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2"
@@ -1180,7 +1816,15 @@
     "@babel/helper-create-regexp-features-plugin" "^7.16.7"
     "@babel/helper-plugin-utils" "^7.16.7"
 
-"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.16.0", "@babel/preset-env@^7.16.4":
+"@babel/plugin-transform-unicode-regex@^7.18.6":
+  version "7.18.6"
+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca"
+  integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==
+  dependencies:
+    "@babel/helper-create-regexp-features-plugin" "^7.18.6"
+    "@babel/helper-plugin-utils" "^7.18.6"
+
+"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.16.4":
   version "7.16.11"
   resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.11.tgz#5dd88fd885fae36f88fd7c8342475c9f0abe2982"
   integrity sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g==
@@ -1260,6 +1904,87 @@
     core-js-compat "^3.20.2"
     semver "^6.3.0"
 
+"@babel/preset-env@^7.16.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.19.0.tgz#fd18caf499a67d6411b9ded68dc70d01ed1e5da7"
+  integrity sha512-1YUju1TAFuzjIQqNM9WsF4U6VbD/8t3wEAlw3LFYuuEr+ywqLRcSXxFKz4DCEj+sN94l/XTDiUXYRrsvMpz9WQ==
+  dependencies:
+    "@babel/compat-data" "^7.19.0"
+    "@babel/helper-compilation-targets" "^7.19.0"
+    "@babel/helper-plugin-utils" "^7.19.0"
+    "@babel/helper-validator-option" "^7.18.6"
+    "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6"
+    "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9"
+    "@babel/plugin-proposal-async-generator-functions" "^7.19.0"
+    "@babel/plugin-proposal-class-properties" "^7.18.6"
+    "@babel/plugin-proposal-class-static-block" "^7.18.6"
+    "@babel/plugin-proposal-dynamic-import" "^7.18.6"
+    "@babel/plugin-proposal-export-namespace-from" "^7.18.9"
+    "@babel/plugin-proposal-json-strings" "^7.18.6"
+    "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9"
+    "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6"
+    "@babel/plugin-proposal-numeric-separator" "^7.18.6"
+    "@babel/plugin-proposal-object-rest-spread" "^7.18.9"
+    "@babel/plugin-proposal-optional-catch-binding" "^7.18.6"
+    "@babel/plugin-proposal-optional-chaining" "^7.18.9"
+    "@babel/plugin-proposal-private-methods" "^7.18.6"
+    "@babel/plugin-proposal-private-property-in-object" "^7.18.6"
+    "@babel/plugin-proposal-unicode-property-regex" "^7.18.6"
+    "@babel/plugin-syntax-async-generators" "^7.8.4"
+    "@babel/plugin-syntax-class-properties" "^7.12.13"
+    "@babel/plugin-syntax-class-static-block" "^7.14.5"
+    "@babel/plugin-syntax-dynamic-import" "^7.8.3"
+    "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
+    "@babel/plugin-syntax-import-assertions" "^7.18.6"
+    "@babel/plugin-syntax-json-strings" "^7.8.3"
+    "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
+    "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
+    "@babel/plugin-syntax-numeric-separator" "^7.10.4"
+    "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
+    "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
+    "@babel/plugin-syntax-optional-chaining" "^7.8.3"
+    "@babel/plugin-syntax-private-property-in-object" "^7.14.5"
+    "@babel/plugin-syntax-top-level-await" "^7.14.5"
+    "@babel/plugin-transform-arrow-functions" "^7.18.6"
+    "@babel/plugin-transform-async-to-generator" "^7.18.6"
+    "@babel/plugin-transform-block-scoped-functions" "^7.18.6"
+    "@babel/plugin-transform-block-scoping" "^7.18.9"
+    "@babel/plugin-transform-classes" "^7.19.0"
+    "@babel/plugin-transform-computed-properties" "^7.18.9"
+    "@babel/plugin-transform-destructuring" "^7.18.13"
+    "@babel/plugin-transform-dotall-regex" "^7.18.6"
+    "@babel/plugin-transform-duplicate-keys" "^7.18.9"
+    "@babel/plugin-transform-exponentiation-operator" "^7.18.6"
+    "@babel/plugin-transform-for-of" "^7.18.8"
+    "@babel/plugin-transform-function-name" "^7.18.9"
+    "@babel/plugin-transform-literals" "^7.18.9"
+    "@babel/plugin-transform-member-expression-literals" "^7.18.6"
+    "@babel/plugin-transform-modules-amd" "^7.18.6"
+    "@babel/plugin-transform-modules-commonjs" "^7.18.6"
+    "@babel/plugin-transform-modules-systemjs" "^7.19.0"
+    "@babel/plugin-transform-modules-umd" "^7.18.6"
+    "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.0"
+    "@babel/plugin-transform-new-target" "^7.18.6"
+    "@babel/plugin-transform-object-super" "^7.18.6"
+    "@babel/plugin-transform-parameters" "^7.18.8"
+    "@babel/plugin-transform-property-literals" "^7.18.6"
+    "@babel/plugin-transform-regenerator" "^7.18.6"
+    "@babel/plugin-transform-reserved-words" "^7.18.6"
+    "@babel/plugin-transform-shorthand-properties" "^7.18.6"
+    "@babel/plugin-transform-spread" "^7.19.0"
+    "@babel/plugin-transform-sticky-regex" "^7.18.6"
+    "@babel/plugin-transform-template-literals" "^7.18.9"
+    "@babel/plugin-transform-typeof-symbol" "^7.18.9"
+    "@babel/plugin-transform-unicode-escapes" "^7.18.10"
+    "@babel/plugin-transform-unicode-regex" "^7.18.6"
+    "@babel/preset-modules" "^0.1.5"
+    "@babel/types" "^7.19.0"
+    babel-plugin-polyfill-corejs2 "^0.3.2"
+    babel-plugin-polyfill-corejs3 "^0.5.3"
+    babel-plugin-polyfill-regenerator "^0.4.0"
+    core-js-compat "^3.22.1"
+    semver "^6.3.0"
+
 "@babel/preset-modules@^0.1.5":
   version "0.1.5"
   resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9"
@@ -1315,9 +2040,9 @@
     regenerator-runtime "^0.13.4"
 
 "@babel/runtime@^7.16.0":
-  version "7.17.2"
-  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941"
-  integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259"
+  integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==
   dependencies:
     regenerator-runtime "^0.13.4"
 
@@ -1346,6 +2071,15 @@
     "@babel/parser" "^7.16.7"
     "@babel/types" "^7.16.7"
 
+"@babel/template@^7.18.10":
+  version "7.18.10"
+  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71"
+  integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==
+  dependencies:
+    "@babel/code-frame" "^7.18.6"
+    "@babel/parser" "^7.18.10"
+    "@babel/types" "^7.18.10"
+
 "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.0", "@babel/traverse@^7.14.2":
   version "7.14.2"
   resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.2.tgz#9201a8d912723a831c2679c7ebbf2fe1416d765b"
@@ -1376,6 +2110,22 @@
     debug "^4.1.0"
     globals "^11.1.0"
 
+"@babel/traverse@^7.18.9", "@babel/traverse@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.0.tgz#eb9c561c7360005c592cc645abafe0c3c4548eed"
+  integrity sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA==
+  dependencies:
+    "@babel/code-frame" "^7.18.6"
+    "@babel/generator" "^7.19.0"
+    "@babel/helper-environment-visitor" "^7.18.9"
+    "@babel/helper-function-name" "^7.19.0"
+    "@babel/helper-hoist-variables" "^7.18.6"
+    "@babel/helper-split-export-declaration" "^7.18.6"
+    "@babel/parser" "^7.19.0"
+    "@babel/types" "^7.19.0"
+    debug "^4.1.0"
+    globals "^11.1.0"
+
 "@babel/types@^7.0.0", "@babel/types@^7.12.13", "@babel/types@^7.13.12", "@babel/types@^7.14.0", "@babel/types@^7.14.2", "@babel/types@^7.14.4", "@babel/types@^7.3.0", "@babel/types@^7.4.4":
   version "7.14.4"
   resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.4.tgz#bfd6980108168593b38b3eb48a24aa026b919bc0"
@@ -1392,6 +2142,49 @@
     "@babel/helper-validator-identifier" "^7.16.7"
     to-fast-properties "^2.0.0"
 
+"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.0.tgz#75f21d73d73dc0351f3368d28db73465f4814600"
+  integrity sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==
+  dependencies:
+    "@babel/helper-string-parser" "^7.18.10"
+    "@babel/helper-validator-identifier" "^7.18.6"
+    to-fast-properties "^2.0.0"
+
+"@badeball/cypress-configuration@^4.0.0":
+  version "4.2.0"
+  resolved "https://registry.yarnpkg.com/@badeball/cypress-configuration/-/cypress-configuration-4.2.0.tgz#4c19bada0e40600b572b4d91933e0bd226cb2e3f"
+  integrity sha512-8Dc6diBW8zUycpCFbr7vqQ8ioNZMvpHV79KGdHVpwpRtkFX6enwG82CKU9DeWys6Ou5dFpXw6NYNYNb46y7UYA==
+  dependencies:
+    "@babel/parser" "^7.18.8"
+    debug "^4.3.2"
+    esbuild "^0.14.23"
+    glob "^7.1.6"
+    minimatch "^3.0.4"
+    node-hook "^1.0.0"
+
+"@badeball/cypress-cucumber-preprocessor@^12.2.0":
+  version "12.2.0"
+  resolved "https://registry.yarnpkg.com/@badeball/cypress-cucumber-preprocessor/-/cypress-cucumber-preprocessor-12.2.0.tgz#1702bbc2a10b40c7e90f10bd1840761a86c7ecc9"
+  integrity sha512-XSuZl4eWMcfq8rauhUnvgbNeKiDLKfaR87huj9VwPAhfIc2cRHNHCiXCasB7ci99McGaudqLqu2QsfZMStTVag==
+  dependencies:
+    "@badeball/cypress-configuration" "^4.0.0"
+    "@cucumber/cucumber-expressions" "^16.0.0"
+    "@cucumber/gherkin" "^24.0.0"
+    "@cucumber/html-formatter" "^19.2.0"
+    "@cucumber/message-streams" "^4.0.1"
+    "@cucumber/messages" "^19.1.2"
+    "@cucumber/tag-expressions" "^4.1.0"
+    base64-js "^1.5.1"
+    chalk "^4.1.2"
+    common-ancestor-path "^1.0.1"
+    cosmiconfig "^7.0.1"
+    debug "^4.2.0"
+    glob "^7.2.0"
+    is-path-inside "^3.0.3"
+    resolve-pkg "^2.0.0"
+    uuid "^8.3.2"
+
 "@bcoe/v8-coverage@^0.2.3":
   version "0.2.3"
   resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
@@ -1461,7 +2254,46 @@
   dependencies:
     postcss-value-parser "^4.2.0"
 
-"@cypress/browserify-preprocessor@^3.0.2":
+"@cucumber/cucumber-expressions@^16.0.0":
+  version "16.0.0"
+  resolved "https://registry.yarnpkg.com/@cucumber/cucumber-expressions/-/cucumber-expressions-16.0.0.tgz#f8bc43da26f12db8f0d74ff3031a881e4fa4516d"
+  integrity sha512-HTh+Pg7oQ5aLuCkSbD2Q6jBaE40M3R/XaLEz+UqD5d9dZRu6P38W4LTooV5bV6dZgBunlMLK8+6ug2ziYvRddw==
+  dependencies:
+    regexp-match-indices "1.0.2"
+
+"@cucumber/gherkin@^24.0.0":
+  version "24.0.0"
+  resolved "https://registry.yarnpkg.com/@cucumber/gherkin/-/gherkin-24.0.0.tgz#b0d2ab328caa5357491f1117c31195d3e545da0c"
+  integrity sha512-b7OsnvX1B8myDAKMc+RAiUX9bzgtNdjGsiMj10O13xu2HBWIOQ19EqBJ4xLO5CFG/lGk1J/+L0lANQVowxLVBg==
+  dependencies:
+    "@cucumber/messages" "^19.0.0"
+
+"@cucumber/html-formatter@^19.2.0":
+  version "19.2.0"
+  resolved "https://registry.yarnpkg.com/@cucumber/html-formatter/-/html-formatter-19.2.0.tgz#47b9fcb58fbb48d0e6124fd2e867d9c6fe299470"
+  integrity sha512-qGms4588jmVF/G3fTbgZvxn6OQw9GaTFV007nZZ9/10M9DfrgRqjFjVxVI9TPV63xOLPicEVoqsKZtcECbdMSA==
+
+"@cucumber/message-streams@^4.0.1":
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/@cucumber/message-streams/-/message-streams-4.0.1.tgz#a5339d3504594bb2edb5732aaae94dddb24d0970"
+  integrity sha512-Kxap9uP5jD8tHUZVjTWgzxemi/0uOsbGjd4LBOSxcJoOCRbESFwemUzilJuzNTB8pcTQUh8D5oudUyxfkJOKmA==
+
+"@cucumber/messages@^19.0.0", "@cucumber/messages@^19.1.2":
+  version "19.1.2"
+  resolved "https://registry.yarnpkg.com/@cucumber/messages/-/messages-19.1.2.tgz#cc846c191b124deb352dd1992bd49a82f30b0add"
+  integrity sha512-vhWkNmQco+7tk/DWqpN0/R9KTNvsKsXVfZ7IsJs+dEeWmTuRztklHq8lJalwMSQBl71+2/KqGHzOO4BMTC9wIQ==
+  dependencies:
+    "@types/uuid" "8.3.4"
+    class-transformer "0.5.1"
+    reflect-metadata "0.1.13"
+    uuid "8.3.2"
+
+"@cucumber/tag-expressions@^4.1.0":
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/@cucumber/tag-expressions/-/tag-expressions-4.1.0.tgz#9a91b0e0dd2f2ba703e3038c52b49b9ac06c2c6f"
+  integrity sha512-chTnjxV3vryL75N90wJIMdMafXmZoO2JgNJLYpsfcALL2/IQrRiny3vM9DgD5RDCSt1LNloMtb7rGey9YWxCsA==
+
+"@cypress/browserify-preprocessor@3.0.2":
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/@cypress/browserify-preprocessor/-/browserify-preprocessor-3.0.2.tgz#1dbecae394937aed47a3524cad47086c2ded8c50"
   integrity sha512-y6mlFR+IR2cqcm3HabSp7AEcX9QfF1EUL4eOaw/7xexdhmdQU8ez6piyRopZQob4BK8oKTsc9PkupsU2rzjqMA==
@@ -1517,6 +2349,11 @@
     debug "^3.1.0"
     lodash.once "^4.1.1"
 
+"@esbuild/linux-loong64@0.14.54":
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz#de2a4be678bd4d0d1ffbb86e6de779cde5999028"
+  integrity sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==
+
 "@eslint/eslintrc@^1.2.1":
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6"
@@ -1744,11 +2581,25 @@
     "@types/yargs" "^16.0.0"
     chalk "^4.0.0"
 
+"@jridgewell/gen-mapping@^0.3.2":
+  version "0.3.2"
+  resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
+  integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
+  dependencies:
+    "@jridgewell/set-array" "^1.0.1"
+    "@jridgewell/sourcemap-codec" "^1.4.10"
+    "@jridgewell/trace-mapping" "^0.3.9"
+
 "@jridgewell/resolve-uri@^3.0.3":
   version "3.0.5"
   resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c"
   integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==
 
+"@jridgewell/set-array@^1.0.1":
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
+  integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
+
 "@jridgewell/sourcemap-codec@^1.4.10":
   version "1.4.11"
   resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec"
@@ -1762,6 +2613,14 @@
     "@jridgewell/resolve-uri" "^3.0.3"
     "@jridgewell/sourcemap-codec" "^1.4.10"
 
+"@jridgewell/trace-mapping@^0.3.9":
+  version "0.3.15"
+  resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774"
+  integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==
+  dependencies:
+    "@jridgewell/resolve-uri" "^3.0.3"
+    "@jridgewell/sourcemap-codec" "^1.4.10"
+
 "@leichtgewicht/ip-codec@^2.0.1":
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz#0300943770e04231041a51bd39f0439b5c7ab4f0"
@@ -2198,11 +3057,6 @@
   dependencies:
     "@types/node" "*"
 
-"@types/cypress-cucumber-preprocessor@^4.0.1":
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/@types/cypress-cucumber-preprocessor/-/cypress-cucumber-preprocessor-4.0.1.tgz#1e4cb1c3cf6c9c2c37bc523b5d5047a515cd4e93"
-  integrity sha512-sK2/uU5CtmJ51zo0JF2Lc4iSw9Fy3xn9ewfewuooV5Qmeb5O+brAHuoXKMV7UWwRbBmd+txhAXAJoi4S5QLDRQ==
-
 "@types/cytoscape@3.14.0":
   version "3.14.0"
   resolved "https://registry.yarnpkg.com/@types/cytoscape/-/cytoscape-3.14.0.tgz#346b5430a7a1533784bcf44fcbe6c5255b948d36"
@@ -2493,10 +3347,10 @@
     "@types/mime" "^1"
     "@types/node" "*"
 
-"@types/sinonjs__fake-timers@^6.0.2":
-  version "6.0.4"
-  resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.4.tgz#0ecc1b9259b76598ef01942f547904ce61a6a77d"
-  integrity sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A==
+"@types/sinonjs__fake-timers@8.1.1":
+  version "8.1.1"
+  resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3"
+  integrity sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==
 
 "@types/sizzle@^2.3.2":
   version "2.3.3"
@@ -2520,6 +3374,11 @@
   resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756"
   integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==
 
+"@types/uuid@8.3.4":
+  version "8.3.4"
+  resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc"
+  integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==
+
 "@types/ws@^8.5.1":
   version "8.5.3"
   resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d"
@@ -2996,11 +3855,6 @@ ansi-styles@^5.0.0:
   resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
   integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
 
-any-promise@^1.0.0:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
-  integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
-
 anymatch@^3.0.3, anymatch@^3.1.0, anymatch@~3.1.1, anymatch@~3.1.2:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
@@ -3174,20 +4028,6 @@ assert@^1.4.0:
     object-assign "^4.1.1"
     util "0.10.3"
 
-assertion-error-formatter@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/assertion-error-formatter/-/assertion-error-formatter-2.0.1.tgz#6bbdffaec8e2fa9e2b0eb158bfe353132d7c0a9b"
-  integrity sha512-cjC3jUCh9spkroKue5PDSKH5RFQ/KNuZJhk3GwHYmB/8qqETxLOmMdLH+ohi/VukNzxDlMvIe7zScvLoOdhb6Q==
-  dependencies:
-    diff "^3.0.0"
-    pad-right "^0.2.2"
-    repeat-string "^1.6.1"
-
-assertion-error@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
-  integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==
-
 ast-types-flow@^0.0.7:
   version "0.0.7"
   resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
@@ -3356,6 +4196,15 @@ babel-plugin-polyfill-corejs2@^0.3.0:
     "@babel/helper-define-polyfill-provider" "^0.3.1"
     semver "^6.1.1"
 
+babel-plugin-polyfill-corejs2@^0.3.2:
+  version "0.3.3"
+  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122"
+  integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==
+  dependencies:
+    "@babel/compat-data" "^7.17.7"
+    "@babel/helper-define-polyfill-provider" "^0.3.3"
+    semver "^6.1.1"
+
 babel-plugin-polyfill-corejs3@^0.5.0:
   version "0.5.2"
   resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72"
@@ -3364,6 +4213,14 @@ babel-plugin-polyfill-corejs3@^0.5.0:
     "@babel/helper-define-polyfill-provider" "^0.3.1"
     core-js-compat "^3.21.0"
 
+babel-plugin-polyfill-corejs3@^0.5.3:
+  version "0.5.3"
+  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz#d7e09c9a899079d71a8b670c6181af56ec19c5c7"
+  integrity sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==
+  dependencies:
+    "@babel/helper-define-polyfill-provider" "^0.3.2"
+    core-js-compat "^3.21.0"
+
 babel-plugin-polyfill-regenerator@^0.3.0:
   version "0.3.1"
   resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990"
@@ -3371,6 +4228,13 @@ babel-plugin-polyfill-regenerator@^0.3.0:
   dependencies:
     "@babel/helper-define-polyfill-provider" "^0.3.1"
 
+babel-plugin-polyfill-regenerator@^0.4.0:
+  version "0.4.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747"
+  integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==
+  dependencies:
+    "@babel/helper-define-polyfill-provider" "^0.3.3"
+
 babel-plugin-transform-react-remove-prop-types@^0.4.24:
   version "0.4.24"
   resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a"
@@ -3424,14 +4288,6 @@ babel-preset-react-app@^10.0.1:
     babel-plugin-macros "^3.1.0"
     babel-plugin-transform-react-remove-prop-types "^0.4.24"
 
-babel-runtime@^6.11.6:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
-  integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
-  dependencies:
-    core-js "^2.4.0"
-    regenerator-runtime "^0.11.0"
-
 babelify@^10.0.0:
   version "10.0.0"
   resolved "https://registry.yarnpkg.com/babelify/-/babelify-10.0.0.tgz#fe73b1a22583f06680d8d072e25a1e0d1d1d7fb5"
@@ -3442,7 +4298,7 @@ balanced-match@^1.0.0:
   resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
   integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
 
-base64-js@^1.0.2:
+base64-js@^1.0.2, base64-js@^1.3.1, base64-js@^1.5.1:
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
   integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
@@ -3459,11 +4315,6 @@ bcrypt-pbkdf@^1.0.0:
   dependencies:
     tweetnacl "^0.14.3"
 
-becke-ch--regex--s0-0-v1--base--pl--lib@^1.2.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/becke-ch--regex--s0-0-v1--base--pl--lib/-/becke-ch--regex--s0-0-v1--base--pl--lib-1.4.0.tgz#429ceebbfa5f7e936e78d73fbdc7da7162b20e20"
-  integrity sha1-Qpzuu/pffpNueNc/vcfacWKyDiA=
-
 bfj@^7.0.2:
   version "7.0.2"
   resolved "https://registry.yarnpkg.com/bfj/-/bfj-7.0.2.tgz#1988ce76f3add9ac2913fd8ba47aad9e651bfbb2"
@@ -3489,7 +4340,7 @@ blob-util@^2.0.2:
   resolved "https://registry.yarnpkg.com/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb"
   integrity sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==
 
-bluebird@3.7.2, bluebird@^3.4.1, bluebird@^3.5.5, bluebird@^3.7.2:
+bluebird@^3.5.5, bluebird@^3.7.2:
   version "3.7.2"
   resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
   integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
@@ -3500,9 +4351,9 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9:
   integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
 
 bn.js@^5.0.0, bn.js@^5.1.1:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002"
-  integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==
+  version "5.2.1"
+  resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
+  integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
 
 body-parser@1.19.2:
   version "1.19.2"
@@ -3565,7 +4416,7 @@ braces@^3.0.1, braces@^3.0.2, braces@~3.0.2:
 brorand@^1.0.1, brorand@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
-  integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
+  integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==
 
 browser-pack@^6.0.1:
   version "6.1.0"
@@ -3793,6 +4644,16 @@ browserslist@^4.17.5, browserslist@^4.19.1:
     node-releases "^2.0.2"
     picocolors "^1.0.0"
 
+browserslist@^4.21.3:
+  version "4.21.3"
+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a"
+  integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==
+  dependencies:
+    caniuse-lite "^1.0.30001370"
+    electron-to-chromium "^1.4.202"
+    node-releases "^2.0.6"
+    update-browserslist-db "^1.0.5"
+
 bser@2.1.1:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05"
@@ -3813,7 +4674,15 @@ buffer-from@^1.0.0:
 buffer-xor@^1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
-  integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=
+  integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==
+
+buffer@^5.6.0:
+  version "5.7.1"
+  resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
+  integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
+  dependencies:
+    base64-js "^1.3.1"
+    ieee754 "^1.1.13"
 
 buffer@~5.2.1:
   version "5.2.1"
@@ -3831,7 +4700,7 @@ builtin-modules@^3.1.0:
 builtin-status-codes@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
-  integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
+  integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==
 
 bytes@3.0.0:
   version "3.0.0"
@@ -3971,6 +4840,11 @@ caniuse-lite@^1.0.30001312:
   resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz#e11eba4b87e24d22697dae05455d5aea28550d5f"
   integrity sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==
 
+caniuse-lite@^1.0.30001370:
+  version "1.0.30001399"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001399.tgz#1bf994ca375d7f33f8d01ce03b7d5139e8587873"
+  integrity sha512-4vQ90tMKS+FkvuVWS5/QY1+d805ODxZiKFzsU8o/RsVJz49ZSRR8EjykLJbqhzdPgadbX6wB538wOzle3JniRA==
+
 case-sensitive-paths-webpack-plugin@^2.4.0:
   version "2.4.0"
   resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4"
@@ -3981,19 +4855,6 @@ caseless@~0.12.0:
   resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
   integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
 
-chai@^4.2.0:
-  version "4.3.6"
-  resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c"
-  integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==
-  dependencies:
-    assertion-error "^1.1.0"
-    check-error "^1.0.2"
-    deep-eql "^3.0.1"
-    get-func-name "^2.0.0"
-    loupe "^2.3.1"
-    pathval "^1.1.1"
-    type-detect "^4.0.5"
-
 chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
   version "2.4.2"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@@ -4039,11 +4900,6 @@ charenc@0.0.2:
   resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
   integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
 
-check-error@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
-  integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=
-
 check-more-types@^2.24.0:
   version "2.24.0"
   resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600"
@@ -4078,21 +4934,6 @@ cheerio@^1.0.0-rc.3:
     parse5-htmlparser2-tree-adapter "^6.0.1"
     tslib "^2.2.0"
 
-chokidar@3.5.2:
-  version "3.5.2"
-  resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"
-  integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==
-  dependencies:
-    anymatch "~3.1.2"
-    braces "~3.0.2"
-    glob-parent "~5.1.2"
-    is-binary-path "~2.1.0"
-    is-glob "~4.0.1"
-    normalize-path "~3.0.0"
-    readdirp "~3.6.0"
-  optionalDependencies:
-    fsevents "~2.3.2"
-
 chokidar@^3.4.0, chokidar@^3.5.3:
   version "3.5.3"
   resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
@@ -4156,6 +4997,11 @@ cjs-module-lexer@^1.0.0:
   resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40"
   integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==
 
+class-transformer@0.5.1:
+  version "0.5.1"
+  resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336"
+  integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==
+
 classnames@^2.2.6:
   version "2.3.1"
   resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
@@ -4189,13 +5035,6 @@ cli-table3@~0.6.1:
   optionalDependencies:
     colors "1.4.0"
 
-cli-table@^0.3.1:
-  version "0.3.11"
-  resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.11.tgz#ac69cdecbe81dccdba4889b9a18b7da312a9d3ee"
-  integrity sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==
-  dependencies:
-    colors "1.0.3"
-
 cli-truncate@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7"
@@ -4294,12 +5133,7 @@ colorette@^2.0.10, colorette@^2.0.16:
   resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da"
   integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==
 
-colors@1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b"
-  integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=
-
-colors@1.4.0, colors@^1.1.2:
+colors@1.4.0:
   version "1.4.0"
   resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
   integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
@@ -4307,7 +5141,7 @@ colors@1.4.0, colors@^1.1.2:
 combine-source-map@^0.8.0, combine-source-map@~0.8.0:
   version "0.8.0"
   resolved "https://registry.yarnpkg.com/combine-source-map/-/combine-source-map-0.8.0.tgz#a58d0df042c186fcf822a8e8015f5450d2d79a8b"
-  integrity sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=
+  integrity sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==
   dependencies:
     convert-source-map "~1.1.0"
     inline-source-map "~0.6.0"
@@ -4321,7 +5155,7 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
   dependencies:
     delayed-stream "~1.0.0"
 
-commander@^2.19.0, commander@^2.20.0, commander@^2.9.0:
+commander@^2.19.0, commander@^2.20.0:
   version "2.20.3"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
   integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -4341,6 +5175,11 @@ commander@^8.3.0:
   resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
   integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
 
+common-ancestor-path@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7"
+  integrity sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==
+
 common-path-prefix@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0"
@@ -4414,7 +5253,7 @@ console-control-strings@^1.0.0, console-control-strings@^1.1.0:
 constants-browserify@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
-  integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
+  integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==
 
 content-disposition@0.5.4:
   version "0.5.4"
@@ -4445,7 +5284,7 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
 convert-source-map@~1.1.0:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860"
-  integrity sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=
+  integrity sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==
 
 cookie-signature@1.0.6:
   version "1.0.6"
@@ -4472,12 +5311,19 @@ core-js-compat@^3.20.2, core-js-compat@^3.21.0:
     browserslist "^4.19.1"
     semver "7.0.0"
 
+core-js-compat@^3.22.1:
+  version "3.25.1"
+  resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.25.1.tgz#6f13a90de52f89bbe6267e5620a412c7f7ff7e42"
+  integrity sha512-pOHS7O0i8Qt4zlPW/eIFjwp+NrTPx+wTL0ctgI2fHn31sZOq89rDsmtc/A2vAX7r6shl+bmVI+678He46jgBlw==
+  dependencies:
+    browserslist "^4.21.3"
+
 core-js-pure@^3.20.2, core-js-pure@^3.8.1:
   version "3.21.1"
   resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.21.1.tgz#8c4d1e78839f5f46208de7230cebfb72bc3bdb51"
   integrity sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==
 
-core-js@^2.4.0, core-js@^2.5.0:
+core-js@^2.5.0:
   version "2.6.12"
   resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
   integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
@@ -4492,16 +5338,6 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
   resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
   integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
 
-cosmiconfig@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc"
-  integrity sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==
-  dependencies:
-    is-directory "^0.3.1"
-    js-yaml "^3.9.0"
-    parse-json "^4.0.0"
-    require-from-string "^2.0.1"
-
 cosmiconfig@^5.0.7:
   version "5.2.1"
   resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
@@ -4834,89 +5670,16 @@ csstype@^2.2.0, csstype@^2.4.0:
   resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.17.tgz#4cf30eb87e1d1a005d8b6510f95292413f6a1c0e"
   integrity sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==
 
-csstype@^3.0.2:
-  version "3.0.8"
-  resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340"
-  integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==
-
-cucumber-expressions@^5.0.13:
-  version "5.0.18"
-  resolved "https://registry.yarnpkg.com/cucumber-expressions/-/cucumber-expressions-5.0.18.tgz#6c70779efd3aebc5e9e7853938b1110322429596"
-  integrity sha1-bHB3nv0668Xp54U5OLERAyJClZY=
-  dependencies:
-    becke-ch--regex--s0-0-v1--base--pl--lib "^1.2.0"
-
-cucumber-expressions@^6.0.1:
-  version "6.6.2"
-  resolved "https://registry.yarnpkg.com/cucumber-expressions/-/cucumber-expressions-6.6.2.tgz#d89640eccc72a78380b6c210eae36a64e7462b81"
-  integrity sha512-WcFSVBiWNLJbIcAAC3t/ACU46vaOKfe1UIF5H3qveoq+Y4XQm9j3YwHurQNufRKBBg8nCnpU7Ttsx7egjS3hwA==
-  dependencies:
-    becke-ch--regex--s0-0-v1--base--pl--lib "^1.2.0"
-
-cucumber-tag-expressions@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/cucumber-tag-expressions/-/cucumber-tag-expressions-1.1.1.tgz#7f5c7b70009bc2b666591bfe64854578bedee85a"
-  integrity sha1-f1x7cACbwrZmWRv+ZIVFeL7e6Fo=
-
-cucumber@^4.2.1:
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/cucumber/-/cucumber-4.2.1.tgz#64cfff6150bbe6b5e94b173470057353d6206719"
-  integrity sha512-3gQ0Vv4kSHsvXEFC6b1c+TfLRDzWD1/kU7e5vm8Kh8j35b95k6favan9/4ixcBNqd7UsU1T6FYcawC87+DlNKw==
-  dependencies:
-    assertion-error-formatter "^2.0.1"
-    babel-runtime "^6.11.6"
-    bluebird "^3.4.1"
-    cli-table "^0.3.1"
-    colors "^1.1.2"
-    commander "^2.9.0"
-    cucumber-expressions "^5.0.13"
-    cucumber-tag-expressions "^1.1.1"
-    duration "^0.2.0"
-    escape-string-regexp "^1.0.5"
-    figures "2.0.0"
-    gherkin "^5.0.0"
-    glob "^7.0.0"
-    indent-string "^3.1.0"
-    is-generator "^1.0.2"
-    is-stream "^1.1.0"
-    knuth-shuffle-seeded "^1.0.6"
-    lodash "^4.17.4"
-    mz "^2.4.0"
-    progress "^2.0.0"
-    resolve "^1.3.3"
-    serialize-error "^2.1.0"
-    stack-chain "^2.0.0"
-    stacktrace-js "^2.0.0"
-    string-argv "0.0.2"
-    title-case "^2.1.1"
-    util-arity "^1.0.2"
-    verror "^1.9.0"
+csstype@^3.0.2:
+  version "3.0.8"
+  resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340"
+  integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==
 
 cy-node-html-label@2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/cy-node-html-label/-/cy-node-html-label-2.0.0.tgz#822c0c8afc88b4ba05268544289d0b367ce21e3b"
   integrity sha512-hjvXlYAXaOjRryy8D3fHaeoRUVsgFi3589rcMtQRky08Ok+y7Lucqh895pNLJLNmXGm2N7083b8sPkPdhP3pag==
 
-cypress-cucumber-preprocessor@^4.3.1:
-  version "4.3.1"
-  resolved "https://registry.yarnpkg.com/cypress-cucumber-preprocessor/-/cypress-cucumber-preprocessor-4.3.1.tgz#c1702bfcdcb55bf9fe9d1436e944710b3d636bfb"
-  integrity sha512-BKUYXqoTeKzkPXohEczDtpAwRCY0ZPtIpfRwJut16yNLqdXQMV+aItwanxe3cbJTFlwg562NAjL4LMdiOhkAjg==
-  dependencies:
-    "@cypress/browserify-preprocessor" "^3.0.2"
-    chai "^4.2.0"
-    chokidar "3.5.2"
-    cosmiconfig "^4.0.0"
-    cucumber "^4.2.1"
-    cucumber-expressions "^6.0.1"
-    cucumber-tag-expressions "^1.1.1"
-    dargs "^7.0.0"
-    debug "^3.0.1"
-    gherkin "^5.1.0"
-    glob "^7.1.2"
-    js-string-escape "^1.0.1"
-    minimist "^1.2.5"
-    through "^2.3.8"
-
 cypress-multi-reporters@^1.6.0:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/cypress-multi-reporters/-/cypress-multi-reporters-1.6.0.tgz#2c6833b92e3df412c233657c55009e2d5e1cc7c1"
@@ -4932,19 +5695,20 @@ cypress-react-selector@^2.3.17:
   dependencies:
     resq "1.10.2"
 
-cypress@^9.2.1:
-  version "9.2.1"
-  resolved "https://registry.yarnpkg.com/cypress/-/cypress-9.2.1.tgz#47f2457e5ca7ede48be9a4176f20f30ccf3b3902"
-  integrity sha512-LVEe4yWCo4xO0Vd8iYjFHRyd5ulRvM56XqMgAdn05Qb9kJ6iJdO/MmjKD8gNd768698cp1FDuSmFQZHVZGk+Og==
+cypress@^10.7.0:
+  version "10.7.0"
+  resolved "https://registry.yarnpkg.com/cypress/-/cypress-10.7.0.tgz#2d37f8b9751c6de33ee48639cb7e67a2ce593231"
+  integrity sha512-gTFvjrUoBnqPPOu9Vl5SBHuFlzx/Wxg/ZXIz2H4lzoOLFelKeF7mbwYUOzgzgF0oieU2WhJAestQdkgwJMMTvQ==
   dependencies:
     "@cypress/request" "^2.88.10"
     "@cypress/xvfb" "^1.2.4"
     "@types/node" "^14.14.31"
-    "@types/sinonjs__fake-timers" "^6.0.2"
+    "@types/sinonjs__fake-timers" "8.1.1"
     "@types/sizzle" "^2.3.2"
     arch "^2.2.0"
     blob-util "^2.0.2"
-    bluebird "3.7.2"
+    bluebird "^3.7.2"
+    buffer "^5.6.0"
     cachedir "^2.3.0"
     chalk "^4.1.0"
     check-more-types "^2.24.0"
@@ -4968,15 +5732,15 @@ cypress@^9.2.1:
     listr2 "^3.8.3"
     lodash "^4.17.21"
     log-symbols "^4.0.0"
-    minimist "^1.2.5"
+    minimist "^1.2.6"
     ospath "^1.2.2"
     pretty-bytes "^5.6.0"
     proxy-from-env "1.0.0"
     request-progress "^3.0.0"
+    semver "^7.3.2"
     supports-color "^8.1.1"
     tmp "~0.2.1"
     untildify "^4.0.0"
-    url "^0.11.0"
     yauzl "^2.10.0"
 
 cytoscape-canvas@3.0.1:
@@ -5083,14 +5847,6 @@ d3-voronoi@^1.1.2:
   resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.4.tgz#dd3c78d7653d2bb359284ae478645d95944c8297"
   integrity sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg==
 
-d@1, d@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a"
-  integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==
-  dependencies:
-    es5-ext "^0.10.50"
-    type "^1.0.1"
-
 dagre@0.8.5:
   version "0.8.5"
   resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.5.tgz#ba30b0055dac12b6c1fcc247817442777d06afee"
@@ -5104,11 +5860,6 @@ damerau-levenshtein@^1.0.7:
   resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
   integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==
 
-dargs@^7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc"
-  integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==
-
 dash-ast@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/dash-ast/-/dash-ast-1.0.0.tgz#12029ba5fb2f8aa6f0a861795b23c1b4b6c27d37"
@@ -5147,14 +5898,14 @@ debug@2.6.9, debug@^2.2.0, debug@^2.6.0, debug@^2.6.9:
   dependencies:
     ms "2.0.0"
 
-debug@4, debug@^4.3.3:
+debug@4, debug@^4.2.0, debug@^4.3.3:
   version "4.3.4"
   resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
   integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
   dependencies:
     ms "2.1.2"
 
-debug@^3.0.1, debug@^3.1.0, debug@^3.1.1, debug@^3.2.7:
+debug@^3.1.0, debug@^3.1.1, debug@^3.2.7:
   version "3.2.7"
   resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
   integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
@@ -5198,13 +5949,6 @@ dedent@^0.7.0:
   resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
   integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
 
-deep-eql@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df"
-  integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==
-  dependencies:
-    type-detect "^4.0.0"
-
 deep-equal@^1.0.1, deep-equal@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
@@ -5256,6 +6000,14 @@ define-properties@^1.1.3:
   dependencies:
     object-keys "^1.0.12"
 
+define-properties@^1.1.4:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1"
+  integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==
+  dependencies:
+    has-property-descriptors "^1.0.0"
+    object-keys "^1.1.1"
+
 defined@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
@@ -5353,11 +6105,6 @@ diff-sequences@^27.5.1:
   resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327"
   integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==
 
-diff@^3.0.0:
-  version "3.5.0"
-  resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
-  integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
-
 diffie-hellman@^5.0.0:
   version "5.0.3"
   resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
@@ -5525,7 +6272,7 @@ dotenv@^10.0.0:
 duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2:
   version "0.1.4"
   resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
-  integrity sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=
+  integrity sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==
   dependencies:
     readable-stream "^2.0.2"
 
@@ -5534,14 +6281,6 @@ duplexer@^0.1.2:
   resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
   integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==
 
-duration@^0.2.0:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/duration/-/duration-0.2.2.tgz#ddf149bc3bc6901150fe9017111d016b3357f529"
-  integrity sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==
-  dependencies:
-    d "1"
-    es5-ext "~0.10.46"
-
 ecc-jsbn@~0.1.1:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
@@ -5567,6 +6306,11 @@ electron-to-chromium@^1.4.17:
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.53.tgz#5d80a91c399b44952ef485857fb5b9d4387d2e60"
   integrity sha512-rFveSKQczlcav+H3zkKqykU6ANseFwXwkl855jOIap5/0gnEcuIhv2ecz6aoTrXavF6I/CEBeRnBnkB51k06ew==
 
+electron-to-chromium@^1.4.202:
+  version "1.4.248"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.248.tgz#dd2dab68277e91e8452536ee9265f484066f94ad"
+  integrity sha512-qShjzEYpa57NnhbW2K+g+Fl+eNoDvQ7I+2MRwWnU6Z6F0HhXekzsECCLv+y2OJUsRodjqoSfwHkIX42VUFtUzg==
+
 electron-to-chromium@^1.4.71:
   version "1.4.73"
   resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.73.tgz#422f6f514315bcace9615903e4a9b6b9fa283137"
@@ -5717,7 +6461,7 @@ error-stack-parser@^2.0.6:
   dependencies:
     stackframe "^1.1.1"
 
-es-abstract@^1.17.2, es-abstract@^1.18.5, es-abstract@^1.19.1:
+es-abstract@^1.17.2, es-abstract@^1.19.1:
   version "1.19.1"
   resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3"
   integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==
@@ -5791,6 +6535,35 @@ es-abstract@^1.19.0:
     string.prototype.trimstart "^1.0.4"
     unbox-primitive "^1.0.1"
 
+es-abstract@^1.19.5, es-abstract@^1.20.0:
+  version "1.20.2"
+  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.2.tgz#8495a07bc56d342a3b8ea3ab01bd986700c2ccb3"
+  integrity sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==
+  dependencies:
+    call-bind "^1.0.2"
+    es-to-primitive "^1.2.1"
+    function-bind "^1.1.1"
+    function.prototype.name "^1.1.5"
+    get-intrinsic "^1.1.2"
+    get-symbol-description "^1.0.0"
+    has "^1.0.3"
+    has-property-descriptors "^1.0.0"
+    has-symbols "^1.0.3"
+    internal-slot "^1.0.3"
+    is-callable "^1.2.4"
+    is-negative-zero "^2.0.2"
+    is-regex "^1.1.4"
+    is-shared-array-buffer "^1.0.2"
+    is-string "^1.0.7"
+    is-weakref "^1.0.2"
+    object-inspect "^1.12.2"
+    object-keys "^1.1.1"
+    object.assign "^4.1.4"
+    regexp.prototype.flags "^1.4.3"
+    string.prototype.trimend "^1.0.5"
+    string.prototype.trimstart "^1.0.5"
+    unbox-primitive "^1.0.2"
+
 es-array-method-boxes-properly@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e"
@@ -5810,31 +6583,132 @@ es-to-primitive@^1.2.1:
     is-date-object "^1.0.1"
     is-symbol "^1.0.2"
 
-es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@~0.10.46:
-  version "0.10.53"
-  resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1"
-  integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==
-  dependencies:
-    es6-iterator "~2.0.3"
-    es6-symbol "~3.1.3"
-    next-tick "~1.0.0"
-
-es6-iterator@~2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
-  integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
-  dependencies:
-    d "1"
-    es5-ext "^0.10.35"
-    es6-symbol "^3.1.1"
-
-es6-symbol@^3.1.1, es6-symbol@~3.1.3:
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18"
-  integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==
-  dependencies:
-    d "^1.0.1"
-    ext "^1.1.2"
+esbuild-android-64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz#505f41832884313bbaffb27704b8bcaa2d8616be"
+  integrity sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==
+
+esbuild-android-arm64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz#8ce69d7caba49646e009968fe5754a21a9871771"
+  integrity sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==
+
+esbuild-darwin-64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz#24ba67b9a8cb890a3c08d9018f887cc221cdda25"
+  integrity sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==
+
+esbuild-darwin-arm64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz#3f7cdb78888ee05e488d250a2bdaab1fa671bf73"
+  integrity sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==
+
+esbuild-freebsd-64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz#09250f997a56ed4650f3e1979c905ffc40bbe94d"
+  integrity sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==
+
+esbuild-freebsd-arm64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz#bafb46ed04fc5f97cbdb016d86947a79579f8e48"
+  integrity sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==
+
+esbuild-linux-32@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz#e2a8c4a8efdc355405325033fcebeb941f781fe5"
+  integrity sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==
+
+esbuild-linux-64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz#de5fdba1c95666cf72369f52b40b03be71226652"
+  integrity sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==
+
+esbuild-linux-arm64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz#dae4cd42ae9787468b6a5c158da4c84e83b0ce8b"
+  integrity sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==
+
+esbuild-linux-arm@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz#a2c1dff6d0f21dbe8fc6998a122675533ddfcd59"
+  integrity sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==
+
+esbuild-linux-mips64le@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz#d9918e9e4cb972f8d6dae8e8655bf9ee131eda34"
+  integrity sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==
+
+esbuild-linux-ppc64le@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz#3f9a0f6d41073fb1a640680845c7de52995f137e"
+  integrity sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==
+
+esbuild-linux-riscv64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz#618853c028178a61837bc799d2013d4695e451c8"
+  integrity sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==
+
+esbuild-linux-s390x@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz#d1885c4c5a76bbb5a0fe182e2c8c60eb9e29f2a6"
+  integrity sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==
+
+esbuild-netbsd-64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz#69ae917a2ff241b7df1dbf22baf04bd330349e81"
+  integrity sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==
+
+esbuild-openbsd-64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz#db4c8495287a350a6790de22edea247a57c5d47b"
+  integrity sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==
+
+esbuild-sunos-64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz#54287ee3da73d3844b721c21bc80c1dc7e1bf7da"
+  integrity sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==
+
+esbuild-windows-32@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz#f8aaf9a5667630b40f0fb3aa37bf01bbd340ce31"
+  integrity sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==
+
+esbuild-windows-64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz#bf54b51bd3e9b0f1886ffdb224a4176031ea0af4"
+  integrity sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==
+
+esbuild-windows-arm64@0.14.54:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz#937d15675a15e4b0e4fafdbaa3a01a776a2be982"
+  integrity sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==
+
+esbuild@^0.14.23:
+  version "0.14.54"
+  resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.54.tgz#8b44dcf2b0f1a66fc22459943dccf477535e9aa2"
+  integrity sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==
+  optionalDependencies:
+    "@esbuild/linux-loong64" "0.14.54"
+    esbuild-android-64 "0.14.54"
+    esbuild-android-arm64 "0.14.54"
+    esbuild-darwin-64 "0.14.54"
+    esbuild-darwin-arm64 "0.14.54"
+    esbuild-freebsd-64 "0.14.54"
+    esbuild-freebsd-arm64 "0.14.54"
+    esbuild-linux-32 "0.14.54"
+    esbuild-linux-64 "0.14.54"
+    esbuild-linux-arm "0.14.54"
+    esbuild-linux-arm64 "0.14.54"
+    esbuild-linux-mips64le "0.14.54"
+    esbuild-linux-ppc64le "0.14.54"
+    esbuild-linux-riscv64 "0.14.54"
+    esbuild-linux-s390x "0.14.54"
+    esbuild-netbsd-64 "0.14.54"
+    esbuild-openbsd-64 "0.14.54"
+    esbuild-sunos-64 "0.14.54"
+    esbuild-windows-32 "0.14.54"
+    esbuild-windows-64 "0.14.54"
+    esbuild-windows-arm64 "0.14.54"
 
 escalade@^3.1.1:
   version "3.1.1"
@@ -6280,13 +7154,6 @@ express@^4.17.3:
     utils-merge "1.0.1"
     vary "~1.1.2"
 
-ext@^1.1.2:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/ext/-/ext-1.4.0.tgz#89ae7a07158f79d35517882904324077e4379244"
-  integrity sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==
-  dependencies:
-    type "^2.0.0"
-
 extend@~3.0.2:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
@@ -6377,13 +7244,6 @@ fd-slicer@~1.1.0:
   dependencies:
     pend "~1.2.0"
 
-figures@2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
-  integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=
-  dependencies:
-    escape-string-regexp "^1.0.5"
-
 figures@^3.2.0:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
@@ -6509,10 +7369,12 @@ follow-redirects@^1.0.0, follow-redirects@^1.14.0:
   resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.8.tgz#016996fb9a11a100566398b1c6839337d7bfa8fc"
   integrity sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==
 
-foreach@^2.0.5:
-  version "2.0.5"
-  resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
-  integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k=
+for-each@^0.3.3:
+  version "0.3.3"
+  resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
+  integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==
+  dependencies:
+    is-callable "^1.1.3"
 
 forever-agent@~0.6.1:
   version "0.6.1"
@@ -6632,6 +7494,16 @@ function.prototype.name@^1.1.0, function.prototype.name@^1.1.2:
     es-abstract "^1.18.0-next.2"
     functions-have-names "^1.2.2"
 
+function.prototype.name@^1.1.5:
+  version "1.1.5"
+  resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621"
+  integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==
+  dependencies:
+    call-bind "^1.0.2"
+    define-properties "^1.1.3"
+    es-abstract "^1.19.0"
+    functions-have-names "^1.2.2"
+
 functional-red-black-tree@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
@@ -6693,11 +7565,6 @@ get-caller-file@^2.0.5:
   resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
   integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
 
-get-func-name@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
-  integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
-
 get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
@@ -6707,6 +7574,15 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
     has "^1.0.3"
     has-symbols "^1.0.1"
 
+get-intrinsic@^1.1.2:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385"
+  integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==
+  dependencies:
+    function-bind "^1.1.1"
+    has "^1.0.3"
+    has-symbols "^1.0.3"
+
 get-own-enumerable-property-symbols@^3.0.0:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
@@ -6768,11 +7644,6 @@ getpass@^0.1.1:
   dependencies:
     assert-plus "^1.0.0"
 
-gherkin@^5.0.0, gherkin@^5.1.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/gherkin/-/gherkin-5.1.0.tgz#684bbb03add24eaf7bdf544f58033eb28fb3c6d5"
-  integrity sha1-aEu7A63STq9731RPWAM+so+zxtU=
-
 glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2:
   version "5.1.2"
   resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
@@ -6804,7 +7675,19 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, gl
     once "^1.3.0"
     path-is-absolute "^1.0.0"
 
-glob@^7.1.0, glob@^7.1.1:
+glob@^7.1.0, glob@^7.2.0:
+  version "7.2.3"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
+  integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
+  dependencies:
+    fs.realpath "^1.0.0"
+    inflight "^1.0.4"
+    inherits "2"
+    minimatch "^3.1.1"
+    once "^1.3.0"
+    path-is-absolute "^1.0.0"
+
+glob@^7.1.1:
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
   integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
@@ -6934,6 +7817,11 @@ has-bigints@^1.0.1:
   resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113"
   integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==
 
+has-bigints@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
+  integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==
+
 has-flag@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@@ -6944,6 +7832,13 @@ has-flag@^4.0.0:
   resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
   integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
 
+has-property-descriptors@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861"
+  integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==
+  dependencies:
+    get-intrinsic "^1.1.1"
+
 has-symbols@^1.0.1, has-symbols@^1.0.2:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423"
@@ -7015,7 +7910,7 @@ history@^4.9.0:
 hmac-drbg@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
-  integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
+  integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==
   dependencies:
     hash.js "^1.0.3"
     minimalistic-assert "^1.0.0"
@@ -7114,7 +8009,7 @@ html-webpack-plugin@^5.5.0:
 htmlescape@^1.1.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351"
-  integrity sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=
+  integrity sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==
 
 htmlparser2@^6.1.0:
   version "6.1.0"
@@ -7212,7 +8107,7 @@ http-signature@~1.3.6:
 https-browserify@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
-  integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
+  integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==
 
 https-proxy-agent@^5.0.0:
   version "5.0.0"
@@ -7286,7 +8181,7 @@ identity-obj-proxy@^3.0.0:
   dependencies:
     harmony-reflect "^1.4.6"
 
-ieee754@^1.1.4:
+ieee754@^1.1.13, ieee754@^1.1.4:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
   integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
@@ -7335,11 +8230,6 @@ imurmurhash@^0.1.4:
   resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
   integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
 
-indent-string@^3.1.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289"
-  integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=
-
 indent-string@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
@@ -7366,7 +8256,7 @@ inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, i
 inherits@2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
-  integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
+  integrity sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==
 
 inherits@2.0.3:
   version "2.0.3"
@@ -7386,7 +8276,7 @@ ini@^1.3.5:
 inline-source-map@~0.6.0:
   version "0.6.2"
   resolved "https://registry.yarnpkg.com/inline-source-map/-/inline-source-map-0.6.2.tgz#f9393471c18a79d1724f863fa38b586370ade2a5"
-  integrity sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=
+  integrity sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==
   dependencies:
     source-map "~0.5.3"
 
@@ -7466,6 +8356,11 @@ is-buffer@^1.1.0, is-buffer@~1.1.6:
   resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
   integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
 
+is-callable@^1.1.3:
+  version "1.2.5"
+  resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.5.tgz#6123e0b1fef5d7591514b371bb018204892f1a2b"
+  integrity sha512-ZIWRujF6MvYGkEuHMYtFRkL2wAtFw89EHfKlXrkPkjQZZRWeh9L1q3SV13NIfHnqxugjLvAOkEHx9mb1zcMnEw==
+
 is-callable@^1.1.4, is-callable@^1.1.5, is-callable@^1.2.3:
   version "1.2.3"
   resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e"
@@ -7504,6 +8399,13 @@ is-core-module@^2.5.0, is-core-module@^2.8.1:
   dependencies:
     has "^1.0.3"
 
+is-core-module@^2.9.0:
+  version "2.10.0"
+  resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed"
+  integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==
+  dependencies:
+    has "^1.0.3"
+
 is-date-object@^1.0.1:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5"
@@ -7541,11 +8443,6 @@ is-generator-function@^1.0.7:
   dependencies:
     has-tostringtag "^1.0.0"
 
-is-generator@^1.0.2:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/is-generator/-/is-generator-1.0.3.tgz#c14c21057ed36e328db80347966c693f886389f3"
-  integrity sha1-wUwhBX7TbjKNuANHlmxpP4hjifM=
-
 is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
@@ -7603,7 +8500,7 @@ is-obj@^1.0.1:
   resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
   integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
 
-is-path-inside@^3.0.2:
+is-path-inside@^3.0.2, is-path-inside@^3.0.3:
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
   integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
@@ -7654,6 +8551,13 @@ is-shared-array-buffer@^1.0.1:
   resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6"
   integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==
 
+is-shared-array-buffer@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79"
+  integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==
+  dependencies:
+    call-bind "^1.0.2"
+
 is-stream@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
@@ -7688,15 +8592,15 @@ is-symbol@^1.0.2, is-symbol@^1.0.3:
   dependencies:
     has-symbols "^1.0.2"
 
-is-typed-array@^1.1.3, is-typed-array@^1.1.7:
-  version "1.1.8"
-  resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.8.tgz#cbaa6585dc7db43318bc5b89523ea384a6f65e79"
-  integrity sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==
+is-typed-array@^1.1.3, is-typed-array@^1.1.9:
+  version "1.1.9"
+  resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.9.tgz#246d77d2871e7d9f5aeb1d54b9f52c71329ece67"
+  integrity sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==
   dependencies:
     available-typed-arrays "^1.0.5"
     call-bind "^1.0.2"
-    es-abstract "^1.18.5"
-    foreach "^2.0.5"
+    es-abstract "^1.20.0"
+    for-each "^0.3.3"
     has-tostringtag "^1.0.0"
 
 is-typedarray@^1.0.0, is-typedarray@~1.0.0:
@@ -8245,11 +9149,6 @@ js-base64@^2.4.3:
   resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4"
   integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==
 
-js-string-escape@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef"
-  integrity sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=
-
 "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -8271,7 +9170,7 @@ js-yaml@3.14.0:
     argparse "^1.0.7"
     esprima "^4.0.0"
 
-js-yaml@^3.13.1, js-yaml@^3.9.0:
+js-yaml@^3.13.1:
   version "3.14.1"
   resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
   integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
@@ -8372,7 +9271,7 @@ json-stable-stringify-without-jsonify@^1.0.1:
 json-stable-stringify@~0.0.0:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz#611c23e814db375527df851193db59dd2af27f45"
-  integrity sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=
+  integrity sha512-nKtD/Qxm7tWdZqJoldEC7fF0S41v0mWbeaXG3637stOWfyGxTgWTYE2wtfKmjzpvxv2MA2xzxsXOIiwUpkX6Qw==
   dependencies:
     jsonify "~0.0.0"
 
@@ -8412,12 +9311,12 @@ jsonfile@^6.0.1:
 jsonify@~0.0.0:
   version "0.0.0"
   resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
-  integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=
+  integrity sha512-trvBk1ki43VZptdBI5rIlG4YOzyeH/WefQt5rj1grasPn4iiZWKet8nkgc4GlsAylaztn0qZfUYOiTsASJFdNA==
 
 jsonparse@^1.2.0:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
-  integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=
+  integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==
 
 jsonpointer@^5.0.0:
   version "5.0.0"
@@ -8480,13 +9379,6 @@ klona@^2.0.5:
   resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc"
   integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==
 
-knuth-shuffle-seeded@^1.0.6:
-  version "1.0.6"
-  resolved "https://registry.yarnpkg.com/knuth-shuffle-seeded/-/knuth-shuffle-seeded-1.0.6.tgz#01f1b65733aa7540ee08d8b0174164d22081e4e1"
-  integrity sha1-AfG2VzOqdUDuCNiwF0Fk0iCB5OE=
-  dependencies:
-    seed-random "~2.2.0"
-
 labeled-stream-splicer@^2.0.0:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz#42a41a16abcd46fd046306cf4f2c3576fffb1c21"
@@ -8664,7 +9556,7 @@ lodash.memoize@^4.1.2:
 lodash.memoize@~3.0.3:
   version "3.0.4"
   resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f"
-  integrity sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=
+  integrity sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==
 
 lodash.merge@^4.6.2:
   version "4.6.2"
@@ -8701,7 +9593,7 @@ lodash.unset@^4.5.2:
   resolved "https://registry.yarnpkg.com/lodash.unset/-/lodash.unset-4.5.2.tgz#370d1d3e85b72a7e1b0cdf2d272121306f23e4ed"
   integrity sha1-Nw0dPoW3Kn4bDN8tJyEhMG8j5O0=
 
-lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0, lodash@~4.17.10:
+lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0, lodash@~4.17.10:
   version "4.17.21"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
   integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -8731,18 +9623,6 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3
   dependencies:
     js-tokens "^3.0.0 || ^4.0.0"
 
-loupe@^2.3.1:
-  version "2.3.4"
-  resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3"
-  integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==
-  dependencies:
-    get-func-name "^2.0.0"
-
-lower-case@^1.1.1:
-  version "1.1.4"
-  resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
-  integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw=
-
 lower-case@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
@@ -8986,7 +9866,7 @@ minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
 minimalistic-crypto-utils@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
-  integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
+  integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==
 
 minimatch@3.0.4, minimatch@~3.0.2:
   version "3.0.4"
@@ -8995,7 +9875,7 @@ minimatch@3.0.4, minimatch@~3.0.2:
   dependencies:
     brace-expansion "^1.1.7"
 
-minimatch@^3.0.4, minimatch@^3.1.2:
+minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
   integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
@@ -9182,15 +10062,6 @@ multimatch@^4.0.0:
     arrify "^2.0.1"
     minimatch "^3.0.4"
 
-mz@^2.4.0:
-  version "2.7.0"
-  resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
-  integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
-  dependencies:
-    any-promise "^1.0.0"
-    object-assign "^4.0.1"
-    thenify-all "^1.0.0"
-
 nan@^2.13.2:
   version "2.14.2"
   resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
@@ -9226,23 +10097,11 @@ neo-async@^2.6.2:
   resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
   integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
 
-next-tick@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
-  integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
-
 nice-try@^1.0.4:
   version "1.0.5"
   resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
   integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
 
-no-case@^2.2.0:
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
-  integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==
-  dependencies:
-    lower-case "^1.1.1"
-
 no-case@^3.0.4:
   version "3.0.4"
   resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d"
@@ -9272,6 +10131,11 @@ node-gyp@^8.4.1:
     tar "^6.1.2"
     which "^2.0.2"
 
+node-hook@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/node-hook/-/node-hook-1.0.0.tgz#82ca39af991d726d5c7952e59c992378bb296f7e"
+  integrity sha512-tBTIHwkzXvbesP0fY495VsqSWCOS5Ttt5+mAmeqUC1yglCiSYarNewfi2Q+HOL+M6pZYYqwGU6jIi5+gIHQbpg==
+
 node-int64@^0.4.0:
   version "0.4.0"
   resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
@@ -9287,6 +10151,11 @@ node-releases@^2.0.2:
   resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01"
   integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==
 
+node-releases@^2.0.6:
+  version "2.0.6"
+  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503"
+  integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==
+
 node-sass@^7.0.1:
   version "7.0.1"
   resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-7.0.1.tgz#ad4f6bc663de8acc0a9360db39165a1e2620aa72"
@@ -9408,7 +10277,7 @@ oauth-sign@~0.9.0:
   resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
   integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
 
-object-assign@^4.0.1, object-assign@^4.1.1:
+object-assign@^4.1.1:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
   integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
@@ -9428,6 +10297,11 @@ object-inspect@^1.11.0, object-inspect@^1.12.0:
   resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0"
   integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==
 
+object-inspect@^1.12.2:
+  version "1.12.2"
+  resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
+  integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
+
 object-is@^1.0.1, object-is@^1.0.2, object-is@^1.1.2:
   version "1.1.5"
   resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac"
@@ -9451,6 +10325,16 @@ object.assign@^4.1.0, object.assign@^4.1.2:
     has-symbols "^1.0.1"
     object-keys "^1.1.1"
 
+object.assign@^4.1.4:
+  version "4.1.4"
+  resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f"
+  integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==
+  dependencies:
+    call-bind "^1.0.2"
+    define-properties "^1.1.4"
+    has-symbols "^1.0.3"
+    object-keys "^1.1.1"
+
 object.entries@^1.1.1:
   version "1.1.4"
   resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.4.tgz#43ccf9a50bc5fd5b649d45ab1a579f24e088cafd"
@@ -9580,7 +10464,7 @@ optionator@^0.9.1:
 os-browserify@~0.3.0:
   version "0.3.0"
   resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
-  integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
+  integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==
 
 ospath@^1.2.2:
   version "1.2.2"
@@ -9590,7 +10474,7 @@ ospath@^1.2.2:
 outpipe@^1.1.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/outpipe/-/outpipe-1.1.1.tgz#50cf8616365e87e031e29a5ec9339a3da4725fa2"
-  integrity sha1-UM+GFjZeh+Ax4ppeyTOaPaRyX6I=
+  integrity sha512-BnNY/RwnDrkmQdUa9U+OfN/Y7AWmKuUPCCd+hbRclZnnANvYpO72zp/a6Q4n829hPbdqEac31XCcsvlEvb+rtA==
   dependencies:
     shell-quote "^1.4.2"
 
@@ -9678,13 +10562,6 @@ p-try@^2.0.0:
   resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
   integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
 
-pad-right@^0.2.2:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/pad-right/-/pad-right-0.2.2.tgz#6fbc924045d244f2a2a244503060d3bfc6009774"
-  integrity sha1-b7ySQEXSRPKiokRQMGDTv8YAl3Q=
-  dependencies:
-    repeat-string "^1.5.2"
-
 pako@~1.0.5:
   version "1.0.11"
   resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
@@ -9708,7 +10585,7 @@ parent-module@^1.0.0:
 parents@^1.0.0, parents@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/parents/-/parents-1.0.1.tgz#fedd4d2bf193a77745fe71e371d73c3307d9c751"
-  integrity sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=
+  integrity sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==
   dependencies:
     path-platform "~0.11.15"
 
@@ -9816,7 +10693,7 @@ path-parse@^1.0.6, path-parse@^1.0.7:
 path-platform@~0.11.15:
   version "0.11.15"
   resolved "https://registry.yarnpkg.com/path-platform/-/path-platform-0.11.15.tgz#e864217f74c36850f0852b78dc7bf7d4a5721bf2"
-  integrity sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=
+  integrity sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==
 
 path-to-regexp@0.1.7:
   version "0.1.7"
@@ -9835,11 +10712,6 @@ path-type@^4.0.0:
   resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
   integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
 
-pathval@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d"
-  integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==
-
 pbkdf2@^3.0.3:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075"
@@ -10526,12 +11398,7 @@ process-nextick-args@~2.0.0:
 process@~0.11.0:
   version "0.11.10"
   resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
-  integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
-
-progress@^2.0.0:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
-  integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
+  integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==
 
 promise-inflight@^1.0.1:
   version "1.0.1"
@@ -10628,12 +11495,12 @@ pump@^3.0.0:
 punycode@1.3.2:
   version "1.3.2"
   resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
-  integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
+  integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==
 
 punycode@^1.3.2:
   version "1.4.1"
   resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
-  integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
+  integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==
 
 punycode@^2.1.0, punycode@^2.1.1:
   version "2.1.1"
@@ -10658,12 +11525,12 @@ qs@~6.5.2:
 querystring-es3@~0.2.0:
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
-  integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=
+  integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==
 
 querystring@0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
-  integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
+  integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==
 
 queue-microtask@^1.2.2:
   version "1.2.3"
@@ -11022,7 +11889,7 @@ react@^17.0.1:
 read-only-stream@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/read-only-stream/-/read-only-stream-2.0.0.tgz#2724fd6a8113d73764ac288d4386270c1dbf17f0"
-  integrity sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=
+  integrity sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==
   dependencies:
     readable-stream "^2.0.2"
 
@@ -11150,6 +12017,11 @@ redux@^4.0.0:
   dependencies:
     "@babel/runtime" "^7.9.2"
 
+reflect-metadata@0.1.13:
+  version "0.1.13"
+  resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
+  integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
+
 regenerate-unicode-properties@^10.0.1:
   version "10.0.1"
   resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56"
@@ -11169,11 +12041,6 @@ regenerate@^1.4.0, regenerate@^1.4.2:
   resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
   integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
 
-regenerator-runtime@^0.11.0:
-  version "0.11.1"
-  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
-  integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
-
 regenerator-runtime@^0.13.4:
   version "0.13.7"
   resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55"
@@ -11191,11 +12058,30 @@ regenerator-transform@^0.14.2:
   dependencies:
     "@babel/runtime" "^7.8.4"
 
+regenerator-transform@^0.15.0:
+  version "0.15.0"
+  resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537"
+  integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==
+  dependencies:
+    "@babel/runtime" "^7.8.4"
+
 regex-parser@^2.2.11:
   version "2.2.11"
   resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58"
   integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==
 
+regexp-match-indices@1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/regexp-match-indices/-/regexp-match-indices-1.0.2.tgz#cf20054a6f7d5b3e116a701a7b00f82889d10da6"
+  integrity sha512-DwZuAkt8NF5mKwGGER1EGh2PRqyvhRhhLviH+R8y8dIuaQROlUfXjt4s9ZTXstIsSkptf06BSvwcEmmfheJJWQ==
+  dependencies:
+    regexp-tree "^0.1.11"
+
+regexp-tree@^0.1.11:
+  version "0.1.24"
+  resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.24.tgz#3d6fa238450a4d66e5bc9c4c14bb720e2196829d"
+  integrity sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==
+
 regexp.prototype.flags@^1.2.0:
   version "1.3.1"
   resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26"
@@ -11212,6 +12098,15 @@ regexp.prototype.flags@^1.4.1:
     call-bind "^1.0.2"
     define-properties "^1.1.3"
 
+regexp.prototype.flags@^1.4.3:
+  version "1.4.3"
+  resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"
+  integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==
+  dependencies:
+    call-bind "^1.0.2"
+    define-properties "^1.1.3"
+    functions-have-names "^1.2.2"
+
 regexpp@^3.2.0:
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
@@ -11241,6 +12136,18 @@ regexpu-core@^5.0.1:
     unicode-match-property-ecmascript "^2.0.0"
     unicode-match-property-value-ecmascript "^2.0.0"
 
+regexpu-core@^5.1.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.1.0.tgz#2f8504c3fd0ebe11215783a41541e21c79942c6d"
+  integrity sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA==
+  dependencies:
+    regenerate "^1.4.2"
+    regenerate-unicode-properties "^10.0.1"
+    regjsgen "^0.6.0"
+    regjsparser "^0.8.2"
+    unicode-match-property-ecmascript "^2.0.0"
+    unicode-match-property-value-ecmascript "^2.0.0"
+
 regjsgen@^0.5.1:
   version "0.5.2"
   resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733"
@@ -11286,11 +12193,6 @@ renderkid@^3.0.0:
     lodash "^4.17.21"
     strip-ansi "^6.0.1"
 
-repeat-string@^1.5.2, repeat-string@^1.6.1:
-  version "1.6.1"
-  resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
-  integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
-
 request-progress@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe"
@@ -11329,7 +12231,7 @@ require-directory@^2.1.1:
   resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
   integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
 
-require-from-string@^2.0.1, require-from-string@^2.0.2:
+require-from-string@^2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
   integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
@@ -11376,6 +12278,13 @@ resolve-pathname@^3.0.0:
   resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd"
   integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==
 
+resolve-pkg@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/resolve-pkg/-/resolve-pkg-2.0.0.tgz#ac06991418a7623edc119084edc98b0e6bf05a41"
+  integrity sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ==
+  dependencies:
+    resolve-from "^5.0.0"
+
 resolve-url-loader@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz#d50d4ddc746bb10468443167acf800dcd6c3ad57"
@@ -11392,12 +12301,12 @@ resolve.exports@^1.1.0:
   resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9"
   integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==
 
-resolve@^1.1.4, resolve@^1.17.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.3.3, resolve@^1.4.0:
-  version "1.22.0"
-  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
-  integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
+resolve@^1.1.4, resolve@^1.17.0, resolve@^1.4.0:
+  version "1.22.1"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
+  integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
   dependencies:
-    is-core-module "^2.8.1"
+    is-core-module "^2.9.0"
     path-parse "^1.0.7"
     supports-preserve-symlinks-flag "^1.0.0"
 
@@ -11409,6 +12318,15 @@ resolve@^1.10.0, resolve@^1.14.2, resolve@^1.19.0:
     is-core-module "^2.2.0"
     path-parse "^1.0.6"
 
+resolve@^1.20.0, resolve@^1.22.0:
+  version "1.22.0"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
+  integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
+  dependencies:
+    is-core-module "^2.8.1"
+    path-parse "^1.0.7"
+    supports-preserve-symlinks-flag "^1.0.0"
+
 resolve@^2.0.0-next.3:
   version "2.0.0-next.3"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46"
@@ -11633,11 +12551,6 @@ scss-tokenizer@^0.3.0:
     js-base64 "^2.4.3"
     source-map "^0.7.1"
 
-seed-random@~2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/seed-random/-/seed-random-2.2.0.tgz#2a9b19e250a817099231a5b99a4daf80b7fbed54"
-  integrity sha1-KpsZ4lCoFwmSMaW5mk2vgLf77VQ=
-
 seedrandom@3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.1.tgz#eb3dde015bcf55df05a233514e5df44ef9dce083"
@@ -11701,11 +12614,6 @@ send@0.17.2:
     range-parser "~1.2.1"
     statuses "~1.5.0"
 
-serialize-error@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a"
-  integrity sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=
-
 serialize-javascript@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa"
@@ -11776,7 +12684,7 @@ shasum-object@^1.0.0:
 shasum@^1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/shasum/-/shasum-1.0.2.tgz#e7012310d8f417f4deb5712150e5678b87ae565f"
-  integrity sha1-5wEjENj0F/TetXEhUOVni4euVl8=
+  integrity sha512-UTzHm/+AzKfO9RgPgRpDIuMSNie1ubXRaljjlhFMNGYoG7z+rm9AHLPMf70R7887xboDH9Q+5YQbWKObFHEAtw==
   dependencies:
     json-stable-stringify "~0.0.0"
     sha.js "~2.4.4"
@@ -11930,11 +12838,6 @@ source-map-support@^0.5.6, source-map-support@~0.5.20:
     buffer-from "^1.0.0"
     source-map "^0.6.0"
 
-source-map@0.5.6:
-  version "0.5.6"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
-  integrity sha1-dc449SvwczxafwwRjYEzSiu19BI=
-
 source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
@@ -12058,18 +12961,6 @@ stable@^0.1.8:
   resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
   integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
 
-stack-chain@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-2.0.0.tgz#d73d1172af89565f07438b5bcc086831b6689b2d"
-  integrity sha512-GGrHXePi305aW7XQweYZZwiRwR7Js3MWoK/EHzzB9ROdc75nCnjSJVi21rdAGxFl+yCx2L2qdfl5y7NO4lTyqg==
-
-stack-generator@^2.0.5:
-  version "2.0.5"
-  resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36"
-  integrity sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q==
-  dependencies:
-    stackframe "^1.1.1"
-
 stack-utils@^2.0.3:
   version "2.0.5"
   resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5"
@@ -12082,23 +12973,6 @@ stackframe@^1.1.1:
   resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303"
   integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==
 
-stacktrace-gps@^3.0.4:
-  version "3.0.4"
-  resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz#7688dc2fc09ffb3a13165ebe0dbcaf41bcf0c69a"
-  integrity sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg==
-  dependencies:
-    source-map "0.5.6"
-    stackframe "^1.1.1"
-
-stacktrace-js@^2.0.0:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.2.tgz#4ca93ea9f494752d55709a081d400fdaebee897b"
-  integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==
-  dependencies:
-    error-stack-parser "^2.0.6"
-    stack-generator "^2.0.5"
-    stacktrace-gps "^3.0.4"
-
 "statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0:
   version "1.5.0"
   resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
@@ -12130,7 +13004,7 @@ stream-browserify@^3.0.0:
 stream-combiner2@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/stream-combiner2/-/stream-combiner2-1.1.1.tgz#fb4d8a1420ea362764e21ad4780397bebcb41cbe"
-  integrity sha1-+02KFCDqNidk4hrUeAOXvry0HL4=
+  integrity sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==
   dependencies:
     duplexer2 "~0.1.0"
     readable-stream "^2.0.2"
@@ -12153,11 +13027,6 @@ stream-splicer@^2.0.0:
     inherits "^2.0.1"
     readable-stream "^2.0.2"
 
-string-argv@0.0.2:
-  version "0.0.2"
-  resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736"
-  integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY=
-
 string-length@^4.0.1:
   version "4.0.2"
   resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"
@@ -12228,6 +13097,15 @@ string.prototype.trimend@^1.0.4:
     call-bind "^1.0.2"
     define-properties "^1.1.3"
 
+string.prototype.trimend@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0"
+  integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==
+  dependencies:
+    call-bind "^1.0.2"
+    define-properties "^1.1.4"
+    es-abstract "^1.19.5"
+
 string.prototype.trimstart@^1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed"
@@ -12236,6 +13114,15 @@ string.prototype.trimstart@^1.0.4:
     call-bind "^1.0.2"
     define-properties "^1.1.3"
 
+string.prototype.trimstart@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef"
+  integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==
+  dependencies:
+    call-bind "^1.0.2"
+    define-properties "^1.1.4"
+    es-abstract "^1.19.5"
+
 string_decoder@^1.1.1:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
@@ -12333,7 +13220,7 @@ stylehacks@^5.1.0:
 subarg@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2"
-  integrity sha1-9izxdYHplrSPyWVpn1TAauJouNI=
+  integrity sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==
   dependencies:
     minimist "^1.1.0"
 
@@ -12537,20 +13424,6 @@ text-table@^0.2.0:
   resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
   integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
 
-thenify-all@^1.0.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
-  integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=
-  dependencies:
-    thenify ">= 3.1.0 < 4"
-
-"thenify@>= 3.1.0 < 4":
-  version "3.3.1"
-  resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f"
-  integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
-  dependencies:
-    any-promise "^1.0.0"
-
 throat@^6.0.1:
   version "6.0.1"
   resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375"
@@ -12589,7 +13462,7 @@ thunky@^1.0.2:
 timers-browserify@^1.0.1:
   version "1.4.2"
   resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d"
-  integrity sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=
+  integrity sha512-PIxwAupJZiYU4JmVZYwXp9FKsHMXb5h0ZEFyuXTAn8WLHOlcij+FEcbrvDsom1o5dr1YggEtFbECvGCW2sT53Q==
   dependencies:
     process "~0.11.0"
 
@@ -12617,14 +13490,6 @@ tippy.js@5.1.2:
   dependencies:
     popper.js "^1.16.0"
 
-title-case@^2.1.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa"
-  integrity sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=
-  dependencies:
-    no-case "^2.2.0"
-    upper-case "^1.0.3"
-
 tmp@~0.2.1:
   version "0.2.1"
   resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
@@ -12765,7 +13630,7 @@ type-check@~0.3.2:
   dependencies:
     prelude-ls "~1.1.2"
 
-type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5:
+type-detect@4.0.8:
   version "4.0.8"
   resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
   integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
@@ -12808,16 +13673,6 @@ type-is@~1.6.18:
     media-typer "0.3.0"
     mime-types "~2.1.24"
 
-type@^1.0.1:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
-  integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
-
-type@^2.0.0:
-  version "2.5.0"
-  resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d"
-  integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==
-
 typed-styles@^0.0.7:
   version "0.0.7"
   resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9"
@@ -12833,7 +13688,7 @@ typedarray-to-buffer@^3.1.5:
 typedarray@^0.0.6:
   version "0.0.6"
   resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
-  integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
+  integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
 
 typesafe-actions@3.2.1:
   version "3.2.1"
@@ -12868,6 +13723,16 @@ unbox-primitive@^1.0.1:
     has-symbols "^1.0.2"
     which-boxed-primitive "^1.0.2"
 
+unbox-primitive@^1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
+  integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==
+  dependencies:
+    call-bind "^1.0.2"
+    has-bigints "^1.0.2"
+    has-symbols "^1.0.3"
+    which-boxed-primitive "^1.0.2"
+
 undeclared-identifiers@^1.1.2:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz#9254c1d37bdac0ac2b52de4b6722792d2a91e30f"
@@ -12976,10 +13841,13 @@ upath@^1.2.0:
   resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
   integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
 
-upper-case@^1.0.3:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
-  integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=
+update-browserslist-db@^1.0.5:
+  version "1.0.9"
+  resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz#2924d3927367a38d5c555413a7ce138fc95fcb18"
+  integrity sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==
+  dependencies:
+    escalade "^3.1.1"
+    picocolors "^1.0.0"
 
 uri-js@^4.2.2:
   version "4.4.1"
@@ -12988,19 +13856,14 @@ uri-js@^4.2.2:
   dependencies:
     punycode "^2.1.0"
 
-url@^0.11.0, url@~0.11.0:
+url@~0.11.0:
   version "0.11.0"
   resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
-  integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=
+  integrity sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==
   dependencies:
     punycode "1.3.2"
     querystring "0.2.0"
 
-util-arity@^1.0.2:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/util-arity/-/util-arity-1.1.0.tgz#59d01af1fdb3fede0ac4e632b0ab5f6ce97c9330"
-  integrity sha1-WdAa8f2z/t4KxOYysKtfbOl8kzA=
-
 util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
@@ -13019,7 +13882,7 @@ util.promisify@~1.0.0:
 util@0.10.3:
   version "0.10.3"
   resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
-  integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk=
+  integrity sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==
   dependencies:
     inherits "2.0.1"
 
@@ -13052,16 +13915,16 @@ utils-merge@1.0.1:
   resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
   integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
 
+uuid@8.3.2, uuid@^8.3.2:
+  version "8.3.2"
+  resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
+  integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
+
 uuid@^3.3.2:
   version "3.4.0"
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
   integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
 
-uuid@^8.3.2:
-  version "8.3.2"
-  resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
-  integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
-
 v8-compile-cache@^2.0.3:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
@@ -13103,15 +13966,6 @@ verror@1.10.0:
     core-util-is "1.0.2"
     extsprintf "^1.2.0"
 
-verror@^1.9.0:
-  version "1.10.1"
-  resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.1.tgz#4bf09eeccf4563b109ed4b3d458380c972b0cdeb"
-  integrity sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==
-  dependencies:
-    assert-plus "^1.0.0"
-    core-util-is "1.0.2"
-    extsprintf "^1.2.0"
-
 victory-area@^36.2.1, victory-area@^36.3.0:
   version "36.3.0"
   resolved "https://registry.yarnpkg.com/victory-area/-/victory-area-36.3.0.tgz#676aa3c96a5d7ac199fcaad8565310fbd6bdfd2f"
@@ -13669,16 +14523,16 @@ which-boxed-primitive@^1.0.2:
     is-symbol "^1.0.3"
 
 which-typed-array@^1.1.2:
-  version "1.1.7"
-  resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.7.tgz#2761799b9a22d4b8660b3c1b40abaa7739691793"
-  integrity sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==
+  version "1.1.8"
+  resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.8.tgz#0cfd53401a6f334d90ed1125754a42ed663eb01f"
+  integrity sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==
   dependencies:
     available-typed-arrays "^1.0.5"
     call-bind "^1.0.2"
-    es-abstract "^1.18.5"
-    foreach "^2.0.5"
+    es-abstract "^1.20.0"
+    for-each "^0.3.3"
     has-tostringtag "^1.0.0"
-    is-typed-array "^1.1.7"
+    is-typed-array "^1.1.9"
 
 which@^1.2.9, which@^1.3.1:
   version "1.3.1"
diff --git a/hack/istio/install-istio-via-istioctl.sh b/hack/istio/install-istio-via-istioctl.sh
index 8969815a2..45c875709 100755
--- a/hack/istio/install-istio-via-istioctl.sh
+++ b/hack/istio/install-istio-via-istioctl.sh
@@ -16,7 +16,7 @@
 # CLIENT_EXE_NAME must be either "oc" or "kubectl"
 ADDONS="prometheus grafana jaeger"
 CLIENT_EXE_NAME="oc"
-CLUSTER_NAME="cluster-default"
+CLUSTER_NAME=""
 CONFIG_PROFILE="" # see "istioctl profile list" for valid values. See: https://istio.io/docs/setup/additional-setup/config-profiles/
 DELETE_ISTIO="false"
 PURGE_UNINSTALL="true"
@@ -25,10 +25,10 @@ ISTIO_DIR=
 ISTIO_EGRESSGATEWAY_ENABLED="true"
 ISTIO_INGRESSGATEWAY_ENABLED="true"
 ISTIO_VERSION=""
-MESH_ID="mesh-default"
+MESH_ID=""
 MTLS="true"
 NAMESPACE="istio-system"
-NETWORK="network-default"
+NETWORK=""
 REDUCE_RESOURCES="false"
 IMAGE_HUB="gcr.io/istio-release"
 IMAGE_TAG="default"
@@ -163,7 +163,7 @@ Valid command line arguments:
        This value overrides any other value set with --client-exe
   -cn|--cluster-name <cluster name>:
        Installs istio as part of cluster with the given name.
-       Default: cluster-default
+       Default: unset (use Istio default of "Kubernetes")
   -cp|--config-profile <profile name>:
        Installs Istio with the given profile.
        Run "istioctl profile list" to see the valid list of configuration profiles available.
@@ -205,13 +205,13 @@ Valid command line arguments:
        Default: true
   -mid|--mesh-id <mesh ID>:
        Installs istio as part of mesh with the given name.
-       Default: mesh-default
+       Default: unset
   -n|--namespace <name>:
        Install Istio in this namespace.
        Default: istio-system
   -net|--network <network>:
        Installs istio as part of network with the given name.
-       Default: network-default
+       Default: unset
   -rr|--reduce-resources (true|false):
        When true some Istio components (such as the sidecar proxies) will be given
        a smaller amount of resources (CPU and memory) which will allow you
diff --git a/hack/setup-kind-in-ci.sh b/hack/setup-kind-in-ci.sh
index 10f55f013..17cb40293 100755
--- a/hack/setup-kind-in-ci.sh
+++ b/hack/setup-kind-in-ci.sh
@@ -51,14 +51,10 @@ if [ "${TARGET_BRANCH}" == "v1.48" ]; then
   ISTIO_VERSION="1.13.0"
 elif [ "${TARGET_BRANCH}" == "v1.36" ]; then
   ISTIO_VERSION="1.10.0"
-elif [ "${TARGET_BRANCH}" == "v1.24" ]; then
-  ISTIO_VERSION="1.7.0"
 fi
 
 KIND_NODE_IMAGE=""
-if [ "${ISTIO_VERSION}" == "1.7.0" ]; then
-  KIND_NODE_IMAGE="kindest/node:v1.18.20@sha256:e3dca5e16116d11363e31639640042a9b1bd2c90f85717a7fc66be34089a8169"
-elif [ "${ISTIO_VERSION}" == "1.10.0" ]; then
+if [ "${ISTIO_VERSION}" == "1.10.0" ]; then
   KIND_NODE_IMAGE="kindest/node:v1.21.10@sha256:84709f09756ba4f863769bdcabe5edafc2ada72d3c8c44d6515fc581b66b029c"
 elif [ "${ISTIO_VERSION}" == "1.13.0" ]; then
   KIND_NODE_IMAGE="kindest/node:v1.23.4@sha256:0e34f0d0fd448aa2f2819cfd74e99fe5793a6e4938b328f657c8e3f81ee0dfb9"
@@ -101,26 +97,12 @@ EOF
 infomsg "Create Kind LoadBalancer via MetalLB"
 lb_addr_range="255.70-255.84"
 
-kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
-kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml
+kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.5/config/manifests/metallb-native.yaml
 
 subnet=$(${DORP} network inspect kind --format '{{(index .IPAM.Config 0).Subnet}}')
 subnet_trimmed=$(echo "${subnet}" | sed -E 's/([0-9]+\.[0-9]+)\.[0-9]+\..*/\1/')
 first_ip="${subnet_trimmed}.$(echo "${lb_addr_range}" | cut -d '-' -f 1)"
 last_ip="${subnet_trimmed}.$(echo "${lb_addr_range}" | cut -d '-' -f 2)"
-cat <<LBCONFIGMAP | kubectl apply -f -
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  namespace: metallb-system
-  name: config
-data:
-  config: |
-    address-pools:
-    - name: default
-      protocol: layer2
-      addresses: ['${first_ip}-${last_ip}']
-LBCONFIGMAP
 
 if [ -n "${ISTIO_VERSION}" ]; then
   DOWNLOAD_ISTIO_VERSION_ARG="--istio-version ${ISTIO_VERSION}"
@@ -129,6 +111,30 @@ fi
 infomsg "Downloading istio"
 hack/istio/download-istio.sh ${DOWNLOAD_ISTIO_VERSION_ARG}
 
+kubectl rollout status deployment controller -n metallb-system
+
+cat <<LBCONFIGMAP | kubectl apply -f -
+apiVersion: metallb.io/v1beta1
+kind: IPAddressPool
+metadata:
+  namespace: metallb-system
+  name: config
+spec:
+  addresses:
+  - ${first_ip}-${last_ip}
+LBCONFIGMAP
+
+cat <<LBCONFIGMAP | kubectl apply -f -
+apiVersion: metallb.io/v1beta1
+kind: L2Advertisement
+metadata:
+  namespace: metallb-system
+  name: l2config
+spec:
+  ipAddressPools:
+  - config
+LBCONFIGMAP
+
 infomsg "Installing istio"
 # Apparently you can't set the requests to zero for the proxy so just setting them to some really low number.
 hack/istio/install-istio-via-istioctl.sh --reduce-resources true --client-exe-path "$(which kubectl)"
@@ -155,6 +161,12 @@ helm install \
   --set external_services.grafana.url="http://grafana.istio-system:3000" \
   --set external_services.grafana.dashboards[0].name="Istio Mesh Dashboard" \
   --set external_services.tracing.url="http://tracing.istio-system:16685/jaeger" \
+  --set health_config.rate[0].kind="service" \
+  --set health_config.rate[0].name="y-server" \
+  --set health_config.rate[0].namespace="alpha" \
+  --set health_config.rate[0].tolerance[0].code="5xx" \
+  --set health_config.rate[0].tolerance[0].degraded=2 \
+  --set health_config.rate[0].tolerance[0].failure=100 \
   kiali-server \
   helm-charts/_output/charts/kiali-server-*-SNAPSHOT.tgz
 
@@ -195,3 +207,6 @@ if [ "${TIMEOUT}" == "True" ]; then
 fi
 
 infomsg "Kiali is ready."
+
+
+
diff --git a/kubernetes/cache/cache.go b/kubernetes/cache/cache.go
index f6924ffe3..639a0c241 100644
--- a/kubernetes/cache/cache.go
+++ b/kubernetes/cache/cache.go
@@ -6,11 +6,16 @@ import (
 	"sync"
 	"time"
 
+	istio "istio.io/client-go/pkg/clientset/versioned"
+	istioext_v1alpha1_listers "istio.io/client-go/pkg/listers/extensions/v1alpha1"
+	istionet_v1alpha3_listers "istio.io/client-go/pkg/listers/networking/v1alpha3"
+	istionet_v1beta1_listers "istio.io/client-go/pkg/listers/networking/v1beta1"
+	istiosec_v1beta1_listers "istio.io/client-go/pkg/listers/security/v1beta1"
+	istiotelem_v1alpha1_listers "istio.io/client-go/pkg/listers/telemetry/v1alpha1"
 	kube "k8s.io/client-go/kubernetes"
+	apps_v1_listers "k8s.io/client-go/listers/apps/v1"
+	core_v1_listers "k8s.io/client-go/listers/core/v1"
 	"k8s.io/client-go/rest"
-	"k8s.io/client-go/tools/cache"
-
-	istio "istio.io/client-go/pkg/clientset/versioned"
 
 	kialiConfig "github.com/kiali/kiali/config"
 	"github.com/kiali/kiali/kubernetes"
@@ -28,8 +33,10 @@ type (
 		// Check if a namespace is listed to be cached; if yes, creates a cache for that namespace
 		CheckNamespace(namespace string) bool
 
-		// Clear a namespace's cache
-		RefreshNamespace(namespace string)
+		// Refresh will recreate the necessary cache. If the cache is cluster-scoped the "namespace" argument
+		// is ignored and the whole cache is recreated, otherwise only the namespace-specific cache is updated.
+		Refresh(namespace string)
+
 		// Stop all caches
 		Stop()
 
@@ -43,10 +50,6 @@ type (
 		RegistryStatusCache
 	}
 
-	// This map will store Informers per specific types
-	// i.e. map["Deployment"], map["Service"]
-	typeCache map[string]cache.SharedIndexInformer
-
 	namespaceCache struct {
 		created       time.Time
 		namespaces    []models.Namespace
@@ -59,15 +62,46 @@ type (
 		proxyStatus *kubernetes.ProxyStatus
 	}
 
+	// cacheLister combines a bunch of lister types into one.
+	// This can probably be simplified or turned into an interface
+	// with go generics.
+	cacheLister struct {
+		// Kube listers
+		configMapLister   core_v1_listers.ConfigMapLister
+		daemonSetLister   apps_v1_listers.DaemonSetLister
+		deploymentLister  apps_v1_listers.DeploymentLister
+		endpointLister    core_v1_listers.EndpointsLister
+		podLister         core_v1_listers.PodLister
+		replicaSetLister  apps_v1_listers.ReplicaSetLister
+		serviceLister     core_v1_listers.ServiceLister
+		statefulSetLister apps_v1_listers.StatefulSetLister
+
+		// Istio listers
+		authzLister           istiosec_v1beta1_listers.AuthorizationPolicyLister
+		destinationRuleLister istionet_v1beta1_listers.DestinationRuleLister
+		envoyFilterLister     istionet_v1alpha3_listers.EnvoyFilterLister
+		gatewayLister         istionet_v1beta1_listers.GatewayLister
+		peerAuthnLister       istiosec_v1beta1_listers.PeerAuthenticationLister
+		requestAuthnLister    istiosec_v1beta1_listers.RequestAuthenticationLister
+		serviceEntryLister    istionet_v1beta1_listers.ServiceEntryLister
+		sidecarLister         istionet_v1beta1_listers.SidecarLister
+		telemetryLister       istiotelem_v1alpha1_listers.TelemetryLister
+		virtualServiceLister  istionet_v1beta1_listers.VirtualServiceLister
+		wasmPluginLister      istioext_v1alpha1_listers.WasmPluginLister
+		workloadEntryLister   istionet_v1beta1_listers.WorkloadEntryLister
+		workloadGroupLister   istionet_v1beta1_listers.WorkloadGroupLister
+	}
+
 	kialiCacheImpl struct {
+		clusterScoped          bool // Creates either cluster-scoped or namespace-scoped informers
 		istioClient            kubernetes.K8SClient
 		k8sApi                 kube.Interface
 		istioApi               istio.Interface
 		refreshDuration        time.Duration
 		cacheNamespacesRegexps []regexp.Regexp
 		cacheIstioTypes        map[string]bool
-		stopChan               map[string]chan struct{}
-		nsCache                map[string]typeCache
+		stopNSChans            map[string]chan struct{}
+		stopClusterScopedChan  chan struct{} // Close this channel to stop the cluster-scoped informers.
 		cacheLock              sync.RWMutex
 		tokenLock              sync.RWMutex
 		tokenNamespaces        map[string]namespaceCache
@@ -79,11 +113,16 @@ type (
 		registryStatusLock     sync.RWMutex
 		registryStatusCreated  *time.Time
 		registryStatus         *kubernetes.RegistryStatus
-		stopCacheChan          chan bool
+		// Stops the background goroutine which refreshes the cache's
+		// service account token.
+		stopCacheChan chan bool
+
+		clusterCacheLister *cacheLister
+		nsCacheLister      map[string]*cacheLister
 	}
 )
 
-func NewKialiCache() (KialiCache, error) {
+func NewKialiCache(namespaceSeedList ...string) (KialiCache, error) {
 	config, err := kubernetes.ConfigClient()
 	if err != nil {
 		return nil, err
@@ -103,6 +142,7 @@ func NewKialiCache() (KialiCache, error) {
 			cacheToken = saToken
 		}
 	}
+
 	istioConfig := rest.Config{
 		Host:            config.Host,
 		TLSClientConfig: config.TLSClientConfig,
@@ -125,12 +165,6 @@ func NewKialiCache() (KialiCache, error) {
 	}
 	log.Tracef("[Kiali Cache] cacheIstioTypes %v", cacheIstioTypes)
 
-	stopChan := make(map[string]chan struct{})
-
-	for _, ns := range cacheNamespaces {
-		stopChan[ns] = make(chan struct{})
-	}
-
 	cacheNamespacesRegexps := make([]regexp.Regexp, len(cacheNamespaces))
 	for i, ns := range cacheNamespaces {
 		cacheNamespacesRegexps[i] = *regexp.MustCompile(strings.TrimSpace(ns))
@@ -141,18 +175,34 @@ func NewKialiCache() (KialiCache, error) {
 		refreshDuration:        refreshDuration,
 		cacheNamespacesRegexps: cacheNamespacesRegexps,
 		cacheIstioTypes:        cacheIstioTypes,
-		stopChan:               stopChan,
-		nsCache:                make(map[string]typeCache),
+		// Only when all namespaces are accessible should the cache be cluster scoped.
+		// Otherwise, kiali may not have access to all namespaces since
+		// the operator only grants clusterroles when all namespaces are accessible.
+		clusterScoped:          kConfig.AllNamespacesAccessible(),
 		tokenNamespaces:        make(map[string]namespaceCache),
 		tokenNamespaceDuration: tokenNamespaceDuration,
 		proxyStatusNamespaces:  make(map[string]map[string]podProxyStatus),
 	}
-
 	kialiCacheImpl.k8sApi = istioClient.GetK8sApi()
 	kialiCacheImpl.istioApi = istioClient.Istio()
 
 	// Update SA Token
 	kialiCacheImpl.stopCacheChan = kialiCacheImpl.refreshCache(istioConfig)
+	kialiCacheImpl.registryRefreshHandler = NewRegistryHandler(kialiCacheImpl.RefreshRegistryStatus)
+
+	if kialiCacheImpl.clusterScoped {
+		log.Debug("[Kiali Cache] Using 'cluster' scoped Kiali Cache")
+		kialiCacheImpl.createClusterScopedCache()
+	} else {
+		log.Debug("[Kiali Cache] Using 'namespace' scoped Kiali Cache")
+		kialiCacheImpl.nsCacheLister = make(map[string]*cacheLister)
+		kialiCacheImpl.stopNSChans = make(map[string]chan struct{})
+
+		for _, ns := range namespaceSeedList {
+			kialiCacheImpl.CheckNamespace(ns)
+		}
+	}
+
 	log.Infof("Kiali Cache is active for namespaces %v", cacheNamespaces)
 	return &kialiCacheImpl, nil
 }
@@ -167,42 +217,60 @@ func (c *kialiCacheImpl) isCached(namespace string) bool {
 	return false
 }
 
-func (c *kialiCacheImpl) createCache(namespace string) bool {
-	if _, exist := c.nsCache[namespace]; exist {
-		return true
-	}
-	informer := make(typeCache)
-	c.registryRefreshHandler = NewRegistryHandler(c, namespace)
-	c.createKubernetesInformers(namespace, &informer)
-	c.createIstioInformers(namespace, &informer)
-	c.nsCache[namespace] = informer
-
-	if _, exist := c.stopChan[namespace]; !exist {
-		c.stopChan[namespace] = make(chan struct{})
+func (c *kialiCacheImpl) createNSCache(namespace string) bool {
+	kubeInformerFactory := c.createKubernetesInformers(namespace)
+	istioInformerFactory := c.createIstioInformers(namespace)
+
+	if _, exist := c.stopNSChans[namespace]; !exist {
+		c.stopNSChans[namespace] = make(chan struct{})
 	}
 
-	go func(stopCh <-chan struct{}) {
-		for _, informer := range c.nsCache[namespace] {
-			go informer.Run(stopCh)
+	kubeInformerFactory.Start(c.stopNSChans[namespace])
+	istioInformerFactory.Start(c.stopNSChans[namespace])
+
+	log.Infof("[Kiali Cache] waiting for [namespace: %s] cache to sync", namespace)
+
+	for _, synced := range kubeInformerFactory.WaitForCacheSync(c.stopNSChans[namespace]) {
+		if !synced {
+			log.Errorf("[Kiali Cache] failed to sync [namespace: %s] kube cache", namespace)
+			return false
 		}
-		<-stopCh
-		log.Infof("Kiali cache for [namespace: %s] stopped", namespace)
-	}(c.stopChan[namespace])
-
-	log.Infof("Waiting for Kiali cache for [namespace: %s] to sync", namespace)
-	isSynced := func() bool {
-		hasSynced := true
-		for _, informer := range c.nsCache[namespace] {
-			hasSynced = hasSynced && informer.HasSynced()
+	}
+	for _, synced := range istioInformerFactory.WaitForCacheSync(c.stopNSChans[namespace]) {
+		if !synced {
+			log.Errorf("[Kiali Cache] failed to sync [namespace: %s] Istio cache", namespace)
+			return false
 		}
-		return hasSynced
 	}
-	if synced := cache.WaitForCacheSync(c.stopChan[namespace], isSynced); !synced {
-		c.stopChan[namespace] <- struct{}{}
-		log.Errorf("Kiali cache for [namespace: %s] sync failure", namespace)
-		return false
+
+	log.Infof("[Kiali Cache] started [namespace: %s] cache", namespace)
+
+	return true
+}
+
+func (c *kialiCacheImpl) createClusterScopedCache() bool {
+	kubeInformerFactory := c.createKubernetesInformers("")
+	istioInformerFactory := c.createIstioInformers("")
+
+	c.stopClusterScopedChan = make(chan struct{})
+	kubeInformerFactory.Start(c.stopClusterScopedChan)
+	istioInformerFactory.Start(c.stopClusterScopedChan)
+
+	log.Info("[Kiali Cache] Waiting for cluster-scoped cache to sync")
+	for _, synced := range kubeInformerFactory.WaitForCacheSync(c.stopClusterScopedChan) {
+		if !synced {
+			log.Error("[Kiali Cache] failed to sync kube cluster-scoped cache")
+			return false
+		}
+	}
+	for _, synced := range istioInformerFactory.WaitForCacheSync(c.stopClusterScopedChan) {
+		if !synced {
+			log.Error("[Kiali Cache] failed to sync Istio cluster-scoped cache")
+			return false
+		}
 	}
-	log.Infof("Kiali cache for [namespace: %s] started", namespace)
+
+	log.Info("[Kiali Cache] started")
 
 	return true
 }
@@ -210,37 +278,44 @@ func (c *kialiCacheImpl) createCache(namespace string) bool {
 // CheckNamespace will
 // - Validate if a namespace is included in the cache
 // - Create and initialize a cache
-// - Validate if a cache is synced
 func (c *kialiCacheImpl) CheckNamespace(namespace string) bool {
-	if !c.isCached(namespace) {
+	if c.clusterScoped {
+		return true
+	} else if !c.isCached(namespace) {
 		return false
 	}
 
 	c.cacheLock.RLock()
-	_, isNsCached := c.nsCache[namespace]
+	_, isNsCached := c.nsCacheLister[namespace]
 	c.cacheLock.RUnlock()
 
 	if !isNsCached {
 		defer c.cacheLock.Unlock()
 		c.cacheLock.Lock()
-		return c.createCache(namespace)
+		return c.createNSCache(namespace)
 	}
-	return c.isKubernetesSynced(namespace) && c.isIstioSynced(namespace)
+
+	return true
 }
 
-// RefreshNamespace will delete the specific namespace's cache and create a new one.
-func (c *kialiCacheImpl) RefreshNamespace(namespace string) {
+// Refresh will recreate the necessary cache. If the cache is cluster-scoped the "namespace" argument
+// is ignored and the whole cache is recreated, otherwise only the namespace-specific cache is updated.
+func (c *kialiCacheImpl) Refresh(namespace string) {
 	defer c.cacheLock.Unlock()
 	c.cacheLock.Lock()
-	if nsChan, exist := c.stopChan[namespace]; exist {
-		close(nsChan)
-		delete(c.stopChan, namespace)
+
+	if c.clusterScoped {
+		c.stop("")
+		c.createClusterScopedCache()
+		return
 	}
-	delete(c.nsCache, namespace)
-	c.createCache(namespace)
+
+	c.stop(namespace)
+	c.createNSCache(namespace)
 }
 
-// RefreshNamespace will delete the specific namespace's cache and create a new one.
+// refreshCache watches for changes to the cache's service account token
+// and recreates the cache(s) when the token changes.
 func (c *kialiCacheImpl) refreshCache(istioConfig rest.Config) chan bool {
 	ticker := time.NewTicker(60 * time.Second)
 	quit := make(chan bool)
@@ -264,8 +339,14 @@ func (c *kialiCacheImpl) refreshCache(istioConfig rest.Config) chan bool {
 							c.istioClient = *istioClient
 							c.k8sApi = istioClient.GetK8sApi()
 							c.istioApi = istioClient.Istio()
-							for ns := range c.nsCache {
-								c.RefreshNamespace(ns)
+							if c.clusterScoped {
+								c.Refresh("")
+							} else {
+								// Need to recreate all the namespace scoped caches
+								// with the new token when it changes.
+								for ns := range c.stopNSChans {
+									c.Refresh(ns)
+								}
 							}
 						}
 
@@ -283,19 +364,31 @@ func (c *kialiCacheImpl) refreshCache(istioConfig rest.Config) chan bool {
 	return quit
 }
 
+// Stop will stop either the cluster wide cache or all of the namespace caches.
 func (c *kialiCacheImpl) Stop() {
 	log.Infof("Stopping Kiali Cache")
 	defer c.cacheLock.Unlock()
 	c.cacheLock.Lock()
-	for namespace, nsChan := range c.stopChan {
-		close(nsChan)
-		delete(c.stopChan, namespace)
+	if c.clusterScoped {
+		c.stop("")
+	} else {
+		for namespace := range c.stopNSChans {
+			c.stop(namespace)
+		}
 	}
-	log.Infof("Clearing Kiali Cache")
-	for ns := range c.nsCache {
-		delete(c.nsCache, ns)
+	close(c.stopCacheChan)
+}
+
+func (c *kialiCacheImpl) stop(namespace string) {
+	if c.clusterScoped {
+		close(c.stopClusterScopedChan)
+	} else {
+		if nsChan, exist := c.stopNSChans[namespace]; exist {
+			close(nsChan)
+			delete(c.stopNSChans, namespace)
+			delete(c.nsCacheLister, namespace)
+		}
 	}
-	c.stopCacheChan <- true
 }
 
 func (c *kialiCacheImpl) GetClient() *kubernetes.K8SClient {
diff --git a/kubernetes/cache/cache_handlers.go b/kubernetes/cache/cache_handlers.go
index 2595abe99..1d62fb428 100644
--- a/kubernetes/cache/cache_handlers.go
+++ b/kubernetes/cache/cache_handlers.go
@@ -1,149 +1,46 @@
 package cache
 
 import (
-	"reflect"
-	"strings"
+	"k8s.io/apimachinery/pkg/api/meta"
+	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	networking_v1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3"
-	networking_v1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
-	security_v1beta1 "istio.io/client-go/pkg/apis/security/v1beta1"
-	core_v1 "k8s.io/api/core/v1"
-	"k8s.io/client-go/tools/cache"
-
-	"github.com/kiali/kiali/kubernetes"
 	"github.com/kiali/kiali/log"
 )
 
 type RegistryRefreshHandler struct {
-	Cache     KialiCache
-	Namespace string
-	cache.ResourceEventHandler
+	refresh func()
 }
 
-func NewRegistryHandler(cache KialiCache, namespace string) RegistryRefreshHandler {
-	log.Infof("Adding a RegistryRefreshHandler for [%s]", namespace)
-	return RegistryRefreshHandler{Cache: cache, Namespace: namespace}
+func NewRegistryHandler(refresh func()) RegistryRefreshHandler {
+	log.Infof("Adding a RegistryRefreshHandler")
+	return RegistryRefreshHandler{refresh: refresh}
 }
 
 func (sh RegistryRefreshHandler) OnAdd(obj interface{}) {
-	sh.Cache.RefreshRegistryStatus()
+	sh.refresh()
 }
 
 func (sh RegistryRefreshHandler) OnUpdate(oldObj, newObj interface{}) {
-	resourceVersion1, resourceVersion2 := sh.parseResourceVersion(oldObj, newObj)
-	if resourceVersion1 != resourceVersion2 {
-		sh.Cache.RefreshRegistryStatus()
+	var (
+		oldMeta v1.Object
+		newMeta v1.Object
+		err     error
+	)
+
+	if oldMeta, err = meta.Accessor(oldObj); err != nil {
+		log.Errorf("oldObj is not a valid kube object. Err: %s", err)
+		return
+	}
+	if newMeta, err = meta.Accessor(newObj); err != nil {
+		log.Errorf("newObj is not a valid kube object. Err: %s", err)
+		return
 	}
-}
 
-func (sh RegistryRefreshHandler) OnDelete(obj interface{}) {
-	sh.Cache.RefreshRegistryStatus()
+	if oldMeta.GetResourceVersion() != newMeta.GetResourceVersion() {
+		sh.refresh()
+	}
 }
 
-func (sh RegistryRefreshHandler) parseResourceVersion(oldObj, newObj interface{}) (string, string) {
-	oldResourceVersion := ""
-	newResourceVersion := ""
-	if oldObj == nil {
-		return oldResourceVersion, newResourceVersion
-	}
-	oldType := reflect.TypeOf(oldObj).String()
-	resourceType := ""
-	split := strings.Split(oldType, ".")
-	if len(split) == 2 {
-		resourceType = split[1]
-	}
-	switch resourceType {
-	case kubernetes.ServiceType:
-		oldConv, ok1 := oldObj.(*core_v1.Service)
-		newConv, ok2 := newObj.(*core_v1.Service)
-		if ok1 && ok2 {
-			oldResourceVersion = oldConv.ResourceVersion
-			newResourceVersion = newConv.ResourceVersion
-		}
-	case kubernetes.EndpointsType:
-		oldConv, ok1 := oldObj.(*core_v1.Endpoints)
-		newConv, ok2 := newObj.(*core_v1.Endpoints)
-		if ok1 && ok2 {
-			oldResourceVersion = oldConv.ResourceVersion
-			newResourceVersion = newConv.ResourceVersion
-		}
-	case kubernetes.DestinationRuleType:
-		oldConv, ok1 := oldObj.(*networking_v1beta1.DestinationRule)
-		newConv, ok2 := newObj.(*networking_v1beta1.DestinationRule)
-		if ok1 && ok2 {
-			oldResourceVersion = oldConv.ResourceVersion
-			newResourceVersion = newConv.ResourceVersion
-		}
-	case kubernetes.EnvoyFilterType:
-		oldConv, ok1 := oldObj.(*networking_v1alpha3.EnvoyFilter)
-		newConv, ok2 := newObj.(*networking_v1alpha3.EnvoyFilter)
-		if ok1 && ok2 {
-			oldResourceVersion = oldConv.ResourceVersion
-			newResourceVersion = newConv.ResourceVersion
-		}
-	case kubernetes.GatewayType:
-		oldConv, ok1 := oldObj.(*networking_v1beta1.Gateway)
-		newConv, ok2 := newObj.(*networking_v1beta1.Gateway)
-		if ok1 && ok2 {
-			oldResourceVersion = oldConv.ResourceVersion
-			newResourceVersion = newConv.ResourceVersion
-		}
-	case kubernetes.ServiceEntryType:
-		oldConv, ok1 := oldObj.(*networking_v1beta1.ServiceEntry)
-		newConv, ok2 := newObj.(*networking_v1beta1.ServiceEntry)
-		if ok1 && ok2 {
-			oldResourceVersion = oldConv.ResourceVersion
-			newResourceVersion = newConv.ResourceVersion
-		}
-	case kubernetes.Sidecars:
-		oldConv, ok1 := oldObj.(*networking_v1beta1.Sidecar)
-		newConv, ok2 := newObj.(*networking_v1beta1.Sidecar)
-		if ok1 && ok2 {
-			oldResourceVersion = oldConv.ResourceVersion
-			newResourceVersion = newConv.ResourceVersion
-		}
-	case kubernetes.VirtualServiceType:
-		oldConv, ok1 := oldObj.(*networking_v1beta1.VirtualService)
-		newConv, ok2 := newObj.(*networking_v1beta1.VirtualService)
-		if ok1 && ok2 {
-			oldResourceVersion = oldConv.ResourceVersion
-			newResourceVersion = newConv.ResourceVersion
-		}
-	case kubernetes.WorkloadEntryType:
-		oldConv, ok1 := oldObj.(*networking_v1beta1.WorkloadEntry)
-		newConv, ok2 := newObj.(*networking_v1beta1.WorkloadEntry)
-		if ok1 && ok2 {
-			oldResourceVersion = oldConv.ResourceVersion
-			newResourceVersion = newConv.ResourceVersion
-		}
-	case kubernetes.WorkloadGroupType:
-		oldConv, ok1 := oldObj.(*networking_v1beta1.WorkloadGroup)
-		newConv, ok2 := newObj.(*networking_v1beta1.WorkloadGroup)
-		if ok1 && ok2 {
-			oldResourceVersion = oldConv.ResourceVersion
-			newResourceVersion = newConv.ResourceVersion
-		}
-	case kubernetes.AuthorizationPoliciesType:
-		oldConv, ok1 := oldObj.(*security_v1beta1.AuthorizationPolicy)
-		newConv, ok2 := newObj.(*security_v1beta1.AuthorizationPolicy)
-		if ok1 && ok2 {
-			oldResourceVersion = oldConv.ResourceVersion
-			newResourceVersion = newConv.ResourceVersion
-		}
-	case kubernetes.PeerAuthenticationsType:
-		oldConv, ok1 := oldObj.(*security_v1beta1.PeerAuthentication)
-		newConv, ok2 := newObj.(*security_v1beta1.PeerAuthentication)
-		if ok1 && ok2 {
-			oldResourceVersion = oldConv.ResourceVersion
-			newResourceVersion = newConv.ResourceVersion
-		}
-	case kubernetes.RequestAuthenticationsType:
-		oldConv, ok1 := oldObj.(*security_v1beta1.RequestAuthentication)
-		newConv, ok2 := newObj.(*security_v1beta1.RequestAuthentication)
-		if ok1 && ok2 {
-			oldResourceVersion = oldConv.ResourceVersion
-			newResourceVersion = newConv.ResourceVersion
-		}
-	}
-	return oldResourceVersion, newResourceVersion
+func (sh RegistryRefreshHandler) OnDelete(obj interface{}) {
+	sh.refresh()
 }
diff --git a/kubernetes/cache/istio.go b/kubernetes/cache/istio.go
index 2af1007d5..20e903216 100644
--- a/kubernetes/cache/istio.go
+++ b/kubernetes/cache/istio.go
@@ -1,7 +1,6 @@
 package cache
 
 import (
-	"errors"
 	"fmt"
 
 	extentions_v1alpha1 "istio.io/client-go/pkg/apis/extensions/v1alpha1"
@@ -13,7 +12,6 @@ import (
 	"k8s.io/apimachinery/pkg/labels"
 
 	"github.com/kiali/kiali/kubernetes"
-	"github.com/kiali/kiali/log"
 )
 
 type (
@@ -56,890 +54,591 @@ func (c *kialiCacheImpl) CheckIstioResource(resourceType string) bool {
 	return exist
 }
 
-func (c *kialiCacheImpl) createIstioInformers(namespace string, informer *typeCache) {
-	sharedInformers := istio.NewSharedInformerFactoryWithOptions(c.istioApi, c.refreshDuration, istio.WithNamespace(namespace))
+func (c *kialiCacheImpl) createIstioInformers(namespace string) istio.SharedInformerFactory {
+	var opts []istio.SharedInformerOption
+	if namespace != "" {
+		opts = append(opts, istio.WithNamespace(namespace))
+	}
+	sharedInformers := istio.NewSharedInformerFactoryWithOptions(c.istioApi, c.refreshDuration, opts...)
+	lister := c.getCacheLister(namespace)
+
+	if c.CheckIstioResource(kubernetes.AuthorizationPolicies) {
+		lister.authzLister = sharedInformers.Security().V1beta1().AuthorizationPolicies().Lister()
+		sharedInformers.Security().V1beta1().AuthorizationPolicies().Informer().AddEventHandler(c.registryRefreshHandler)
+	}
 	if c.CheckIstioResource(kubernetes.DestinationRules) {
-		(*informer)[kubernetes.DestinationRuleType] = sharedInformers.Networking().V1beta1().DestinationRules().Informer()
-		(*informer)[kubernetes.DestinationRuleType].AddEventHandler(c.registryRefreshHandler)
+		lister.destinationRuleLister = sharedInformers.Networking().V1beta1().DestinationRules().Lister()
+		sharedInformers.Networking().V1beta1().DestinationRules().Informer().AddEventHandler(c.registryRefreshHandler)
 	}
 	if c.CheckIstioResource(kubernetes.EnvoyFilters) {
-		(*informer)[kubernetes.EnvoyFilterType] = sharedInformers.Networking().V1alpha3().EnvoyFilters().Informer()
-		(*informer)[kubernetes.EnvoyFilterType].AddEventHandler(c.registryRefreshHandler)
+		lister.envoyFilterLister = sharedInformers.Networking().V1alpha3().EnvoyFilters().Lister()
+		sharedInformers.Networking().V1alpha3().EnvoyFilters().Informer().AddEventHandler(c.registryRefreshHandler)
 	}
 	if c.CheckIstioResource(kubernetes.Gateways) {
-		(*informer)[kubernetes.GatewayType] = sharedInformers.Networking().V1beta1().Gateways().Informer()
-		(*informer)[kubernetes.GatewayType].AddEventHandler(c.registryRefreshHandler)
+		lister.gatewayLister = sharedInformers.Networking().V1beta1().Gateways().Lister()
+		sharedInformers.Networking().V1beta1().Gateways().Informer().AddEventHandler(c.registryRefreshHandler)
+	}
+	if c.CheckIstioResource(kubernetes.PeerAuthentications) {
+		lister.peerAuthnLister = sharedInformers.Security().V1beta1().PeerAuthentications().Lister()
+		sharedInformers.Security().V1beta1().PeerAuthentications().Informer().AddEventHandler(c.registryRefreshHandler)
+	}
+	if c.CheckIstioResource(kubernetes.RequestAuthentications) {
+		lister.requestAuthnLister = sharedInformers.Security().V1beta1().RequestAuthentications().Lister()
+		sharedInformers.Security().V1beta1().RequestAuthentications().Informer().AddEventHandler(c.registryRefreshHandler)
 	}
 	if c.CheckIstioResource(kubernetes.ServiceEntries) {
-		(*informer)[kubernetes.ServiceEntryType] = sharedInformers.Networking().V1beta1().ServiceEntries().Informer()
-		(*informer)[kubernetes.ServiceEntryType].AddEventHandler(c.registryRefreshHandler)
+		lister.serviceEntryLister = sharedInformers.Networking().V1beta1().ServiceEntries().Lister()
+		sharedInformers.Networking().V1beta1().ServiceEntries().Informer().AddEventHandler(c.registryRefreshHandler)
 	}
 	if c.CheckIstioResource(kubernetes.Sidecars) {
-		(*informer)[kubernetes.SidecarType] = sharedInformers.Networking().V1beta1().Sidecars().Informer()
-		(*informer)[kubernetes.SidecarType].AddEventHandler(c.registryRefreshHandler)
+		lister.sidecarLister = sharedInformers.Networking().V1beta1().Sidecars().Lister()
+		sharedInformers.Networking().V1beta1().Sidecars().Informer().AddEventHandler(c.registryRefreshHandler)
+	}
+	if c.CheckIstioResource(kubernetes.Telemetries) {
+		lister.telemetryLister = sharedInformers.Telemetry().V1alpha1().Telemetries().Lister()
+		sharedInformers.Telemetry().V1alpha1().Telemetries().Informer().AddEventHandler(c.registryRefreshHandler)
 	}
 	if c.CheckIstioResource(kubernetes.VirtualServices) {
-		(*informer)[kubernetes.VirtualServiceType] = sharedInformers.Networking().V1beta1().VirtualServices().Informer()
-		(*informer)[kubernetes.VirtualServiceType].AddEventHandler(c.registryRefreshHandler)
+		lister.virtualServiceLister = sharedInformers.Networking().V1beta1().VirtualServices().Lister()
+		sharedInformers.Networking().V1beta1().VirtualServices().Informer().AddEventHandler(c.registryRefreshHandler)
+	}
+	if c.CheckIstioResource(kubernetes.WasmPlugins) {
+		lister.wasmPluginLister = sharedInformers.Extensions().V1alpha1().WasmPlugins().Lister()
+		sharedInformers.Extensions().V1alpha1().WasmPlugins().Informer().AddEventHandler(c.registryRefreshHandler)
 	}
 	if c.CheckIstioResource(kubernetes.WorkloadEntries) {
-		(*informer)[kubernetes.WorkloadEntryType] = sharedInformers.Networking().V1beta1().WorkloadEntries().Informer()
-		(*informer)[kubernetes.WorkloadEntryType].AddEventHandler(c.registryRefreshHandler)
+		lister.workloadEntryLister = sharedInformers.Networking().V1beta1().WorkloadEntries().Lister()
+		sharedInformers.Networking().V1beta1().WorkloadEntries().Informer().AddEventHandler(c.registryRefreshHandler)
 	}
 	if c.CheckIstioResource(kubernetes.WorkloadGroups) {
-		(*informer)[kubernetes.WorkloadGroupType] = sharedInformers.Networking().V1beta1().WorkloadGroups().Informer()
-		(*informer)[kubernetes.WorkloadGroupType].AddEventHandler(c.registryRefreshHandler)
+		lister.workloadGroupLister = sharedInformers.Networking().V1beta1().WorkloadGroups().Lister()
+		sharedInformers.Networking().V1beta1().WorkloadGroups().Informer().AddEventHandler(c.registryRefreshHandler)
 	}
 
-	if c.CheckIstioResource(kubernetes.AuthorizationPolicies) {
-		(*informer)[kubernetes.AuthorizationPoliciesType] = sharedInformers.Security().V1beta1().AuthorizationPolicies().Informer()
-		(*informer)[kubernetes.AuthorizationPoliciesType].AddEventHandler(c.registryRefreshHandler)
-	}
-	if c.CheckIstioResource(kubernetes.PeerAuthentications) {
-		(*informer)[kubernetes.PeerAuthenticationsType] = sharedInformers.Security().V1beta1().PeerAuthentications().Informer()
-		(*informer)[kubernetes.PeerAuthenticationsType].AddEventHandler(c.registryRefreshHandler)
-	}
-	if c.CheckIstioResource(kubernetes.RequestAuthentications) {
-		(*informer)[kubernetes.RequestAuthenticationsType] = sharedInformers.Security().V1beta1().RequestAuthentications().Informer()
-		(*informer)[kubernetes.RequestAuthenticationsType].AddEventHandler(c.registryRefreshHandler)
-	}
-}
-
-func (c *kialiCacheImpl) isIstioSynced(namespace string) bool {
-	var isSynced bool
-	if nsCache, exist := c.nsCache[namespace]; exist {
-		isSynced = true
-		if c.CheckIstioResource(kubernetes.DestinationRules) {
-			isSynced = isSynced && nsCache[kubernetes.DestinationRuleType].HasSynced()
-		}
-		if c.CheckIstioResource(kubernetes.EnvoyFilters) {
-			isSynced = isSynced && nsCache[kubernetes.EnvoyFilterType].HasSynced()
-		}
-		if c.CheckIstioResource(kubernetes.Gateways) {
-			isSynced = isSynced && nsCache[kubernetes.GatewayType].HasSynced()
-		}
-		if c.CheckIstioResource(kubernetes.ServiceEntries) {
-			isSynced = isSynced && nsCache[kubernetes.ServiceEntryType].HasSynced()
-		}
-		if c.CheckIstioResource(kubernetes.Sidecars) {
-			isSynced = isSynced && nsCache[kubernetes.SidecarType].HasSynced()
-		}
-		if c.CheckIstioResource(kubernetes.VirtualServices) {
-			isSynced = isSynced && nsCache[kubernetes.VirtualServiceType].HasSynced()
-		}
-		if c.CheckIstioResource(kubernetes.WorkloadGroups) {
-			isSynced = isSynced && nsCache[kubernetes.WorkloadGroupType].HasSynced()
-		}
-		if c.CheckIstioResource(kubernetes.WorkloadEntries) {
-			isSynced = isSynced && nsCache[kubernetes.WorkloadEntryType].HasSynced()
-		}
-
-		if c.CheckIstioResource(kubernetes.AuthorizationPolicies) {
-			isSynced = isSynced && nsCache[kubernetes.AuthorizationPoliciesType].HasSynced()
-		}
-		if c.CheckIstioResource(kubernetes.PeerAuthentications) {
-			isSynced = isSynced && nsCache[kubernetes.PeerAuthenticationsType].HasSynced()
-		}
-		if c.CheckIstioResource(kubernetes.RequestAuthentications) {
-			isSynced = isSynced && nsCache[kubernetes.RequestAuthenticationsType].HasSynced()
-		}
-	} else {
-		isSynced = false
-	}
-	return isSynced
+	return sharedInformers
 }
 
 func (c *kialiCacheImpl) GetDestinationRule(namespace, name string) (*networking_v1beta1.DestinationRule, error) {
 	if !c.CheckIstioResource(kubernetes.DestinationRules) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.DestinationRuleType)
 	}
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.DestinationRuleType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			l, ok := obj.(*networking_v1beta1.DestinationRule)
-			if !ok {
-				return nil, errors.New("bad DestinationRule type found in cache")
-			}
-			// Informers don't always populate Kind field
-			l.Kind = kubernetes.DestinationRuleType
-			log.Tracef("[Kiali Cache] Get [resource: DestinationRule] for [namespace: %s] [name: %s]", namespace, name)
-			return l, nil
-		}
-	}
-	return nil, nil
+
+	dr, err := c.getCacheLister(namespace).destinationRuleLister.DestinationRules(namespace).Get(name)
+	if err != nil {
+		return nil, err
+	}
+
+	dr.Kind = kubernetes.DestinationRuleType
+	return dr, nil
 }
 
 func (c *kialiCacheImpl) GetDestinationRules(namespace, labelSelector string) ([]*networking_v1beta1.DestinationRule, error) {
 	if !c.CheckIstioResource(kubernetes.DestinationRules) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.DestinationRuleType)
 	}
-	if nsCache, nsOk := c.nsCache[namespace]; nsOk {
-		l := nsCache[kubernetes.DestinationRuleType].GetStore().List()
-		lenL := len(l)
-		if lenL > 0 {
-			_, ok := l[0].(*networking_v1beta1.DestinationRule)
-			if !ok {
-				return []*networking_v1beta1.DestinationRule{}, errors.New("bad DestinationRule type found in cache")
-			}
-			nsL := make([]*networking_v1beta1.DestinationRule, lenL)
-			for i, li := range l {
-				nsL[i] = li.(*networking_v1beta1.DestinationRule)
-				// Informers don't always populate Kind field
-				nsL[i].Kind = kubernetes.DestinationRuleType
-			}
-			log.Tracef("[Kiali Cache] Get [resource: DestinationRule] for [namespace: %s] = %d", namespace, lenL)
-			if labelSelector == "" {
-				return nsL, nil
-			}
-			var filteredL []*networking_v1beta1.DestinationRule
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []*networking_v1beta1.DestinationRule{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, li := range nsL {
-				if selector.Matches(labels.Set(li.Labels)) {
-					filteredL = append(filteredL, li)
-				}
-			}
-			return filteredL, nil
-		}
-	}
-	return []*networking_v1beta1.DestinationRule{}, nil
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
+	}
+
+	drs, err := c.getCacheLister(namespace).destinationRuleLister.DestinationRules(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+
+	// Lister returns nil when there are no results but callers of the cache expect an empty array
+	// so keeping the behavior the same since it matters for json marshalling.
+	if drs == nil {
+		return []*networking_v1beta1.DestinationRule{}, nil
+	}
+
+	for _, dr := range drs {
+		dr.Kind = kubernetes.DestinationRuleType
+	}
+	return drs, nil
 }
 
 func (c *kialiCacheImpl) GetEnvoyFilter(namespace, name string) (*networking_v1alpha3.EnvoyFilter, error) {
 	if !c.CheckIstioResource(kubernetes.EnvoyFilters) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.EnvoyFilterType)
 	}
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.EnvoyFilterType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			l, ok := obj.(*networking_v1alpha3.EnvoyFilter)
-			if !ok {
-				return nil, errors.New("bad EnvoyFilter type found in cache")
-			}
-			l.Kind = kubernetes.EnvoyFilterType
-			log.Tracef("[Kiali Cache] Get [resource: EnvoyFilter] for [namespace: %s] [name: %s]", namespace, name)
-			return l, nil
-		}
-	}
-	return nil, nil
+
+	ef, err := c.getCacheLister(namespace).envoyFilterLister.EnvoyFilters(namespace).Get(name)
+	if err != nil {
+		return nil, err
+	}
+
+	ef.Kind = kubernetes.EnvoyFilterType
+	return ef, nil
 }
 
 func (c *kialiCacheImpl) GetEnvoyFilters(namespace, labelSelector string) ([]*networking_v1alpha3.EnvoyFilter, error) {
 	if !c.CheckIstioResource(kubernetes.EnvoyFilters) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.EnvoyFilterType)
 	}
-	if nsCache, nsOk := c.nsCache[namespace]; nsOk {
-		l := nsCache[kubernetes.EnvoyFilterType].GetStore().List()
-		lenL := len(l)
-		if lenL > 0 {
-			_, ok := l[0].(*networking_v1alpha3.EnvoyFilter)
-			if !ok {
-				return []*networking_v1alpha3.EnvoyFilter{}, errors.New("bad EnvoyFilter type found in cache")
-			}
-			nsL := make([]*networking_v1alpha3.EnvoyFilter, lenL)
-			for i, li := range l {
-				nsL[i] = li.(*networking_v1alpha3.EnvoyFilter)
-				nsL[i].Kind = kubernetes.EnvoyFilterType
-			}
-			log.Tracef("[Kiali Cache] Get [resource: EnvoyFilter] for [namespace: %s] = %d", namespace, lenL)
-			if labelSelector == "" {
-				return nsL, nil
-			}
-			var filteredL []*networking_v1alpha3.EnvoyFilter
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []*networking_v1alpha3.EnvoyFilter{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, li := range nsL {
-				if selector.Matches(labels.Set(li.Labels)) {
-					filteredL = append(filteredL, li)
-				}
-			}
-			return filteredL, nil
-		}
-	}
-	return []*networking_v1alpha3.EnvoyFilter{}, nil
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
+	}
+
+	efs, err := c.getCacheLister(namespace).envoyFilterLister.EnvoyFilters(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+
+	// Lister returns nil when there are no results but callers of the cache expect an empty array
+	// so keeping the behavior the same since it matters for json marshalling.
+	if efs == nil {
+		return []*networking_v1alpha3.EnvoyFilter{}, nil
+	}
+
+	for _, ef := range efs {
+		ef.Kind = kubernetes.EnvoyFilterType
+	}
+	return efs, nil
 }
 
 func (c *kialiCacheImpl) GetGateway(namespace, name string) (*networking_v1beta1.Gateway, error) {
 	if !c.CheckIstioResource(kubernetes.Gateways) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.GatewayType)
 	}
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.GatewayType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			l, ok := obj.(*networking_v1beta1.Gateway)
-			if !ok {
-				return nil, errors.New("bad Gateway type found in cache")
-			}
-			l.Kind = kubernetes.GatewayType
-			log.Tracef("[Kiali Cache] Get [resource: Gateway] for [namespace: %s] [name: %s]", namespace, name)
-			return l, nil
-		}
-	}
-	return nil, nil
+
+	gw, err := c.getCacheLister(namespace).gatewayLister.Gateways(namespace).Get(name)
+	if err != nil {
+		return nil, err
+	}
+
+	gw.Kind = kubernetes.GatewayType
+	return gw, nil
 }
 
 func (c *kialiCacheImpl) GetGateways(namespace, labelSelector string) ([]*networking_v1beta1.Gateway, error) {
 	if !c.CheckIstioResource(kubernetes.Gateways) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.Gateways)
 	}
-	if nsCache, nsOk := c.nsCache[namespace]; nsOk {
-		l := nsCache[kubernetes.GatewayType].GetStore().List()
-		lenL := len(l)
-		if lenL > 0 {
-			_, ok := l[0].(*networking_v1beta1.Gateway)
-			if !ok {
-				return []*networking_v1beta1.Gateway{}, errors.New("bad Gateway type found in cache")
-			}
-			nsL := make([]*networking_v1beta1.Gateway, lenL)
-			for i, li := range l {
-				nsL[i] = li.(*networking_v1beta1.Gateway)
-				nsL[i].Kind = kubernetes.GatewayType
-			}
-			log.Tracef("[Kiali Cache] Get [resource: Gateway] for [namespace: %s] = %d", namespace, lenL)
-			if labelSelector == "" {
-				return nsL, nil
-			}
-			var filteredL []*networking_v1beta1.Gateway
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []*networking_v1beta1.Gateway{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, li := range nsL {
-				if selector.Matches(labels.Set(li.Labels)) {
-					filteredL = append(filteredL, li)
-				}
-			}
-			return filteredL, nil
-		}
-	}
-	return []*networking_v1beta1.Gateway{}, nil
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
+	}
+
+	gateways, err := c.getCacheLister(namespace).gatewayLister.Gateways(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+
+	// Lister returns nil when there are no results but callers of the cache expect an empty array
+	// so keeping the behavior the same since it matters for json marshalling.
+	if gateways == nil {
+		return []*networking_v1beta1.Gateway{}, nil
+	}
+
+	for _, gw := range gateways {
+		gw.Kind = kubernetes.GatewayType
+	}
+	return gateways, nil
 }
 
 func (c *kialiCacheImpl) GetServiceEntry(namespace, name string) (*networking_v1beta1.ServiceEntry, error) {
 	if !c.CheckIstioResource(kubernetes.ServiceEntries) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.ServiceEntryType)
 	}
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.ServiceEntryType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			l, ok := obj.(*networking_v1beta1.ServiceEntry)
-			if !ok {
-				return nil, errors.New("bad ServiceEntry type found in cache")
-			}
-			l.Kind = kubernetes.ServiceEntryType
-			log.Tracef("[Kiali Cache] Get [resource: ServiceEntry] for [namespace: %s] [name: %s]", namespace, name)
-			return l, nil
-		}
-	}
-	return nil, nil
+
+	se, err := c.getCacheLister(namespace).serviceEntryLister.ServiceEntries(namespace).Get(name)
+	if err != nil {
+		return nil, err
+	}
+
+	se.Kind = kubernetes.ServiceEntryType
+	return se, nil
 }
 
 func (c *kialiCacheImpl) GetServiceEntries(namespace, labelSelector string) ([]*networking_v1beta1.ServiceEntry, error) {
 	if !c.CheckIstioResource(kubernetes.ServiceEntries) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.ServiceEntryType)
 	}
-	if nsCache, nsOk := c.nsCache[namespace]; nsOk {
-		l := nsCache[kubernetes.ServiceEntryType].GetStore().List()
-		lenL := len(l)
-		if lenL > 0 {
-			_, ok := l[0].(*networking_v1beta1.ServiceEntry)
-			if !ok {
-				return []*networking_v1beta1.ServiceEntry{}, errors.New("bad ServiceEntry type found in cache")
-			}
-			nsL := make([]*networking_v1beta1.ServiceEntry, lenL)
-			for i, li := range l {
-				nsL[i] = li.(*networking_v1beta1.ServiceEntry)
-				nsL[i].Kind = kubernetes.ServiceEntryType
-			}
-			log.Tracef("[Kiali Cache] Get [resource: ServiceEntry] for [namespace: %s] = %d", namespace, lenL)
-			if labelSelector == "" {
-				return nsL, nil
-			}
-			var filteredL []*networking_v1beta1.ServiceEntry
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []*networking_v1beta1.ServiceEntry{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, li := range nsL {
-				if selector.Matches(labels.Set(li.Labels)) {
-					filteredL = append(filteredL, li)
-				}
-			}
-			return filteredL, nil
-		}
-	}
-	return []*networking_v1beta1.ServiceEntry{}, nil
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
+	}
+
+	ses, err := c.getCacheLister(namespace).serviceEntryLister.ServiceEntries(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+
+	// Lister returns nil when there are no results but callers of the cache expect an empty array
+	// so keeping the behavior the same since it matters for json marshalling.
+	if ses == nil {
+		return []*networking_v1beta1.ServiceEntry{}, nil
+	}
+
+	for _, se := range ses {
+		se.Kind = kubernetes.ServiceEntryType
+	}
+	return ses, nil
 }
 
 func (c *kialiCacheImpl) GetSidecar(namespace, name string) (*networking_v1beta1.Sidecar, error) {
 	if !c.CheckIstioResource(kubernetes.Sidecars) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.SidecarType)
 	}
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.SidecarType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			l, ok := obj.(*networking_v1beta1.Sidecar)
-			if !ok {
-				return nil, errors.New("bad Sidecar type found in cache")
-			}
-			l.Kind = kubernetes.SidecarType
-			log.Tracef("[Kiali Cache] Get [resource: Sidecar] for [namespace: %s] [name: %s]", namespace, name)
-			return l, nil
-		}
-	}
-	return nil, nil
+
+	sc, err := c.getCacheLister(namespace).sidecarLister.Sidecars(namespace).Get(name)
+	if err != nil {
+		return nil, err
+	}
+
+	sc.Kind = kubernetes.SidecarType
+	return sc, nil
 }
 
 func (c *kialiCacheImpl) GetSidecars(namespace, labelSelector string) ([]*networking_v1beta1.Sidecar, error) {
 	if !c.CheckIstioResource(kubernetes.Sidecars) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.SidecarType)
 	}
-	if nsCache, nsOk := c.nsCache[namespace]; nsOk {
-		l := nsCache[kubernetes.SidecarType].GetStore().List()
-		lenL := len(l)
-		if lenL > 0 {
-			_, ok := l[0].(*networking_v1beta1.Sidecar)
-			if !ok {
-				return []*networking_v1beta1.Sidecar{}, errors.New("bad Sidecar type found in cache")
-			}
-			nsL := make([]*networking_v1beta1.Sidecar, lenL)
-			for i, li := range l {
-				nsL[i] = li.(*networking_v1beta1.Sidecar)
-				nsL[i].Kind = kubernetes.SidecarType
-			}
-			log.Tracef("[Kiali Cache] Get [resource: Sidecar] for [namespace: %s] = %d", namespace, lenL)
-			if labelSelector == "" {
-				return nsL, nil
-			}
-			var filteredL []*networking_v1beta1.Sidecar
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []*networking_v1beta1.Sidecar{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, li := range nsL {
-				if selector.Matches(labels.Set(li.Labels)) {
-					filteredL = append(filteredL, li)
-				}
-			}
-			return filteredL, nil
-		}
-	}
-	return []*networking_v1beta1.Sidecar{}, nil
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
+	}
+
+	sidecars, err := c.getCacheLister(namespace).sidecarLister.Sidecars(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+
+	// Lister returns nil when there are no results but callers of the cache expect an empty array
+	// so keeping the behavior the same since it matters for json marshalling.
+	if sidecars == nil {
+		return []*networking_v1beta1.Sidecar{}, nil
+	}
+
+	for _, sc := range sidecars {
+		sc.Kind = kubernetes.SidecarType
+	}
+	return sidecars, nil
 }
 
 func (c *kialiCacheImpl) GetVirtualService(namespace, name string) (*networking_v1beta1.VirtualService, error) {
 	if !c.CheckIstioResource(kubernetes.VirtualServices) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.VirtualServiceType)
 	}
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.VirtualServiceType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			l, ok := obj.(*networking_v1beta1.VirtualService)
-			if !ok {
-				return nil, errors.New("bad VirtualService type found in cache")
-			}
-			l.Kind = kubernetes.VirtualServiceType
-			log.Tracef("[Kiali Cache] Get [resource: VirtualService] for [namespace: %s] [name: %s]", namespace, name)
-			return l, nil
-		}
-	}
-	return nil, nil
+
+	vs, err := c.getCacheLister(namespace).virtualServiceLister.VirtualServices(namespace).Get(name)
+	if err != nil {
+		return nil, err
+	}
+
+	vs.Kind = kubernetes.VirtualServiceType
+	return vs, nil
 }
 
 func (c *kialiCacheImpl) GetVirtualServices(namespace, labelSelector string) ([]*networking_v1beta1.VirtualService, error) {
 	if !c.CheckIstioResource(kubernetes.VirtualServices) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.VirtualServiceType)
 	}
-	if nsCache, nsOk := c.nsCache[namespace]; nsOk {
-		l := nsCache[kubernetes.VirtualServiceType].GetStore().List()
-		lenL := len(l)
-		if lenL > 0 {
-			_, ok := l[0].(*networking_v1beta1.VirtualService)
-			if !ok {
-				return []*networking_v1beta1.VirtualService{}, errors.New("bad VirtualService type found in cache")
-			}
-			nsL := make([]*networking_v1beta1.VirtualService, lenL)
-			for i, li := range l {
-				nsL[i] = li.(*networking_v1beta1.VirtualService)
-				nsL[i].Kind = kubernetes.VirtualServiceType
-			}
-			log.Tracef("[Kiali Cache] Get [resource: VirtualService] for [namespace: %s] = %d", namespace, lenL)
-			if labelSelector == "" {
-				return nsL, nil
-			}
-			var filteredL []*networking_v1beta1.VirtualService
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []*networking_v1beta1.VirtualService{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, li := range nsL {
-				if selector.Matches(labels.Set(li.Labels)) {
-					filteredL = append(filteredL, li)
-				}
-			}
-			return filteredL, nil
-		}
-	}
-	return []*networking_v1beta1.VirtualService{}, nil
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
+	}
+
+	vs, err := c.getCacheLister(namespace).virtualServiceLister.VirtualServices(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+
+	// Lister returns nil when there are no results but callers of the cache expect an empty array
+	// so keeping the behavior the same since it matters for json marshalling.
+	if vs == nil {
+		return []*networking_v1beta1.VirtualService{}, nil
+	}
+
+	for _, v := range vs {
+		v.Kind = kubernetes.VirtualServiceType
+	}
+	return vs, nil
 }
 
 func (c *kialiCacheImpl) GetWorkloadEntry(namespace, name string) (*networking_v1beta1.WorkloadEntry, error) {
 	if !c.CheckIstioResource(kubernetes.WorkloadEntries) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.WorkloadEntryType)
 	}
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.WorkloadEntryType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			l, ok := obj.(*networking_v1beta1.WorkloadEntry)
-			if !ok {
-				return nil, errors.New("bad WorkloadEntry type found in cache")
-			}
-			l.Kind = kubernetes.WorkloadEntryType
-			log.Tracef("[Kiali Cache] Get [resource: WorkloadEntry] for [namespace: %s] [name: %s]", namespace, name)
-			return l, nil
-		}
-	}
-	return nil, nil
+
+	we, err := c.getCacheLister(namespace).workloadEntryLister.WorkloadEntries(namespace).Get(name)
+	if err != nil {
+		return nil, err
+	}
+
+	we.Kind = kubernetes.WorkloadEntryType
+	return we, nil
 }
 
 func (c *kialiCacheImpl) GetWorkloadEntries(namespace, labelSelector string) ([]*networking_v1beta1.WorkloadEntry, error) {
 	if !c.CheckIstioResource(kubernetes.WorkloadEntries) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.WorkloadEntryType)
 	}
-	if nsCache, nsOk := c.nsCache[namespace]; nsOk {
-		l := nsCache[kubernetes.WorkloadEntryType].GetStore().List()
-		lenL := len(l)
-		if lenL > 0 {
-			_, ok := l[0].(*networking_v1beta1.WorkloadEntry)
-			if !ok {
-				return []*networking_v1beta1.WorkloadEntry{}, errors.New("bad WorkloadEntry type found in cache")
-			}
-			nsL := make([]*networking_v1beta1.WorkloadEntry, lenL)
-			for i, li := range l {
-				nsL[i] = li.(*networking_v1beta1.WorkloadEntry)
-				nsL[i].Kind = kubernetes.WorkloadEntryType
-			}
-			log.Tracef("[Kiali Cache] Get [resource: WorkloadEntry] for [namespace: %s] = %d", namespace, lenL)
-			if labelSelector == "" {
-				return nsL, nil
-			}
-			var filteredL []*networking_v1beta1.WorkloadEntry
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []*networking_v1beta1.WorkloadEntry{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, li := range nsL {
-				if selector.Matches(labels.Set(li.Labels)) {
-					filteredL = append(filteredL, li)
-				}
-			}
-			return filteredL, nil
-		}
-	}
-	return []*networking_v1beta1.WorkloadEntry{}, nil
+
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
+	}
+
+	we, err := c.getCacheLister(namespace).workloadEntryLister.WorkloadEntries(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+
+	// Lister returns nil when there are no results but callers of the cache expect an empty array
+	// so keeping the behavior the same since it matters for json marshalling.
+	if we == nil {
+		return []*networking_v1beta1.WorkloadEntry{}, nil
+	}
+
+	for _, w := range we {
+		w.Kind = kubernetes.WorkloadEntryType
+	}
+	return we, nil
 }
 
 func (c *kialiCacheImpl) GetWorkloadGroup(namespace, name string) (*networking_v1beta1.WorkloadGroup, error) {
 	if !c.CheckIstioResource(kubernetes.WorkloadGroups) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.WorkloadGroupType)
 	}
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.WorkloadGroupType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			l, ok := obj.(*networking_v1beta1.WorkloadGroup)
-			if !ok {
-				return nil, errors.New("bad WorkloadGroup type found in cache")
-			}
-			l.Kind = kubernetes.WorkloadGroupType
-			log.Tracef("[Kiali Cache] Get [resource: WorkloadGroup] for [namespace: %s] [name: %s]", namespace, name)
-			return l, nil
-		}
-	}
-	return nil, nil
+
+	wg, err := c.getCacheLister(namespace).workloadGroupLister.WorkloadGroups(namespace).Get(name)
+	if err != nil {
+		return nil, err
+	}
+
+	wg.Kind = kubernetes.WorkloadGroupType
+	return wg, nil
 }
 
 func (c *kialiCacheImpl) GetWorkloadGroups(namespace, labelSelector string) ([]*networking_v1beta1.WorkloadGroup, error) {
 	if !c.CheckIstioResource(kubernetes.WorkloadGroups) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.WorkloadGroups)
 	}
-	if nsCache, nsOk := c.nsCache[namespace]; nsOk {
-		l := nsCache[kubernetes.WorkloadGroupType].GetStore().List()
-		lenL := len(l)
-		if lenL > 0 {
-			_, ok := l[0].(*networking_v1beta1.WorkloadGroup)
-			if !ok {
-				return []*networking_v1beta1.WorkloadGroup{}, errors.New("bad WorkloadGroup type found in cache")
-			}
-			nsL := make([]*networking_v1beta1.WorkloadGroup, lenL)
-			for i, li := range l {
-				nsL[i] = li.(*networking_v1beta1.WorkloadGroup)
-				nsL[i].Kind = kubernetes.WorkloadGroupType
-			}
-			log.Tracef("[Kiali Cache] Get [resource: WorkloadGroup] for [namespace: %s] = %d", namespace, lenL)
-			if labelSelector == "" {
-				return nsL, nil
-			}
-			var filteredL []*networking_v1beta1.WorkloadGroup
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []*networking_v1beta1.WorkloadGroup{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, li := range nsL {
-				if selector.Matches(labels.Set(li.Labels)) {
-					filteredL = append(filteredL, li)
-				}
-			}
-			return filteredL, nil
-		}
-	}
-	return []*networking_v1beta1.WorkloadGroup{}, nil
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
+	}
+
+	wg, err := c.getCacheLister(namespace).workloadGroupLister.WorkloadGroups(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+
+	// Lister returns nil when there are no results but callers of the cache expect an empty array
+	// so keeping the behavior the same since it matters for json marshalling.
+	if wg == nil {
+		return []*networking_v1beta1.WorkloadGroup{}, nil
+	}
+
+	for _, w := range wg {
+		w.Kind = kubernetes.WorkloadGroupType
+	}
+	return wg, nil
 }
 
 func (c *kialiCacheImpl) GetWasmPlugin(namespace, name string) (*extentions_v1alpha1.WasmPlugin, error) {
 	if !c.CheckIstioResource(kubernetes.WasmPlugins) {
-		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.WorkloadGroupType)
+		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.WasmPluginType)
+	}
+
+	wp, err := c.getCacheLister(namespace).wasmPluginLister.WasmPlugins(namespace).Get(name)
+	if err != nil {
+		return nil, err
 	}
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.WasmPluginType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			l, ok := obj.(*extentions_v1alpha1.WasmPlugin)
-			if !ok {
-				return nil, errors.New("bad WorkloadGroup type found in cache")
-			}
-			l.Kind = kubernetes.WasmPlugins
-			log.Tracef("[Kiali Cache] Get [resource: WasmPlugin] for [namespace: %s] [name: %s]", namespace, name)
-			return l, nil
-		}
-	}
-	return nil, nil
+
+	wp.Kind = kubernetes.WasmPluginType
+	return wp, nil
 }
 
 func (c *kialiCacheImpl) GetWasmPlugins(namespace, labelSelector string) ([]*extentions_v1alpha1.WasmPlugin, error) {
 	if !c.CheckIstioResource(kubernetes.WasmPlugins) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.WorkloadGroups)
 	}
-	if nsCache, nsOk := c.nsCache[namespace]; nsOk {
-		l := nsCache[kubernetes.WasmPluginType].GetStore().List()
-		lenL := len(l)
-		if lenL > 0 {
-			_, ok := l[0].(*extentions_v1alpha1.WasmPlugin)
-			if !ok {
-				return []*extentions_v1alpha1.WasmPlugin{}, errors.New("bad WorkloadGroup type found in cache")
-			}
-			nsL := make([]*extentions_v1alpha1.WasmPlugin, lenL)
-			for i, li := range l {
-				nsL[i] = li.(*extentions_v1alpha1.WasmPlugin)
-				nsL[i].Kind = kubernetes.WasmPluginType
-			}
-			log.Tracef("[Kiali Cache] Get [resource: WorkloadGroup] for [namespace: %s] = %d", namespace, lenL)
-			if labelSelector == "" {
-				return nsL, nil
-			}
-			var filteredL []*extentions_v1alpha1.WasmPlugin
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []*extentions_v1alpha1.WasmPlugin{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, li := range nsL {
-				if selector.Matches(labels.Set(li.Labels)) {
-					filteredL = append(filteredL, li)
-				}
-			}
-			return filteredL, nil
-		}
-	}
-	return []*extentions_v1alpha1.WasmPlugin{}, nil
+
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
+	}
+
+	wp, err := c.getCacheLister(namespace).wasmPluginLister.WasmPlugins(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+
+	// Lister returns nil when there are no results but callers of the cache expect an empty array
+	// so keeping the behavior the same since it matters for json marshalling.
+	if wp == nil {
+		return []*extentions_v1alpha1.WasmPlugin{}, nil
+	}
+
+	for _, w := range wp {
+		w.Kind = kubernetes.WasmPluginType
+	}
+	return wp, nil
 }
 
 func (c *kialiCacheImpl) GetTelemetry(namespace, name string) (*v1alpha1.Telemetry, error) {
 	if !c.CheckIstioResource(kubernetes.Telemetries) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.WorkloadGroupType)
 	}
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.TelemetryType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			l, ok := obj.(*v1alpha1.Telemetry)
-			if !ok {
-				return nil, errors.New("bad WorkloadGroup type found in cache")
-			}
-			l.Kind = kubernetes.Telemetries
-			log.Tracef("[Kiali Cache] Get [resource: Telemetry] for [namespace: %s] [name: %s]", namespace, name)
-			return l, nil
-		}
-	}
-	return nil, nil
+
+	t, err := c.getCacheLister(namespace).telemetryLister.Telemetries(namespace).Get(name)
+	if err != nil {
+		return nil, err
+	}
+
+	t.Kind = kubernetes.TelemetryType
+	return t, nil
 }
 
 func (c *kialiCacheImpl) GetTelemetries(namespace, labelSelector string) ([]*v1alpha1.Telemetry, error) {
 	if !c.CheckIstioResource(kubernetes.Telemetries) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.WorkloadGroups)
 	}
-	if nsCache, nsOk := c.nsCache[namespace]; nsOk {
-		l := nsCache[kubernetes.Telemetries].GetStore().List()
-		lenL := len(l)
-		if lenL > 0 {
-			_, ok := l[0].(*v1alpha1.Telemetry)
-			if !ok {
-				return []*v1alpha1.Telemetry{}, errors.New("bad WorkloadGroup type found in cache")
-			}
-			nsL := make([]*v1alpha1.Telemetry, lenL)
-			for i, li := range l {
-				nsL[i] = li.(*v1alpha1.Telemetry)
-				nsL[i].Kind = kubernetes.TelemetryType
-			}
-			log.Tracef("[Kiali Cache] Get [resource: WorkloadGroup] for [namespace: %s] = %d", namespace, lenL)
-			if labelSelector == "" {
-				return nsL, nil
-			}
-			var filteredL []*v1alpha1.Telemetry
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []*v1alpha1.Telemetry{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, li := range nsL {
-				if selector.Matches(labels.Set(li.Labels)) {
-					filteredL = append(filteredL, li)
-				}
-			}
-			return filteredL, nil
-		}
-	}
-	return []*v1alpha1.Telemetry{}, nil
+
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
+	}
+
+	t, err := c.getCacheLister(namespace).telemetryLister.Telemetries(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+
+	// Lister returns nil when there are no results but callers of the cache expect an empty array
+	// so keeping the behavior the same since it matters for json marshalling.
+	if t == nil {
+		return []*v1alpha1.Telemetry{}, nil
+	}
+
+	for _, w := range t {
+		w.Kind = kubernetes.TelemetryType
+	}
+
+	return t, nil
 }
 
 func (c *kialiCacheImpl) GetAuthorizationPolicy(namespace, name string) (*security_v1beta1.AuthorizationPolicy, error) {
 	if !c.CheckIstioResource(kubernetes.AuthorizationPolicies) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.AuthorizationPoliciesType)
 	}
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.AuthorizationPoliciesType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			l, ok := obj.(*security_v1beta1.AuthorizationPolicy)
-			if !ok {
-				return nil, errors.New("bad AuthorizationPolicy type found in cache")
-			}
-			l.Kind = kubernetes.AuthorizationPoliciesType
-			log.Tracef("[Kiali Cache] Get [resource: AuthorizationPolicy] for [namespace: %s] [name: %s]", namespace, name)
-			return l, nil
-		}
-	}
-	return nil, nil
+
+	ap, err := c.getCacheLister(namespace).authzLister.AuthorizationPolicies(namespace).Get(name)
+	if err != nil {
+		return nil, err
+	}
+
+	ap.Kind = kubernetes.AuthorizationPoliciesType
+	return ap, nil
 }
 
 func (c *kialiCacheImpl) GetAuthorizationPolicies(namespace, labelSelector string) ([]*security_v1beta1.AuthorizationPolicy, error) {
 	if !c.CheckIstioResource(kubernetes.AuthorizationPolicies) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.AuthorizationPolicies)
 	}
-	if nsCache, nsOk := c.nsCache[namespace]; nsOk {
-		l := nsCache[kubernetes.AuthorizationPoliciesType].GetStore().List()
-		lenL := len(l)
-		if lenL > 0 {
-			_, ok := l[0].(*security_v1beta1.AuthorizationPolicy)
-			if !ok {
-				return []*security_v1beta1.AuthorizationPolicy{}, errors.New("bad AuthorizationPolicy type found in cache")
-			}
-			nsL := make([]*security_v1beta1.AuthorizationPolicy, lenL)
-			for i, li := range l {
-				nsL[i] = li.(*security_v1beta1.AuthorizationPolicy)
-				nsL[i].Kind = kubernetes.AuthorizationPoliciesType
-			}
-			log.Tracef("[Kiali Cache] Get [resource: AuthorizationPolicy] for [namespace: %s] = %d", namespace, lenL)
-			if labelSelector == "" {
-				return nsL, nil
-			}
-			var filteredL []*security_v1beta1.AuthorizationPolicy
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []*security_v1beta1.AuthorizationPolicy{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, li := range nsL {
-				if selector.Matches(labels.Set(li.Labels)) {
-					filteredL = append(filteredL, li)
-				}
-			}
-			return filteredL, nil
-		}
-	}
-	return []*security_v1beta1.AuthorizationPolicy{}, nil
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
+	}
+
+	authPolicies, err := c.getCacheLister(namespace).authzLister.AuthorizationPolicies(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+
+	// Lister returns nil when there are no results but callers of the cache expect an empty array
+	// so keeping the behavior the same since it matters for json marshalling.
+	if authPolicies == nil {
+		return []*security_v1beta1.AuthorizationPolicy{}, nil
+	}
+
+	for _, ap := range authPolicies {
+		ap.Kind = kubernetes.AuthorizationPoliciesType
+	}
+	return authPolicies, nil
 }
 
 func (c *kialiCacheImpl) GetPeerAuthentication(namespace, name string) (*security_v1beta1.PeerAuthentication, error) {
 	if !c.CheckIstioResource(kubernetes.PeerAuthentications) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.PeerAuthenticationsType)
 	}
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.PeerAuthenticationsType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			l, ok := obj.(*security_v1beta1.PeerAuthentication)
-			if !ok {
-				return nil, errors.New("bad PeerAuthentication type found in cache")
-			}
-			l.Kind = kubernetes.PeerAuthenticationsType
-			log.Tracef("[Kiali Cache] Get [resource: PeerAuthentication] for [namespace: %s] [name: %s]", namespace, name)
-			return l, nil
-		}
-	}
-	return nil, nil
+
+	pa, err := c.getCacheLister(namespace).peerAuthnLister.PeerAuthentications(namespace).Get(name)
+	if err != nil {
+		return nil, err
+	}
+
+	pa.Kind = kubernetes.PeerAuthenticationsType
+	return pa, nil
 }
 
 func (c *kialiCacheImpl) GetPeerAuthentications(namespace, labelSelector string) ([]*security_v1beta1.PeerAuthentication, error) {
 	if !c.CheckIstioResource(kubernetes.PeerAuthentications) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.PeerAuthenticationsType)
 	}
-	if nsCache, nsOk := c.nsCache[namespace]; nsOk {
-		l := nsCache[kubernetes.PeerAuthenticationsType].GetStore().List()
-		lenL := len(l)
-		if lenL > 0 {
-			_, ok := l[0].(*security_v1beta1.PeerAuthentication)
-			if !ok {
-				return []*security_v1beta1.PeerAuthentication{}, errors.New("bad PeerAuthentication type found in cache")
-			}
-			nsL := make([]*security_v1beta1.PeerAuthentication, lenL)
-			for i, li := range l {
-				nsL[i] = li.(*security_v1beta1.PeerAuthentication)
-				nsL[i].Kind = kubernetes.PeerAuthenticationsType
-			}
-			log.Tracef("[Kiali Cache] Get [resource: PeerAuthentication] for [namespace: %s] = %d", namespace, lenL)
-			if labelSelector == "" {
-				return nsL, nil
-			}
-			var filteredL []*security_v1beta1.PeerAuthentication
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []*security_v1beta1.PeerAuthentication{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, li := range nsL {
-				if selector.Matches(labels.Set(li.Labels)) {
-					filteredL = append(filteredL, li)
-				}
-			}
-			return filteredL, nil
-		}
-	}
-	return []*security_v1beta1.PeerAuthentication{}, nil
+
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
+	}
+
+	peerAuths, err := c.getCacheLister(namespace).peerAuthnLister.PeerAuthentications(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+
+	// Lister returns nil when there are no results but callers of the cache expect an empty array
+	// so keeping the behavior the same since it matters for json marshalling.
+	if peerAuths == nil {
+		return []*security_v1beta1.PeerAuthentication{}, nil
+	}
+
+	for _, pa := range peerAuths {
+		pa.Kind = kubernetes.PeerAuthenticationsType
+	}
+	return peerAuths, nil
 }
 
 func (c *kialiCacheImpl) GetRequestAuthentication(namespace, name string) (*security_v1beta1.RequestAuthentication, error) {
 	if !c.CheckIstioResource(kubernetes.RequestAuthentications) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.RequestAuthentications)
 	}
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.RequestAuthenticationsType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			l, ok := obj.(*security_v1beta1.RequestAuthentication)
-			if !ok {
-				return nil, errors.New("bad RequestAuthentication type found in cache")
-			}
-			l.Kind = kubernetes.RequestAuthenticationsType
-			log.Tracef("[Kiali Cache] Get [resource: RequestAuthentication] for [namespace: %s] [name: %s]", namespace, name)
-			return l, nil
-		}
-	}
-	return nil, nil
+
+	ra, err := c.getCacheLister(namespace).requestAuthnLister.RequestAuthentications(namespace).Get(name)
+	if err != nil {
+		return nil, err
+	}
+
+	ra.Kind = kubernetes.RequestAuthenticationsType
+	return ra, nil
 }
 
 func (c *kialiCacheImpl) GetRequestAuthentications(namespace, labelSelector string) ([]*security_v1beta1.RequestAuthentication, error) {
 	if !c.CheckIstioResource(kubernetes.RequestAuthentications) {
 		return nil, fmt.Errorf("Kiali cache doesn't support [resourceType: %s]", kubernetes.RequestAuthenticationsType)
 	}
-	if nsCache, nsOk := c.nsCache[namespace]; nsOk {
-		l := nsCache[kubernetes.RequestAuthenticationsType].GetStore().List()
-		lenL := len(l)
-		if lenL > 0 {
-			_, ok := l[0].(*security_v1beta1.RequestAuthentication)
-			if !ok {
-				return []*security_v1beta1.RequestAuthentication{}, errors.New("bad RequestAuthentication type found in cache")
-			}
-			nsL := make([]*security_v1beta1.RequestAuthentication, lenL)
-			for i, li := range l {
-				nsL[i] = li.(*security_v1beta1.RequestAuthentication)
-				nsL[i].Kind = kubernetes.RequestAuthenticationsType
-			}
-			log.Tracef("[Kiali Cache] Get [resource: RequestAuthentication] for [namespace: %s] = %d", namespace, lenL)
-			if labelSelector == "" {
-				return nsL, nil
-			}
-			var filteredL []*security_v1beta1.RequestAuthentication
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []*security_v1beta1.RequestAuthentication{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, li := range nsL {
-				if selector.Matches(labels.Set(li.Labels)) {
-					filteredL = append(filteredL, li)
-				}
-			}
-			return filteredL, nil
-		}
-	}
-	return []*security_v1beta1.RequestAuthentication{}, nil
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
+	}
+
+	reqAuths, err := c.getCacheLister(namespace).requestAuthnLister.RequestAuthentications(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+
+	// Lister returns nil when there are no results but callers of the cache expect an empty array
+	// so keeping the behavior the same since it matters for json marshalling.
+	if reqAuths == nil {
+		return []*security_v1beta1.RequestAuthentication{}, nil
+	}
+
+	for _, ra := range reqAuths {
+		ra.Kind = kubernetes.RequestAuthenticationsType
+	}
+	return reqAuths, nil
 }
diff --git a/kubernetes/cache/kubernetes.go b/kubernetes/cache/kubernetes.go
index 5f05f3eed..ade7085e0 100644
--- a/kubernetes/cache/kubernetes.go
+++ b/kubernetes/cache/kubernetes.go
@@ -1,9 +1,6 @@
 package cache
 
 import (
-	"errors"
-	"fmt"
-
 	apps_v1 "k8s.io/api/apps/v1"
 	core_v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/labels"
@@ -30,279 +27,189 @@ type (
 	}
 )
 
-func (c *kialiCacheImpl) createKubernetesInformers(namespace string, informer *typeCache) {
-	sharedInformers := informers.NewSharedInformerFactoryWithOptions(c.k8sApi, c.refreshDuration, informers.WithNamespace(namespace))
-	(*informer)[kubernetes.DeploymentType] = sharedInformers.Apps().V1().Deployments().Informer()
-	(*informer)[kubernetes.StatefulSetType] = sharedInformers.Apps().V1().StatefulSets().Informer()
-	(*informer)[kubernetes.ReplicaSetType] = sharedInformers.Apps().V1().ReplicaSets().Informer()
-	(*informer)[kubernetes.DaemonSetType] = sharedInformers.Apps().V1().DaemonSets().Informer()
-	(*informer)[kubernetes.ServiceType] = sharedInformers.Core().V1().Services().Informer()
-	(*informer)[kubernetes.ServiceType].AddEventHandler(c.registryRefreshHandler)
-	(*informer)[kubernetes.PodType] = sharedInformers.Core().V1().Pods().Informer()
-	(*informer)[kubernetes.ConfigMapType] = sharedInformers.Core().V1().ConfigMaps().Informer()
-	(*informer)[kubernetes.EndpointsType] = sharedInformers.Core().V1().Endpoints().Informer()
-	(*informer)[kubernetes.EndpointsType].AddEventHandler(c.registryRefreshHandler)
-}
+// createKubernetesInformers creates kube informers for all objects kiali watches and
+// saves them to the typeCache. If namespace is not empty, the informers are scoped
+// to the namespace. Otherwise, the informers are cluster-wide.
+func (c *kialiCacheImpl) createKubernetesInformers(namespace string) informers.SharedInformerFactory {
+	var opts []informers.SharedInformerOption
+	if namespace != "" {
+		opts = append(opts, informers.WithNamespace(namespace))
+	}
+	sharedInformers := informers.NewSharedInformerFactoryWithOptions(c.k8sApi, c.refreshDuration, opts...)
+
+	lister := &cacheLister{
+		deploymentLister:  sharedInformers.Apps().V1().Deployments().Lister(),
+		statefulSetLister: sharedInformers.Apps().V1().StatefulSets().Lister(),
+		daemonSetLister:   sharedInformers.Apps().V1().DaemonSets().Lister(),
+		serviceLister:     sharedInformers.Core().V1().Services().Lister(),
+		endpointLister:    sharedInformers.Core().V1().Endpoints().Lister(),
+		podLister:         sharedInformers.Core().V1().Pods().Lister(),
+		replicaSetLister:  sharedInformers.Apps().V1().ReplicaSets().Lister(),
+		configMapLister:   sharedInformers.Core().V1().ConfigMaps().Lister(),
+	}
+	sharedInformers.Core().V1().Services().Informer().AddEventHandler(c.registryRefreshHandler)
+	sharedInformers.Core().V1().Endpoints().Informer().AddEventHandler(c.registryRefreshHandler)
 
-func (c *kialiCacheImpl) isKubernetesSynced(namespace string) bool {
-	var isSynced bool
-	if nsCache, exist := c.nsCache[namespace]; exist {
-		isSynced = nsCache[kubernetes.DeploymentType].HasSynced() &&
-			nsCache[kubernetes.StatefulSetType].HasSynced() &&
-			nsCache[kubernetes.ReplicaSetType].HasSynced() &&
-			nsCache[kubernetes.DaemonSetType].HasSynced() &&
-			nsCache[kubernetes.ServiceType].HasSynced() &&
-			nsCache[kubernetes.PodType].HasSynced() &&
-			nsCache[kubernetes.ConfigMapType].HasSynced() &&
-			nsCache[kubernetes.EndpointsType].HasSynced()
+	if c.clusterScoped {
+		c.clusterCacheLister = lister
 	} else {
-		isSynced = false
+		c.nsCacheLister[namespace] = lister
+	}
+
+	return sharedInformers
+}
+
+func (c *kialiCacheImpl) getCacheLister(namespace string) *cacheLister {
+	if c.clusterScoped {
+		return c.clusterCacheLister
 	}
-	return isSynced
+	return c.nsCacheLister[namespace]
 }
 
 func (c *kialiCacheImpl) GetConfigMap(namespace, name string) (*core_v1.ConfigMap, error) {
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.ConfigMapType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			cm, ok := obj.(*core_v1.ConfigMap)
-			if !ok {
-				return nil, errors.New("bad ConfigMap type found in cache")
-			}
-			log.Tracef("[Kiali Cache] Get [resource: ConfigMap] for [namespace: %s] [name: %s]", namespace, name)
-			return cm, nil
-		}
+	log.Tracef("[Kiali Cache] Get [resource: ConfigMap] for [namespace: %s] [name: %s]", namespace, name)
+	cfg, err := c.getCacheLister(namespace).configMapLister.ConfigMaps(namespace).Get(name)
+	if err != nil {
+		return nil, err
 	}
-	return nil, nil
+
+	cfg.Kind = kubernetes.ConfigMapType
+	return cfg, nil
 }
 
 func (c *kialiCacheImpl) GetDaemonSets(namespace string) ([]apps_v1.DaemonSet, error) {
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		daeset := nsCache[kubernetes.DaemonSetType].GetStore().List()
-		lenDaeSet := len(daeset)
-		if lenDaeSet > 0 {
-			_, ok := daeset[0].(*apps_v1.DaemonSet)
-			if !ok {
-				return nil, errors.New("bad DaemonSet type found in cache")
-			}
-			nsDaeSets := make([]apps_v1.DaemonSet, lenDaeSet)
-			for i, ds := range daeset {
-				nsDaeSets[i] = *(ds.(*apps_v1.DaemonSet))
-			}
-			log.Tracef("[Kiali Cache] Get [resource: DaemonSet] for [namespace: %s] = %d", namespace, lenDaeSet)
-			return nsDaeSets, nil
-		}
+	daemonSets, err := c.getCacheLister(namespace).daemonSetLister.DaemonSets(namespace).List(labels.Everything())
+	if err != nil {
+		return nil, err
+	}
+	log.Tracef("[Kiali Cache] Get [resource: DaemonSet] for [namespace: %s] = %d", namespace, len(daemonSets))
+
+	retSets := []apps_v1.DaemonSet{}
+	for _, ds := range daemonSets {
+		ds.Kind = kubernetes.DaemonSetType
+		retSets = append(retSets, *ds)
 	}
-	return []apps_v1.DaemonSet{}, nil
+	return retSets, nil
 }
 
 func (c *kialiCacheImpl) GetDaemonSet(namespace, name string) (*apps_v1.DaemonSet, error) {
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.DaemonSetType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			ds, ok := obj.(*apps_v1.DaemonSet)
-			if !ok {
-				return nil, errors.New("bad DaemonSet type found in cache")
-			}
-			log.Tracef("[Kiali Cache] Get [resource: DaemonSet] for [namespace: %s] [name: %s]", namespace, name)
-			return ds, nil
-		}
+	log.Tracef("[Kiali Cache] Get [resource: DaemonSet] for [namespace: %s] [name: %s]", namespace, name)
+	ds, err := c.getCacheLister(namespace).daemonSetLister.DaemonSets(namespace).Get(name)
+	if err != nil {
+		return nil, err
 	}
-	return nil, nil
+
+	ds.Kind = kubernetes.DaemonSetType
+	return c.getCacheLister(namespace).daemonSetLister.DaemonSets(namespace).Get(name)
 }
 
 func (c *kialiCacheImpl) GetDeployments(namespace string) ([]apps_v1.Deployment, error) {
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		deps := nsCache[kubernetes.DeploymentType].GetStore().List()
-		lenDeps := len(deps)
-		if lenDeps > 0 {
-			_, ok := deps[0].(*apps_v1.Deployment)
-			if !ok {
-				return nil, errors.New("bad Deployment type found in cache")
-			}
-			nsDeps := make([]apps_v1.Deployment, lenDeps)
-			for i, dep := range deps {
-				nsDeps[i] = *(dep.(*apps_v1.Deployment))
-			}
-			log.Tracef("[Kiali Cache] Get [resource: Deployment] for [namespace: %s] = %d", namespace, lenDeps)
-			return nsDeps, nil
-		}
+	deployments, err := c.getCacheLister(namespace).deploymentLister.Deployments(namespace).List(labels.Everything())
+	if err != nil {
+		return nil, err
+	}
+	log.Tracef("[Kiali Cache] Get [resource: Deployment] for [namespace: %s] = %d", namespace, len(deployments))
+
+	retDeployments := []apps_v1.Deployment{}
+	for _, deployment := range deployments {
+		deployment.Kind = kubernetes.DeploymentType
+		retDeployments = append(retDeployments, *deployment)
 	}
-	return []apps_v1.Deployment{}, nil
+	return retDeployments, nil
 }
 
 func (c *kialiCacheImpl) GetDeployment(namespace, name string) (*apps_v1.Deployment, error) {
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.DeploymentType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			dep, ok := obj.(*apps_v1.Deployment)
-			if !ok {
-				return nil, errors.New("bad Deployment type found in cache")
-			}
-			log.Tracef("[Kiali Cache] Get [resource: Deployment] for [namespace: %s] [name: %s]", namespace, name)
-			return dep, nil
-		}
+	log.Tracef("[Kiali Cache] Get [resource: Deployment] for [namespace: %s] [name: %s]", namespace, name)
+	deployment, err := c.getCacheLister(namespace).deploymentLister.Deployments(namespace).Get(name)
+	if err != nil {
+		return nil, err
 	}
-	return nil, nil
+
+	deployment.Kind = kubernetes.DeploymentType
+	return deployment, nil
 }
 
 func (c *kialiCacheImpl) GetEndpoints(namespace, name string) (*core_v1.Endpoints, error) {
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.EndpointsType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			eps, ok := obj.(*core_v1.Endpoints)
-			if !ok {
-				return nil, errors.New("bad Endpoints type found in cache")
-			}
-			log.Tracef("[Kiali Cache] Get [resource: Endpoints] for [namespace: %s] [name: %s]", namespace, name)
-			return eps, nil
-		}
+	log.Tracef("[Kiali Cache] Get [resource: Endpoints] for [namespace: %s] [name: %s]", namespace, name)
+	endpoints, err := c.getCacheLister(namespace).endpointLister.Endpoints(namespace).Get(name)
+	if err != nil {
+		return nil, err
 	}
-	return nil, nil
+
+	endpoints.Kind = kubernetes.EndpointsType
+	return endpoints, nil
 }
 
 func (c *kialiCacheImpl) GetStatefulSets(namespace string) ([]apps_v1.StatefulSet, error) {
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		ss := nsCache[kubernetes.StatefulSetType].GetStore().List()
-		lenSs := len(ss)
-		if lenSs > 0 {
-			_, ok := ss[0].(*apps_v1.StatefulSet)
-			if !ok {
-				return nil, errors.New("bad StatefulSet type found in cache")
-			}
-			nsSs := make([]apps_v1.StatefulSet, lenSs)
-			for i, s := range ss {
-				nsSs[i] = *(s.(*apps_v1.StatefulSet))
-			}
-			log.Tracef("[Kiali Cache] Get [resource: StatefulSet] for [namespace: %s] = %d", namespace, lenSs)
-			return nsSs, nil
-		}
+	statefulSets, err := c.getCacheLister(namespace).statefulSetLister.StatefulSets(namespace).List(labels.Everything())
+	if err != nil {
+		return nil, err
 	}
-	return []apps_v1.StatefulSet{}, nil
+	log.Tracef("[Kiali Cache] Get [resource: StatefulSet] for [namespace: %s] = %d", namespace, len(statefulSets))
+
+	retSets := []apps_v1.StatefulSet{}
+	for _, ss := range statefulSets {
+		ss.Kind = kubernetes.StatefulSetType
+		retSets = append(retSets, *ss)
+	}
+	return retSets, nil
 }
 
 func (c *kialiCacheImpl) GetStatefulSet(namespace, name string) (*apps_v1.StatefulSet, error) {
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.StatefulSetType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			ss, ok := obj.(*apps_v1.StatefulSet)
-			if !ok {
-				return nil, errors.New("bad StatefulSet type found in cache")
-			}
-			log.Tracef("[Kiali Cache] Get [resource: StatefulSet] for [namespace: %s] [name: %s]", namespace, name)
-			return ss, nil
-		}
+	log.Tracef("[Kiali Cache] Get [resource: StatefulSet] for [namespace: %s] [name: %s]", namespace, name)
+	statefulSet, err := c.getCacheLister(namespace).statefulSetLister.StatefulSets(namespace).Get(name)
+	if err != nil {
+		return nil, err
 	}
-	return nil, nil
+
+	statefulSet.Kind = kubernetes.StatefulSetType
+	return statefulSet, nil
 }
 
 func (c *kialiCacheImpl) GetServices(namespace string, selectorLabels map[string]string) ([]core_v1.Service, error) {
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		services := nsCache[kubernetes.ServiceType].GetStore().List()
-		lenServices := len(services)
-		if lenServices > 0 {
-			_, ok := services[0].(*core_v1.Service)
-			if !ok {
-				return []core_v1.Service{}, errors.New("bad Service type found in cache")
-			}
-			nsServices := make([]core_v1.Service, lenServices)
-			for i, service := range services {
-				nsServices[i] = *(service.(*core_v1.Service))
-			}
-			log.Tracef("[Kiali Cache] Get [resource: Service] for [namespace: %s] = %d", namespace, lenServices)
-			if selectorLabels == nil {
-				return nsServices, nil
-			}
-			var filteredServices []core_v1.Service
-			labelsMap := labels.Set(selectorLabels)
-			for _, svc := range nsServices {
-				svcSelector := labels.Set(svc.Spec.Selector).AsSelector()
-				if !svcSelector.Empty() && svcSelector.Matches(labelsMap) {
-					filteredServices = append(filteredServices, svc)
-				}
-			}
-			return filteredServices, nil
-		}
+	services, err := c.getCacheLister(namespace).serviceLister.Services(namespace).List(labels.Set(selectorLabels).AsSelector())
+	if err != nil {
+		return nil, err
 	}
-	return []core_v1.Service{}, nil
+	log.Tracef("[Kiali Cache] Get [resource: Service] for [namespace: %s] = %d", namespace, len(services))
+
+	retServices := []core_v1.Service{}
+	for _, service := range services {
+		service.Kind = kubernetes.ServiceType
+		retServices = append(retServices, *service)
+	}
+	return retServices, nil
 }
 
 func (c *kialiCacheImpl) GetService(namespace, name string) (*core_v1.Service, error) {
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		// Cache stores natively items with namespace/name pattern, we can skip the Indexer by name and make a direct call
-		key := namespace + "/" + name
-		obj, exist, err := nsCache[kubernetes.ServiceType].GetStore().GetByKey(key)
-		if err != nil {
-			return nil, err
-		}
-		if exist {
-			svc, ok := obj.(*core_v1.Service)
-			if !ok {
-				return nil, errors.New("bad Service type found in cache")
-			}
-			log.Tracef("[Kiali Cache] Get [resource: Service] for [namespace: %s] [name: %s]", namespace, name)
-			return svc, nil
-		}
+	log.Tracef("[Kiali Cache] Get [resource: Service] for [namespace: %s] [name: %s]", namespace, name)
+	service, err := c.getCacheLister(namespace).serviceLister.Services(namespace).Get(name)
+	if err != nil {
+		return nil, err
 	}
-	return nil, nil
+
+	service.Kind = kubernetes.ServiceType
+	return service, nil
 }
 
 func (c *kialiCacheImpl) GetPods(namespace, labelSelector string) ([]core_v1.Pod, error) {
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		pods := nsCache[kubernetes.PodType].GetStore().List()
-		lenPods := len(pods)
-		if lenPods > 0 {
-			_, ok := pods[0].(*core_v1.Pod)
-			if !ok {
-				return []core_v1.Pod{}, errors.New("bad Pod type found in cache")
-			}
-			nsPods := make([]core_v1.Pod, lenPods)
-			for i, pod := range pods {
-				nsPods[i] = *(pod.(*core_v1.Pod))
-			}
-			log.Tracef("[Kiali Cache] Get [resource: Pod] for [namespace: %s] = %d", namespace, lenPods)
-			if labelSelector == "" {
-				return nsPods, nil
-			}
-			var filteredPods []core_v1.Pod
-			selector, selErr := labels.Parse(labelSelector)
-			if selErr != nil {
-				return []core_v1.Pod{}, fmt.Errorf("%s can not be processed as selector: %v", labelSelector, selErr)
-			}
-			for _, pod := range nsPods {
-				if selector.Matches(labels.Set(pod.Labels)) {
-					filteredPods = append(filteredPods, pod)
-				}
-			}
-			return filteredPods, nil
-		}
+	selector, err := labels.Parse(labelSelector)
+	if err != nil {
+		return nil, err
 	}
-	return []core_v1.Pod{}, nil
+
+	pods, err := c.getCacheLister(namespace).podLister.Pods(namespace).List(selector)
+	if err != nil {
+		return nil, err
+	}
+	log.Tracef("[Kiali Cache] Get [resource: Pod] for [namespace: %s] = %d", namespace, len(pods))
+
+	retPods := []core_v1.Pod{}
+	for _, pod := range pods {
+		pod.Kind = kubernetes.PodType
+		retPods = append(retPods, *pod)
+	}
+	return retPods, nil
 }
 
 // GetReplicaSets returns the cached ReplicaSets for the namespace.  For any given Owner (i.e. Deployment),
@@ -311,45 +218,42 @@ func (c *kialiCacheImpl) GetPods(namespace, labelSelector string) ([]core_v1.Pod
 // same Deployment (current and older revisions).
 // see also: ../kubernetes.go
 func (c *kialiCacheImpl) GetReplicaSets(namespace string) ([]apps_v1.ReplicaSet, error) {
-	if nsCache, ok := c.nsCache[namespace]; ok {
-		reps := nsCache[kubernetes.ReplicaSetType].GetStore().List()
-		if len(reps) > 0 {
-			_, ok := reps[0].(*apps_v1.ReplicaSet)
-			if !ok {
-				return nil, errors.New("bad ReplicaSet type found in cache")
-			}
+	reps, err := c.getCacheLister(namespace).replicaSetLister.ReplicaSets(namespace).List(labels.Everything())
+	if err != nil {
+		return nil, err
+	}
 
-			activeRSMap := map[string]*apps_v1.ReplicaSet{}
-			for _, ref := range reps {
-				rs := ref.(*apps_v1.ReplicaSet)
-				if len(rs.OwnerReferences) > 0 {
-					for _, ownerRef := range rs.OwnerReferences {
-						if ownerRef.Controller != nil && *ownerRef.Controller {
-							if currRS, ok := activeRSMap[ownerRef.Name]; ok {
-								if currRS.CreationTimestamp.Time.Before(rs.CreationTimestamp.Time) {
-									activeRSMap[ownerRef.Name] = rs
-								}
-							} else {
+	result := []apps_v1.ReplicaSet{}
+	if len(reps) > 0 {
+		activeRSMap := map[string]*apps_v1.ReplicaSet{}
+		for _, rs := range reps {
+			if len(rs.OwnerReferences) > 0 {
+				for _, ownerRef := range rs.OwnerReferences {
+					if ownerRef.Controller != nil && *ownerRef.Controller {
+						if currRS, ok := activeRSMap[ownerRef.Name]; ok {
+							if currRS.CreationTimestamp.Time.Before(rs.CreationTimestamp.Time) {
 								activeRSMap[ownerRef.Name] = rs
 							}
+						} else {
+							activeRSMap[ownerRef.Name] = rs
 						}
 					}
-				} else {
-					// it is it's own controller
-					activeRSMap[rs.Name] = rs
 				}
+			} else {
+				// it is it's own controller
+				activeRSMap[rs.Name] = rs
 			}
+		}
 
-			lenRS := len(activeRSMap)
-			result := make([]apps_v1.ReplicaSet, lenRS)
-			i := 0
-			for _, activeRS := range activeRSMap {
-				result[i] = *(activeRS)
-				i = i + 1
-			}
-			log.Tracef("[Kiali Cache] Get [resource: ReplicaSet] for [namespace: %s] = %d", namespace, lenRS)
-			return result, nil
+		lenRS := len(activeRSMap)
+		result = make([]apps_v1.ReplicaSet, lenRS)
+		i := 0
+		for _, activeRS := range activeRSMap {
+			activeRS.Kind = kubernetes.ReplicaSetType
+			result[i] = *(activeRS)
+			i = i + 1
 		}
+		log.Tracef("[Kiali Cache] Get [resource: ReplicaSet] for [namespace: %s] = %d", namespace, lenRS)
 	}
-	return []apps_v1.ReplicaSet{}, nil
+	return result, nil
 }
diff --git a/kubernetes/kubernetes.go b/kubernetes/kubernetes.go
index 475b286fa..d9168cc69 100644
--- a/kubernetes/kubernetes.go
+++ b/kubernetes/kubernetes.go
@@ -469,7 +469,7 @@ func (in *K8SClient) GetSelfSubjectAccessReview(ctx context.Context, namespace,
 		ctx, span = otel.Tracer(observability.TracerName()).Start(ctx, "GetSelfSubjectAccessReview",
 			trace.WithAttributes(
 				attribute.String("package", "kubernetes"),
-				attribute.String("namspace", namespace),
+				attribute.String("namespace", namespace),
 				attribute.String("api", api),
 				attribute.String("resourceType", resourceType),
 				attribute.StringSlice("verbs", verbs),
diff --git a/make/Makefile.ui.mk b/make/Makefile.ui.mk
index 41a455ade..b5facef8e 100644
--- a/make/Makefile.ui.mk
+++ b/make/Makefile.ui.mk
@@ -27,8 +27,8 @@ cypress-gui:
 
 ## perf-tests-run: Runs the frontend perf tests locally without the GUI.
 perf-tests-run:
-	@cd ${ROOTDIR}/frontend && ${ROOTDIR}/frontend/node_modules/cypress/bin/cypress run --headless --config numTestsKeptInMemory=0,video=false --config-file cypress-perf.json
+	@cd ${ROOTDIR}/frontend && ${ROOTDIR}/frontend/node_modules/cypress/bin/cypress run --headless --config numTestsKeptInMemory=0,video=false --config-file cypress-perf.config.ts
 
 ## perf-tests-gui: Runs the frontend perf tests locally with the GUI.
 perf-tests-gui:
-	@cd ${ROOTDIR}/frontend && yarn cypress --config-file cypress-perf.json 
+	@cd ${ROOTDIR}/frontend && yarn cypress --config-file cypress-perf.config.ts
diff --git a/server/server.go b/server/server.go
index f6cf8db4d..d6686b797 100644
--- a/server/server.go
+++ b/server/server.go
@@ -85,6 +85,11 @@ func NewServer() *Server {
 
 // Start HTTP server asynchronously. TLS may be active depending on the global configuration.
 func (s *Server) Start() {
+	// Start the business to initialize cache dependencies.
+	// The business cache should start before the server endpoint to ensure
+	// that the cache is ready before it's used by one of the server handlers.
+	business.Start()
+
 	conf := config.Get()
 	log.Infof("Server endpoint will start at [%v%v]", s.httpServer.Addr, conf.Server.WebRoot)
 	log.Infof("Server endpoint will serve static content from [%v]", conf.Server.StaticContentRootDirectory)
@@ -106,9 +111,6 @@ func (s *Server) Start() {
 	if conf.Server.Observability.Metrics.Enabled {
 		StartMetricsServer()
 	}
-
-	// Start the business to initialize cache dependencies
-	business.Start()
 }
 
 // Stop the HTTP server



Test patch:
diff --git a/config/config_test.go b/config/config_test.go
index 11a3d65a2..640cfa865 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -207,7 +207,6 @@ func TestError(t *testing.T) {
 }
 
 func TestRaces(t *testing.T) {
-
 	wg := sync.WaitGroup{}
 	wg.Add(10)
 
@@ -232,7 +231,6 @@ func TestRaces(t *testing.T) {
 
 func TestMarshalUnmarshalCompatibilityMatrix(t *testing.T) {
 	matrix, err := NewCompatibilityMatrix()
-
 	if err != nil {
 		t.Errorf("Failed to marshal: %v", err)
 	}
@@ -240,3 +238,41 @@ func TestMarshalUnmarshalCompatibilityMatrix(t *testing.T) {
 	fmt.Printf("%+v", matrix)
 	t.Logf("Config from compatibility matrix file: %+v", matrix)
 }
+
+func TestAllNamespacesAccessible(t *testing.T) {
+	cases := map[string]struct {
+		expectedAccessible   bool
+		accessibleNamespaces []string
+	}{
+		"with **": {
+			expectedAccessible:   true,
+			accessibleNamespaces: []string{"**"},
+		},
+		"with ** and others": {
+			expectedAccessible:   true,
+			accessibleNamespaces: []string{"test1", "test2", "**"},
+		},
+		"without **": {
+			expectedAccessible:   false,
+			accessibleNamespaces: []string{"test1", "test2"},
+		},
+		"empty": {
+			expectedAccessible:   false,
+			accessibleNamespaces: []string{},
+		},
+	}
+
+	for name, tc := range cases {
+		t.Run(name, func(t *testing.T) {
+			assert := assert.New(t)
+
+			conf := &Config{
+				Deployment: DeploymentConfig{
+					AccessibleNamespaces: tc.accessibleNamespaces,
+				},
+			}
+
+			assert.Equal(tc.expectedAccessible, conf.AllNamespacesAccessible())
+		})
+	}
+}
diff --git a/kubernetes/cache/cache_handlers_test.go b/kubernetes/cache/cache_handlers_test.go
new file mode 100644
index 000000000..e3f2741a1
--- /dev/null
+++ b/kubernetes/cache/cache_handlers_test.go
@@ -0,0 +1,89 @@
+package cache
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+type fakeRegistryStatus struct {
+	statusRefreshed bool
+}
+
+func (f *fakeRegistryStatus) RefreshRegistryStatus() {
+	f.statusRefreshed = true
+}
+
+func TestRegistryStatusUpdatedOnAdd(t *testing.T) {
+	assert := assert.New(t)
+	kialiCache := &fakeRegistryStatus{}
+	handler := NewRegistryHandler(kialiCache.RefreshRegistryStatus)
+	handler.OnAdd(&corev1.Service{})
+	assert.True(kialiCache.statusRefreshed)
+}
+
+func TestRegistryStatusUpdatedOnDelete(t *testing.T) {
+	assert := assert.New(t)
+	kialiCache := &fakeRegistryStatus{}
+	handler := NewRegistryHandler(kialiCache.RefreshRegistryStatus)
+	handler.OnDelete(&corev1.Service{})
+	assert.True(kialiCache.statusRefreshed)
+}
+
+func TestRegistryStatusUpdatedOnUpdate(t *testing.T) {
+	cases := map[string]struct {
+		old, new        interface{}
+		expectedRefresh bool
+	}{
+		"Same revision": {
+			old: &corev1.Service{
+				ObjectMeta: metav1.ObjectMeta{
+					ResourceVersion: "1",
+				},
+			},
+			new: &corev1.Service{
+				ObjectMeta: metav1.ObjectMeta{
+					ResourceVersion: "1",
+				},
+			},
+			expectedRefresh: false,
+		},
+		"Different revision": {
+			old: &corev1.Service{
+				ObjectMeta: metav1.ObjectMeta{
+					ResourceVersion: "1",
+				},
+			},
+			new: &corev1.Service{
+				ObjectMeta: metav1.ObjectMeta{
+					ResourceVersion: "2",
+				},
+			},
+			expectedRefresh: true,
+		},
+		"old object not typemeta": {
+			old:             &struct{}{},
+			new:             &corev1.Service{},
+			expectedRefresh: false,
+		},
+		"new object not typemeta": {
+			old:             &corev1.Service{},
+			new:             &struct{}{},
+			expectedRefresh: false,
+		},
+	}
+
+	for name, tc := range cases {
+		t.Run(name, func(t *testing.T) {
+			assert := assert.New(t)
+			kialiCache := &fakeRegistryStatus{}
+			handler := NewRegistryHandler(kialiCache.RefreshRegistryStatus)
+
+			handler.OnUpdate(tc.old, tc.new)
+
+			assert.Equal(tc.expectedRefresh, kialiCache.statusRefreshed)
+		})
+	}
+}
diff --git a/kubernetes/cache/cache_test.go b/kubernetes/cache/cache_test.go
index a5835156f..671558abe 100644
--- a/kubernetes/cache/cache_test.go
+++ b/kubernetes/cache/cache_test.go
@@ -3,12 +3,32 @@ package cache
 import (
 	"regexp"
 	"testing"
+	"time"
 
 	"github.com/stretchr/testify/assert"
+	istiofake "istio.io/client-go/pkg/clientset/versioned/fake"
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	kubefake "k8s.io/client-go/kubernetes/fake"
 
 	"github.com/kiali/kiali/kubernetes"
 )
 
+func newTestKialiCache(kubeObjects []runtime.Object, istioObjects []runtime.Object) *kialiCacheImpl {
+	kialiCache := &kialiCacheImpl{
+		k8sApi:                kubefake.NewSimpleClientset(kubeObjects...),
+		istioApi:              istiofake.NewSimpleClientset(istioObjects...),
+		clusterScoped:         false,
+		stopClusterScopedChan: make(chan struct{}),
+		stopNSChans:           make(map[string]chan struct{}),
+		nsCacheLister:         make(map[string]*cacheLister),
+		stopCacheChan:         make(chan bool),
+	}
+	kialiCache.registryRefreshHandler = NewRegistryHandler(kialiCache.RefreshRegistryStatus)
+	return kialiCache
+}
+
 func TestNewKialiCache_isCached(t *testing.T) {
 	assert := assert.New(t)
 
@@ -16,8 +36,6 @@ func TestNewKialiCache_isCached(t *testing.T) {
 		istioClient:            kubernetes.K8SClient{},
 		refreshDuration:        0,
 		cacheNamespacesRegexps: []regexp.Regexp{*regexp.MustCompile("bookinfo"), *regexp.MustCompile("a.*"), *regexp.MustCompile("galicia")},
-		stopChan:               nil,
-		nsCache:                map[string]typeCache{},
 	}
 
 	assert.True(kialiCacheImpl.isCached("bookinfo"))
@@ -27,3 +45,110 @@ func TestNewKialiCache_isCached(t *testing.T) {
 	assert.False(kialiCacheImpl.isCached("bbcdefghi"))
 	assert.True(kialiCacheImpl.isCached("galicia"))
 }
+
+func TestClusterScopedCacheStopped(t *testing.T) {
+	assert := assert.New(t)
+
+	kialiCacheImpl := newTestKialiCache(nil, nil)
+	stopCh := make(chan struct{})
+	kialiCacheImpl.stopClusterScopedChan = stopCh
+	kialiCacheImpl.clusterScoped = true
+	kialiCacheImpl.Refresh("")
+
+	kialiCacheImpl.Stop()
+	select {
+	case <-time.After(300 * time.Millisecond):
+		assert.Fail("Cache should have been stopped")
+	case <-stopCh:
+	}
+}
+
+func TestNSScopedCacheStopped(t *testing.T) {
+	assert := assert.New(t)
+
+	stopChs := map[string]chan struct{}{
+		"ns1": make(chan struct{}),
+		"ns2": make(chan struct{}),
+	}
+	kialiCacheImpl := newTestKialiCache(nil, nil)
+	kialiCacheImpl.stopNSChans = stopChs
+	kialiCacheImpl.clusterScoped = false
+
+	kialiCacheImpl.Stop()
+	for ns, stopCh := range stopChs {
+		select {
+		case <-time.After(300 * time.Millisecond):
+			assert.Failf("Cache for namespace: %s should have been stopped", ns)
+		case <-stopCh:
+		}
+	}
+
+	assert.Empty(kialiCacheImpl.nsCacheLister)
+}
+
+func TestRefreshClusterScoped(t *testing.T) {
+	assert := assert.New(t)
+
+	svc := &corev1.Service{ObjectMeta: metav1.ObjectMeta{Name: "svc1", Namespace: "ns1"}}
+	kialiCache := newTestKialiCache([]runtime.Object{svc}, nil)
+	kialiCache.clusterScoped = true
+	kialiCache.clusterCacheLister = &cacheLister{}
+	oldLister := kialiCache.clusterCacheLister
+	kialiCache.Refresh("")
+	assert.NotEqual(kialiCache.clusterCacheLister, oldLister)
+}
+
+func TestRefreshMultipleTimesClusterScoped(t *testing.T) {
+	assert := assert.New(t)
+
+	kialiCache := newTestKialiCache(nil, nil)
+	kialiCache.clusterScoped = true
+	kialiCache.clusterCacheLister = &cacheLister{}
+	oldLister := kialiCache.clusterCacheLister
+
+	kialiCache.Refresh("")
+	kialiCache.Refresh("")
+	assert.NotEqual(kialiCache.clusterCacheLister, oldLister)
+}
+
+func TestRefreshNSScoped(t *testing.T) {
+	assert := assert.New(t)
+
+	kialiCache := newTestKialiCache(nil, nil)
+	kialiCache.clusterScoped = false
+	kialiCache.nsCacheLister = map[string]*cacheLister{}
+
+	kialiCache.Refresh("ns1")
+	assert.NotEqual(kialiCache.nsCacheLister, map[string]*cacheLister{})
+	assert.Contains(kialiCache.nsCacheLister, "ns1")
+}
+
+func TestCheckNamespaceClusterScoped(t *testing.T) {
+	assert := assert.New(t)
+
+	kialiCache := newTestKialiCache(nil, nil)
+	kialiCache.clusterScoped = true
+
+	// Should always return true for cluster scoped cache.
+	assert.True(kialiCache.CheckNamespace("ns1"))
+}
+
+func TestCheckNamespaceNotIncluded(t *testing.T) {
+	assert := assert.New(t)
+
+	kialiCache := newTestKialiCache(nil, nil)
+	kialiCache.clusterScoped = false
+
+	assert.False(kialiCache.CheckNamespace("ns1"))
+}
+
+func TestCheckNamespaceIsIncluded(t *testing.T) {
+	assert := assert.New(t)
+
+	regex := regexp.MustCompile("ns.*")
+	kialiCache := newTestKialiCache(nil, nil)
+	kialiCache.clusterScoped = false
+	kialiCache.cacheNamespacesRegexps = []regexp.Regexp{*regex}
+
+	assert.True(kialiCache.CheckNamespace("ns1"))
+}
diff --git a/kubernetes/cache/istio_test.go b/kubernetes/cache/istio_test.go
index 65084a3f5..81110dd40 100644
--- a/kubernetes/cache/istio_test.go
+++ b/kubernetes/cache/istio_test.go
@@ -3,12 +3,13 @@ package cache
 import (
 	"fmt"
 	"testing"
-	"time"
 
 	"github.com/stretchr/testify/assert"
 	networking_v1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
-	"k8s.io/apimachinery/pkg/fields"
-	"k8s.io/client-go/tools/cache"
+	istiofake "istio.io/client-go/pkg/clientset/versioned/fake"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	kubefake "k8s.io/client-go/kubernetes/fake"
 
 	"github.com/kiali/kiali/kubernetes"
 )
@@ -22,25 +23,17 @@ func TestGetSidecar(t *testing.T) {
 		"version": "v1",
 	}
 
-	fakeInform := &fakeInformer{
-		SharedIndexInformer: createIstioIndexInformer(nil, kubernetes.Sidecars, time.Minute, "anyns"),
-		Store: &cache.FakeCustomStore{
-			ListFunc: func() []interface{} {
-				return []interface{}{sidecar}
-			},
-		},
-	}
-
 	kialiCacheImpl := kialiCacheImpl{
-		nsCache: map[string]typeCache{
-			sidecar.Namespace: {
-				kubernetes.SidecarType: fakeInform,
-			},
-		},
+		clusterScoped:         true,
+		stopClusterScopedChan: make(chan struct{}),
+		istioApi:              istiofake.NewSimpleClientset(sidecar),
+		k8sApi:                kubefake.NewSimpleClientset(),
 		cacheIstioTypes: map[string]bool{
 			kubernetes.PluralType[kubernetes.Sidecars]: true,
 		},
+		clusterCacheLister: &cacheLister{},
 	}
+	kialiCacheImpl.registryRefreshHandler = NewRegistryHandler(kialiCacheImpl.RefreshRegistryStatus)
 
 	cases := map[string]struct {
 		selector        string
@@ -89,6 +82,7 @@ func TestGetSidecar(t *testing.T) {
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
 			assert := assert.New(t)
+			kialiCacheImpl.Refresh(tc.namespace)
 
 			namespace := sidecar.Namespace
 			if tc.namespace != "" {
@@ -106,10 +100,41 @@ func TestGetSidecar(t *testing.T) {
 	}
 }
 
-func createIstioIndexInformer(getter cache.Getter, resourceType string, refreshDuration time.Duration, namespace string) cache.SharedIndexInformer {
-	return cache.NewSharedIndexInformer(cache.NewListWatchFromClient(getter, resourceType, namespace, fields.Everything()),
-		&networking_v1beta1.Sidecar{},
-		refreshDuration,
-		cache.Indexers{},
-	)
+func TestGetNonCachedResource(t *testing.T) {
+	assert := assert.New(t)
+	sidecar := &networking_v1beta1.VirtualService{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: "sidecar", Namespace: "test", Labels: map[string]string{"app": "bookinfo", "version": "v1"},
+		},
+	}
+	kialiCache := newTestKialiCache(nil, []runtime.Object{sidecar})
+	kialiCache.cacheIstioTypes = nil
+	_, err := kialiCache.GetVirtualServices("testing-ns", "app=bookinfo")
+	assert.Error(err)
+}
+
+// Other parts of the codebase assume that this kind field is present so it's important
+// that the cache sets it.
+func TestGetAndListReturnKindInfo(t *testing.T) {
+	assert := assert.New(t)
+	vs := &networking_v1beta1.VirtualService{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: "vs", Namespace: "test",
+		},
+	}
+	kialiCache := newTestKialiCache(nil, []runtime.Object{vs})
+	kialiCache.cacheIstioTypes = map[string]bool{
+		kubernetes.PluralType[kubernetes.VirtualServices]: true,
+	}
+	kialiCache.Refresh("test")
+
+	vsFromCache, err := kialiCache.GetVirtualService("test", "vs")
+	assert.NoError(err)
+	assert.Equal(kubernetes.VirtualServiceType, vsFromCache.Kind)
+
+	vsListFromCache, err := kialiCache.GetVirtualServices("test", "")
+	assert.NoError(err)
+	for _, vs := range vsListFromCache {
+		assert.Equal(kubernetes.VirtualServiceType, vs.Kind)
+	}
 }
diff --git a/kubernetes/cache/kubernetes_test.go b/kubernetes/cache/kubernetes_test.go
new file mode 100644
index 000000000..f31ee0f38
--- /dev/null
+++ b/kubernetes/cache/kubernetes_test.go
@@ -0,0 +1,35 @@
+package cache
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	apps_v1 "k8s.io/api/apps/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+
+	"github.com/kiali/kiali/kubernetes"
+)
+
+// Other parts of the codebase assume that this kind field is present so it's important
+// that the cache sets it.
+func TestKubeGetAndListReturnKindInfo(t *testing.T) {
+	assert := assert.New(t)
+	d := &apps_v1.Deployment{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: "deployment", Namespace: "test",
+		},
+	}
+	kialiCache := newTestKialiCache([]runtime.Object{d}, nil)
+	kialiCache.Refresh("test")
+
+	deploymentFromCache, err := kialiCache.GetDeployment("test", "deployment")
+	assert.NoError(err)
+	assert.Equal(kubernetes.DeploymentType, deploymentFromCache.Kind)
+
+	deploymentListFromCache, err := kialiCache.GetDeployments("test")
+	assert.NoError(err)
+	for _, deployment := range deploymentListFromCache {
+		assert.Equal(kubernetes.DeploymentType, deployment.Kind)
+	}
+}
diff --git a/kubernetes/cache/tls_test_helper.go b/kubernetes/cache/tls_test_helper.go
index 5fa97c797..194b81761 100644
--- a/kubernetes/cache/tls_test_helper.go
+++ b/kubernetes/cache/tls_test_helper.go
@@ -5,21 +5,11 @@ import (
 
 	networking_v1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
 	security_v1beta1 "istio.io/client-go/pkg/apis/security/v1beta1"
-	"k8s.io/client-go/tools/cache"
 
 	"github.com/kiali/kiali/kubernetes"
 	"github.com/kiali/kiali/models"
 )
 
-type fakeInformer struct {
-	cache.SharedIndexInformer
-	Store *cache.FakeCustomStore
-}
-
-func (f *fakeInformer) GetStore() cache.Store {
-	return f.Store
-}
-
 // Fake KialiCache used for TLS Scenarios
 // It populates the Namespaces, Informers and Registry information needed
 func FakeTlsKialiCache(token string, namespaces []string, pa []*security_v1beta1.PeerAuthentication, dr []*networking_v1beta1.DestinationRule) KialiCache {