2023-09-09 17:01:10 +00:00
|
|
|
<script setup lang="ts">
|
2023-10-04 20:38:55 +00:00
|
|
|
// @ts-nocheck
|
2023-10-22 13:52:30 +00:00
|
|
|
// reason for no check is, that we have some mixing of typescript and chart js which seems to be not to be fixed that easy
|
|
|
|
|
2023-10-03 13:15:17 +00:00
|
|
|
import { setActivePinia } from "pinia";
|
|
|
|
import pinia from "../store/index";
|
2023-09-09 17:01:10 +00:00
|
|
|
setActivePinia(pinia);
|
|
|
|
|
2023-11-18 15:53:54 +00:00
|
|
|
import { settingsStore as settings } from "../store/settingsStore.js";
|
2023-09-09 17:01:10 +00:00
|
|
|
|
2023-10-03 13:15:17 +00:00
|
|
|
import { useStateStore } from "../store/stateStore.js";
|
2023-09-09 17:01:10 +00:00
|
|
|
const state = useStateStore(pinia);
|
|
|
|
|
2023-09-29 08:26:27 +00:00
|
|
|
import {
|
|
|
|
Chart as ChartJS,
|
|
|
|
CategoryScale,
|
|
|
|
LinearScale,
|
|
|
|
PointElement,
|
|
|
|
LineElement,
|
|
|
|
Title,
|
|
|
|
Tooltip,
|
2023-10-03 13:15:17 +00:00
|
|
|
Legend,
|
|
|
|
} from "chart.js";
|
|
|
|
import { Line, Scatter } from "vue-chartjs";
|
2023-10-22 13:24:34 +00:00
|
|
|
import { computed } from "vue";
|
2023-10-03 13:15:17 +00:00
|
|
|
|
|
|
|
function selectStatsControl(obj) {
|
|
|
|
switch (obj.delegateTarget.id) {
|
|
|
|
case "list-waterfall-list":
|
2023-11-27 02:37:28 +00:00
|
|
|
settings.local.spectrum = "waterfall";
|
2023-10-03 13:15:17 +00:00
|
|
|
break;
|
|
|
|
case "list-scatter-list":
|
2023-11-27 02:37:28 +00:00
|
|
|
settings.local.spectrum = "scatter";
|
2023-10-03 13:15:17 +00:00
|
|
|
break;
|
|
|
|
case "list-chart-list":
|
2023-11-27 02:37:28 +00:00
|
|
|
settings.local.spectrum = "chart";
|
2023-10-03 13:15:17 +00:00
|
|
|
break;
|
|
|
|
default:
|
2023-11-27 02:37:28 +00:00
|
|
|
settings.local.spectrum = "waterfall";
|
2023-10-03 13:15:17 +00:00
|
|
|
}
|
2023-11-18 15:53:54 +00:00
|
|
|
//saveSettingsToFile();
|
2023-09-29 08:26:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ChartJS.register(
|
|
|
|
CategoryScale,
|
|
|
|
LinearScale,
|
|
|
|
PointElement,
|
|
|
|
LineElement,
|
|
|
|
Title,
|
|
|
|
Tooltip,
|
2023-10-03 13:15:17 +00:00
|
|
|
Legend,
|
|
|
|
);
|
2023-10-02 12:45:47 +00:00
|
|
|
|
|
|
|
// https://www.chartjs.org/docs/latest/samples/line/segments.html
|
2023-10-03 13:15:17 +00:00
|
|
|
const skipped = (speedCtx, value) =>
|
|
|
|
speedCtx.p0.skip || speedCtx.p1.skip ? value : undefined;
|
|
|
|
const down = (speedCtx, value) =>
|
|
|
|
speedCtx.p0.parsed.y > speedCtx.p1.parsed.y ? value : undefined;
|
2023-10-02 12:45:47 +00:00
|
|
|
|
2023-10-03 13:15:17 +00:00
|
|
|
var transmissionSpeedChartOptions = {
|
2023-10-04 20:38:55 +00:00
|
|
|
//type: "line",
|
2023-10-03 13:15:17 +00:00
|
|
|
responsive: true,
|
|
|
|
animations: true,
|
2023-10-09 08:20:52 +00:00
|
|
|
maintainAspectRatio: false,
|
2023-10-03 13:15:17 +00:00
|
|
|
cubicInterpolationMode: "monotone",
|
|
|
|
tension: 0.4,
|
|
|
|
scales: {
|
|
|
|
SNR: {
|
|
|
|
type: "linear",
|
|
|
|
ticks: { beginAtZero: false, color: "rgb(255, 99, 132)" },
|
|
|
|
position: "right",
|
|
|
|
},
|
|
|
|
SPEED: {
|
|
|
|
type: "linear",
|
|
|
|
ticks: { beginAtZero: false, color: "rgb(120, 100, 120)" },
|
|
|
|
position: "left",
|
|
|
|
grid: {
|
|
|
|
drawOnChartArea: false, // only want the grid lines for one axis to show up
|
2023-10-02 12:45:47 +00:00
|
|
|
},
|
|
|
|
},
|
2023-10-03 13:15:17 +00:00
|
|
|
x: { ticks: { beginAtZero: true } },
|
|
|
|
},
|
|
|
|
};
|
2023-10-02 12:45:47 +00:00
|
|
|
|
2023-09-29 08:26:27 +00:00
|
|
|
const transmissionSpeedChartData = computed(() => ({
|
2023-10-03 13:15:17 +00:00
|
|
|
labels: state.arq_speed_list_timestamp,
|
2023-09-29 08:26:27 +00:00
|
|
|
datasets: [
|
2023-10-02 12:45:47 +00:00
|
|
|
{
|
2023-10-03 13:15:17 +00:00
|
|
|
type: "line",
|
|
|
|
label: "SNR[dB]",
|
|
|
|
data: state.arq_speed_list_snr,
|
|
|
|
borderColor: "rgb(75, 192, 192, 1.0)",
|
|
|
|
pointRadius: 1,
|
|
|
|
segment: {
|
|
|
|
borderColor: (speedCtx) =>
|
|
|
|
skipped(speedCtx, "rgb(0,0,0,0.4)") ||
|
|
|
|
down(speedCtx, "rgb(192,75,75)"),
|
|
|
|
borderDash: (speedCtx) => skipped(speedCtx, [3, 3]),
|
2023-10-02 12:45:47 +00:00
|
|
|
},
|
2023-10-03 13:15:17 +00:00
|
|
|
spanGaps: true,
|
|
|
|
backgroundColor: "rgba(75, 192, 192, 0.2)",
|
|
|
|
order: 1,
|
|
|
|
yAxisID: "SNR",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: "bar",
|
|
|
|
label: "Speed[bpm]",
|
|
|
|
data: state.arq_speed_list_bpm,
|
|
|
|
borderColor: "rgb(120, 100, 120, 1.0)",
|
|
|
|
backgroundColor: "rgba(120, 100, 120, 0.2)",
|
|
|
|
order: 0,
|
|
|
|
yAxisID: "SPEED",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}));
|
2023-09-11 14:09:17 +00:00
|
|
|
|
2023-10-02 12:45:47 +00:00
|
|
|
const scatterChartOptions = {
|
|
|
|
responsive: true,
|
2023-10-09 08:20:52 +00:00
|
|
|
maintainAspectRatio: false,
|
2023-10-02 12:45:47 +00:00
|
|
|
scales: {
|
|
|
|
x: {
|
2023-10-03 13:15:17 +00:00
|
|
|
type: "linear",
|
|
|
|
position: "bottom",
|
2023-10-02 12:45:47 +00:00
|
|
|
grid: {
|
|
|
|
display: true,
|
|
|
|
lineWidth: 1, // Set the line width for x-axis grid lines
|
|
|
|
},
|
|
|
|
ticks: {
|
|
|
|
display: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
y: {
|
2023-10-03 13:15:17 +00:00
|
|
|
type: "linear",
|
|
|
|
position: "left",
|
2023-10-02 12:45:47 +00:00
|
|
|
grid: {
|
|
|
|
display: true,
|
|
|
|
lineWidth: 1, // Set the line width for y-axis grid lines
|
|
|
|
},
|
|
|
|
ticks: {
|
|
|
|
display: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
plugins: {
|
|
|
|
legend: {
|
|
|
|
display: false,
|
|
|
|
},
|
|
|
|
tooltip: {
|
|
|
|
enabled: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2023-10-02 12:50:39 +00:00
|
|
|
// dummy data
|
|
|
|
//state.scatter = [{"x":"166","y":"46"},{"x":"-193","y":"-139"},{"x":"-165","y":"-291"},{"x":"311","y":"-367"},{"x":"389","y":"199"},{"x":"78","y":"372"},{"x":"242","y":"-431"},{"x":"-271","y":"-248"},{"x":"28","y":"-130"},{"x":"-20","y":"187"},{"x":"74","y":"362"},{"x":"-316","y":"-229"},{"x":"-180","y":"261"},{"x":"321","y":"360"},{"x":"438","y":"-288"},{"x":"378","y":"-94"},{"x":"462","y":"-163"},{"x":"-265","y":"248"},{"x":"210","y":"314"},{"x":"230","y":"-320"},{"x":"261","y":"-244"},{"x":"-283","y":"-373"}]
|
2023-09-11 14:09:17 +00:00
|
|
|
|
2023-09-29 08:26:27 +00:00
|
|
|
const scatterChartData = computed(() => ({
|
|
|
|
datasets: [
|
2023-10-03 13:15:17 +00:00
|
|
|
{
|
|
|
|
type: "scatter",
|
|
|
|
fill: true,
|
|
|
|
data: state.scatter,
|
|
|
|
label: "Scatter",
|
|
|
|
tension: 0.1,
|
|
|
|
borderColor: "rgb(0, 255, 0)",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}));
|
2023-10-09 14:11:01 +00:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<script lang="ts">
|
2023-10-22 08:12:00 +00:00
|
|
|
import { initWaterfall } from "../js/waterfallHandler.js";
|
2023-12-04 03:43:48 +00:00
|
|
|
var localSpectrum;
|
2023-10-09 14:11:01 +00:00
|
|
|
export default {
|
|
|
|
mounted() {
|
|
|
|
// This code will be executed after the component is mounted to the DOM
|
|
|
|
// You can access DOM elements or perform other initialization here
|
|
|
|
//const myElement = this.$refs.waterfall; // Access the DOM element with ref
|
|
|
|
|
|
|
|
// init waterfall
|
2023-12-04 03:43:48 +00:00
|
|
|
localSpectrum = initWaterfall("waterfall-main");
|
2023-12-04 03:49:02 +00:00
|
|
|
window.addEventListener(
|
|
|
|
"wf-data-avail",
|
|
|
|
function (evt) {
|
|
|
|
localSpectrum.addData(evt.detail);
|
|
|
|
},
|
|
|
|
false,
|
|
|
|
);
|
2023-10-09 14:11:01 +00:00
|
|
|
},
|
2023-10-22 08:12:00 +00:00
|
|
|
};
|
2023-09-29 08:26:27 +00:00
|
|
|
</script>
|
2023-09-11 14:09:17 +00:00
|
|
|
|
2023-09-09 17:01:10 +00:00
|
|
|
<template>
|
2023-10-22 08:12:00 +00:00
|
|
|
<div class="card mb-1" style="height: calc(var(--variable-height) - 20px)">
|
2023-09-30 19:57:23 +00:00
|
|
|
<div class="card-header p-1">
|
|
|
|
<div class="container">
|
|
|
|
<div class="row">
|
2023-10-28 13:14:04 +00:00
|
|
|
<div class="col-11 p-0">
|
2023-10-25 15:20:39 +00:00
|
|
|
<div class="btn-group h-100" role="group">
|
2023-09-30 19:57:23 +00:00
|
|
|
<div
|
2023-10-25 15:20:39 +00:00
|
|
|
class="list-group bg-body-tertiary list-group-horizontal"
|
2023-09-30 19:57:23 +00:00
|
|
|
id="list-tab"
|
|
|
|
role="tablist"
|
|
|
|
>
|
|
|
|
<a
|
2023-10-25 15:20:39 +00:00
|
|
|
class="py-0 list-group-item list-group-item-dark list-group-item-action"
|
2023-09-30 19:57:23 +00:00
|
|
|
id="list-waterfall-list"
|
|
|
|
data-bs-toggle="list"
|
|
|
|
href="#list-waterfall"
|
|
|
|
role="tab"
|
|
|
|
aria-controls="list-waterfall"
|
2023-11-27 03:00:29 +00:00
|
|
|
v-bind:class="{
|
|
|
|
active: settings.local.spectrum === 'waterfall',
|
|
|
|
}"
|
2023-09-30 19:57:23 +00:00
|
|
|
@click="selectStatsControl($event)"
|
|
|
|
><strong><i class="bi bi-water"></i></strong
|
|
|
|
></a>
|
|
|
|
<a
|
2023-10-25 15:20:39 +00:00
|
|
|
class="py-0 list-group-item list-group-item-dark list-group-item-action"
|
2023-09-30 19:57:23 +00:00
|
|
|
id="list-scatter-list"
|
|
|
|
data-bs-toggle="list"
|
|
|
|
href="#list-scatter"
|
|
|
|
role="tab"
|
|
|
|
aria-controls="list-scatter"
|
2023-11-27 03:00:29 +00:00
|
|
|
v-bind:class="{
|
|
|
|
active: settings.local.spectrum === 'scatter',
|
|
|
|
}"
|
2023-09-30 19:57:23 +00:00
|
|
|
@click="selectStatsControl($event)"
|
|
|
|
><strong><i class="bi bi-border-outer"></i></strong
|
|
|
|
></a>
|
|
|
|
<a
|
2023-10-25 15:20:39 +00:00
|
|
|
class="py-0 list-group-item list-group-item-dark list-group-item-action"
|
2023-09-30 19:57:23 +00:00
|
|
|
id="list-chart-list"
|
|
|
|
data-bs-toggle="list"
|
|
|
|
href="#list-chart"
|
|
|
|
role="tab"
|
|
|
|
aria-controls="list-chart"
|
2023-11-27 02:37:28 +00:00
|
|
|
v-bind:class="{ active: settings.local.spectrum === 'chart' }"
|
2023-09-30 19:57:23 +00:00
|
|
|
@click="selectStatsControl($event)"
|
|
|
|
><strong><i class="bi bi-graph-up-arrow"></i></strong
|
|
|
|
></a>
|
2023-09-09 17:01:10 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
2023-09-30 19:57:23 +00:00
|
|
|
<div class="btn-group" role="group" aria-label="Busy indicators">
|
|
|
|
<button
|
2023-10-19 14:54:24 +00:00
|
|
|
class="btn btn-sm ms-1 p-1 disabled"
|
2023-09-30 19:57:23 +00:00
|
|
|
type="button"
|
|
|
|
data-bs-placement="top"
|
|
|
|
data-bs-toggle="tooltip"
|
|
|
|
data-bs-trigger="hover"
|
|
|
|
data-bs-html="true"
|
2023-10-03 13:15:17 +00:00
|
|
|
v-bind:class="{
|
2023-11-28 22:29:01 +00:00
|
|
|
'btn-warning': state.channel_busy_slot[0] === true,
|
2023-11-28 22:29:27 +00:00
|
|
|
'btn-outline-secondary': state.channel_busy_slot[0] === false,
|
2023-10-03 13:15:17 +00:00
|
|
|
}"
|
2023-09-30 19:57:23 +00:00
|
|
|
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
|
|
|
|
>
|
2023-10-17 13:32:28 +00:00
|
|
|
S1
|
2023-09-30 19:57:23 +00:00
|
|
|
</button>
|
2023-10-16 15:26:28 +00:00
|
|
|
|
|
|
|
<button
|
2023-10-17 13:32:28 +00:00
|
|
|
class="btn btn-sm p-1 disabled"
|
2023-10-16 15:26:28 +00:00
|
|
|
type="button"
|
|
|
|
data-bs-placement="top"
|
|
|
|
data-bs-toggle="tooltip"
|
|
|
|
data-bs-trigger="hover"
|
|
|
|
data-bs-html="true"
|
|
|
|
v-bind:class="{
|
2023-11-28 22:29:01 +00:00
|
|
|
'btn-warning': state.channel_busy_slot[1] === true,
|
2023-11-28 22:29:27 +00:00
|
|
|
'btn-outline-secondary': state.channel_busy_slot[1] === false,
|
2023-10-16 15:26:28 +00:00
|
|
|
}"
|
|
|
|
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
|
|
|
|
>
|
2023-10-17 13:32:28 +00:00
|
|
|
S2
|
2023-10-16 15:26:28 +00:00
|
|
|
</button>
|
|
|
|
|
2023-10-17 13:32:28 +00:00
|
|
|
<button
|
|
|
|
class="btn btn-sm p-1 disabled"
|
|
|
|
type="button"
|
|
|
|
data-bs-placement="top"
|
|
|
|
data-bs-toggle="tooltip"
|
|
|
|
data-bs-trigger="hover"
|
|
|
|
data-bs-html="true"
|
|
|
|
v-bind:class="{
|
2023-11-28 22:29:01 +00:00
|
|
|
'btn-warning': state.channel_busy_slot[2] === true,
|
2023-11-28 22:29:27 +00:00
|
|
|
'btn-outline-secondary': state.channel_busy_slot[2] === false,
|
2023-10-17 13:32:28 +00:00
|
|
|
}"
|
|
|
|
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
|
|
|
|
>
|
|
|
|
S3
|
|
|
|
</button>
|
2023-10-16 15:26:28 +00:00
|
|
|
|
2023-10-17 13:32:28 +00:00
|
|
|
<button
|
|
|
|
class="btn btn-sm p-1 disabled"
|
|
|
|
type="button"
|
|
|
|
data-bs-placement="top"
|
|
|
|
data-bs-toggle="tooltip"
|
|
|
|
data-bs-trigger="hover"
|
|
|
|
data-bs-html="true"
|
|
|
|
v-bind:class="{
|
2023-11-28 22:29:01 +00:00
|
|
|
'btn-warning': state.channel_busy_slot[3] === true,
|
2023-11-28 22:29:27 +00:00
|
|
|
'btn-outline-secondary': state.channel_busy_slot[3] === false,
|
2023-10-17 13:32:28 +00:00
|
|
|
}"
|
|
|
|
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
|
|
|
|
>
|
|
|
|
S4
|
|
|
|
</button>
|
2023-10-16 15:26:28 +00:00
|
|
|
|
2023-10-17 13:32:28 +00:00
|
|
|
<button
|
|
|
|
class="btn btn-sm p-1 disabled"
|
|
|
|
type="button"
|
|
|
|
data-bs-placement="top"
|
|
|
|
data-bs-toggle="tooltip"
|
|
|
|
data-bs-trigger="hover"
|
|
|
|
data-bs-html="true"
|
|
|
|
v-bind:class="{
|
2023-11-28 22:29:01 +00:00
|
|
|
'btn-warning': state.channel_busy_slot[4] === true,
|
2023-11-28 22:29:27 +00:00
|
|
|
'btn-outline-secondary': state.channel_busy_slot[4] === false,
|
2023-10-17 13:32:28 +00:00
|
|
|
}"
|
|
|
|
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
|
|
|
|
>
|
|
|
|
S5
|
|
|
|
</button>
|
2023-10-16 15:26:28 +00:00
|
|
|
|
2023-09-30 19:57:23 +00:00
|
|
|
<button
|
2023-10-17 13:32:28 +00:00
|
|
|
class="btn btn-sm p-1 disabled"
|
2023-09-30 19:57:23 +00:00
|
|
|
type="button"
|
|
|
|
data-bs-placement="top"
|
|
|
|
data-bs-toggle="tooltip"
|
|
|
|
data-bs-trigger="hover"
|
|
|
|
data-bs-html="true"
|
|
|
|
title="Recieving data: illuminates <strong class='text-success'>green</strong> if receiving codec2 data"
|
2023-10-03 13:15:17 +00:00
|
|
|
v-bind:class="{
|
2023-11-19 04:17:43 +00:00
|
|
|
'btn-success': state.is_codec2_traffic === true,
|
|
|
|
'btn-outline-secondary': state.is_codec2_traffic === false,
|
2023-10-03 13:15:17 +00:00
|
|
|
}"
|
2023-09-30 19:57:23 +00:00
|
|
|
>
|
2023-10-20 01:40:54 +00:00
|
|
|
data
|
2023-09-30 19:57:23 +00:00
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="col-1 text-end">
|
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
id="openHelpModalWaterfall"
|
|
|
|
data-bs-toggle="modal"
|
|
|
|
data-bs-target="#waterfallHelpModal"
|
|
|
|
class="btn m-0 p-0 border-0"
|
|
|
|
>
|
|
|
|
<i class="bi bi-question-circle" style="font-size: 1rem"></i>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2023-10-09 08:20:52 +00:00
|
|
|
<div class="card-body p-1">
|
2023-09-30 19:57:23 +00:00
|
|
|
<div class="tab-content" id="nav-stats-tabContent">
|
|
|
|
<div
|
|
|
|
class="tab-pane fade"
|
2023-11-27 03:00:29 +00:00
|
|
|
v-bind:class="{
|
|
|
|
'show active': settings.local.spectrum === 'waterfall',
|
|
|
|
}"
|
2023-09-30 19:57:23 +00:00
|
|
|
id="list-waterfall"
|
|
|
|
role="stats_tabpanel"
|
|
|
|
aria-labelledby="list-waterfall-list"
|
|
|
|
>
|
|
|
|
<canvas
|
2023-12-04 03:43:48 +00:00
|
|
|
ref="waterfall-main"
|
|
|
|
id="waterfall-main"
|
2023-12-04 03:49:02 +00:00
|
|
|
style="
|
|
|
|
position: relative;
|
|
|
|
z-index: 2;
|
|
|
|
aspect-ratio: unset;
|
|
|
|
width: 100%;
|
|
|
|
height: 200px;
|
|
|
|
"
|
2023-12-04 03:43:48 +00:00
|
|
|
class="force-gpu"
|
2023-09-30 19:57:23 +00:00
|
|
|
></canvas>
|
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
class="tab-pane fade"
|
2023-11-27 03:00:29 +00:00
|
|
|
v-bind:class="{
|
|
|
|
'show active': settings.local.spectrum === 'scatter',
|
|
|
|
}"
|
2023-09-30 19:57:23 +00:00
|
|
|
id="list-scatter"
|
|
|
|
role="tabpanel"
|
|
|
|
aria-labelledby="list-scatter-list"
|
|
|
|
>
|
2023-10-02 12:45:47 +00:00
|
|
|
<Scatter :data="scatterChartData" :options="scatterChartOptions" />
|
2023-09-30 19:57:23 +00:00
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
class="tab-pane fade"
|
2023-11-27 02:37:28 +00:00
|
|
|
v-bind:class="{ 'show active': settings.local.spectrum === 'chart' }"
|
2023-09-30 19:57:23 +00:00
|
|
|
id="list-chart"
|
|
|
|
role="tabpanel"
|
|
|
|
aria-labelledby="list-chart-list"
|
|
|
|
>
|
|
|
|
<Line
|
|
|
|
:data="transmissionSpeedChartData"
|
|
|
|
:options="transmissionSpeedChartOptions"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!--278px-->
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|