mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Remaining proto updates
This commit is contained in:
parent
e12efcac51
commit
67335178a9
8 changed files with 962 additions and 924 deletions
|
|
@ -984,7 +984,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph
|
|||
public func sendFactoryReset(destNum: Int64) -> Bool {
|
||||
|
||||
var adminPacket = AdminMessage()
|
||||
adminPacket.factoryReset = true
|
||||
adminPacket.factoryReset = 1
|
||||
|
||||
var meshPacket: MeshPacket = MeshPacket()
|
||||
meshPacket.to = UInt32(connectedPeripheral.num)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -60,14 +60,14 @@ struct LocalConfig {
|
|||
|
||||
///
|
||||
/// The part of the config that is specific to the Wifi Settings
|
||||
var wifi: Config.WiFiConfig {
|
||||
get {return _storage._wifi ?? Config.WiFiConfig()}
|
||||
set {_uniqueStorage()._wifi = newValue}
|
||||
var network: Config.NetworkConfig {
|
||||
get {return _storage._network ?? Config.NetworkConfig()}
|
||||
set {_uniqueStorage()._network = newValue}
|
||||
}
|
||||
/// Returns true if `wifi` has been explicitly set.
|
||||
var hasWifi: Bool {return _storage._wifi != nil}
|
||||
/// Clears the value of `wifi`. Subsequent reads from it will return its default value.
|
||||
mutating func clearWifi() {_uniqueStorage()._wifi = nil}
|
||||
/// Returns true if `network` has been explicitly set.
|
||||
var hasNetwork: Bool {return _storage._network != nil}
|
||||
/// Clears the value of `network`. Subsequent reads from it will return its default value.
|
||||
mutating func clearNetwork() {_uniqueStorage()._network = nil}
|
||||
|
||||
///
|
||||
/// The part of the config that is specific to the Display
|
||||
|
|
@ -229,7 +229,7 @@ extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
1: .same(proto: "device"),
|
||||
2: .same(proto: "position"),
|
||||
3: .same(proto: "power"),
|
||||
4: .same(proto: "wifi"),
|
||||
4: .same(proto: "network"),
|
||||
5: .same(proto: "display"),
|
||||
6: .same(proto: "lora"),
|
||||
7: .same(proto: "bluetooth"),
|
||||
|
|
@ -240,7 +240,7 @@ extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
var _device: Config.DeviceConfig? = nil
|
||||
var _position: Config.PositionConfig? = nil
|
||||
var _power: Config.PowerConfig? = nil
|
||||
var _wifi: Config.NetworkConfig? = nil
|
||||
var _network: Config.NetworkConfig? = nil
|
||||
var _display: Config.DisplayConfig? = nil
|
||||
var _lora: Config.LoRaConfig? = nil
|
||||
var _bluetooth: Config.BluetoothConfig? = nil
|
||||
|
|
@ -254,7 +254,7 @@ extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
_device = source._device
|
||||
_position = source._position
|
||||
_power = source._power
|
||||
_wifi = source._wifi
|
||||
_network = source._network
|
||||
_display = source._display
|
||||
_lora = source._lora
|
||||
_bluetooth = source._bluetooth
|
||||
|
|
@ -280,7 +280,7 @@ extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
case 1: try { try decoder.decodeSingularMessageField(value: &_storage._device) }()
|
||||
case 2: try { try decoder.decodeSingularMessageField(value: &_storage._position) }()
|
||||
case 3: try { try decoder.decodeSingularMessageField(value: &_storage._power) }()
|
||||
case 4: try { try decoder.decodeSingularMessageField(value: &_storage._wifi) }()
|
||||
case 4: try { try decoder.decodeSingularMessageField(value: &_storage._network) }()
|
||||
case 5: try { try decoder.decodeSingularMessageField(value: &_storage._display) }()
|
||||
case 6: try { try decoder.decodeSingularMessageField(value: &_storage._lora) }()
|
||||
case 7: try { try decoder.decodeSingularMessageField(value: &_storage._bluetooth) }()
|
||||
|
|
@ -306,7 +306,7 @@ extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
try { if let v = _storage._power {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
|
||||
} }()
|
||||
try { if let v = _storage._wifi {
|
||||
try { if let v = _storage._network {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
|
||||
} }()
|
||||
try { if let v = _storage._display {
|
||||
|
|
@ -333,7 +333,7 @@ extension LocalConfig: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementati
|
|||
if _storage._device != rhs_storage._device {return false}
|
||||
if _storage._position != rhs_storage._position {return false}
|
||||
if _storage._power != rhs_storage._power {return false}
|
||||
if _storage._wifi != rhs_storage._wifi {return false}
|
||||
if _storage._network != rhs_storage._network {return false}
|
||||
if _storage._display != rhs_storage._display {return false}
|
||||
if _storage._lora != rhs_storage._lora {return false}
|
||||
if _storage._bluetooth != rhs_storage._bluetooth {return false}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -248,7 +248,7 @@ struct ModuleConfig {
|
|||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
var mode: ModuleConfig.SerialConfig.Serial_Mode = .modeDefault
|
||||
var mode: ModuleConfig.SerialConfig.Serial_Mode = .default
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
|
|
@ -328,29 +328,29 @@ struct ModuleConfig {
|
|||
/// TODO: REPLACE
|
||||
enum Serial_Mode: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
case modeDefault // = 0
|
||||
case modeSimple // = 1
|
||||
case modeProto // = 2
|
||||
case `default` // = 0
|
||||
case simple // = 1
|
||||
case proto // = 2
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
init() {
|
||||
self = .modeDefault
|
||||
self = .default
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .modeDefault
|
||||
case 1: self = .modeSimple
|
||||
case 2: self = .modeProto
|
||||
case 0: self = .default
|
||||
case 1: self = .simple
|
||||
case 2: self = .proto
|
||||
default: self = .UNRECOGNIZED(rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
switch self {
|
||||
case .modeDefault: return 0
|
||||
case .modeSimple: return 1
|
||||
case .modeProto: return 2
|
||||
case .default: return 0
|
||||
case .simple: return 1
|
||||
case .proto: return 2
|
||||
case .UNRECOGNIZED(let i): return i
|
||||
}
|
||||
}
|
||||
|
|
@ -512,15 +512,15 @@ struct ModuleConfig {
|
|||
|
||||
///
|
||||
/// Generate input event on CW of this kind.
|
||||
var inputbrokerEventCw: ModuleConfig.CannedMessageConfig.InputEventChar = .keyNone
|
||||
var inputbrokerEventCw: ModuleConfig.CannedMessageConfig.InputEventChar = .none
|
||||
|
||||
///
|
||||
/// Generate input event on CCW of this kind.
|
||||
var inputbrokerEventCcw: ModuleConfig.CannedMessageConfig.InputEventChar = .keyNone
|
||||
var inputbrokerEventCcw: ModuleConfig.CannedMessageConfig.InputEventChar = .none
|
||||
|
||||
///
|
||||
/// Generate input event on Press of this kind.
|
||||
var inputbrokerEventPress: ModuleConfig.CannedMessageConfig.InputEventChar = .keyNone
|
||||
var inputbrokerEventPress: ModuleConfig.CannedMessageConfig.InputEventChar = .none
|
||||
|
||||
///
|
||||
/// Enable the Up/Down/Select input device. Can be RAK rotary encoder or 3 buttons. Uses the a/b/press definitions from inputbroker.
|
||||
|
|
@ -549,65 +549,65 @@ struct ModuleConfig {
|
|||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
case keyNone // = 0
|
||||
case none // = 0
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
case keyUp // = 17
|
||||
case up // = 17
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
case keyDown // = 18
|
||||
case down // = 18
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
case keyLeft // = 19
|
||||
case left // = 19
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
case keyRight // = 20
|
||||
case right // = 20
|
||||
|
||||
///
|
||||
/// '\n'
|
||||
case keySelect // = 10
|
||||
case select // = 10
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
case keyBack // = 27
|
||||
case back // = 27
|
||||
|
||||
///
|
||||
/// TODO: REPLACE
|
||||
case keyCancel // = 24
|
||||
case cancel // = 24
|
||||
case UNRECOGNIZED(Int)
|
||||
|
||||
init() {
|
||||
self = .keyNone
|
||||
self = .none
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .keyNone
|
||||
case 10: self = .keySelect
|
||||
case 17: self = .keyUp
|
||||
case 18: self = .keyDown
|
||||
case 19: self = .keyLeft
|
||||
case 20: self = .keyRight
|
||||
case 24: self = .keyCancel
|
||||
case 27: self = .keyBack
|
||||
case 0: self = .none
|
||||
case 10: self = .select
|
||||
case 17: self = .up
|
||||
case 18: self = .down
|
||||
case 19: self = .left
|
||||
case 20: self = .right
|
||||
case 24: self = .cancel
|
||||
case 27: self = .back
|
||||
default: self = .UNRECOGNIZED(rawValue)
|
||||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
switch self {
|
||||
case .keyNone: return 0
|
||||
case .keySelect: return 10
|
||||
case .keyUp: return 17
|
||||
case .keyDown: return 18
|
||||
case .keyLeft: return 19
|
||||
case .keyRight: return 20
|
||||
case .keyCancel: return 24
|
||||
case .keyBack: return 27
|
||||
case .none: return 0
|
||||
case .select: return 10
|
||||
case .up: return 17
|
||||
case .down: return 18
|
||||
case .left: return 19
|
||||
case .right: return 20
|
||||
case .cancel: return 24
|
||||
case .back: return 27
|
||||
case .UNRECOGNIZED(let i): return i
|
||||
}
|
||||
}
|
||||
|
|
@ -647,23 +647,23 @@ extension ModuleConfig.SerialConfig.Serial_Baud: CaseIterable {
|
|||
extension ModuleConfig.SerialConfig.Serial_Mode: CaseIterable {
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static var allCases: [ModuleConfig.SerialConfig.Serial_Mode] = [
|
||||
.modeDefault,
|
||||
.modeSimple,
|
||||
.modeProto,
|
||||
.default,
|
||||
.simple,
|
||||
.proto,
|
||||
]
|
||||
}
|
||||
|
||||
extension ModuleConfig.CannedMessageConfig.InputEventChar: CaseIterable {
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static var allCases: [ModuleConfig.CannedMessageConfig.InputEventChar] = [
|
||||
.keyNone,
|
||||
.keyUp,
|
||||
.keyDown,
|
||||
.keyLeft,
|
||||
.keyRight,
|
||||
.keySelect,
|
||||
.keyBack,
|
||||
.keyCancel,
|
||||
.none,
|
||||
.up,
|
||||
.down,
|
||||
.left,
|
||||
.right,
|
||||
.select,
|
||||
.back,
|
||||
.cancel,
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -957,7 +957,7 @@ extension ModuleConfig.SerialConfig: SwiftProtobuf.Message, SwiftProtobuf._Messa
|
|||
if self.timeout != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.timeout, fieldNumber: 6)
|
||||
}
|
||||
if self.mode != .modeDefault {
|
||||
if self.mode != .default {
|
||||
try visitor.visitSingularEnumField(value: self.mode, fieldNumber: 7)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
|
|
@ -978,7 +978,7 @@ extension ModuleConfig.SerialConfig: SwiftProtobuf.Message, SwiftProtobuf._Messa
|
|||
|
||||
extension ModuleConfig.SerialConfig.Serial_Baud: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "BAUD_Default"),
|
||||
0: .same(proto: "BAUD_DEFAULT"),
|
||||
1: .same(proto: "BAUD_110"),
|
||||
2: .same(proto: "BAUD_300"),
|
||||
3: .same(proto: "BAUD_600"),
|
||||
|
|
@ -999,9 +999,9 @@ extension ModuleConfig.SerialConfig.Serial_Baud: SwiftProtobuf._ProtoNameProvidi
|
|||
|
||||
extension ModuleConfig.SerialConfig.Serial_Mode: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "MODE_Default"),
|
||||
1: .same(proto: "MODE_SIMPLE"),
|
||||
2: .same(proto: "MODE_PROTO"),
|
||||
0: .same(proto: "DEFAULT"),
|
||||
1: .same(proto: "SIMPLE"),
|
||||
2: .same(proto: "PROTO"),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -1174,7 +1174,7 @@ extension ModuleConfig.TelemetryConfig: SwiftProtobuf.Message, SwiftProtobuf._Me
|
|||
2: .standard(proto: "environment_update_interval"),
|
||||
3: .standard(proto: "environment_measurement_enabled"),
|
||||
4: .standard(proto: "environment_screen_enabled"),
|
||||
7: .standard(proto: "environment_display_fahrenheit"),
|
||||
5: .standard(proto: "environment_display_fahrenheit"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
|
|
@ -1187,7 +1187,7 @@ extension ModuleConfig.TelemetryConfig: SwiftProtobuf.Message, SwiftProtobuf._Me
|
|||
case 2: try { try decoder.decodeSingularUInt32Field(value: &self.environmentUpdateInterval) }()
|
||||
case 3: try { try decoder.decodeSingularBoolField(value: &self.environmentMeasurementEnabled) }()
|
||||
case 4: try { try decoder.decodeSingularBoolField(value: &self.environmentScreenEnabled) }()
|
||||
case 7: try { try decoder.decodeSingularBoolField(value: &self.environmentDisplayFahrenheit) }()
|
||||
case 5: try { try decoder.decodeSingularBoolField(value: &self.environmentDisplayFahrenheit) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
|
@ -1207,7 +1207,7 @@ extension ModuleConfig.TelemetryConfig: SwiftProtobuf.Message, SwiftProtobuf._Me
|
|||
try visitor.visitSingularBoolField(value: self.environmentScreenEnabled, fieldNumber: 4)
|
||||
}
|
||||
if self.environmentDisplayFahrenheit != false {
|
||||
try visitor.visitSingularBoolField(value: self.environmentDisplayFahrenheit, fieldNumber: 7)
|
||||
try visitor.visitSingularBoolField(value: self.environmentDisplayFahrenheit, fieldNumber: 5)
|
||||
}
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
|
@ -1274,13 +1274,13 @@ extension ModuleConfig.CannedMessageConfig: SwiftProtobuf.Message, SwiftProtobuf
|
|||
if self.inputbrokerPinPress != 0 {
|
||||
try visitor.visitSingularUInt32Field(value: self.inputbrokerPinPress, fieldNumber: 4)
|
||||
}
|
||||
if self.inputbrokerEventCw != .keyNone {
|
||||
if self.inputbrokerEventCw != .none {
|
||||
try visitor.visitSingularEnumField(value: self.inputbrokerEventCw, fieldNumber: 5)
|
||||
}
|
||||
if self.inputbrokerEventCcw != .keyNone {
|
||||
if self.inputbrokerEventCcw != .none {
|
||||
try visitor.visitSingularEnumField(value: self.inputbrokerEventCcw, fieldNumber: 6)
|
||||
}
|
||||
if self.inputbrokerEventPress != .keyNone {
|
||||
if self.inputbrokerEventPress != .none {
|
||||
try visitor.visitSingularEnumField(value: self.inputbrokerEventPress, fieldNumber: 7)
|
||||
}
|
||||
if self.updown1Enabled != false {
|
||||
|
|
@ -1317,13 +1317,13 @@ extension ModuleConfig.CannedMessageConfig: SwiftProtobuf.Message, SwiftProtobuf
|
|||
|
||||
extension ModuleConfig.CannedMessageConfig.InputEventChar: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "KEY_NONE"),
|
||||
10: .same(proto: "KEY_SELECT"),
|
||||
17: .same(proto: "KEY_UP"),
|
||||
18: .same(proto: "KEY_DOWN"),
|
||||
19: .same(proto: "KEY_LEFT"),
|
||||
20: .same(proto: "KEY_RIGHT"),
|
||||
24: .same(proto: "KEY_CANCEL"),
|
||||
27: .same(proto: "KEY_BACK"),
|
||||
0: .same(proto: "NONE"),
|
||||
10: .same(proto: "SELECT"),
|
||||
17: .same(proto: "UP"),
|
||||
18: .same(proto: "DOWN"),
|
||||
19: .same(proto: "LEFT"),
|
||||
20: .same(proto: "RIGHT"),
|
||||
24: .same(proto: "CANCEL"),
|
||||
27: .same(proto: "BACK"),
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ enum TelemetrySensorType: SwiftProtobuf.Enum {
|
|||
|
||||
///
|
||||
/// No external telemetry sensor explicitly set
|
||||
case unset // = 0
|
||||
case sensorUnset // = 0
|
||||
|
||||
///
|
||||
/// High accuracy temperature, pressure, humidity
|
||||
|
|
@ -55,12 +55,12 @@ enum TelemetrySensorType: SwiftProtobuf.Enum {
|
|||
case UNRECOGNIZED(Int)
|
||||
|
||||
init() {
|
||||
self = .unset
|
||||
self = .sensorUnset
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .unset
|
||||
case 0: self = .sensorUnset
|
||||
case 1: self = .bme280
|
||||
case 2: self = .bme680
|
||||
case 3: self = .mcp9808
|
||||
|
|
@ -73,7 +73,7 @@ enum TelemetrySensorType: SwiftProtobuf.Enum {
|
|||
|
||||
var rawValue: Int {
|
||||
switch self {
|
||||
case .unset: return 0
|
||||
case .sensorUnset: return 0
|
||||
case .bme280: return 1
|
||||
case .bme680: return 2
|
||||
case .mcp9808: return 3
|
||||
|
|
@ -91,7 +91,7 @@ enum TelemetrySensorType: SwiftProtobuf.Enum {
|
|||
extension TelemetrySensorType: CaseIterable {
|
||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
||||
static var allCases: [TelemetrySensorType] = [
|
||||
.unset,
|
||||
.sensorUnset,
|
||||
.bme280,
|
||||
.bme680,
|
||||
.mcp9808,
|
||||
|
|
@ -249,7 +249,7 @@ extension Telemetry.OneOf_Variant: @unchecked Sendable {}
|
|||
|
||||
extension TelemetrySensorType: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "UNSET"),
|
||||
0: .same(proto: "SENSOR_UNSET"),
|
||||
1: .same(proto: "BME280"),
|
||||
2: .same(proto: "BME680"),
|
||||
3: .same(proto: "MCP9808"),
|
||||
|
|
|
|||
|
|
@ -76,21 +76,21 @@ enum InputEventChars: Int, CaseIterable, Identifiable {
|
|||
switch self {
|
||||
|
||||
case .keyNone:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyNone
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.none
|
||||
case .keyUp:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyUp
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.up
|
||||
case .keyDown:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyDown
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.down
|
||||
case .keyLeft:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyLeft
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.left
|
||||
case .keyRight:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyRight
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.right
|
||||
case .keySelect:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keySelect
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.select
|
||||
case .keyBack:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyBack
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.back
|
||||
case .keyCancel:
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.keyCancel
|
||||
return ModuleConfig.CannedMessageConfig.InputEventChar.cancel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,11 +130,11 @@ enum SerialModeTypes: Int, CaseIterable, Identifiable {
|
|||
switch self {
|
||||
|
||||
case .modeDefault:
|
||||
return ModuleConfig.SerialConfig.Serial_Mode.modeDefault
|
||||
return ModuleConfig.SerialConfig.Serial_Mode.default
|
||||
case .modeSimple:
|
||||
return ModuleConfig.SerialConfig.Serial_Mode.modeSimple
|
||||
return ModuleConfig.SerialConfig.Serial_Mode.simple
|
||||
case .modeProto:
|
||||
return ModuleConfig.SerialConfig.Serial_Mode.modeProto
|
||||
return ModuleConfig.SerialConfig.Serial_Mode.proto
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue