Repository: evcc-io/evcc
Pull request #10253 (2023-10-09 20:12:27)

Add Smartfox
Add support for https://smartfox.at/produktuebersicht/

So sieht ein request zu `/all` aus:

```json
{
    "datetime": "2023-10-09T08:30:33",
    "energy_in": 72885595,
    "energy_out": 51855688,
    "energy_sf": 11579706,
    "day_energy_in": 2853,
    "day_energy_out": 5,
    "day_energy_sf": 43,
    "power_io": -18,
    "power_sf": 458,
    "powers": [
        -32,
        -84,
        98
    ],
    "voltages": [
        233,
        235,
        235
    ],
    "currents": [
        1.12,
        1.17,
        1.49
    ],
    "analog": {
        "percent": 7,
        "mode": 2,
        "output": 0,
        "power": 458.666667,
        "monitoring": "inaktive"
    },
    "digital": [
        {
            "state": "0",
            "FACremain": 0,
            "runtime": 0
        },
        {
            "state": "0",
            "FACremain": 0,
            "runtime": 0
        },
        {
            "state": "0",
            "FACremain": 0,
            "runtime": 0
        },
        {
            "state": "0",
            "FACremain": 0,
            "runtime": 0
        }
    ],
    "PvPower": [
        369
    ],
    "PvEnergy": [
        81506304
    ]
}
```
In diesem Fall:

- 369W von PV (`PvEnergy`)
- 458W sind für den Heizstab für die Warmwasserbereitung (`power_sf`)
- 18W gehen im Grid (`power_io`),


Patch:
diff --git a/assets/js/components/ChargingPlanArrival.vue b/assets/js/components/ChargingPlanArrival.vue
index 59fab295..3d2e6969 100644
--- a/assets/js/components/ChargingPlanArrival.vue
+++ b/assets/js/components/ChargingPlanArrival.vue
@@ -15,12 +15,8 @@
 						:disabled="!socBasedCharging"
 						@change="changeMinSoc"
 					>
-						<option
-							v-for="soc in [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50]"
-							:key="soc"
-							:value="soc"
-						>
-							{{ soc ? `${soc}%` : "--" }}
+						<option v-for="soc in minSocOptions" :key="soc.value" :value="soc.value">
+							{{ soc.name }}
 						</option>
 					</select>
 				</div>
@@ -45,6 +41,16 @@ export default {
 	data: function () {
 		return { selectedMinSoc: this.minSoc };
 	},
+	computed: {
+		minSocOptions() {
+			// a list of entries from 0 to 95 with a step of 5
+			return Array.from(Array(20).keys())
+				.map((i) => i * 5)
+				.map((soc) => {
+					return { value: soc, name: soc === 0 ? "--" : `${soc}%` };
+				});
+		},
+	},
 	watch: {
 		minSoc: function (value) {
 			this.selectedMinSoc = value;
diff --git a/assets/js/components/Loadpoint.vue b/assets/js/components/Loadpoint.vue
index 04b869af..777d072a 100644
--- a/assets/js/components/Loadpoint.vue
+++ b/assets/js/components/Loadpoint.vue
@@ -195,6 +195,7 @@ export default {
 		guardAction: String,
 		smartCostLimit: Number,
 		smartCostType: String,
+		smartCostActive: Boolean,
 		tariffGrid: Number,
 		tariffCo2: Number,
 		currency: String,
diff --git a/assets/js/components/Loadpoints.vue b/assets/js/components/Loadpoints.vue
index 0a03afb2..283060c6 100644
--- a/assets/js/components/Loadpoints.vue
+++ b/assets/js/components/Loadpoints.vue
@@ -15,6 +15,7 @@
 					:vehicles="vehicles"
 					:smartCostLimit="smartCostLimit"
 					:smartCostType="smartCostType"
+					:smartCostActive="smartCostActive"
 					:tariffGrid="tariffGrid"
 					:tariffCo2="tariffCo2"
 					:currency="currency"
@@ -51,6 +52,7 @@ export default {
 		vehicles: Array,
 		smartCostLimit: Number,
 		smartCostType: String,
+		smartCostActive: Boolean,
 		tariffGrid: Number,
 		tariffCo2: Number,
 		currency: String,
diff --git a/assets/js/components/Site.vue b/assets/js/components/Site.vue
index ed332cd0..642e46d1 100644
--- a/assets/js/components/Site.vue
+++ b/assets/js/components/Site.vue
@@ -23,6 +23,7 @@
 				:vehicles="vehicles"
 				:smartCostLimit="smartCostLimit"
 				:smartCostType="smartCostType"
+				:smartCostActive="smartCostActive"
 				:tariffGrid="tariffGrid"
 				:tariffCo2="tariffCo2"
 				:currency="currency"
@@ -103,6 +104,7 @@ export default {
 		sponsorTokenExpires: Number,
 		smartCostLimit: Number,
 		smartCostType: String,
+		smartCostActive: Boolean,
 	},
 	computed: {
 		energyflow: function () {
diff --git a/assets/js/components/Vehicle.vue b/assets/js/components/Vehicle.vue
index 617f1e2b..e9c5192b 100644
--- a/assets/js/components/Vehicle.vue
+++ b/assets/js/components/Vehicle.vue
@@ -119,6 +119,7 @@ export default {
 		climaterActive: Boolean,
 		smartCostLimit: Number,
 		smartCostType: String,
+		smartCostActive: Boolean,
 		tariffGrid: Number,
 		tariffCo2: Number,
 		currency: String,
diff --git a/assets/js/components/VehicleStatus.vue b/assets/js/components/VehicleStatus.vue
index 95529d07..4e212ace 100644
--- a/assets/js/components/VehicleStatus.vue
+++ b/assets/js/components/VehicleStatus.vue
@@ -28,8 +28,10 @@ export default {
 		climaterActive: Boolean,
 		smartCostLimit: Number,
 		smartCostType: String,
+		smartCostActive: Boolean,
 		tariffGrid: Number,
 		tariffCo2: Number,
+		currency: String,
 	},
 	computed: {
 		phaseTimerActive() {
@@ -46,9 +48,6 @@ export default {
 		guardTimerActive() {
 			return this.guardRemainingInterpolated > 0 && this.guardAction === "enable";
 		},
-		isCo2() {
-			return this.smartCostType === CO2_TYPE;
-		},
 		message: function () {
 			const t = (key, data) => {
 				return this.$t(`main.vehicleStatus.${key}`, data);
@@ -77,14 +76,17 @@ export default {
 				}
 			}
 
-			// clean energy
-			if (this.charging && this.isCo2 && this.tariffCo2 < this.smartCostLimit) {
-				return t("cleanEnergyCharging");
-			}
-
-			// cheap energy
-			if (this.charging && !this.isCo2 && this.tariffGrid < this.smartCostLimit) {
-				return t("cheapEnergyCharging");
+			// clean or cheap energy
+			if (this.charging && this.smartCostActive) {
+				return this.smartCostType === CO2_TYPE
+					? t("cleanEnergyCharging", {
+							co2: this.fmtCo2Short(this.tariffCo2),
+							limit: this.fmtCo2Short(this.smartCostLimit),
+					  })
+					: t("cheapEnergyCharging", {
+							price: this.fmtPricePerKWh(this.tariffGrid, this.currency, true),
+							limit: this.fmtPricePerKWh(this.smartCostLimit, this.currency, true),
+					  });
 			}
 
 			if (this.pvTimerActive && !this.enabled && this.pvAction === "enable") {
diff --git a/charger/daheimladen-mb.go b/charger/daheimladen-mb.go
index 89d09d76..df7e844e 100644
--- a/charger/daheimladen-mb.go
+++ b/charger/daheimladen-mb.go
@@ -203,9 +203,10 @@ func (wb *DaheimLadenMB) MaxCurrent(current int64) error {
 		return fmt.Errorf("invalid current %d", current)
 	}
 
-	err := wb.setCurrent(wb.curr)
+	curr := uint16(current * 10)
+	err := wb.setCurrent(curr)
 	if err == nil {
-		wb.curr = uint16(current * 10)
+		wb.curr = curr
 	}
 
 	return err
diff --git a/charger/eebus.go b/charger/eebus.go
index 43e086c5..255a7c0b 100644
--- a/charger/eebus.go
+++ b/charger/eebus.go
@@ -453,11 +453,9 @@ func (c *EEBus) currents() (float64, float64, float64, error) {
 		return 0, 0, 0, err
 	}
 
-	count := len(currents)
-	if count < 3 {
-		for fill := 0; fill < 3-count; fill++ {
-			currents = append(currents, 0)
-		}
+	// fill phases
+	for i := len(currents); i < 3; i++ {
+		currents = append(currents, 0)
 	}
 
 	return currents[0], currents[1], currents[2], nil
diff --git a/core/loadpoint.go b/core/loadpoint.go
index 95cbcc3b..bd4ad667 100644
--- a/core/loadpoint.go
+++ b/core/loadpoint.go
@@ -1377,7 +1377,7 @@ func (lp *Loadpoint) publishSocAndRange() {
 		return
 	}
 
-	if err == nil || lp.vehicleSocPollAllowed() {
+	if err == nil || lp.chargerHasFeature(api.IntegratedDevice) || lp.vehicleSocPollAllowed() {
 		lp.socUpdated = lp.clock.Now()
 
 		f, err := lp.socEstimator.Soc(lp.getChargedEnergy())
diff --git a/core/site.go b/core/site.go
index 8bce3faa..f59f7349 100644
--- a/core/site.go
+++ b/core/site.go
@@ -515,7 +515,7 @@ func (site *Site) updateMeters() error {
 			}
 		}
 
-		site.publish("batteryCapacity", math.Round(totalCapacity))
+		site.publish("batteryCapacity", totalCapacity)
 
 		// convert weighed socs to total soc
 		if totalCapacity == 0 {
@@ -524,7 +524,7 @@ func (site *Site) updateMeters() error {
 		site.batterySoc /= totalCapacity
 
 		site.log.DEBUG.Printf("battery soc: %.0f%%", math.Round(site.batterySoc))
-		site.publish("batterySoc", math.Round(site.batterySoc))
+		site.publish("batterySoc", site.batterySoc)
 
 		site.log.DEBUG.Printf("battery power: %.0fW", site.batteryPower)
 		site.publish("batteryPower", site.batteryPower)
@@ -758,6 +758,7 @@ func (site *Site) update(lp Updater) {
 		if err == nil {
 			limit := site.GetSmartCostLimit()
 			autoCharge = limit != 0 && rate.Price <= limit
+			site.publish("smartCostActive", autoCharge)
 		} else {
 			site.log.ERROR.Println("tariff:", err)
 		}
@@ -802,6 +803,7 @@ func (site *Site) prepare() {
 	site.publish("residualPower", site.ResidualPower)
 	site.publish("smartCostLimit", site.SmartCostLimit)
 	site.publish("smartCostType", nil)
+	site.publish("smartCostActive", false)
 	if tariff := site.GetTariff(PlannerTariff); tariff != nil {
 		site.publish("smartCostType", tariff.Type().String())
 	}
diff --git a/evcc.dist.yaml b/evcc.dist.yaml
index 84acbf63..990598d2 100644
--- a/evcc.dist.yaml
+++ b/evcc.dist.yaml
@@ -188,6 +188,12 @@ tariffs:
     # region: dk1 # or dk2
     # charges: # optional, additional charges per kWh
     # tax: # optional, additional tax (0.1 for 10%)
+
+    # type: entsoe # Entso-E european market data
+    # domain: BZN|DE-LU # https://transparency.entsoe.eu/content/static_content/Static%20content/web%20api/Guide.html#_areas
+    # securitytoken: # api token
+    # charges: # optional, additional charges per kWh
+    # tax: # optional, additional tax (0.1 for 10%)
   feedin:
     # rate for feeding excess (pv) energy to the grid
     type: fixed
diff --git a/go.mod b/go.mod
index cd9d1a46..39c53323 100644
--- a/go.mod
+++ b/go.mod
@@ -92,7 +92,7 @@ require (
 	gitlab.com/bboehmke/sunny v0.15.1-0.20211022160056-2fba1c86ade6
 	golang.org/x/crypto/x509roots/fallback v0.0.0-20231005151211-e3cc52e598e3
 	golang.org/x/exp v0.0.0-20231006140011-7918f672742d
-	golang.org/x/net v0.16.0
+	golang.org/x/net v0.17.0
 	golang.org/x/oauth2 v0.13.0
 	golang.org/x/sync v0.4.0
 	golang.org/x/text v0.13.0
diff --git a/go.sum b/go.sum
index 1b1dc724..33dd7c68 100644
--- a/go.sum
+++ b/go.sum
@@ -959,8 +959,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
-golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=
-golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
diff --git a/i18n/de.toml b/i18n/de.toml
index 8f9293b7..57ac6eda 100644
--- a/i18n/de.toml
+++ b/i18n/de.toml
@@ -282,8 +282,8 @@ vehicleTarget = "Fahrzeuglimit: {soc}%"
 
 [main.vehicleStatus]
 charging = "Ladevorgang aktiv …"
-cheapEnergyCharging = "Günstige Energie verfügbar. Ladevorgang aktiv …"
-cleanEnergyCharging = "Saubere Energie verfügbar. Ladevorgang aktiv …"
+cheapEnergyCharging = "Lade günstige Energie: {price} (Grenze < {limit})"
+cleanEnergyCharging = "Lade saubere Energie: {co2} (Grenze < {limit})"
 climating = "Vorklimatisierung erkannt."
 connected = "Verbunden."
 disconnected = "Nicht verbunden."
diff --git a/i18n/en.toml b/i18n/en.toml
index 6430c9e6..f437018f 100644
--- a/i18n/en.toml
+++ b/i18n/en.toml
@@ -279,8 +279,8 @@ vehicleTarget = "Vehicle limit: {soc}%"
 
 [main.vehicleStatus]
 charging = "Charging…"
-cheapEnergyCharging = "Cheap energy available. Charging…"
-cleanEnergyCharging = "Clean energy available. Charging…"
+cheapEnergyCharging = "Charging cheap energy: {price} (limit < {limit})"
+cleanEnergyCharging = "Charging clean energy: {co2} (limit < {limit})"
 climating = "Pre-conditioning detected."
 connected = "Connected."
 disconnected = "Disconnected."
diff --git a/package-lock.json b/package-lock.json
index 1ae70346..25127f0d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -28,7 +28,7 @@
         "eslint-plugin-prettier": "^5.0.0-alpha.1",
         "eslint-plugin-promise": "^6.0.0",
         "eslint-plugin-vue": "^9.3.0",
-        "happy-dom": "^11.0.5",
+        "happy-dom": "^12.9.1",
         "histoire": "^0.17.0",
         "markty-toml": "^0.1.1",
         "prettier": "^3.0.0",
@@ -92,29 +92,29 @@
       }
     },
     "node_modules/@babel/compat-data": {
-      "version": "7.22.9",
-      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz",
-      "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz",
+      "integrity": "sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==",
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/core": {
-      "version": "7.22.17",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.17.tgz",
-      "integrity": "sha512-2EENLmhpwplDux5PSsZnSbnSkB3tZ6QTksgO25xwEL7pIDcNOMhF5v/s6RzwjMZzZzw9Ofc30gHv5ChCC8pifQ==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.0.tgz",
+      "integrity": "sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==",
       "dependencies": {
         "@ampproject/remapping": "^2.2.0",
         "@babel/code-frame": "^7.22.13",
-        "@babel/generator": "^7.22.15",
+        "@babel/generator": "^7.23.0",
         "@babel/helper-compilation-targets": "^7.22.15",
-        "@babel/helper-module-transforms": "^7.22.17",
-        "@babel/helpers": "^7.22.15",
-        "@babel/parser": "^7.22.16",
+        "@babel/helper-module-transforms": "^7.23.0",
+        "@babel/helpers": "^7.23.0",
+        "@babel/parser": "^7.23.0",
         "@babel/template": "^7.22.15",
-        "@babel/traverse": "^7.22.17",
-        "@babel/types": "^7.22.17",
-        "convert-source-map": "^1.7.0",
+        "@babel/traverse": "^7.23.0",
+        "@babel/types": "^7.23.0",
+        "convert-source-map": "^2.0.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.2",
         "json5": "^2.2.3",
@@ -129,11 +129,11 @@
       }
     },
     "node_modules/@babel/generator": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz",
-      "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
+      "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
       "dependencies": {
-        "@babel/types": "^7.22.15",
+        "@babel/types": "^7.23.0",
         "@jridgewell/gen-mapping": "^0.3.2",
         "@jridgewell/trace-mapping": "^0.3.17",
         "jsesc": "^2.5.1"
@@ -233,20 +233,20 @@
       }
     },
     "node_modules/@babel/helper-environment-visitor": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz",
-      "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+      "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-function-name": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz",
-      "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+      "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
       "dependencies": {
-        "@babel/template": "^7.22.5",
-        "@babel/types": "^7.22.5"
+        "@babel/template": "^7.22.15",
+        "@babel/types": "^7.23.0"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -264,11 +264,11 @@
       }
     },
     "node_modules/@babel/helper-member-expression-to-functions": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.15.tgz",
-      "integrity": "sha512-qLNsZbgrNh0fDQBCPocSL8guki1hcPvltGDv/NxvUoABwFq7GkKSu1nRXeJkVZc+wJvne2E0RKQz+2SQrz6eAA==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz",
+      "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==",
       "dependencies": {
-        "@babel/types": "^7.22.15"
+        "@babel/types": "^7.23.0"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -286,15 +286,15 @@
       }
     },
     "node_modules/@babel/helper-module-transforms": {
-      "version": "7.22.17",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.17.tgz",
-      "integrity": "sha512-XouDDhQESrLHTpnBtCKExJdyY4gJCdrvH2Pyv8r8kovX2U8G0dRUOT45T9XlbLtuu9CLXP15eusnkprhoPV5iQ==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz",
+      "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==",
       "dependencies": {
-        "@babel/helper-environment-visitor": "^7.22.5",
+        "@babel/helper-environment-visitor": "^7.22.20",
         "@babel/helper-module-imports": "^7.22.15",
         "@babel/helper-simple-access": "^7.22.5",
         "@babel/helper-split-export-declaration": "^7.22.6",
-        "@babel/helper-validator-identifier": "^7.22.15"
+        "@babel/helper-validator-identifier": "^7.22.20"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -323,13 +323,13 @@
       }
     },
     "node_modules/@babel/helper-remap-async-to-generator": {
-      "version": "7.22.17",
-      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.17.tgz",
-      "integrity": "sha512-bxH77R5gjH3Nkde6/LuncQoLaP16THYPscurp1S8z7S9ZgezCyV3G8Hc+TZiCmY8pz4fp8CvKSgtJMW0FkLAxA==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz",
+      "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==",
       "dependencies": {
         "@babel/helper-annotate-as-pure": "^7.22.5",
-        "@babel/helper-environment-visitor": "^7.22.5",
-        "@babel/helper-wrap-function": "^7.22.17"
+        "@babel/helper-environment-visitor": "^7.22.20",
+        "@babel/helper-wrap-function": "^7.22.20"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -339,12 +339,12 @@
       }
     },
     "node_modules/@babel/helper-replace-supers": {
-      "version": "7.22.9",
-      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz",
-      "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz",
+      "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==",
       "dependencies": {
-        "@babel/helper-environment-visitor": "^7.22.5",
-        "@babel/helper-member-expression-to-functions": "^7.22.5",
+        "@babel/helper-environment-visitor": "^7.22.20",
+        "@babel/helper-member-expression-to-functions": "^7.22.15",
         "@babel/helper-optimise-call-expression": "^7.22.5"
       },
       "engines": {
@@ -396,9 +396,9 @@
       }
     },
     "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz",
-      "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+      "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
       "engines": {
         "node": ">=6.9.0"
       }
@@ -412,37 +412,37 @@
       }
     },
     "node_modules/@babel/helper-wrap-function": {
-      "version": "7.22.17",
-      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.17.tgz",
-      "integrity": "sha512-nAhoheCMlrqU41tAojw9GpVEKDlTS8r3lzFmF0lP52LwblCPbuFSO7nGIZoIcoU5NIm1ABrna0cJExE4Ay6l2Q==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz",
+      "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==",
       "dependencies": {
         "@babel/helper-function-name": "^7.22.5",
         "@babel/template": "^7.22.15",
-        "@babel/types": "^7.22.17"
+        "@babel/types": "^7.22.19"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helpers": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.15.tgz",
-      "integrity": "sha512-7pAjK0aSdxOwR+CcYAqgWOGy5dcfvzsTIfFTb2odQqW47MDfv14UaJDY6eng8ylM2EaeKXdxaSWESbkmaQHTmw==",
+      "version": "7.23.1",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.1.tgz",
+      "integrity": "sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==",
       "dependencies": {
         "@babel/template": "^7.22.15",
-        "@babel/traverse": "^7.22.15",
-        "@babel/types": "^7.22.15"
+        "@babel/traverse": "^7.23.0",
+        "@babel/types": "^7.23.0"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/highlight": {
-      "version": "7.22.13",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.13.tgz",
-      "integrity": "sha512-C/BaXcnnvBCmHTpz/VGZ8jgtE2aYlW4hxDhseJAWZb7gqGM/qtCK6iZUb0TyKFf7BOUsBH7Q7fkRsDRhg1XklQ==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+      "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.22.5",
+        "@babel/helper-validator-identifier": "^7.22.20",
         "chalk": "^2.4.2",
         "js-tokens": "^4.0.0"
       },
@@ -451,9 +451,9 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.22.16",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz",
-      "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+      "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
       "bin": {
         "parser": "bin/babel-parser.js"
       },
@@ -781,9 +781,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-block-scoping": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.15.tgz",
-      "integrity": "sha512-G1czpdJBZCtngoK1sJgloLiOHUnkb/bLZwqVZD8kXmq0ZnVfTTWUcs9OWtp0mBtYJ+4LQY1fllqBkOIPhXmFmw==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz",
+      "integrity": "sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==",
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
       },
@@ -863,9 +863,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-destructuring": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.15.tgz",
-      "integrity": "sha512-HzG8sFl1ZVGTme74Nw+X01XsUTqERVQ6/RLHo3XjGRzm7XD6QTtfS3NJotVgCGy8BzkDqRjRBD8dAyJn5TuvSQ==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz",
+      "integrity": "sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==",
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
       },
@@ -1039,11 +1039,11 @@
       }
     },
     "node_modules/@babel/plugin-transform-modules-amd": {
-      "version": "7.22.5",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz",
-      "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz",
+      "integrity": "sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw==",
       "dependencies": {
-        "@babel/helper-module-transforms": "^7.22.5",
+        "@babel/helper-module-transforms": "^7.23.0",
         "@babel/helper-plugin-utils": "^7.22.5"
       },
       "engines": {
@@ -1054,11 +1054,11 @@
       }
     },
     "node_modules/@babel/plugin-transform-modules-commonjs": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.15.tgz",
-      "integrity": "sha512-jWL4eh90w0HQOTKP2MoXXUpVxilxsB2Vl4ji69rSjS3EcZ/v4sBmn+A3NpepuJzBhOaEBbR7udonlHHn5DWidg==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz",
+      "integrity": "sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==",
       "dependencies": {
-        "@babel/helper-module-transforms": "^7.22.15",
+        "@babel/helper-module-transforms": "^7.23.0",
         "@babel/helper-plugin-utils": "^7.22.5",
         "@babel/helper-simple-access": "^7.22.5"
       },
@@ -1070,14 +1070,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-modules-systemjs": {
-      "version": "7.22.11",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.11.tgz",
-      "integrity": "sha512-rIqHmHoMEOhI3VkVf5jQ15l539KrwhzqcBO6wdCNWPWc/JWt9ILNYNUssbRpeq0qWns8svuw8LnMNCvWBIJ8wA==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz",
+      "integrity": "sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==",
       "dependencies": {
         "@babel/helper-hoist-variables": "^7.22.5",
-        "@babel/helper-module-transforms": "^7.22.9",
+        "@babel/helper-module-transforms": "^7.23.0",
         "@babel/helper-plugin-utils": "^7.22.5",
-        "@babel/helper-validator-identifier": "^7.22.5"
+        "@babel/helper-validator-identifier": "^7.22.20"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1209,9 +1209,9 @@
       }
     },
     "node_modules/@babel/plugin-transform-optional-chaining": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.15.tgz",
-      "integrity": "sha512-ngQ2tBhq5vvSJw2Q2Z9i7ealNkpDMU0rGWnHPKqRZO0tzZ5tlaoz4hDvhXioOoaE0X2vfNss1djwg0DXlfu30A==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz",
+      "integrity": "sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==",
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
         "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
@@ -1444,11 +1444,11 @@
       }
     },
     "node_modules/@babel/preset-env": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.15.tgz",
-      "integrity": "sha512-tZFHr54GBkHk6hQuVA8w4Fmq+MSPsfvMG0vPnOYyTnJpyfMqybL8/MbNCPRT9zc2KBO2pe4tq15g6Uno4Jpoag==",
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.20.tgz",
+      "integrity": "sha512-11MY04gGC4kSzlPHRfvVkNAZhUxOvm7DCJ37hPDnUENwe06npjIRAfInEMTGSb4LZK5ZgDFkv5hw0lGebHeTyg==",
       "dependencies": {
-        "@babel/compat-data": "^7.22.9",
+        "@babel/compat-data": "^7.22.20",
         "@babel/helper-compilation-targets": "^7.22.15",
         "@babel/helper-plugin-utils": "^7.22.5",
         "@babel/helper-validator-option": "^7.22.15",
@@ -1522,7 +1522,7 @@
         "@babel/plugin-transform-unicode-regex": "^7.22.5",
         "@babel/plugin-transform-unicode-sets-regex": "^7.22.5",
         "@babel/preset-modules": "0.1.6-no-external-plugins",
-        "@babel/types": "^7.22.15",
+        "@babel/types": "^7.22.19",
         "babel-plugin-polyfill-corejs2": "^0.4.5",
         "babel-plugin-polyfill-corejs3": "^0.8.3",
         "babel-plugin-polyfill-regenerator": "^0.5.2",
@@ -1555,9 +1555,9 @@
       "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA=="
     },
     "node_modules/@babel/runtime": {
-      "version": "7.22.15",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz",
-      "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==",
+      "version": "7.23.1",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.1.tgz",
+      "integrity": "sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==",
       "dependencies": {
         "regenerator-runtime": "^0.14.0"
       },
@@ -1584,18 +1584,18 @@
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.22.17",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.17.tgz",
-      "integrity": "sha512-xK4Uwm0JnAMvxYZxOVecss85WxTEIbTa7bnGyf/+EgCL5Zt3U7htUpEOWv9detPlamGKuRzCqw74xVglDWpPdg==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.0.tgz",
+      "integrity": "sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==",
       "dependencies": {
         "@babel/code-frame": "^7.22.13",
-        "@babel/generator": "^7.22.15",
-        "@babel/helper-environment-visitor": "^7.22.5",
-        "@babel/helper-function-name": "^7.22.5",
+        "@babel/generator": "^7.23.0",
+        "@babel/helper-environment-visitor": "^7.22.20",
+        "@babel/helper-function-name": "^7.23.0",
         "@babel/helper-hoist-variables": "^7.22.5",
         "@babel/helper-split-export-declaration": "^7.22.6",
-        "@babel/parser": "^7.22.16",
-        "@babel/types": "^7.22.17",
+        "@babel/parser": "^7.23.0",
+        "@babel/types": "^7.23.0",
         "debug": "^4.1.0",
         "globals": "^11.1.0"
       },
@@ -1604,12 +1604,12 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.22.17",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz",
-      "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==",
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
+      "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
       "dependencies": {
         "@babel/helper-string-parser": "^7.22.5",
-        "@babel/helper-validator-identifier": "^7.22.15",
+        "@babel/helper-validator-identifier": "^7.22.20",
         "to-fast-properties": "^2.0.0"
       },
       "engines": {
@@ -1651,14 +1651,14 @@
       "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ=="
     },
     "node_modules/@codemirror/commands": {
-      "version": "6.2.5",
-      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.2.5.tgz",
-      "integrity": "sha512-dSi7ow2P2YgPBZflR9AJoaTHvqmeGIgkhignYMd5zK5y6DANTvxKxp6eMEpIDUJkRAaOY/TFZ4jP1ADIO/GLVA==",
+      "version": "6.3.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.0.tgz",
+      "integrity": "sha512-tFfcxRIlOWiQDFhjBSWJ10MxcvbCIsRr6V64SgrcaY0MwNk32cUOcCuNlWo8VjV4qRQCgNgUAnIeo0svkk4R5Q==",
       "dependencies": {
         "@codemirror/language": "^6.0.0",
         "@codemirror/state": "^6.2.0",
         "@codemirror/view": "^6.0.0",
-        "@lezer/common": "^1.0.0"
+        "@lezer/common": "^1.1.0"
       }
     },
     "node_modules/@codemirror/lang-json": {
@@ -1671,22 +1671,22 @@
       }
     },
     "node_modules/@codemirror/language": {
-      "version": "6.9.0",
-      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.9.0.tgz",
-      "integrity": "sha512-nFu311/0ne/qGuGCL3oKuktBgzVOaxCHZPZv1tLSZkNjPYxxvkjSbzno3MlErG2tgw1Yw1yF8BxMCegeMXqpiw==",
+      "version": "6.9.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.9.1.tgz",
+      "integrity": "sha512-lWRP3Y9IUdOms6DXuBpoWwjkR7yRmnS0hKYCbSfPz9v6Em1A1UCRujAkDiCrdYfs1Z0Eu4dGtwovNPStIfkgNA==",
       "dependencies": {
         "@codemirror/state": "^6.0.0",
         "@codemirror/view": "^6.0.0",
-        "@lezer/common": "^1.0.0",
+        "@lezer/common": "^1.1.0",
         "@lezer/highlight": "^1.0.0",
         "@lezer/lr": "^1.0.0",
         "style-mod": "^4.0.0"
       }
     },
     "node_modules/@codemirror/lint": {
-      "version": "6.4.1",
-      "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.4.1.tgz",
-      "integrity": "sha512-2Hx945qKX7FBan5/gUdTM8fsMYrNG9clIgEcPXestbLVFAUyQYFAuju/5BMNf/PwgpVaX5pvRm4+ovjbp9D9gQ==",
+      "version": "6.4.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.4.2.tgz",
+      "integrity": "sha512-wzRkluWb1ptPKdzlsrbwwjYCPLgzU6N88YBAmlZi8WFyuiEduSd05MnJYNogzyc8rPK7pj6m95ptUApc8sHKVA==",
       "dependencies": {
         "@codemirror/state": "^6.0.0",
         "@codemirror/view": "^6.0.0",
@@ -1710,9 +1710,9 @@
       }
     },
     "node_modules/@codemirror/view": {
-      "version": "6.18.1",
-      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.18.1.tgz",
-      "integrity": "sha512-xcsXcMkIMd7l3WZEWoc4ljteAiqzxb5gVerRxk5132p5cLix6rTydWTQjsj2oxORepfsrwy1fC4r20iMa9plrg==",
+      "version": "6.21.3",
+      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.21.3.tgz",
+      "integrity": "sha512-8l1aSQ6MygzL4Nx7GVYhucSXvW4jQd0F6Zm3v9Dg+6nZEfwzJVqi4C2zHfDljID+73gsQrWp9TgHc81xU15O4A==",
       "dependencies": {
         "@codemirror/state": "^6.1.4",
         "style-mod": "^4.1.0",
@@ -2064,9 +2064,9 @@
       }
     },
     "node_modules/@eslint-community/regexpp": {
-      "version": "4.8.1",
-      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz",
-      "integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==",
+      "version": "4.9.1",
+      "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz",
+      "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==",
       "engines": {
         "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
       }
@@ -2094,9 +2094,9 @@
       }
     },
     "node_modules/@eslint/eslintrc/node_modules/globals": {
-      "version": "13.21.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz",
-      "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==",
+      "version": "13.23.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
+      "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
       "dependencies": {
         "type-fest": "^0.20.2"
       },
@@ -2108,9 +2108,9 @@
       }
     },
     "node_modules/@eslint/js": {
-      "version": "8.49.0",
-      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.49.0.tgz",
-      "integrity": "sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==",
+      "version": "8.51.0",
+      "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz",
+      "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==",
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
       }
@@ -2232,12 +2232,12 @@
       "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
     },
     "node_modules/@intlify/core-base": {
-      "version": "9.4.0",
-      "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.4.0.tgz",
-      "integrity": "sha512-bIvtuEjLES35l39R0OccYbmr/fatSr4VSRThhouvFc05mnoAZyJGgj3st1iLaHGlFTmvd507uww1427o56r36Q==",
+      "version": "9.5.0",
+      "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.5.0.tgz",
+      "integrity": "sha512-y3ufM1RJbI/DSmJf3lYs9ACq3S/iRvaSsE3rPIk0MGH7fp+JxU6rdryv/EYcwfcr3Y1aHFlCBir6S391hRZ57w==",
       "dependencies": {
-        "@intlify/message-compiler": "9.4.0",
-        "@intlify/shared": "9.4.0"
+        "@intlify/message-compiler": "9.5.0",
+        "@intlify/shared": "9.5.0"
       },
       "engines": {
         "node": ">= 16"
@@ -2247,11 +2247,11 @@
       }
     },
     "node_modules/@intlify/message-compiler": {
-      "version": "9.4.0",
-      "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.4.0.tgz",
-      "integrity": "sha512-EdjqOH3bQqEjZcUOwo90wuW4ZuFr41FDxVni6WNKS0V0myKgwz9EuvLDcnEbjJMIX8vKAWPjWfnSTt5fMwKHLA==",
+      "version": "9.5.0",
+      "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.5.0.tgz",
+      "integrity": "sha512-CAhVNfEZcOVFg0/5MNyt+OFjvs4J/ARjCj2b+54/FvFP0EDJI5lIqMTSDBE7k0atMROSP0SvWCkwu/AZ5xkK1g==",
       "dependencies": {
-        "@intlify/shared": "9.4.0",
+        "@intlify/shared": "9.5.0",
         "source-map-js": "^1.0.2"
       },
       "engines": {
@@ -2262,9 +2262,9 @@
       }
     },
     "node_modules/@intlify/shared": {
-      "version": "9.4.0",
-      "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.4.0.tgz",
-      "integrity": "sha512-AFqymip2kToqA0B6KZPg5jSrdcVHoli9t/VhGKE2iiMq9utFuMoGdDC/JOCIZgwxo6aXAk86QyU2XtzEoMuZ6A==",
+      "version": "9.5.0",
+      "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.5.0.tgz",
+      "integrity": "sha512-tAxV14LMXZDZbu32XzLMTsowNlgJNmLwWHYzvMUl6L8gvQeoYiZONjY7AUsqZW8TOZDX9lfvF6adPkk9FSRdDA==",
       "engines": {
         "node": ">= 16"
       },
@@ -2337,9 +2337,9 @@
       }
     },
     "node_modules/@lezer/common": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.4.tgz",
-      "integrity": "sha512-lZHlk8p67x4aIDtJl6UQrXSOP6oi7dQR3W/geFVrENdA1JDaAJWldnVqVjPMJupbTKbzDfFcePfKttqVidS/dg=="
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.1.0.tgz",
+      "integrity": "sha512-XPIN3cYDXsoJI/oDWoR2tD++juVrhgIago9xyKhZ7IhGlzdDM9QgC8D8saKNCz5pindGcznFr2HBSsEQSWnSjw=="
     },
     "node_modules/@lezer/highlight": {
       "version": "1.1.6",
@@ -2359,9 +2359,9 @@
       }
     },
     "node_modules/@lezer/lr": {
-      "version": "1.3.10",
-      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.3.10.tgz",
-      "integrity": "sha512-BZfVvf7Re5BIwJHlZXbJn9L8lus5EonxQghyn+ih8Wl36XMFBPTXC0KM0IdUtj9w/diPHsKlXVgL+AlX2jYJ0Q==",
+      "version": "1.3.13",
+      "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.3.13.tgz",
+      "integrity": "sha512-RLAbau/4uSzKgIKj96mI5WUtG1qtiR0Frn0Ei9zhPj8YOkHM+1Bb8SgdVvmR/aWJCFIzjo2KFnDiRZ75Xf5NdQ==",
       "dependencies": {
         "@lezer/common": "^1.0.0"
       }
@@ -2451,21 +2451,17 @@
       }
     },
     "node_modules/@playwright/test": {
-      "version": "1.37.1",
-      "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.37.1.tgz",
-      "integrity": "sha512-bq9zTli3vWJo8S3LwB91U0qDNQDpEXnw7knhxLM0nwDvexQAwx9tO8iKDZSqqneVq+URd/WIoz+BALMqUTgdSg==",
+      "version": "1.38.1",
+      "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.38.1.tgz",
+      "integrity": "sha512-NqRp8XMwj3AK+zKLbZShl0r/9wKgzqI/527bkptKXomtuo+dOjU9NdMASQ8DNC9z9zLOMbG53T4eihYr3XR+BQ==",
       "dependencies": {
-        "@types/node": "*",
-        "playwright-core": "1.37.1"
+        "playwright": "1.38.1"
       },
       "bin": {
         "playwright": "cli.js"
       },
       "engines": {
         "node": ">=16"
-      },
-      "optionalDependencies": {
-        "fsevents": "2.3.2"
       }
     },
     "node_modules/@polka/url": {
@@ -2543,9 +2539,9 @@
       }
     },
     "node_modules/@types/chai": {
-      "version": "4.3.6",
-      "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.6.tgz",
-      "integrity": "sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw=="
+      "version": "4.3.7",
+      "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.7.tgz",
+      "integrity": "sha512-/k+vesl92vMvMygmQrFe9Aimxi6oQXFUX9mA5HanTrKUSAMoLauSi6PNFOdRw0oeqilaW600GNx2vSaT2f8aIQ=="
     },
     "node_modules/@types/chai-subset": {
       "version": "1.3.3",
@@ -2556,9 +2552,9 @@
       }
     },
     "node_modules/@types/flexsearch": {
-      "version": "0.7.3",
-      "resolved": "https://registry.npmjs.org/@types/flexsearch/-/flexsearch-0.7.3.tgz",
-      "integrity": "sha512-HXwADeHEP4exXkCIwy2n1+i0f1ilP1ETQOH5KDOugjkTFZPntWo0Gr8stZOaebkxsdx+k0X/K6obU/+it07ocg=="
+      "version": "0.7.4",
+      "resolved": "https://registry.npmjs.org/@types/flexsearch/-/flexsearch-0.7.4.tgz",
+      "integrity": "sha512-R5ZZmhxOBquntySny8dWYLDGdPJlX9K6p6vcj1w5NWGQ33X4V8MEtdQXK5KFFR1j6o0RhbPMdLSVg5XULVn3oA=="
     },
     "node_modules/@types/fs-extra": {
       "version": "9.0.13",
@@ -2588,14 +2584,17 @@
       }
     },
     "node_modules/@types/mdurl": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
