code shrinking
This commit is contained in:
parent
a270474022
commit
5a286459f1
|
|
@ -39,133 +39,46 @@ type client struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func descClient(ns string) *client {
|
func descClient(ns string) *client {
|
||||||
|
if ns += "_client_"; ns == "_client_" {
|
||||||
|
ns = "client_"
|
||||||
|
}
|
||||||
|
|
||||||
labels := []string{"id", "mac", "user_id", "site_id", "site_name",
|
labels := []string{"id", "mac", "user_id", "site_id", "site_name",
|
||||||
"network_id", "ap_mac", "gw_mac", "sw_mac", "ap_name", "gw_name",
|
"network_id", "ap_mac", "gw_mac", "sw_mac", "ap_name", "gw_name",
|
||||||
"sw_name", "radio_name", "radio", "radio_proto", "name", "channel",
|
"sw_name", "radio_name", "radio", "radio_proto", "name", "channel",
|
||||||
"vlan", "ip", "essid", "bssid", "radio_desc"}
|
"vlan", "ip", "essid", "bssid", "radio_desc"}
|
||||||
ns2 := "client"
|
|
||||||
|
|
||||||
return &client{
|
return &client{
|
||||||
Anomalies: prometheus.NewDesc(
|
Anomalies: prometheus.NewDesc(ns+"Anomalies", "Client Anomalies", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "Anomalies"),
|
BytesR: prometheus.NewDesc(ns+"BytesR", "Client Data Rate", labels, nil),
|
||||||
"Client Anomalies", labels, nil,
|
CCQ: prometheus.NewDesc(ns+"CCQ", "Client Connection Quality", labels, nil),
|
||||||
),
|
Noise: prometheus.NewDesc(ns+"Noise", "Client AP Noise", labels, nil),
|
||||||
BytesR: prometheus.NewDesc(
|
RoamCount: prometheus.NewDesc(ns+"RoamCount", "Client Roam Counter", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "BytesR"),
|
RSSI: prometheus.NewDesc(ns+"RSSI", "Client RSSI", labels, nil),
|
||||||
"Client Data Rate", labels, nil,
|
RxBytes: prometheus.NewDesc(ns+"RxBytes", "Client Receive Bytes", labels, nil),
|
||||||
),
|
RxBytesR: prometheus.NewDesc(ns+"RxBytesR", "Client Receive Data Rate", labels, nil),
|
||||||
CCQ: prometheus.NewDesc(
|
RxPackets: prometheus.NewDesc(ns+"RxPackets", "Client Receive Packets", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "CCQ"),
|
RxRate: prometheus.NewDesc(ns+"RxRate", "Client Receive Rate", labels, nil),
|
||||||
"Client Connection Quality", labels, nil,
|
Signal: prometheus.NewDesc(ns+"Signal", "Client Signal Strength", labels, nil),
|
||||||
),
|
TxBytes: prometheus.NewDesc(ns+"TxBytes", "Client Transmit Bytes", labels, nil),
|
||||||
Noise: prometheus.NewDesc(
|
TxBytesR: prometheus.NewDesc(ns+"TxBytesR", "Client Transmit Data Rate", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "Noise"),
|
TxPackets: prometheus.NewDesc(ns+"TxPackets", "Client Transmit Packets", labels, nil),
|
||||||
"Client AP Noise", labels, nil,
|
TxPower: prometheus.NewDesc(ns+"TxPower", "Client Transmit Power", labels, nil),
|
||||||
),
|
TxRate: prometheus.NewDesc(ns+"TxRate", "Client Transmit Rate", labels, nil),
|
||||||
RoamCount: prometheus.NewDesc(
|
Uptime: prometheus.NewDesc(ns+"Uptime", "Client Uptime", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "RoamCount"),
|
WifiTxAttempts: prometheus.NewDesc(ns+"WifiTxAttempts", "Client Wifi Transmit Attempts", labels, nil),
|
||||||
"Client Roam Counter", labels, nil,
|
WiredRxBytes: prometheus.NewDesc(ns+"WiredRxBytes", "Client Wired Receive Bytes", labels, nil),
|
||||||
),
|
WiredRxBytesR: prometheus.NewDesc(ns+"WiredRxBytesR", "Client Wired Receive Data Rate", labels, nil),
|
||||||
RSSI: prometheus.NewDesc(
|
WiredRxPackets: prometheus.NewDesc(ns+"WiredRxPackets", "Client Wired Receive Packets", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "RSSI"),
|
WiredTxBytes: prometheus.NewDesc(ns+"WiredTxBytes", "Client Wired Transmit Bytes", labels, nil),
|
||||||
"Client RSSI", labels, nil,
|
WiredTxBytesR: prometheus.NewDesc(ns+"WiredTxBytesR", "Client Wired Data Rate", labels, nil),
|
||||||
),
|
WiredTxPackets: prometheus.NewDesc(ns+"WiredTxPackets", "Client Wired Transmit Packets", labels, nil),
|
||||||
RxBytes: prometheus.NewDesc(
|
DpiStatsApp: prometheus.NewDesc(ns+"DpiStatsApp", "Client DPI Stats App", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "RxBytes"),
|
DpiStatsCat: prometheus.NewDesc(ns+"DpiStatsCat", "Client DPI Stats Cat", labels, nil),
|
||||||
"Client Receive Bytes", labels, nil,
|
DpiStatsRxBytes: prometheus.NewDesc(ns+"DpiStatsRxBytes", "Client DPI Stats Receive Bytes", labels, nil),
|
||||||
),
|
DpiStatsRxPackets: prometheus.NewDesc(ns+"DpiStatsRxPackets", "Client DPI Stats Receive Packets", labels, nil),
|
||||||
RxBytesR: prometheus.NewDesc(
|
DpiStatsTxBytes: prometheus.NewDesc(ns+"DpiStatsTxBytes", "Client DPI Stats Transmit Bytes", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "RxBytesR"),
|
DpiStatsTxPackets: prometheus.NewDesc(ns+"DpiStatsTxPackets", "Client DPI Stats Transmit Packets", labels, nil),
|
||||||
"Client Receive Data Rate", labels, nil,
|
|
||||||
),
|
|
||||||
RxPackets: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "RxPackets"),
|
|
||||||
"Client Receive Packets", labels, nil,
|
|
||||||
),
|
|
||||||
RxRate: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "RxRate"),
|
|
||||||
"Client Receive Rate", labels, nil,
|
|
||||||
),
|
|
||||||
Signal: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "Signal"),
|
|
||||||
"Client Signal Strength", labels, nil,
|
|
||||||
),
|
|
||||||
TxBytes: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "TxBytes"),
|
|
||||||
"Client Transmit Bytes", labels, nil,
|
|
||||||
),
|
|
||||||
TxBytesR: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "TxBytesR"),
|
|
||||||
"Client Transmit Data Rate", labels, nil,
|
|
||||||
),
|
|
||||||
TxPackets: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "TxPackets"),
|
|
||||||
"Client Transmit Packets", labels, nil,
|
|
||||||
),
|
|
||||||
TxPower: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "TxPower"),
|
|
||||||
"Client Transmit Power", labels, nil,
|
|
||||||
),
|
|
||||||
TxRate: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "TxRate"),
|
|
||||||
"Client Transmit Rate", labels, nil,
|
|
||||||
),
|
|
||||||
Uptime: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "Uptime"),
|
|
||||||
"Client Uptime", labels, nil,
|
|
||||||
),
|
|
||||||
WifiTxAttempts: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "WifiTxAttempts"),
|
|
||||||
"Client Wifi Transmit Attempts", labels, nil,
|
|
||||||
),
|
|
||||||
WiredRxBytes: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "WiredRxBytes"),
|
|
||||||
"Client Wired Receive Bytes", labels, nil,
|
|
||||||
),
|
|
||||||
WiredRxBytesR: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "WiredRxBytesR"),
|
|
||||||
"Client Wired Receive Data Rate", labels, nil,
|
|
||||||
),
|
|
||||||
WiredRxPackets: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "WiredRxPackets"),
|
|
||||||
"Client Wired Receive Packets", labels, nil,
|
|
||||||
),
|
|
||||||
WiredTxBytes: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "WiredTxBytes"),
|
|
||||||
"Client Wired Transmit Bytes", labels, nil,
|
|
||||||
),
|
|
||||||
WiredTxBytesR: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "WiredTxBytesR"),
|
|
||||||
"Client Wired Data Rate", labels, nil,
|
|
||||||
),
|
|
||||||
WiredTxPackets: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "WiredTxPackets"),
|
|
||||||
"Client Wired Transmit Packets", labels, nil,
|
|
||||||
),
|
|
||||||
DpiStatsApp: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "DpiStatsApp"),
|
|
||||||
"Client DPI Stats App", labels, nil,
|
|
||||||
),
|
|
||||||
DpiStatsCat: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "DpiStatsCat"),
|
|
||||||
"Client DPI Stats Cat", labels, nil,
|
|
||||||
),
|
|
||||||
DpiStatsRxBytes: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "DpiStatsRxBytes"),
|
|
||||||
"Client DPI Stats Receive Bytes", labels, nil,
|
|
||||||
),
|
|
||||||
DpiStatsRxPackets: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "DpiStatsRxPackets"),
|
|
||||||
"Client DPI Stats Receive Packets", labels, nil,
|
|
||||||
),
|
|
||||||
DpiStatsTxBytes: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "DpiStatsTxBytes"),
|
|
||||||
"Client DPI Stats Transmit Bytes", labels, nil,
|
|
||||||
),
|
|
||||||
DpiStatsTxPackets: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "DpiStatsTxPackets"),
|
|
||||||
"Client DPI Stats Transmit Packets", labels, nil,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
"github.com/davidnewhall/unifi-poller/metrics"
|
"github.com/davidnewhall/unifi-poller/metrics"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"golift.io/unifi"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UnifiCollectorCnfg defines the data needed to collect and report UniFi Metrics.
|
// UnifiCollectorCnfg defines the data needed to collect and report UniFi Metrics.
|
||||||
|
|
@ -127,12 +128,12 @@ func (u *unifiCollector) Collect(ch chan<- prometheus.Metric) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
func (u *unifiCollector) export(ch chan<- prometheus.Metric, exports []*metricExports, ts time.Time) {
|
func (u *unifiCollector) export(ch chan<- prometheus.Metric, exports []*metricExports, ts time.Time) {
|
||||||
for _, e := range exports {
|
for _, e := range exports {
|
||||||
v, ok := e.Value.(float64)
|
v, ok := e.Value.(float64)
|
||||||
if !ok {
|
if !ok {
|
||||||
j, ok := e.Value.(int64)
|
j, ok := e.Value.(int64)
|
||||||
v = float64(j)
|
|
||||||
if !ok {
|
if !ok {
|
||||||
// log.Printf("not a number: %v %v", e.Value, e.Desc.String())
|
// log.Printf("not a number: %v %v", e.Value, e.Desc.String())
|
||||||
if u.Config.ReportErrors {
|
if u.Config.ReportErrors {
|
||||||
|
|
@ -140,7 +141,29 @@ func (u *unifiCollector) export(ch chan<- prometheus.Metric, exports []*metricEx
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
v = float64(j)
|
||||||
}
|
}
|
||||||
ch <- prometheus.NewMetricWithTimestamp(ts, prometheus.MustNewConstMetric(e.Desc, e.ValueType, v, e.Labels...))
|
ch <- prometheus.NewMetricWithTimestamp(ts, prometheus.MustNewConstMetric(e.Desc, e.ValueType, v, e.Labels...))
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
func (u *unifiCollector) export(ch chan<- prometheus.Metric, exports []*metricExports, ts time.Time) {
|
||||||
|
for _, e := range exports {
|
||||||
|
var val float64
|
||||||
|
switch v := e.Value.(type) {
|
||||||
|
case float64:
|
||||||
|
val = v
|
||||||
|
case int64:
|
||||||
|
val = float64(v)
|
||||||
|
case unifi.FlexInt:
|
||||||
|
val = v.Val
|
||||||
|
default:
|
||||||
|
if u.Config.ReportErrors {
|
||||||
|
ch <- prometheus.NewInvalidMetric(e.Desc, fmt.Errorf("not a number: %v", e.Value))
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ch <- prometheus.NewMetricWithTimestamp(ts, prometheus.MustNewConstMetric(e.Desc, e.ValueType, val, e.Labels...))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,106 +34,37 @@ type site struct {
|
||||||
|
|
||||||
// XXX: The help values can be more verbose.
|
// XXX: The help values can be more verbose.
|
||||||
func descSite(ns string) *site {
|
func descSite(ns string) *site {
|
||||||
|
if ns += "_site_"; ns == "_site_" {
|
||||||
|
ns = "site_"
|
||||||
|
}
|
||||||
|
|
||||||
labels := []string{"name", "desc", "site_name", "subsystem", "status", "gwversion"}
|
labels := []string{"name", "desc", "site_name", "subsystem", "status", "gwversion"}
|
||||||
ns2 := "site"
|
|
||||||
|
|
||||||
return &site{
|
return &site{
|
||||||
NumUser: prometheus.NewDesc(
|
NumUser: prometheus.NewDesc(ns+"NumUser", "NumUser", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "NumUser"),
|
NumGuest: prometheus.NewDesc(ns+"NumGuest", "NumGuest", labels, nil),
|
||||||
"NumUser", labels, nil,
|
NumIot: prometheus.NewDesc(ns+"NumIot", "NumIot", labels, nil),
|
||||||
),
|
TxBytesR: prometheus.NewDesc(ns+"TxBytesR", "TxBytesR", labels, nil),
|
||||||
NumGuest: prometheus.NewDesc(
|
RxBytesR: prometheus.NewDesc(ns+"RxBytesR", "RxBytesR", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "NumGuest"),
|
NumAp: prometheus.NewDesc(ns+"NumAp", "NumAp", labels, nil),
|
||||||
"NumGuest", labels, nil,
|
NumAdopted: prometheus.NewDesc(ns+"NumAdopted", "NumAdopted", labels, nil),
|
||||||
),
|
NumDisabled: prometheus.NewDesc(ns+"NumDisabled", "NumDisabled", labels, nil),
|
||||||
NumIot: prometheus.NewDesc(
|
NumDisconnected: prometheus.NewDesc(ns+"NumDisconnected", "NumDisconnected", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "NumIot"),
|
NumPending: prometheus.NewDesc(ns+"NumPending", "NumPending", labels, nil),
|
||||||
"NumIot", labels, nil,
|
NumGw: prometheus.NewDesc(ns+"NumGw", "NumGw", labels, nil),
|
||||||
),
|
NumSw: prometheus.NewDesc(ns+"NumSw", "NumSw", labels, nil),
|
||||||
TxBytesR: prometheus.NewDesc(
|
NumSta: prometheus.NewDesc(ns+"NumSta", "NumSta", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "TxBytesR"),
|
Latency: prometheus.NewDesc(ns+"Latency", "Latency", labels, nil),
|
||||||
"TxBytesR", labels, nil,
|
Drops: prometheus.NewDesc(ns+"Drops", "Drops", labels, nil),
|
||||||
),
|
XputUp: prometheus.NewDesc(ns+"XputUp", "XputUp", labels, nil),
|
||||||
RxBytesR: prometheus.NewDesc(
|
XputDown: prometheus.NewDesc(ns+"XputDown", "XputDown", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "RxBytesR"),
|
SpeedtestPing: prometheus.NewDesc(ns+"SpeedtestPing", "SpeedtestPing", labels, nil),
|
||||||
"RxBytesR", labels, nil,
|
RemoteUserNumActive: prometheus.NewDesc(ns+"RemoteUserNumActive", "RemoteUserNumActive", labels, nil),
|
||||||
),
|
RemoteUserNumInactive: prometheus.NewDesc(ns+"RemoteUserNumInactive", "RemoteUserNumInactive", labels, nil),
|
||||||
NumAp: prometheus.NewDesc(
|
RemoteUserRxBytes: prometheus.NewDesc(ns+"RemoteUserRxBytes", "RemoteUserRxBytes", labels, nil),
|
||||||
prometheus.BuildFQName(ns, ns2, "NumAp"),
|
RemoteUserTxBytes: prometheus.NewDesc(ns+"RemoteUserTxBytes", "RemoteUserTxBytes", labels, nil),
|
||||||
"NumAp", labels, nil,
|
RemoteUserRxPackets: prometheus.NewDesc(ns+"RemoteUserRxPackets", "RemoteUserRxPackets", labels, nil),
|
||||||
),
|
RemoteUserTxPackets: prometheus.NewDesc(ns+"RemoteUserTxPackets", "RemoteUserTxPackets", labels, nil),
|
||||||
NumAdopted: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "NumAdopted"),
|
|
||||||
"NumAdopted", labels, nil,
|
|
||||||
),
|
|
||||||
NumDisabled: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "NumDisabled"),
|
|
||||||
"NumDisabled", labels, nil,
|
|
||||||
),
|
|
||||||
NumDisconnected: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "NumDisconnected"),
|
|
||||||
"NumDisconnected", labels, nil,
|
|
||||||
),
|
|
||||||
NumPending: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "NumPending"),
|
|
||||||
"NumPending", labels, nil,
|
|
||||||
),
|
|
||||||
NumGw: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "NumGw"),
|
|
||||||
"NumGw", labels, nil,
|
|
||||||
),
|
|
||||||
NumSw: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "NumSw"),
|
|
||||||
"NumSw", labels, nil,
|
|
||||||
),
|
|
||||||
NumSta: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "NumSta"),
|
|
||||||
"NumSta", labels, nil,
|
|
||||||
),
|
|
||||||
Latency: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "Latency"),
|
|
||||||
"Latency", labels, nil,
|
|
||||||
),
|
|
||||||
Drops: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "Drops"),
|
|
||||||
"Drops", labels, nil,
|
|
||||||
),
|
|
||||||
XputUp: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "XputUp"),
|
|
||||||
"XputUp", labels, nil,
|
|
||||||
),
|
|
||||||
XputDown: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "XputDown"),
|
|
||||||
"XputDown", labels, nil,
|
|
||||||
),
|
|
||||||
SpeedtestPing: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "SpeedtestPing"),
|
|
||||||
"SpeedtestPing", labels, nil,
|
|
||||||
),
|
|
||||||
RemoteUserNumActive: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "RemoteUserNumActive"),
|
|
||||||
"RemoteUserNumActive", labels, nil,
|
|
||||||
),
|
|
||||||
RemoteUserNumInactive: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "RemoteUserNumInactive"),
|
|
||||||
"RemoteUserNumInactive", labels, nil,
|
|
||||||
),
|
|
||||||
RemoteUserRxBytes: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "RemoteUserRxBytes"),
|
|
||||||
"RemoteUserRxBytes", labels, nil,
|
|
||||||
),
|
|
||||||
RemoteUserTxBytes: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "RemoteUserTxBytes"),
|
|
||||||
"RemoteUserTxBytes", labels, nil,
|
|
||||||
),
|
|
||||||
RemoteUserRxPackets: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "RemoteUserRxPackets"),
|
|
||||||
"RemoteUserRxPackets", labels, nil,
|
|
||||||
),
|
|
||||||
RemoteUserTxPackets: prometheus.NewDesc(
|
|
||||||
prometheus.BuildFQName(ns, ns2, "RemoteUserTxPackets"),
|
|
||||||
"RemoteUserTxPackets", labels, nil,
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue