webapp: migrated first part form javascript to typescript

This commit is contained in:
Thomas Basler 2022-06-22 00:06:35 +02:00
parent 51eb2d1070
commit e6c36dd0db
24 changed files with 206 additions and 109 deletions

View File

@ -20,6 +20,8 @@
"devDependencies": { "devDependencies": {
"@babel/core": "^7.18.5", "@babel/core": "^7.18.5",
"@babel/eslint-parser": "^7.18.2", "@babel/eslint-parser": "^7.18.2",
"@types/bootstrap": "^5.1.12",
"@types/node": "^18.0.0",
"@typescript-eslint/parser": "^5.29.0", "@typescript-eslint/parser": "^5.29.0",
"@vue/cli-plugin-babel": "~5.0.0", "@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0", "@vue/cli-plugin-eslint": "~5.0.0",

View File

@ -4,7 +4,7 @@
<h1>DTU Settings</h1> <h1>DTU Settings</h1>
</div> </div>
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType"> <BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
{{ this.alertMessage }} {{ alertMessage }}
</BootstrapAlert> </BootstrapAlert>
<form @submit="saveDtuConfig"> <form @submit="saveDtuConfig">
<div class="card"> <div class="card">
@ -47,7 +47,7 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import BootstrapAlert from "@/components/partials/BootstrapAlert.vue"; import BootstrapAlert from "@/components/partials/BootstrapAlert.vue";
@ -57,7 +57,11 @@ export default defineComponent({
}, },
data() { data() {
return { return {
dtuConfigList: [], dtuConfigList: {
dtu_serial: 0,
dtu_pollinterval: 0,
dtu_palevel: 0
},
palevelList: [ palevelList: [
{ key: 0, value: "Minimum (-18 dBm)" }, { key: 0, value: "Minimum (-18 dBm)" },
{ key: 1, value: "Low (-12 dBm)" }, { key: 1, value: "Low (-12 dBm)" },
@ -77,12 +81,12 @@ export default defineComponent({
fetch("/api/dtu/config") fetch("/api/dtu/config")
.then((response) => response.json()) .then((response) => response.json())
.then( .then(
function (data) { (data) => {
this.dtuConfigList = data; this.dtuConfigList = data;
}.bind(this) }
); );
}, },
saveDtuConfig(e) { saveDtuConfig(e: Event) {
e.preventDefault(); e.preventDefault();
const formData = new FormData(); const formData = new FormData();
@ -100,11 +104,11 @@ export default defineComponent({
} }
}) })
.then( .then(
function (response) { (response) => {
this.alertMessage = response.message; this.alertMessage = response.message;
this.alertType = response.type; this.alertType = response.type;
this.showAlert = true; this.showAlert = true;
}.bind(this) }
); );
}, },
}, },

View File

@ -45,10 +45,17 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import InverterChannelInfo from "@/components/partials/InverterChannelInfo"; import InverterChannelInfo from "@/components/partials/InverterChannelInfo.vue";
import bootstrap from "bootstrap/dist/js/bootstrap.js"; import * as bootstrap from 'bootstrap';
declare interface Inverter {
serial: number,
name: string,
age_critical: boolean,
data_age: 0
}
export default defineComponent({ export default defineComponent({
components: { components: {
@ -56,10 +63,10 @@ export default defineComponent({
}, },
data() { data() {
return { return {
socket: null, socket: {} as WebSocket,
heartInterval: null, heartInterval: 0,
waitForData: true, waitForData: true,
inverterData: [], inverterData: [] as Inverter[],
isFirstFetchAfterConnect: true, isFirstFetchAfterConnect: true,
}; };
}, },
@ -93,12 +100,12 @@ export default defineComponent({
this.socket = new WebSocket(webSocketUrl); this.socket = new WebSocket(webSocketUrl);
this.socket.onmessage = function (event) { this.socket.onmessage = (event) => {
console.log(event); console.log(event);
this.inverterData = JSON.parse(event.data); this.inverterData = JSON.parse(event.data);
this.waitForData = false; this.waitForData = false;
this.heartCheck(); // Reset heartbeat detection this.heartCheck(); // Reset heartbeat detection
}.bind(this); };
this.socket.onopen = function (event) { this.socket.onopen = function (event) {
console.log(event); console.log(event);

View File

@ -5,7 +5,7 @@
</div> </div>
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType"> <BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
{{ this.alertMessage }} {{ alertMessage }}
</BootstrapAlert> </BootstrapAlert>
<div class="card"> <div class="card">
@ -92,10 +92,17 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import BootstrapAlert from "@/components/partials/BootstrapAlert.vue"; import BootstrapAlert from "@/components/partials/BootstrapAlert.vue";
declare interface Inverter {
id: string,
serial: number,
name: string,
type: string
}
export default defineComponent({ export default defineComponent({
components: { components: {
BootstrapAlert, BootstrapAlert,
@ -103,18 +110,9 @@ export default defineComponent({
data() { data() {
return { return {
editId: "-1", editId: "-1",
inverterData: { inverterData: {} as Inverter,
id: "", editInverterData: {} as Inverter,
serial: "", inverters: [] as Inverter[],
name: "",
},
editInverterData: {
id: "",
serial: "",
name: "",
type: "",
},
inverters: [],
alertMessage: "", alertMessage: "",
alertType: "info", alertType: "info",
showAlert: false, showAlert: false,
@ -152,18 +150,18 @@ export default defineComponent({
} }
}) })
.then( .then(
function (response) { (response) => {
this.alertMessage = response.message; this.alertMessage = response.message;
this.alertType = response.type; this.alertType = response.type;
this.showAlert = true; this.showAlert = true;
}.bind(this) }
) )
.then(this.getInverters()); .then(() => { this.getInverters() });
this.inverterData.serial = ""; this.inverterData.serial = 0;
this.inverterData.name = ""; this.inverterData.name = "";
}, },
onDelete(id) { onDelete(id: string) {
const formData = new FormData(); const formData = new FormData();
formData.append("data", JSON.stringify({ id: id })); formData.append("data", JSON.stringify({ id: id }));
@ -179,15 +177,15 @@ export default defineComponent({
} }
}) })
.then( .then(
function (response) { (response) => {
this.alertMessage = response.message; this.alertMessage = response.message;
this.alertType = response.type; this.alertType = response.type;
this.showAlert = true; this.showAlert = true;
}.bind(this) }
) )
.then(this.getInverters()); .then(() => { this.getInverters() });
}, },
onEdit(inverter) { onEdit(inverter: Inverter) {
this.editId = inverter.id; this.editId = inverter.id;
this.editInverterData.serial = inverter.serial; this.editInverterData.serial = inverter.serial;
this.editInverterData.name = inverter.name; this.editInverterData.name = inverter.name;
@ -195,10 +193,10 @@ export default defineComponent({
}, },
onCancel() { onCancel() {
this.editId = "-1"; this.editId = "-1";
this.editInverterData.serial = ""; this.editInverterData.serial = 0;
this.editInverterData.name = ""; this.editInverterData.name = "";
}, },
onEditSubmit(id) { onEditSubmit(id: string) {
const formData = new FormData(); const formData = new FormData();
this.editInverterData.id = id; this.editInverterData.id = id;
formData.append("data", JSON.stringify(this.editInverterData)); formData.append("data", JSON.stringify(this.editInverterData));
@ -215,16 +213,16 @@ export default defineComponent({
} }
}) })
.then( .then(
function (response) { (response) => {
this.alertMessage = response.message; this.alertMessage = response.message;
this.alertType = response.type; this.alertType = response.type;
this.showAlert = true; this.showAlert = true;
}.bind(this) }
) )
.then(this.getInverters()); .then(() => { this.getInverters() });
this.editId = "-1"; this.editId = "-1";
this.editInverterData.serial = ""; this.editInverterData.serial = 0;
this.editInverterData.name = ""; this.editInverterData.name = "";
this.editInverterData.type = ""; this.editInverterData.type = "";
}, },

View File

@ -4,7 +4,7 @@
<h1>MqTT Settings</h1> <h1>MqTT Settings</h1>
</div> </div>
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType"> <BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
{{ this.alertMessage }} {{ alertMessage }}
</BootstrapAlert> </BootstrapAlert>
<form @submit="saveMqttConfig"> <form @submit="saveMqttConfig">
<div class="card"> <div class="card">
@ -132,7 +132,7 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import BootstrapAlert from "@/components/partials/BootstrapAlert.vue"; import BootstrapAlert from "@/components/partials/BootstrapAlert.vue";
@ -142,7 +142,19 @@ export default defineComponent({
}, },
data() { data() {
return { return {
mqttConfigList: [], mqttConfigList: {
mqtt_enabled: false,
mqtt_hostname: "",
mqtt_port: 0,
mqtt_username: "",
mqtt_password: "",
mqtt_topic: "",
mqtt_publish_interval: 0,
mqtt_retain: false,
mqtt_lwt_topic: "",
mqtt_lwt_online: "",
mqtt_lwt_offline: ""
},
alertMessage: "", alertMessage: "",
alertType: "info", alertType: "info",
showAlert: false, showAlert: false,
@ -157,7 +169,7 @@ export default defineComponent({
.then((response) => response.json()) .then((response) => response.json())
.then((data) => (this.mqttConfigList = data)); .then((data) => (this.mqttConfigList = data));
}, },
saveMqttConfig(e) { saveMqttConfig(e: Event) {
e.preventDefault(); e.preventDefault();
const formData = new FormData(); const formData = new FormData();
@ -175,11 +187,11 @@ export default defineComponent({
} }
}) })
.then( .then(
function (response) { (response) => {
this.alertMessage = response.message; this.alertMessage = response.message;
this.alertType = response.type; this.alertType = response.type;
this.showAlert = true; this.showAlert = true;
}.bind(this) }
); );
}, },
}, },

View File

@ -80,13 +80,22 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
data() { data() {
return { return {
mqttDataList: [], mqttDataList: {
mqtt_enabled: false,
mqtt_hostname: "",
mqtt_port: 0,
mqtt_username: "",
mqtt_topic: "",
mqtt_publish_interval: 0,
mqtt_retain: false,
mqtt_connected: false
},
}; };
}, },
created() { created() {

View File

@ -69,9 +69,3 @@
</div> </div>
</nav> </nav>
</template> </template>
<script>
</script>
<style>
</style>

View File

@ -4,7 +4,7 @@
<h1>Network Settings</h1> <h1>Network Settings</h1>
</div> </div>
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType"> <BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
{{ this.alertMessage }} {{ alertMessage }}
</BootstrapAlert> </BootstrapAlert>
<form @submit="saveNetworkConfig"> <form @submit="saveNetworkConfig">
<div class="card"> <div class="card">
@ -97,7 +97,7 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import BootstrapAlert from "@/components/partials/BootstrapAlert.vue"; import BootstrapAlert from "@/components/partials/BootstrapAlert.vue";
@ -107,7 +107,17 @@ export default defineComponent({
}, },
data() { data() {
return { return {
networkConfigList: [], networkConfigList: {
ssid: "",
password: "",
hostname: "",
dhcp: false,
ipaddress: "",
netmask: "",
gateway: "",
dns1: "",
dns2: ""
},
alertMessage: "", alertMessage: "",
alertType: "info", alertType: "info",
showAlert: false, showAlert: false,
@ -122,7 +132,7 @@ export default defineComponent({
.then((response) => response.json()) .then((response) => response.json())
.then((data) => (this.networkConfigList = data)); .then((data) => (this.networkConfigList = data));
}, },
saveNetworkConfig(e) { saveNetworkConfig(e: Event) {
e.preventDefault(); e.preventDefault();
const formData = new FormData(); const formData = new FormData();
@ -140,11 +150,11 @@ export default defineComponent({
} }
}) })
.then( .then(
function (response) { (response) => {
this.alertMessage = response.message; this.alertMessage = response.message;
this.alertType = response.type; this.alertType = response.type;
this.showAlert = true; this.showAlert = true;
}.bind(this) }
); );
}, },
}, },

View File

@ -14,7 +14,7 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import WifiStationInfo from "./partials/WifiStationInfo.vue"; import WifiStationInfo from "./partials/WifiStationInfo.vue";
import WifiApInfo from "./partials/WifiApInfo.vue"; import WifiApInfo from "./partials/WifiApInfo.vue";

View File

@ -4,7 +4,7 @@
<h1>NTP Settings</h1> <h1>NTP Settings</h1>
</div> </div>
<BootstrapAlert v-model="showAlert" dismissible :variant="alertType"> <BootstrapAlert v-model="showAlert" dismissible :variant="alertType">
{{ this.alertMessage }} {{ alertMessage }}
</BootstrapAlert> </BootstrapAlert>
<form @submit="saveNtpConfig"> <form @submit="saveNtpConfig">
<div class="card"> <div class="card">
@ -44,7 +44,7 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import BootstrapAlert from "@/components/partials/BootstrapAlert.vue"; import BootstrapAlert from "@/components/partials/BootstrapAlert.vue";
@ -54,7 +54,11 @@ export default defineComponent({
}, },
data() { data() {
return { return {
ntpConfigList: [], ntpConfigList: {
ntp_server: "",
ntp_timezone: "",
ntp_timezone_descr: ""
},
timezoneList: {}, timezoneList: {},
timezoneSelect: "", timezoneSelect: "",
alertMessage: "", alertMessage: "",
@ -82,16 +86,16 @@ export default defineComponent({
fetch("/api/ntp/config") fetch("/api/ntp/config")
.then((response) => response.json()) .then((response) => response.json())
.then( .then(
function (data) { (data) => {
this.ntpConfigList = data; this.ntpConfigList = data;
this.timezoneSelect = this.timezoneSelect =
this.ntpConfigList.ntp_timezone_descr + this.ntpConfigList.ntp_timezone_descr +
"---" + "---" +
this.ntpConfigList.ntp_timezone; this.ntpConfigList.ntp_timezone;
}.bind(this) }
); );
}, },
saveNtpConfig(e) { saveNtpConfig(e: Event) {
e.preventDefault(); e.preventDefault();
const formData = new FormData(); const formData = new FormData();
@ -109,11 +113,11 @@ export default defineComponent({
} }
}) })
.then( .then(
function (response) { (response) => {
this.alertMessage = response.message; this.alertMessage = response.message;
this.alertType = response.type; this.alertType = response.type;
this.showAlert = true; this.showAlert = true;
}.bind(this) }
); );
}, },
}, },

View File

@ -56,13 +56,19 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
data() { data() {
return { return {
ntpDataList: [], ntpDataList: {
ntp_server: "",
ntp_timezone: "",
ntp_timezone_descr: "",
ntp_status: false,
ntp_localtime: ""
},
}; };
}, },
created() { created() {

View File

@ -12,7 +12,7 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import HardwareInfo from "@/components/partials/HardwareInfo.vue"; import HardwareInfo from "@/components/partials/HardwareInfo.vue";
import FirmwareInfo from "@/components/partials/FirmwareInfo.vue"; import FirmwareInfo from "@/components/partials/FirmwareInfo.vue";

View File

@ -15,7 +15,7 @@ export const toInteger = (value, defaultValue = NaN) => {
}; };
export default defineComponent({ export default defineComponent({
name: "BAlert", name: "BootstrapAlert",
props: { props: {
dismissLabel: { type: String, default: "Close" }, dismissLabel: { type: String, default: "Close" },
dismissible: { type: Boolean, default: false }, dismissible: { type: Boolean, default: false },

View File

@ -46,13 +46,22 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
data() { data() {
return { return {
systemDataList: [], systemDataList: {
hostname: "",
sdkversion: "",
firmware_version: "",
git_hash: "",
resetreason_0: "",
resetreason_1: "",
cfgsavecount: 0,
uptime: 0
},
}; };
}, },
created() { created() {
@ -60,11 +69,11 @@ export default defineComponent({
}, },
computed: { computed: {
timeInHours() { timeInHours() {
return (value) => { return (value: number) => {
const days = parseInt(Math.floor(value / 3600 / 24)); const days = Math.floor(value / 3600 / 24);
const hours = parseInt(Math.floor((value - days * 3600 * 24) / 3600)); const hours = Math.floor((value - days * 3600 * 24) / 3600);
const minutes = parseInt(Math.floor((value - days * 3600 * 24 - hours * 3600) / 60)); const minutes = Math.floor((value - days * 3600 * 24 - hours * 3600) / 60);
const seconds = parseInt((value - days * 3600 * 24 - hours * 3600 + minutes * 60) % 60); const seconds = (value - days * 3600 * 24 - hours * 3600 + minutes * 60) % 60;
const dHours = hours > 9 ? hours : "0" + hours; const dHours = hours > 9 ? hours : "0" + hours;
const dMins = minutes > 9 ? minutes : "0" + minutes; const dMins = minutes > 9 ? minutes : "0" + minutes;

View File

@ -3,9 +3,9 @@
<th>{{ name }}</th> <th>{{ name }}</th>
<td> <td>
<div class="progress"> <div class="progress">
<div class="progress-bar" role="progressbar" :style="{ width: this.getPercent() + '%' }" <div class="progress-bar" role="progressbar" :style="{ width: getPercent() + '%' }"
v-bind:aria-valuenow="this.getPercent()" aria-valuemin="0" aria-valuemax="100"> v-bind:aria-valuenow="getPercent()" aria-valuemin="0" aria-valuemax="100">
{{ this.getPercent() }}% {{ getPercent() }}%
</div> </div>
</div> </div>
</td> </td>
@ -18,14 +18,14 @@
</tr> </tr>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
props: { props: {
name: String, name: String,
total: Number, total: { type: Number, required: true },
used: Number, used: { type: Number, required: true },
}, },
methods: { methods: {
getPercent() { getPercent() {

View File

@ -30,13 +30,18 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
data() { data() {
return { return {
systemDataList: [], systemDataList: {
chipmodel: "",
chiprevision: "",
chipcores: "",
cpufreq: ""
},
}; };
}, },
created() { created() {

View File

@ -22,13 +22,16 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
data() { data() {
return { return {
networkDataList: [], networkDataList: {
ap_ip: "",
ap_mac: ""
},
}; };
}, },
created() { created() {

View File

@ -38,13 +38,20 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
data() { data() {
return { return {
networkDataList: [], networkDataList: {
sta_ip: "",
sta_netmask: "",
sta_gateway: "",
sta_dns1: "",
sta_dns2: "",
sta_mac: ""
},
}; };
}, },
created() { created() {

View File

@ -24,7 +24,7 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
@ -33,7 +33,7 @@ export default defineComponent({
channelNumber: Number, channelNumber: Number,
}, },
methods: { methods: {
formatNumber(num) { formatNumber(num: string) {
return parseFloat(num).toFixed(2); return parseFloat(num).toFixed(2);
}, },
}, },

View File

@ -25,7 +25,7 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import FsInfo from "@/components/partials/FsInfo.vue"; import FsInfo from "@/components/partials/FsInfo.vue";
@ -35,7 +35,14 @@ export default defineComponent({
}, },
data() { data() {
return { return {
systemDataList: [], systemDataList: {
heap_total: 0,
heap_used: 0,
littlefs_total: 0,
littlefs_used: 0,
sketch_total: 0,
sketch_used: 0
},
}; };
}, },
created() { created() {

View File

@ -32,13 +32,17 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
data() { data() {
return { return {
networkDataList: [], networkDataList: {
ap_status: false,
ap_ssid: "",
ap_stationnum: 0
},
}; };
}, },
created() { created() {

View File

@ -23,7 +23,7 @@
</tr> </tr>
<tr> <tr>
<th>Quality</th> <th>Quality</th>
<td>{{ this.getRSSIasQuality(networkDataList.sta_rssi) }} %</td> <td>{{ getRSSIasQuality(networkDataList.sta_rssi) }} %</td>
</tr> </tr>
<tr> <tr>
<th>RSSI</th> <th>RSSI</th>
@ -36,13 +36,17 @@
</div> </div>
</template> </template>
<script> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
export default defineComponent({ export default defineComponent({
data() { data() {
return { return {
networkDataList: [], networkDataList: {
sta_status: false,
sta_ssid: "",
sta_rssi: 0
},
}; };
}, },
created() { created() {
@ -54,7 +58,7 @@ export default defineComponent({
.then((response) => response.json()) .then((response) => response.json())
.then((data) => (this.networkDataList = data)); .then((data) => (this.networkDataList = data));
}, },
getRSSIasQuality(rssi) { getRSSIasQuality(rssi: number) {
let quality = 0; let quality = 0;
if (rssi <= -100) { if (rssi <= -100) {

View File

@ -4,6 +4,6 @@ import router from './router'
import { BootstrapIconsPlugin } from 'bootstrap-icons-vue'; import { BootstrapIconsPlugin } from 'bootstrap-icons-vue';
import "bootstrap/dist/css/bootstrap.min.css" import "bootstrap/dist/css/bootstrap.min.css"
import "bootstrap/dist/js/bootstrap.js" import "bootstrap"
createApp(App).use(router).use(BootstrapIconsPlugin).mount('#app') createApp(App).use(router).use(BootstrapIconsPlugin).mount('#app')

View File

@ -1151,7 +1151,7 @@
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1"
integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==
"@popperjs/core@^2.11.5": "@popperjs/core@^2.11.5", "@popperjs/core@^2.9.2":
version "2.11.5" version "2.11.5"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64"
integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw== integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==
@ -1208,6 +1208,13 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/bootstrap@^5.1.12":
version "5.1.12"
resolved "https://registry.yarnpkg.com/@types/bootstrap/-/bootstrap-5.1.12.tgz#4d704f6385fda2f1a56cc458f1f4cafab6e9f7e3"
integrity sha512-pSS5BGEgepwzdbsBGswBWFmgrnYpp7c4UfuYe1FJWwkrcjm/JVwfG4gBkOYtd92Otd3RdJK0ByBWMkBROfLEPw==
dependencies:
"@popperjs/core" "^2.9.2"
"@types/connect-history-api-fallback@^1.3.5": "@types/connect-history-api-fallback@^1.3.5":
version "1.3.5" version "1.3.5"
resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae"
@ -1303,6 +1310,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.35.tgz#635b7586086d51fb40de0a2ec9d1014a5283ba4a" resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.35.tgz#635b7586086d51fb40de0a2ec9d1014a5283ba4a"
integrity sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg== integrity sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==
"@types/node@^18.0.0":
version "18.0.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a"
integrity sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==
"@types/normalize-package-data@^2.4.0": "@types/normalize-package-data@^2.4.0":
version "2.4.1" version "2.4.1"
resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301"