-      "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA=="
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.3.tgz",
+      "integrity": "sha512-T5k6kTXak79gwmIOaDF2UUQXFbnBE0zBUzF20pz7wDYu0RQMzWg+Ml/Pz50214NsFHBITkoi5VtdjFZnJ2ijjA=="
     },
     "node_modules/@types/node": {
-      "version": "20.6.0",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz",
-      "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg=="
+      "version": "20.8.4",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.4.tgz",
+      "integrity": "sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==",
+      "dependencies": {
+        "undici-types": "~5.25.1"
+      }
     },
     "node_modules/@vitejs/plugin-legacy": {
       "version": "4.1.1",
@@ -2622,9 +2621,9 @@
       }
     },
     "node_modules/@vitejs/plugin-vue": {
-      "version": "4.3.4",
-      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.3.4.tgz",
-      "integrity": "sha512-ciXNIHKPriERBisHFBvnTbfKa6r9SAesOYXeGDzgegcvy9Q4xdScSHAmKbNT0M3O0S9LKhIf5/G+UYG4NnnzYw==",
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-4.4.0.tgz",
+      "integrity": "sha512-xdguqb+VUwiRpSg+nsc2HtbAUSGak25DXYvpQQi4RVU1Xq1uworyoH/md9Rfd8zMmPR/pSghr309QNcftUVseg==",
       "engines": {
         "node": "^14.18.0 || >=16.0.0"
       },
@@ -2634,24 +2633,24 @@
       }
     },
     "node_modules/@vitest/expect": {
-      "version": "0.34.4",
-      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.4.tgz",
-      "integrity": "sha512-XlMKX8HyYUqB8dsY8Xxrc64J2Qs9pKMt2Z8vFTL4mBWXJsg4yoALHzJfDWi8h5nkO4Zua4zjqtapQ/IluVkSnA==",
+      "version": "0.34.6",
+      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.6.tgz",
+      "integrity": "sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==",
       "dependencies": {
-        "@vitest/spy": "0.34.4",
-        "@vitest/utils": "0.34.4",
-        "chai": "^4.3.7"
+        "@vitest/spy": "0.34.6",
+        "@vitest/utils": "0.34.6",
+        "chai": "^4.3.10"
       },
       "funding": {
         "url": "https://opencollective.com/vitest"
       }
     },
     "node_modules/@vitest/runner": {
-      "version": "0.34.4",
-      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.4.tgz",
-      "integrity": "sha512-hwwdB1StERqUls8oV8YcpmTIpVeJMe4WgYuDongVzixl5hlYLT2G8afhcdADeDeqCaAmZcSgLTLtqkjPQF7x+w==",
+      "version": "0.34.6",
+      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.6.tgz",
+      "integrity": "sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==",
       "dependencies": {
-        "@vitest/utils": "0.34.4",
+        "@vitest/utils": "0.34.6",
         "p-limit": "^4.0.0",
         "pathe": "^1.1.1"
       },
@@ -2690,9 +2689,9 @@
       }
     },
     "node_modules/@vitest/snapshot": {
-      "version": "0.34.4",
-      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.4.tgz",
-      "integrity": "sha512-GCsh4coc3YUSL/o+BPUo7lHQbzpdttTxL6f4q0jRx2qVGoYz/cyTRDJHbnwks6TILi6560bVWoBpYC10PuTLHw==",
+      "version": "0.34.6",
+      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.6.tgz",
+      "integrity": "sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==",
       "dependencies": {
         "magic-string": "^0.30.1",
         "pathe": "^1.1.1",
@@ -2708,9 +2707,9 @@
       "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q=="
     },
     "node_modules/@vitest/spy": {
-      "version": "0.34.4",
-      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.4.tgz",
-      "integrity": "sha512-PNU+fd7DUPgA3Ya924b1qKuQkonAW6hL7YUjkON3wmBwSTIlhOSpy04SJ0NrRsEbrXgMMj6Morh04BMf8k+w0g==",
+      "version": "0.34.6",
+      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.6.tgz",
+      "integrity": "sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==",
       "dependencies": {
         "tinyspy": "^2.1.1"
       },
@@ -2719,9 +2718,9 @@
       }
     },
     "node_modules/@vitest/utils": {
-      "version": "0.34.4",
-      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.4.tgz",
-      "integrity": "sha512-yR2+5CHhp/K4ySY0Qtd+CAL9f5Yh1aXrKfAT42bq6CtlGPh92jIDDDSg7ydlRow1CP+dys4TrOrbELOyNInHSg==",
+      "version": "0.34.6",
+      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz",
+      "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==",
       "dependencies": {
         "diff-sequences": "^29.4.3",
         "loupe": "^2.3.6",
@@ -2778,9 +2777,9 @@
       }
     },
     "node_modules/@vue/devtools-api": {
-      "version": "6.5.0",
-      "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.0.tgz",
-      "integrity": "sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q=="
+      "version": "6.5.1",
+      "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.5.1.tgz",
+      "integrity": "sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA=="
     },
     "node_modules/@vue/reactivity": {
       "version": "3.3.4",
@@ -3091,9 +3090,9 @@
       }
     },
     "node_modules/axios": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz",
-      "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==",
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz",
+      "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==",
       "dependencies": {
         "follow-redirects": "^1.15.0",
         "form-data": "^4.0.0",
@@ -3114,12 +3113,12 @@
       }
     },
     "node_modules/babel-plugin-polyfill-corejs3": {
-      "version": "0.8.3",
-      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.3.tgz",
-      "integrity": "sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==",
+      "version": "0.8.4",
+      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.4.tgz",
+      "integrity": "sha512-9l//BZZsPR+5XjyJMPtZSK4jv0BsTO1zDac2GC6ygx9WLGlcsnRd1Co0B2zT5fF5Ic6BZy+9m3HNZ3QcOeDKfg==",
       "dependencies": {
         "@babel/helper-define-polyfill-provider": "^0.4.2",
-        "core-js-compat": "^3.31.0"
+        "core-js-compat": "^3.32.2"
       },
       "peerDependencies": {
         "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0"
@@ -3207,9 +3206,9 @@
       "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
     },
     "node_modules/bootstrap": {
-      "version": "5.3.1",
-      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.1.tgz",
-      "integrity": "sha512-jzwza3Yagduci2x0rr9MeFSORjcHpt0lRZukZPZQJT1Dth5qzV7XcgGqYzi39KGAVYR8QEDVoO0ubFKOxzMG+g==",
+      "version": "5.3.2",
+      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz",
+      "integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==",
       "funding": [
         {
           "type": "github",
@@ -3256,9 +3255,9 @@
       }
     },
     "node_modules/browserslist": {
-      "version": "4.21.10",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz",
-      "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==",
+      "version": "4.22.1",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
+      "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
       "funding": [
         {
           "type": "opencollective",
@@ -3274,10 +3273,10 @@
         }
       ],
       "dependencies": {
-        "caniuse-lite": "^1.0.30001517",
-        "electron-to-chromium": "^1.4.477",
+        "caniuse-lite": "^1.0.30001541",
+        "electron-to-chromium": "^1.4.535",
         "node-releases": "^2.0.13",
-        "update-browserslist-db": "^1.0.11"
+        "update-browserslist-db": "^1.0.13"
       },
       "bin": {
         "browserslist": "cli.js"
@@ -3289,7 +3288,8 @@
     "node_modules/buffer-from": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
-      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
+      "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+      "peer": true
     },
     "node_modules/bundle-name": {
       "version": "3.0.0",
@@ -3351,9 +3351,9 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001534",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001534.tgz",
-      "integrity": "sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q==",
+      "version": "1.0.30001547",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz",
+      "integrity": "sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA==",
       "funding": [
         {
           "type": "opencollective",
@@ -3370,9 +3370,9 @@
       ]
     },
     "node_modules/canvas-confetti": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.6.0.tgz",
-      "integrity": "sha512-ej+w/m8Jzpv9Z7W7uJZer14Ke8P2ogsjg4ZMGIuq4iqUOqY2Jq8BNW42iGmNfRwREaaEfFIczLuZZiEVSYNHAA==",
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.0.tgz",
+      "integrity": "sha512-0UGU/T5Un/Cd4Aj4fu/p/oVQm8Il+brK5xcmY+y77u7PXuyNJD4ODUWe01A5o3GUI9Bb8lOBlQ10VdaDsY1FBA==",
       "funding": {
         "type": "donate",
         "url": "https://www.paypal.me/kirilvatev"
@@ -3389,17 +3389,17 @@
       }
     },
     "node_modules/chai": {
-      "version": "4.3.8",
-      "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.8.tgz",
-      "integrity": "sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==",
+      "version": "4.3.10",
+      "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz",
+      "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==",
       "dependencies": {
         "assertion-error": "^1.1.0",
-        "check-error": "^1.0.2",
-        "deep-eql": "^4.1.2",
-        "get-func-name": "^2.0.0",
-        "loupe": "^2.3.1",
+        "check-error": "^1.0.3",
+        "deep-eql": "^4.1.3",
+        "get-func-name": "^2.0.2",
+        "loupe": "^2.3.6",
         "pathval": "^1.1.1",
-        "type-detect": "^4.0.5"
+        "type-detect": "^4.0.8"
       },
       "engines": {
         "node": ">=4"
@@ -3438,9 +3438,12 @@
       }
     },
     "node_modules/check-error": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
-      "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
+      "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
+      "dependencies": {
+        "get-func-name": "^2.0.2"
+      },
       "engines": {
         "node": "*"
       }
@@ -3589,14 +3592,14 @@
       }
     },
     "node_modules/convert-source-map": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
-      "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
     },
     "node_modules/core-js": {
-      "version": "3.32.2",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.32.2.tgz",
-      "integrity": "sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==",
+      "version": "3.33.0",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.0.tgz",
+      "integrity": "sha512-HoZr92+ZjFEKar5HS6MC776gYslNOKHt75mEBKWKnPeFDpZ6nH5OeF3S6HFT1mUAUZKrzkez05VboaX8myjSuw==",
       "hasInstallScript": true,
       "funding": {
         "type": "opencollective",
@@ -3604,11 +3607,11 @@
       }
     },
     "node_modules/core-js-compat": {
-      "version": "3.32.2",
-      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.2.tgz",
-      "integrity": "sha512-+GjlguTDINOijtVRUxrQOv3kfu9rl+qPNdX2LTbJ/ZyVTuxK+ksVSAGX1nHstu4hrv1En/uPTtWgq2gI5wt4AQ==",
+      "version": "3.33.0",
+      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.0.tgz",
+      "integrity": "sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==",
       "dependencies": {
-        "browserslist": "^4.21.10"
+        "browserslist": "^4.22.1"
       },
       "funding": {
         "type": "opencollective",
@@ -3763,9 +3766,9 @@
       }
     },
     "node_modules/define-data-property": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.0.1.tgz",
-      "integrity": "sha512-22M+6zEspQHx10bfFQl2ET39IvfuQ7+rZIH7+ard8fCC4hPmkOSy+8JhKxBRLaWUziJ0O63NTYT97LR8zUfPTw==",
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz",
+      "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==",
       "dependencies": {
         "get-intrinsic": "^1.2.1",
         "gopd": "^1.0.1",
@@ -3959,9 +3962,9 @@
       "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.4.519",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.519.tgz",
-      "integrity": "sha512-kqs9oGYL4UFVkLKhqCTgBCYZv+wZ374yABDMqlDda9HvlkQxvSr7kgf4hfWVjMieDbX+1MwPHFBsOGCMIBaFKg=="
+      "version": "1.4.549",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.549.tgz",
+      "integrity": "sha512-gpXfJslSi4hYDkA0mTLEpYKRv9siAgSUgZ+UWyk+J5Cttpd1ThCVwdclzIwQSclz3hYn049+M2fgrP1WpvF8xg=="
     },
     "node_modules/emoji-regex": {
       "version": "8.0.0",
@@ -3988,17 +3991,17 @@
       }
     },
     "node_modules/es-abstract": {
-      "version": "1.22.1",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz",
-      "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==",
+      "version": "1.22.2",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz",
+      "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==",
       "dependencies": {
         "array-buffer-byte-length": "^1.0.0",
-        "arraybuffer.prototype.slice": "^1.0.1",
+        "arraybuffer.prototype.slice": "^1.0.2",
         "available-typed-arrays": "^1.0.5",
         "call-bind": "^1.0.2",
         "es-set-tostringtag": "^2.0.1",
         "es-to-primitive": "^1.2.1",
-        "function.prototype.name": "^1.1.5",
+        "function.prototype.name": "^1.1.6",
         "get-intrinsic": "^1.2.1",
         "get-symbol-description": "^1.0.0",
         "globalthis": "^1.0.3",
@@ -4014,23 +4017,23 @@
         "is-regex": "^1.1.4",
         "is-shared-array-buffer": "^1.0.2",
         "is-string": "^1.0.7",
-        "is-typed-array": "^1.1.10",
+        "is-typed-array": "^1.1.12",
         "is-weakref": "^1.0.2",
         "object-inspect": "^1.12.3",
         "object-keys": "^1.1.1",
         "object.assign": "^4.1.4",
-        "regexp.prototype.flags": "^1.5.0",
-        "safe-array-concat": "^1.0.0",
+        "regexp.prototype.flags": "^1.5.1",
+        "safe-array-concat": "^1.0.1",
         "safe-regex-test": "^1.0.0",
-        "string.prototype.trim": "^1.2.7",
-        "string.prototype.trimend": "^1.0.6",
-        "string.prototype.trimstart": "^1.0.6",
+        "string.prototype.trim": "^1.2.8",
+        "string.prototype.trimend": "^1.0.7",
+        "string.prototype.trimstart": "^1.0.7",
         "typed-array-buffer": "^1.0.0",
         "typed-array-byte-length": "^1.0.0",
         "typed-array-byte-offset": "^1.0.0",
         "typed-array-length": "^1.0.4",
         "unbox-primitive": "^1.0.2",
-        "which-typed-array": "^1.1.10"
+        "which-typed-array": "^1.1.11"
       },
       "engines": {
         "node": ">= 0.4"
@@ -4154,14 +4157,14 @@
       }
     },
     "node_modules/eslint": {
-      "version": "8.49.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.49.0.tgz",
-      "integrity": "sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==",
+      "version": "8.51.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz",
+      "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==",
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.2.0",
         "@eslint-community/regexpp": "^4.6.1",
         "@eslint/eslintrc": "^2.1.2",
-        "@eslint/js": "8.49.0",
+        "@eslint/js": "8.51.0",
         "@humanwhocodes/config-array": "^0.11.11",
         "@humanwhocodes/module-importer": "^1.0.1",
         "@nodelib/fs.walk": "^1.2.8",
@@ -4550,9 +4553,9 @@
       }
     },
     "node_modules/eslint/node_modules/globals": {
-      "version": "13.21.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz",
-      "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==",
+      "version": "13.23.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz",
+      "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==",
       "dependencies": {
         "type-fest": "^0.20.2"
       },
@@ -4808,11 +4811,11 @@
       }
     },
     "node_modules/flat-cache": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.0.tgz",
-      "integrity": "sha512-OHx4Qwrrt0E4jEIcI5/Xb+f+QmJYNj2rrK8wiIdQOIrB9WrrJL8cjZvXdXuBTkkEwEqLycb5BeZDV1o2i9bTew==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz",
+      "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==",
       "dependencies": {
-        "flatted": "^3.2.7",
+        "flatted": "^3.2.9",
         "keyv": "^4.5.3",
         "rimraf": "^3.0.2"
       },
@@ -4821,9 +4824,9 @@
       }
     },
     "node_modules/flatted": {
-      "version": "3.2.7",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
-      "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ=="
+      "version": "3.2.9",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
+      "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ=="
     },
     "node_modules/flexsearch": {
       "version": "0.7.21",
@@ -4831,9 +4834,9 @@
       "integrity": "sha512-W7cHV7Hrwjid6lWmy0IhsWDFQboWSng25U3VVywpHOTJnnAZNPScog67G+cVpeX9f7yDD21ih0WDrMMT+JoaYg=="
     },
     "node_modules/follow-redirects": {
-      "version": "1.15.2",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
-      "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+      "version": "1.15.3",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
+      "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
       "funding": [
         {
           "type": "individual",
@@ -4889,9 +4892,9 @@
       "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
     },
     "node_modules/fsevents": {
-      "version": "2.3.2",
-      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
-      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
       "hasInstallScript": true,
       "optional": true,
       "os": [
@@ -5139,9 +5142,9 @@
       }
     },
     "node_modules/happy-dom": {
-      "version": "11.0.5",
-      "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-11.0.5.tgz",
-      "integrity": "sha512-l3wkk4lW7QiboAZL2+F3mDN+1tQoNDwLF1Ya8iHEO7pORzQPdGm7kWSAiOgkGNskfrzCV9Pp9jVwgn6vWgRaUA==",
+      "version": "12.9.1",
+      "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-12.9.1.tgz",
+      "integrity": "sha512-UvQ3IwKn1G3iiNCdTrhijdLGqf8Vj7d3OpmYcPwlKakjFy83oYbW6TmOKDLMTVLO9whmOC1HIpS09wf/14k7cA==",
       "dependencies": {
         "css.escape": "^1.5.1",
         "entities": "^4.5.0",
@@ -5163,12 +5166,9 @@
       }
     },
     "node_modules/has": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
-      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
-      "dependencies": {
-        "function-bind": "^1.1.1"
-      },
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
+      "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
       "engines": {
         "node": ">= 0.4.0"
       }
@@ -5246,9 +5246,9 @@
       }
     },
     "node_modules/histoire": {
-      "version": "0.17.0",
-      "resolved": "https://registry.npmjs.org/histoire/-/histoire-0.17.0.tgz",
-      "integrity": "sha512-q5fX2yAiw1vjlC0xaEcm8uqiJzdKmItozyNa24ujFVD+YjKpBE1R6tl/zpUIfqOBgpifMgh7xQD5uU4ZFd7v/g==",
+      "version": "0.17.2",
+      "resolved": "https://registry.npmjs.org/histoire/-/histoire-0.17.2.tgz",
+      "integrity": "sha512-Mz+4AWBs+P2TeopXJ0qG4ZsrpuLggNPNF3yG4Q8yg8kXcd6a9DXUWuEElYbglod/xP5XB8efaDy2nibLTybJzg==",
       "dependencies": {
         "@akryum/tinypool": "^0.3.1",
         "@histoire/app": "^0.17.0",
@@ -5280,7 +5280,7 @@
         "sade": "^1.8.1",
         "shiki-es": "^0.2.0",
         "sirv": "^2.0.3",
-        "vite-node": "0.28.4"
+        "vite-node": "^0.34.1"
       },
       "bin": {
         "histoire": "bin.mjs"
@@ -5762,9 +5762,9 @@
       }
     },
     "node_modules/joi": {
-      "version": "17.10.1",
-      "resolved": "https://registry.npmjs.org/joi/-/joi-17.10.1.tgz",
-      "integrity": "sha512-vIiDxQKmRidUVp8KngT8MZSOcmRVm2zV7jbMjNYWuHcJWI0bUck3nRTGQjhpPlQenIQIBC5Vp9AhcnHbWQqafw==",
+      "version": "17.11.0",
+      "resolved": "https://registry.npmjs.org/joi/-/joi-17.11.0.tgz",
+      "integrity": "sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ==",
       "dependencies": {
         "@hapi/hoek": "^9.0.0",
         "@hapi/topo": "^5.0.0",
@@ -5906,9 +5906,9 @@
       }
     },
     "node_modules/keyv": {
-      "version": "4.5.3",
-      "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz",
-      "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==",
+      "version": "4.5.4",
+      "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+      "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
       "dependencies": {
         "json-buffer": "3.0.1"
       }
@@ -5922,12 +5922,12 @@
       }
     },
     "node_modules/launch-editor": {
-      "version": "2.6.0",
-      "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.0.tgz",
-      "integrity": "sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==",
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz",
+      "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==",
       "dependencies": {
         "picocolors": "^1.0.0",
-        "shell-quote": "^1.7.3"
+        "shell-quote": "^1.8.1"
       }
     },
     "node_modules/levn": {
@@ -6020,9 +6020,9 @@
       }
     },
     "node_modules/magic-string": {
-      "version": "0.30.3",
-      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz",
-      "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==",
+      "version": "0.30.4",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.4.tgz",
+      "integrity": "sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==",
       "dependencies": {
         "@jridgewell/sourcemap-codec": "^1.4.15"
       },
@@ -6621,10 +6621,27 @@
       "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz",
       "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q=="
     },
+    "node_modules/playwright": {
+      "version": "1.38.1",
+      "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.38.1.tgz",
+      "integrity": "sha512-oRMSJmZrOu1FP5iu3UrCx8JEFRIMxLDM0c/3o4bpzU5Tz97BypefWf7TuTNPWeCe279TPal5RtPPZ+9lW/Qkow==",
+      "dependencies": {
+        "playwright-core": "1.38.1"
+      },
+      "bin": {
+        "playwright": "cli.js"
+      },
+      "engines": {
+        "node": ">=16"
+      },
+      "optionalDependencies": {
+        "fsevents": "2.3.2"
+      }
+    },
     "node_modules/playwright-core": {
-      "version": "1.37.1",
-      "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz",
-      "integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==",
+      "version": "1.38.1",
+      "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.38.1.tgz",
+      "integrity": "sha512-tQqNFUKa3OfMf4b2jQ7aGLB8o9bS3bOY0yMEtldtC2+spf8QXG9zvXLTXUeRsoNuxEYMgLYR+NXfAa1rjKRcrg==",
       "bin": {
         "playwright-core": "cli.js"
       },
@@ -6632,10 +6649,23 @@
         "node": ">=16"
       }
     },
+    "node_modules/playwright/node_modules/fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "hasInstallScript": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
     "node_modules/postcss": {
-      "version": "8.4.29",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz",
-      "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==",
+      "version": "8.4.31",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
       "funding": [
         {
           "type": "opencollective",
@@ -6837,9 +6867,9 @@
       "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="
     },
     "node_modules/regenerate-unicode-properties": {
-      "version": "10.1.0",
-      "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz",
-      "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==",
+      "version": "10.1.1",
+      "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz",
+      "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==",
       "dependencies": {
         "regenerate": "^1.4.2"
       },
@@ -6936,9 +6966,9 @@
       "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
     },
     "node_modules/resolve": {
-      "version": "1.22.4",
-      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz",
-      "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==",
+      "version": "1.22.6",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz",
+      "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==",
       "dependencies": {
         "is-core-module": "^2.13.0",
         "path-parse": "^1.0.7",
@@ -7002,9 +7032,9 @@
       }
     },
     "node_modules/rollup": {
-      "version": "3.29.1",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.1.tgz",
-      "integrity": "sha512-c+ebvQz0VIH4KhhCpDsI+Bik0eT8ZFEVZEYw0cGMVqIP8zc+gnwl7iXCamTw7vzv2MeuZFZfdx5JJIq+ehzDlg==",
+      "version": "3.29.4",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz",
+      "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==",
       "bin": {
         "rollup": "dist/bin/rollup"
       },
@@ -7263,11 +7293,12 @@
       }
     },
     "node_modules/set-function-name": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.0.tgz",
-      "integrity": "sha512-WmS8UHojv5s1eSoRSmzO5zzgDq8PE1/X/ij0k+9fMYmINCc6+j+SF3Om8YyucKn2yjnK4ItNZOoQycNnHsZJTw==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz",
+      "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==",
       "dependencies": {
         "define-data-property": "^1.0.1",
+        "functions-have-names": "^1.2.3",
         "has-property-descriptors": "^1.0.0"
       },
       "engines": {
@@ -7392,6 +7423,7 @@
       "version": "0.5.21",
       "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
       "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+      "peer": true,
       "dependencies": {
         "buffer-from": "^1.0.0",
         "source-map": "^0.6.0"
@@ -7588,9 +7620,9 @@
       "integrity": "sha512-1TlOwvKWdXxAY9vba+huLu99zrQURDWA8pUTYsRIYDZYQbGyK+pyEP4h4dlySsqo7ozyJBmYD20F+iUHhAltEg=="
     },
     "node_modules/terser": {
-      "version": "5.19.4",
-      "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.4.tgz",
-      "integrity": "sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g==",
+      "version": "5.21.0",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-5.21.0.tgz",
+      "integrity": "sha512-WtnFKrxu9kaoXuiZFSGrcAvvBqAdmKx0SFNmVNYdJamMu9yyN3I/QF0FbH4QcqJQ+y1CJnzxGIKH0cSj+FGYRw==",
       "peer": true,
       "dependencies": {
         "@jridgewell/source-map": "^0.3.3",
@@ -7630,9 +7662,9 @@
       }
     },
     "node_modules/tinyspy": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.1.1.tgz",
-      "integrity": "sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==",
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.0.tgz",
+      "integrity": "sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==",
       "engines": {
         "node": ">=14.0.0"
       }
@@ -7866,9 +7898,9 @@
       "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
     },
     "node_modules/ufo": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.0.tgz",
-      "integrity": "sha512-bRn3CsoojyNStCZe0BG0Mt4Nr/4KF+rhFlnNXybgqt5pXHNFRlqinSoQaTrGyzE4X8aHplSb+TorH+COin9Yxw=="
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.1.tgz",
+      "integrity": "sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw=="
     },
     "node_modules/unbox-primitive": {
       "version": "1.0.2",
@@ -7884,6 +7916,11 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/undici-types": {
+      "version": "5.25.3",
+      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
+      "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA=="
+    },
     "node_modules/unicode-canonical-property-names-ecmascript": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
@@ -7945,9 +7982,9 @@
       }
     },
     "node_modules/update-browserslist-db": {
-      "version": "1.0.11",
-      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
-      "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
+      "version": "1.0.13",
+      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+      "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
       "funding": [
         {
           "type": "opencollective",
@@ -8020,9 +8057,9 @@
       }
     },
     "node_modules/vite": {
-      "version": "4.4.9",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz",
-      "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==",
+      "version": "4.4.11",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.11.tgz",
+      "integrity": "sha512-ksNZJlkcU9b0lBwAGZGGaZHCMqHsc8OpgtoYhsQ4/I2v5cnpmmmqe5pM4nv/4Hn6G/2GhTdj0DhZh2e+Er1q5A==",
       "dependencies": {
         "esbuild": "^0.18.10",
         "postcss": "^8.4.27",
@@ -8074,27 +8111,25 @@
       }
     },
     "node_modules/vite-node": {
-      "version": "0.28.4",
-      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.28.4.tgz",
-      "integrity": "sha512-KM0Q0uSG/xHHKOJvVHc5xDBabgt0l70y7/lWTR7Q0pR5/MrYxadT+y32cJOE65FfjGmJgxpVEEY+69btJgcXOQ==",
+      "version": "0.34.6",
+      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.6.tgz",
+      "integrity": "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==",
       "dependencies": {
         "cac": "^6.7.14",
         "debug": "^4.3.4",
-        "mlly": "^1.1.0",
-        "pathe": "^1.1.0",
+        "mlly": "^1.4.0",
+        "pathe": "^1.1.1",
         "picocolors": "^1.0.0",
-        "source-map": "^0.6.1",
-        "source-map-support": "^0.5.21",
-        "vite": "^3.0.0 || ^4.0.0"
+        "vite": "^3.0.0 || ^4.0.0 || ^5.0.0-0"
       },
       "bin": {
         "vite-node": "vite-node.mjs"
       },
       "engines": {
-        "node": ">=v14.16.0"
+        "node": ">=v14.18.0"
       },
       "funding": {
-        "url": "https://github.com/sponsors/antfu"
+        "url": "https://opencollective.com/vitest"
       }
     },
     "node_modules/vite-node/node_modules/pathe": {
@@ -8118,22 +8153,22 @@
       }
     },
     "node_modules/vitest": {
-      "version": "0.34.4",
-      "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.4.tgz",
-      "integrity": "sha512-SE/laOsB6995QlbSE6BtkpXDeVNLJc1u2LHRG/OpnN4RsRzM3GQm4nm3PQCK5OBtrsUqnhzLdnT7se3aeNGdlw==",
+      "version": "0.34.6",
+      "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.6.tgz",
+      "integrity": "sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==",
       "dependencies": {
         "@types/chai": "^4.3.5",
         "@types/chai-subset": "^1.3.3",
         "@types/node": "*",
-        "@vitest/expect": "0.34.4",
-        "@vitest/runner": "0.34.4",
-        "@vitest/snapshot": "0.34.4",
-        "@vitest/spy": "0.34.4",
-        "@vitest/utils": "0.34.4",
+        "@vitest/expect": "0.34.6",
+        "@vitest/runner": "0.34.6",
+        "@vitest/snapshot": "0.34.6",
+        "@vitest/spy": "0.34.6",
+        "@vitest/utils": "0.34.6",
         "acorn": "^8.9.0",
         "acorn-walk": "^8.2.0",
         "cac": "^6.7.14",
-        "chai": "^4.3.7",
+        "chai": "^4.3.10",
         "debug": "^4.3.4",
         "local-pkg": "^0.4.3",
         "magic-string": "^0.30.1",
@@ -8144,7 +8179,7 @@
         "tinybench": "^2.5.0",
         "tinypool": "^0.7.0",
         "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0",
-        "vite-node": "0.34.4",
+        "vite-node": "0.34.6",
         "why-is-node-running": "^2.2.2"
       },
       "bin": {
@@ -8198,28 +8233,6 @@
       "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.1.tgz",
       "integrity": "sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q=="
     },
-    "node_modules/vitest/node_modules/vite-node": {
-      "version": "0.34.4",
-      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.4.tgz",
-      "integrity": "sha512-ho8HtiLc+nsmbwZMw8SlghESEE3KxJNp04F/jPUCLVvaURwt0d+r9LxEqCX5hvrrOQ0GSyxbYr5ZfRYhQ0yVKQ==",
-      "dependencies": {
-        "cac": "^6.7.14",
-        "debug": "^4.3.4",
-        "mlly": "^1.4.0",
-        "pathe": "^1.1.1",
-        "picocolors": "^1.0.0",
-        "vite": "^3.0.0 || ^4.0.0"
-      },
-      "bin": {
-        "vite-node": "vite-node.mjs"
-      },
-      "engines": {
-        "node": ">=v14.18.0"
-      },
-      "funding": {
-        "url": "https://opencollective.com/vitest"
-      }
-    },
     "node_modules/vue": {
       "version": "3.3.4",
       "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz",
@@ -8238,9 +8251,9 @@
       "integrity": "sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ=="
     },
     "node_modules/vue-eslint-parser": {
-      "version": "9.3.1",
-      "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz",
-      "integrity": "sha512-Clr85iD2XFZ3lJ52/ppmUDG/spxQu6+MAeHXjjyI4I1NUYZ9xmenQp4N0oaHJhrA8OOxltCVxMRfANGa70vU0g==",
+      "version": "9.3.2",
+      "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.2.tgz",
+      "integrity": "sha512-q7tWyCVaV9f8iQyIA5Mkj/S6AoJ9KBN8IeUSf3XEmBrOtxOZnfTg5s4KClbZBCK3GtnT/+RyCLZyDHuZwTuBjg==",
       "dependencies": {
         "debug": "^4.3.4",
         "eslint-scope": "^7.1.1",
@@ -8296,12 +8309,12 @@
       "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog=="
     },
     "node_modules/vue-i18n": {
-      "version": "9.4.0",
-      "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.4.0.tgz",
-      "integrity": "sha512-701V7wv6m/Fesbu58rRJv9Rd3en/9F7Nxyn/NiwcR7bJkEfwflMJg5wVezkeHy1tIqjXME1e1zbHhK1dNaR8mg==",
+      "version": "9.5.0",
+      "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.5.0.tgz",
+      "integrity": "sha512-NiI3Ph1qMstNf7uhYh8trQBOBFLxeJgcOxBq51pCcZ28Vs18Y7BDS58r8HGDKCYgXdLUYqPDXdKatIF4bvBVZg==",
       "dependencies": {
-        "@intlify/core-base": "9.4.0",
-        "@intlify/shared": "9.4.0",
+        "@intlify/core-base": "9.5.0",
+        "@intlify/shared": "9.5.0",
         "@vue/devtools-api": "^6.5.0"
       },
       "engines": {
@@ -8323,9 +8336,9 @@
       }
     },
     "node_modules/vue-router": {
-      "version": "4.2.4",
-      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.4.tgz",
-      "integrity": "sha512-9PISkmaCO02OzPVOMq2w82ilty6+xJmQrarYZDkjZBfl4RvYAlt4PKnEX21oW4KTtWfa9OuO/b3qk1Od3AEdCQ==",
+      "version": "4.2.5",
+      "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.2.5.tgz",
+      "integrity": "sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==",
       "dependencies": {
         "@vue/devtools-api": "^6.5.0"
       },
@@ -8543,9 +8556,9 @@
       "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
     },
     "node_modules/ws": {
-      "version": "8.14.1",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.1.tgz",
-      "integrity": "sha512-4OOseMUq8AzRBI/7SLMUwO+FEDnguetSk7KMb1sHwvF2w2Wv5Hoj0nlifx8vtGsftE/jWHojPy8sMMzYLJ2G/A==",
+      "version": "8.14.2",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
+      "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
       "engines": {
         "node": ">=10.0.0"
       },
diff --git a/package.json b/package.json
index b5fa3eae..cf45edc7 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,7 @@
     "eslint-plugin-prettier": "^5.0.0-alpha.1",
     "eslint-plugin-promise": "^6.0.0",
     "eslint-plugin-vue": "^9.3.0",
-    "happy-dom": "^11.0.5",
+    "happy-dom": "^12.9.1",
     "histoire": "^0.17.0",
     "markty-toml": "^0.1.1",
     "prettier": "^3.0.0",
diff --git a/templates/definition/meter/smartfox.yaml b/templates/definition/meter/smartfox.yaml
new file mode 100644
index 00000000..287dcdfb
--- /dev/null
+++ b/templates/definition/meter/smartfox.yaml
@@ -0,0 +1,80 @@
+template: smartfox
+products:
+  - brand: Smartfox
+    description:
+      generic: Smartfox Reg/Reg extended/Pro/Pro 2/Pro Light/Pro Light 2/Light
+requirements:
+  description:
+    de: |
+      Kann verwendet werden, um Daten für 'grid', 'pv' und 'aux' zu erhalten. 
+      Wenn "usage" nicht definiert ist, wird die Leistung für die Warmwasserbereitung zurückgegeben (als "aux" zu verwenden).
+    en: |
+      Can be used to get 'grid', 'pv' and 'aux' data. 
+      If 'usage' is not defined, then return the power for the water heating (to be used as 'aux').
+params:
+  - name: usage
+    choice: ["grid", "pv"]
+  - name: host
+render: |
+  {{- define "uri" -}}
+  http://{{ .host }}/all
+  {{- end }}
+  type: custom
+  {{- if not .usage }}
+  power:
+    source: http
+    uri: {{ include "uri" . }}
+    jq: .power_sf
+  {{- end }}
+  {{- if eq .usage "grid" }}
+  power:
+    source: http
+    uri: {{ include "uri" . }}
+    jq: .power_io
+  energy:
+    source: http
+    uri: {{ include "uri" . }}
+    jq: .energy_in
+    scale: 0.001  
+  voltages:
+  - source: http
+    uri: {{ include "uri" . }}
+    jq: .voltages[0]
+  - source: http
+    uri: {{ include "uri" . }}
+    jq: .voltages[1]
+  - source: http
+    uri: {{ include "uri" . }}
+    jq: .voltages[2]
+  currents:
+  - source: http
+    uri: {{ include "uri" . }}
+    jq: .currents[0]
+  - source: http
+    uri: {{ include "uri" . }}
+    jq: .currents[1]
+  - source: http
+    uri: {{ include "uri" . }}
+    jq: .currents[2]
+  powers:
+  - source: http
+    uri: {{ include "uri" . }}
+    jq: .powers[0]
+  - source: http
+    uri: {{ include "uri" . }}
+    jq: .powers[1]
+  - source: http
+    uri: {{ include "uri" . }}
+    jq: .powers[2]
+  {{- end }}
+  {{- if eq .usage "pv" }}
+  power:
+    source: http
+    uri: {{ include "uri" . }}
+    jq: .PvPower[0]
+  energy:
+    source: http
+    uri: {{ include "uri" . }}
+    jq: .PvEnergy[0]
+    scale: 0.001
+  {{- end }}
diff --git a/templates/evcc.io/brands.json b/templates/evcc.io/brands.json
index bbcfb9d1..7cc19fab 100644
--- a/templates/evcc.io/brands.json
+++ b/templates/evcc.io/brands.json
@@ -122,6 +122,7 @@
   "Shelly",
   "Siemens",
   "SMA",
+  "Smartfox",
   "SofarSolar",
   "Solaranzeige",
   "SolarEdge",
@@ -173,6 +174,7 @@
   "Senergy",
   "Shelly",
   "SMA",
+  "Smartfox",
   "SofarSolar",
   "Solaranzeige",
   "SolarEdge",
diff --git a/util/templates/generate/main.go b/util/templates/generate/main.go
index 99497038..15934bc4 100644
--- a/util/templates/generate/main.go
+++ b/util/templates/generate/main.go
@@ -6,7 +6,6 @@ import (
 	"os"
 	"path"
 	"slices"
-	"sort"
 	"strings"
 
 	"github.com/evcc-io/evcc/util/templates"
@@ -88,8 +87,8 @@ func clearDir(dir string) error {
 }
 
 func sorted(keys []string) []string {
-	sort.Slice(keys, func(i, j int) bool {
-		return strings.ToLower(keys[i]) < strings.ToLower(keys[j])
+	slices.SortFunc(keys, func(i, j string) int {
+		return strings.Compare(strings.ToLower(i), strings.ToLower(j))
 	})
 	return slices.Compact(keys)
 }
diff --git a/vehicle/ford.go b/vehicle/ford.go
index b5e4b75b..177448fa 100644
--- a/vehicle/ford.go
+++ b/vehicle/ford.go
@@ -7,6 +7,7 @@ import (
 	"github.com/evcc-io/evcc/api"
 	"github.com/evcc-io/evcc/util"
 	"github.com/evcc-io/evcc/vehicle/ford"
+	"github.com/evcc-io/evcc/vehicle/ford/autonomic"
 )
 
 // https://github.com/d4v3y0rk/ffpass-module
@@ -28,11 +29,9 @@ func NewFordFromConfig(other map[string]interface{}) (api.Vehicle, error) {
 	cc := struct {
 		embed               `mapstructure:",squash"`
 		User, Password, VIN string
-		Expiry              time.Duration
 		Cache               time.Duration
 	}{
-		Expiry: expiry,
-		Cache:  interval,
+		Cache: interval,
 	}
 
 	if err := util.DecodeOther(other, &cc); err != nil {
@@ -58,9 +57,19 @@ func NewFordFromConfig(other map[string]interface{}) (api.Vehicle, error) {
 	api := ford.NewAPI(log, identity)
 
 	cc.VIN, err = ensureVehicle(cc.VIN, api.Vehicles)
+	if err != nil {
+		return nil, err
+	}
+
+	autoIdentity, err := autonomic.NewIdentity(log, identity)
+	if err != nil {
+		return nil, err
+	}
+
+	autoApi := autonomic.NewAPI(log, autoIdentity)
 
 	if err == nil {
-		v.Provider = ford.NewProvider(api, cc.VIN, cc.Expiry, cc.Cache)
+		v.Provider = ford.NewProvider(autoApi, cc.VIN, cc.Cache)
 	}
 
 	return v, err
diff --git a/vehicle/ford/api.go b/vehicle/ford/api.go
index 37d98027..37476545 100644
--- a/vehicle/ford/api.go
+++ b/vehicle/ford/api.go
@@ -27,19 +27,22 @@ func NewAPI(log *util.Logger, ts oauth2.TokenSource) *API {
 	v.Client.Transport = &transport.Decorator{
 		Decorator: func(req *http.Request) error {
 			token, err := ts.Token()
-			if err == nil {
-				for k, v := range map[string]string{
-					"Content-type":   request.JSONContent,
-					"User-Agent":     "FordPass/5 CFNetwork/1333.0.4 Darwin/21.5.0",
-					"locale":         "de-DE",
-					"Application-Id": ApplicationID,
-					"Auth-Token":     token.AccessToken,
-					"CountryCode":    "DEU",
-				} {
-					req.Header.Set(k, v)
-				}
+			if err != nil {
+				return err
 			}
-			return err
+
+			for k, v := range map[string]string{
+				"Content-type":   request.JSONContent,
+				"User-Agent":     "FordPass/5 CFNetwork/1333.0.4 Darwin/21.5.0",
+				"locale":         "de-DE",
+				"Application-Id": ApplicationID,
+				"Auth-Token":     token.AccessToken,
+				"CountryCode":    "DEU",
+			} {
+				req.Header.Set(k, v)
+			}
+
+			return nil
 		},
 		Base: v.Client.Transport,
 	}
diff --git a/vehicle/ford/autonomic/api.go b/vehicle/ford/autonomic/api.go
new file mode 100644
index 00000000..7cc9fff1
--- /dev/null
+++ b/vehicle/ford/autonomic/api.go
@@ -0,0 +1,87 @@
+package autonomic
+
+import (
+	"fmt"
+	"net/http"
+	"strings"
+
+	"github.com/evcc-io/evcc/util"
+	"github.com/evcc-io/evcc/util/request"
+	"github.com/evcc-io/evcc/util/transport"
+	"golang.org/x/oauth2"
+)
+
+const ApiURI = "https://api.autonomic.ai/v1beta/telemetry/sources/fordpass"
+
+var (
+	ApplicationID = "667D773E-1BDC-4139-8AD0-2B16474E8DC7"
+	Dyna          = "MT_3_30_2352378557_3-0_" + "uuidv4()" + "_0_789_87"
+)
+
+// API is the Ford api client
+type API struct {
+	*request.Helper
+}
+
+// NewAPI creates a new api client
+func NewAPI(log *util.Logger, ts oauth2.TokenSource) *API {
+	v := &API{
+		Helper: request.NewHelper(log),
+	}
+
+	v.Client.Transport = &transport.Decorator{
+		Decorator: func(req *http.Request) error {
+			token, err := ts.Token()
+			if err != nil {
+				return err
+			}
+
+			for k, v := range map[string]string{
+				"Content-type":   request.JSONContent,
+				"Application-Id": ApplicationID,
+				"x-dynatrace":    Dyna,
+				"Authorization":  "Bearer " + token.AccessToken,
+			} {
+				req.Header.Set(k, v)
+			}
+
+			return nil
+		},
+		Base: v.Client.Transport,
+	}
+
+	return v
+}
+
+// Status retrieves a metrics result using :query
+func (v *API) Status(vin string) (MetricsResponse, error) {
+	var res MetricsResponse
+
+	uri := fmt.Sprintf("%s/vehicles/%s:query", ApiURI, vin)
+	req, err := request.New(http.MethodPost, uri, strings.NewReader("{}"), request.JSONEncoding)
+	if err == nil {
+		err = v.DoJSON(req, &res)
+	}
+
+	return res, err
+}
+
+// Refresh executes the refresh command
+func (v *API) Refresh(vin string) (any, error) {
+	var res map[string]any
+
+	data := map[string]any{
+		"properties": struct{}{},
+		"tags":       struct{}{},
+		"type":       "statusRefresh",
+		"wakeUp":     true,
+	}
+
+	uri := fmt.Sprintf("%s/vehicles/%s/command", ApiURI, vin)
+	req, err := request.New(http.MethodPost, uri, request.MarshalJSON(data), request.JSONEncoding)
+	if err == nil {
+		err = v.DoJSON(req, &res)
+	}
+
+	return res, err
+}
diff --git a/vehicle/ford/autonomic/identity.go b/vehicle/ford/autonomic/identity.go
new file mode 100644
index 00000000..2f062b37
--- /dev/null
+++ b/vehicle/ford/autonomic/identity.go
@@ -0,0 +1,78 @@
+package autonomic
+
+import (
+	"net/http"
+	"net/url"
+	"strings"
+
+	"github.com/evcc-io/evcc/util"
+	"github.com/evcc-io/evcc/util/oauth"
+	"github.com/evcc-io/evcc/util/request"
+	"golang.org/x/oauth2"
+)
+
+// https://accounts.autonomic.ai/v1/auth/oidc/.well-known/openid-configuration/
+var OAuth2Config = &oauth2.Config{
+	Endpoint: oauth2.Endpoint{
+		AuthURL:  "https://accounts.autonomic.ai/v1/auth/oidc/authorize",
+		TokenURL: "https://accounts.autonomic.ai/v1/auth/oidc/token",
+	},
+	Scopes: []string{"openid"},
+}
+
+type Identity struct {
+	*request.Helper
+	ts oauth2.TokenSource
+	oauth2.TokenSource
+}
+
+// NewIdentity creates autonomic token source
+func NewIdentity(log *util.Logger, ts oauth2.TokenSource) (*Identity, error) {
+	v := &Identity{
+		Helper: request.NewHelper(log),
+		ts:     ts,
+	}
+
+	token, err := ts.Token()
+	if err != nil {
+		return nil, err
+	}
+
+	auto, err := v.exchange(token)
+	if err != nil {
+		return nil, err
+	}
+
+	v.TokenSource = oauth.RefreshTokenSource(auto, v)
+
+	return v, nil
+}
+
+// exchange authenticates with username/password to get new aws credentials
+func (v *Identity) exchange(token *oauth2.Token) (*oauth2.Token, error) {
+	data := url.Values{
+		"subject_token":      {token.AccessToken},
+		"subject_issuer":     {"fordpass"},
+		"client_id":          {"fordpass-prod"},
+		"grant_type":         {"urn:ietf:params:oauth:grant-type:token-exchange"},
+		"subject_token_type": {"urn:ietf:params:oauth:token-type:jwt"},
+	}
+
+	var auto *oauth.Token
+	req, err := request.New(http.MethodPost, OAuth2Config.Endpoint.TokenURL, strings.NewReader(data.Encode()), request.URLEncoding)
+	if err == nil {
+		err = v.DoJSON(req, &auto)
+	}
+
+	return (*oauth2.Token)(auto), err
+}
+
+// RefreshToken implements oauth.TokenRefresher
+func (v *Identity) RefreshToken(_ *oauth2.Token) (*oauth2.Token, error) {
+	token, err := v.ts.Token()
+	if err != nil {
+		return nil, err
+	}
+
+	return v.exchange(token)
+}
diff --git a/vehicle/ford/autonomic/types.go b/vehicle/ford/autonomic/types.go
new file mode 100644
index 00000000..db69030d
--- /dev/null
+++ b/vehicle/ford/autonomic/types.go
@@ -0,0 +1,32 @@
+package autonomic
+
+import "time"
+
+type IntValue struct {
+	UpdateTime time.Time
+	Value      int
+}
+type FloatValue struct {
+	UpdateTime time.Time
+	Value      float64
+}
+type StringValue struct {
+	UpdateTime time.Time
+	Value      string
+}
+
+type MetricsResponse struct {
+	Metrics struct {
+		Position struct {
+			Value struct {
+				Location struct {
+					Lat, Lon float64
+				}
+			}
+		}
+		Odometer                FloatValue
+		XevPlugChargerStatus    StringValue
+		XevBatteryRange         FloatValue
+		XevBatteryStateOfCharge FloatValue
+	}
+}
diff --git a/vehicle/ford/identity.go b/vehicle/ford/identity.go
index 443f62fa..a321e5d0 100644
--- a/vehicle/ford/identity.go
+++ b/vehicle/ford/identity.go
@@ -41,7 +41,7 @@ type Identity struct {
 	oauth2.TokenSource
 }
 
-// NewIdentity creates Fiat identity
+// NewIdentity creates Ford identity
 func NewIdentity(log *util.Logger, user, password string) *Identity {
 	return &Identity{
 		Helper:   request.NewHelper(log),
diff --git a/vehicle/ford/provider.go b/vehicle/ford/provider.go
index 1df8ccb1..7718bf91 100644
--- a/vehicle/ford/provider.go
+++ b/vehicle/ford/provider.go
@@ -1,85 +1,40 @@
 package ford
 
 import (
+	"fmt"
 	"time"
 
 	"github.com/evcc-io/evcc/api"
 	"github.com/evcc-io/evcc/provider"
+	"github.com/evcc-io/evcc/vehicle/ford/autonomic"
 )
 
-const refreshTimeout = time.Minute
-
 type Provider struct {
-	statusG     func() (StatusResponse, error)
-	expiry      time.Duration
-	refreshTime time.Time
-	refreshId   string
-	wakeup      func() error
+	statusG  func() (autonomic.MetricsResponse, error)
+	refreshG func() error
 }
 
-func NewProvider(api *API, vin string, expiry, cache time.Duration) *Provider {
+func NewProvider(api *autonomic.API, vin string, cache time.Duration) *Provider {
 	impl := &Provider{
-		expiry: expiry,
+		statusG: provider.Cached(func() (autonomic.MetricsResponse, error) {
+			return api.Status(vin)
+		}, cache),
+		refreshG: func() error {
+			_, err := api.Refresh(vin)
+			return err
+		},
 	}
 
-	impl.statusG = provider.Cached(func() (StatusResponse, error) {
-		return impl.status(
-			func() (StatusResponse, error) { return api.Status(vin) },
-			func(id string) (StatusResponse, error) { return api.RefreshResult(vin, id) },
-			func() (string, error) { return api.RefreshRequest(vin) },
-		)
-	}, cache)
-
-	impl.wakeup = func() error { return api.WakeUp(vin) }
-
 	return impl
 }
 
-func (v *Provider) status(
-	statusG func() (StatusResponse, error),
-	refreshG func(id string) (StatusResponse, error),
-	refreshRequest func() (string, error),
-) (StatusResponse, error) {
-	if v.refreshId != "" {
-		res, err := refreshG(v.refreshId)
-
-		// update successful and completed
-		if err == nil {
-			v.refreshId = ""
-			return res, nil
-		}
-
-		// update still in progress, keep retrying
-		if time.Since(v.refreshTime) < refreshTimeout {
-			return res, api.ErrMustRetry
-		}
-
-		// give up
-		v.refreshId = ""
-		return res, api.ErrTimeout
-	}
-
-	res, err := statusG()
-
-	if err == nil {
-		if time.Since(res.VehicleStatus.LastRefresh.Time) > v.expiry {
-			if v.refreshId, err = refreshRequest(); err == nil {
-				v.refreshTime = time.Now()
-				err = api.ErrMustRetry
-			}
-		}
-	}
-
-	return res, err
-}
-
 var _ api.Battery = (*Provider)(nil)
 
 // Soc implements the api.Battery interface
 func (v *Provider) Soc() (float64, error) {
 	res, err := v.statusG()
 	if err == nil {
-		return res.VehicleStatus.BatteryFillLevel.Value, nil
+		return res.Metrics.XevBatteryStateOfCharge.Value, nil
 	}
 
 	return 0, err
@@ -91,7 +46,7 @@ var _ api.VehicleRange = (*Provider)(nil)
 func (v *Provider) Range() (int64, error) {
 	res, err := v.statusG()
 	if err == nil {
-		return int64(res.VehicleStatus.ElVehDTE.Value), nil
+		return int64(res.Metrics.XevBatteryRange.Value), nil
 	}
 
 	return 0, err
@@ -101,15 +56,19 @@ var _ api.ChargeState = (*Provider)(nil)
 
 // Status implements the api.ChargeState interface
 func (v *Provider) Status() (api.ChargeStatus, error) {
-	status := api.StatusA // disconnected
+	status := api.StatusNone
 
 	res, err := v.statusG()
 	if err == nil {
-		if res.VehicleStatus.PlugStatus.Value == 1 {
+		switch res.Metrics.XevPlugChargerStatus.Value {
+		case "DISCONNECTED":
+			status = api.StatusA // disconnected
+		case "CONNECTED":
 			status = api.StatusB // connected, not charging
-		}
-		if res.VehicleStatus.ChargingStatus.Value == "ChargingAC" {
+		case "CHARGING", "CHARGINGAC":
 			status = api.StatusC // charging
+		default:
+			err = fmt.Errorf("unknown charge status: %s", res.Metrics.XevPlugChargerStatus.Value)
 		}
 	}
 
@@ -121,7 +80,7 @@ var _ api.VehicleOdometer = (*Provider)(nil)
 // Odometer implements the api.VehicleOdometer interface
 func (v *Provider) Odometer() (float64, error) {
 	res, err := v.statusG()
-	return res.VehicleStatus.Odometer.Value, err
+	return res.Metrics.Odometer.Value, err
 }
 
 var _ api.VehiclePosition = (*Provider)(nil)
@@ -129,20 +88,13 @@ var _ api.VehiclePosition = (*Provider)(nil)
 // Position implements the api.VehiclePosition interface
 func (v *Provider) Position() (float64, float64, error) {
 	res, err := v.statusG()
-	return res.VehicleStatus.Gps.Latitude, res.VehicleStatus.Gps.Longitude, err
-}
-
-var _ api.VehicleFinishTimer = (*Provider)(nil)
-
-// FinishTime implements the api.VehicleFinishTimer interface
-func (v *Provider) FinishTime() (time.Time, error) {
-	res, err := v.statusG()
-	return res.VehicleStatus.ChargeEndTime.Value.Time, err
+	loc := res.Metrics.Position.Value.Location
+	return loc.Lat, loc.Lon, err
 }
 
 var _ api.Resurrector = (*Provider)(nil)
 
 // WakeUp implements the api.Resurrector interface
 func (v *Provider) WakeUp() error {
-	return v.wakeup()
+	return v.refreshG()
 }


Test patch:
diff --git a/assets/js/components/VehicleStatus.test.js b/assets/js/components/VehicleStatus.test.js
index 7612c3b9..01ba809a 100644
--- a/assets/js/components/VehicleStatus.test.js
+++ b/assets/js/components/VehicleStatus.test.js
@@ -207,8 +207,9 @@ describe("smart grid charging", () => {
         tariffCo2: 400,
         smartCostLimit: 500,
         smartCostType: "co2",
+        smartCostActive: true,
       },
-      "cleanEnergyCharging"
+      `cleanEnergyCharging:{"co2":"400 g","limit":"500 g"}`
     );
   });
   test("show cheap energy message", () => {
@@ -219,9 +220,10 @@ describe("smart grid charging", () => {
         charging: true,
         tariffGrid: 0.28,
         smartCostLimit: 0.29,
-        currency: "EUR",
+        currency: "CHF",
+        smartCostActive: true,
       },
-      "cheapEnergyCharging"
+      `cheapEnergyCharging:{"price":"28,0 rp","limit":"29,0 rp"}`
     );
   });
 });