From cd6532f5dff3d38bed269356b8a1ec001e8deccc Mon Sep 17 00:00:00 2001
From: Imre Halasz <imre.halasz@thethingsindustries.com>
Date: Wed, 18 Dec 2024 14:39:08 +0100
Subject: [PATCH 1/4] api: Add `LastBatteryPercentage` to the
 `ApplicationUplink`

---
 api/ttn/lorawan/v3/api.md                  |   16 +
 api/ttn/lorawan/v3/api.swagger.json        |   24 +
 api/ttn/lorawan/v3/messages.proto          |   20 +-
 pkg/ttnpb/applicationserver.pb.paths.fm.go |    8 +
 pkg/ttnpb/messages.pb.go                   | 1196 +++++++++++---------
 pkg/ttnpb/messages.pb.paths.fm.go          |   20 +
 pkg/ttnpb/messages.pb.setters.fm.go        |   64 ++
 pkg/ttnpb/messages.pb.validate.go          |  120 ++
 pkg/ttnpb/messages_flags.pb.go             |   10 +
 pkg/ttnpb/messages_json.pb.go              |   16 +
 sdk/js/generated/api-definition.json       |    4 +
 sdk/js/generated/api.json                  |   72 ++
 12 files changed, 1027 insertions(+), 543 deletions(-)

diff --git a/api/ttn/lorawan/v3/api.md b/api/ttn/lorawan/v3/api.md
index 196bc6e43a..e20c978f2d 100644
--- a/api/ttn/lorawan/v3/api.md
+++ b/api/ttn/lorawan/v3/api.md
@@ -615,6 +615,7 @@
   - [Message `DownlinkQueueRequest`](#ttn.lorawan.v3.DownlinkQueueRequest)
   - [Message `GatewayTxAcknowledgment`](#ttn.lorawan.v3.GatewayTxAcknowledgment)
   - [Message `GatewayUplinkMessage`](#ttn.lorawan.v3.GatewayUplinkMessage)
+  - [Message `LastBatteryPercentage`](#ttn.lorawan.v3.LastBatteryPercentage)
   - [Message `MessagePayloadFormatters`](#ttn.lorawan.v3.MessagePayloadFormatters)
   - [Message `TxAcknowledgment`](#ttn.lorawan.v3.TxAcknowledgment)
   - [Message `UplinkMessage`](#ttn.lorawan.v3.UplinkMessage)
@@ -8795,6 +8796,7 @@ Application uplink message.
 | `locations` | [`ApplicationUplink.LocationsEntry`](#ttn.lorawan.v3.ApplicationUplink.LocationsEntry) | repeated | End device location metadata, set by the Application Server while handling the message. |
 | `version_ids` | [`EndDeviceVersionIdentifiers`](#ttn.lorawan.v3.EndDeviceVersionIdentifiers) |  | End device version identifiers, set by the Application Server while handling the message. |
 | `network_ids` | [`NetworkIdentifiers`](#ttn.lorawan.v3.NetworkIdentifiers) |  | Network identifiers, set by the Network Server that handles the message. |
+| `last_battery_percentage` | [`LastBatteryPercentage`](#ttn.lorawan.v3.LastBatteryPercentage) |  | Last battery percentage of the end device. Received via the DevStatus MAC command at last_dev_status_received_at or earlier. Set by the Network Server while handling the message. |
 
 #### Field Rules
 
@@ -8940,6 +8942,20 @@ ncrc: [scheduled.advanced]
 | ----- | ----------- |
 | `message` | <p>`message.required`: `true`</p> |
 
+### <a name="ttn.lorawan.v3.LastBatteryPercentage">Message `LastBatteryPercentage`</a>
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| `f_cnt` | [`uint32`](#uint32) |  | Frame counter value of last uplink containing DevStatusAns. |
+| `value` | [`google.protobuf.FloatValue`](#google.protobuf.FloatValue) |  | The battery percentage of the end device. The value is defined in the [0, 100] interval. |
+| `received_at` | [`google.protobuf.Timestamp`](#google.protobuf.Timestamp) |  | Time when last DevStatus MAC command was received. |
+
+#### Field Rules
+
+| Field | Validations |
+| ----- | ----------- |
+| `value` | <p>`float.lte`: `1`</p><p>`float.gte`: `0`</p> |
+
 ### <a name="ttn.lorawan.v3.MessagePayloadFormatters">Message `MessagePayloadFormatters`</a>
 
 | Field | Type | Label | Description |
diff --git a/api/ttn/lorawan/v3/api.swagger.json b/api/ttn/lorawan/v3/api.swagger.json
index d9eb432aee..57c7d5b5ce 100644
--- a/api/ttn/lorawan/v3/api.swagger.json
+++ b/api/ttn/lorawan/v3/api.swagger.json
@@ -21068,6 +21068,10 @@
         "network_ids": {
           "$ref": "#/definitions/v3NetworkIdentifiers",
           "description": "Network identifiers, set by the Network Server that handles the message."
+        },
+        "last_battery_percentage": {
+          "$ref": "#/definitions/v3LastBatteryPercentage",
+          "description": "Last battery percentage of the end device.\nReceived via the DevStatus MAC command at last_dev_status_received_at or earlier.\nSet by the Network Server while handling the message."
         }
       }
     },
@@ -25802,6 +25806,26 @@
         }
       }
     },
+    "v3LastBatteryPercentage": {
+      "type": "object",
+      "properties": {
+        "f_cnt": {
+          "type": "integer",
+          "format": "int64",
+          "description": "Frame counter value of last uplink containing DevStatusAns."
+        },
+        "value": {
+          "type": "number",
+          "format": "float",
+          "description": "The battery percentage of the end device.\nThe value is defined in the [0, 100] interval."
+        },
+        "received_at": {
+          "type": "string",
+          "format": "date-time",
+          "description": "Time when last DevStatus MAC command was received."
+        }
+      }
+    },
     "v3ListBandsResponse": {
       "type": "object",
       "properties": {
diff --git a/api/ttn/lorawan/v3/messages.proto b/api/ttn/lorawan/v3/messages.proto
index 043bca2328..4bd951ffb8 100644
--- a/api/ttn/lorawan/v3/messages.proto
+++ b/api/ttn/lorawan/v3/messages.proto
@@ -186,6 +186,19 @@ message GatewayUplinkMessage {
   string band_id = 2;
 }
 
+message LastBatteryPercentage {
+  // Frame counter value of last uplink containing DevStatusAns.
+  uint32 f_cnt = 1;
+  // The battery percentage of the end device.
+  // The value is defined in the [0, 100] interval.
+  google.protobuf.FloatValue value = 2 [(validate.rules).float = {
+    gte: 0,
+    lte: 1
+  }];
+  // Time when last DevStatus MAC command was received.
+  google.protobuf.Timestamp received_at = 3;
+}
+
 message ApplicationUplink {
   option (thethings.flags.message) = {
     select: true,
@@ -259,7 +272,12 @@ message ApplicationUplink {
   // Network identifiers, set by the Network Server that handles the message.
   NetworkIdentifiers network_ids = 16;
 
-  // next: 20
+  // Last battery percentage of the end device.
+  // Received via the DevStatus MAC command at last_dev_status_received_at or earlier.
+  // Set by the Network Server while handling the message.
+  LastBatteryPercentage last_battery_percentage = 20;
+
+  // next: 21
 }
 
 message ApplicationUplinkNormalized {
diff --git a/pkg/ttnpb/applicationserver.pb.paths.fm.go b/pkg/ttnpb/applicationserver.pb.paths.fm.go
index f71deb4fc6..f3b7f770d2 100644
--- a/pkg/ttnpb/applicationserver.pb.paths.fm.go
+++ b/pkg/ttnpb/applicationserver.pb.paths.fm.go
@@ -183,6 +183,10 @@ var DecodeUplinkRequestFieldPathsNested = []string{
 	"uplink.f_port",
 	"uplink.frm_payload",
 	"uplink.last_a_f_cnt_down",
+	"uplink.last_battery_percentage",
+	"uplink.last_battery_percentage.f_cnt",
+	"uplink.last_battery_percentage.received_at",
+	"uplink.last_battery_percentage.value",
 	"uplink.locations",
 	"uplink.network_ids",
 	"uplink.network_ids.cluster_address",
@@ -254,6 +258,10 @@ var DecodeUplinkResponseFieldPathsNested = []string{
 	"uplink.f_port",
 	"uplink.frm_payload",
 	"uplink.last_a_f_cnt_down",
+	"uplink.last_battery_percentage",
+	"uplink.last_battery_percentage.f_cnt",
+	"uplink.last_battery_percentage.received_at",
+	"uplink.last_battery_percentage.value",
 	"uplink.locations",
 	"uplink.network_ids",
 	"uplink.network_ids.cluster_address",
diff --git a/pkg/ttnpb/messages.pb.go b/pkg/ttnpb/messages.pb.go
index 57aa6472b7..518c13f878 100644
--- a/pkg/ttnpb/messages.pb.go
+++ b/pkg/ttnpb/messages.pb.go
@@ -588,6 +588,73 @@ func (x *GatewayUplinkMessage) GetBandId() string {
 	return ""
 }
 
+type LastBatteryPercentage struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Frame counter value of last uplink containing DevStatusAns.
+	FCnt uint32 `protobuf:"varint,1,opt,name=f_cnt,json=fCnt,proto3" json:"f_cnt,omitempty"`
+	// The battery percentage of the end device.
+	// The value is defined in the [0, 100] interval.
+	Value *wrapperspb.FloatValue `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
+	// Time when last DevStatus MAC command was received.
+	ReceivedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=received_at,json=receivedAt,proto3" json:"received_at,omitempty"`
+}
+
+func (x *LastBatteryPercentage) Reset() {
+	*x = LastBatteryPercentage{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *LastBatteryPercentage) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LastBatteryPercentage) ProtoMessage() {}
+
+func (x *LastBatteryPercentage) ProtoReflect() protoreflect.Message {
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LastBatteryPercentage.ProtoReflect.Descriptor instead.
+func (*LastBatteryPercentage) Descriptor() ([]byte, []int) {
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *LastBatteryPercentage) GetFCnt() uint32 {
+	if x != nil {
+		return x.FCnt
+	}
+	return 0
+}
+
+func (x *LastBatteryPercentage) GetValue() *wrapperspb.FloatValue {
+	if x != nil {
+		return x.Value
+	}
+	return nil
+}
+
+func (x *LastBatteryPercentage) GetReceivedAt() *timestamppb.Timestamp {
+	if x != nil {
+		return x.ReceivedAt
+	}
+	return nil
+}
+
 type ApplicationUplink struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -644,12 +711,16 @@ type ApplicationUplink struct {
 	VersionIds *EndDeviceVersionIdentifiers `protobuf:"bytes,15,opt,name=version_ids,json=versionIds,proto3" json:"version_ids,omitempty"`
 	// Network identifiers, set by the Network Server that handles the message.
 	NetworkIds *NetworkIdentifiers `protobuf:"bytes,16,opt,name=network_ids,json=networkIds,proto3" json:"network_ids,omitempty"`
+	// Last battery percentage of the end device.
+	// Received via the DevStatus MAC command at last_dev_status_received_at or earlier.
+	// Set by the Network Server while handling the message.
+	LastBatteryPercentage *LastBatteryPercentage `protobuf:"bytes,20,opt,name=last_battery_percentage,json=lastBatteryPercentage,proto3" json:"last_battery_percentage,omitempty"`
 }
 
 func (x *ApplicationUplink) Reset() {
 	*x = ApplicationUplink{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[5]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[6]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -662,7 +733,7 @@ func (x *ApplicationUplink) String() string {
 func (*ApplicationUplink) ProtoMessage() {}
 
 func (x *ApplicationUplink) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[5]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[6]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -675,7 +746,7 @@ func (x *ApplicationUplink) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplicationUplink.ProtoReflect.Descriptor instead.
 func (*ApplicationUplink) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{5}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{6}
 }
 
 func (x *ApplicationUplink) GetSessionKeyId() []byte {
@@ -811,6 +882,13 @@ func (x *ApplicationUplink) GetNetworkIds() *NetworkIdentifiers {
 	return nil
 }
 
+func (x *ApplicationUplink) GetLastBatteryPercentage() *LastBatteryPercentage {
+	if x != nil {
+		return x.LastBatteryPercentage
+	}
+	return nil
+}
+
 type ApplicationUplinkNormalized struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -851,7 +929,7 @@ type ApplicationUplinkNormalized struct {
 func (x *ApplicationUplinkNormalized) Reset() {
 	*x = ApplicationUplinkNormalized{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[6]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[7]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -864,7 +942,7 @@ func (x *ApplicationUplinkNormalized) String() string {
 func (*ApplicationUplinkNormalized) ProtoMessage() {}
 
 func (x *ApplicationUplinkNormalized) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[6]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[7]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -877,7 +955,7 @@ func (x *ApplicationUplinkNormalized) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplicationUplinkNormalized.ProtoReflect.Descriptor instead.
 func (*ApplicationUplinkNormalized) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{6}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{7}
 }
 
 func (x *ApplicationUplinkNormalized) GetSessionKeyId() []byte {
@@ -991,7 +1069,7 @@ type ApplicationLocation struct {
 func (x *ApplicationLocation) Reset() {
 	*x = ApplicationLocation{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[7]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[8]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1004,7 +1082,7 @@ func (x *ApplicationLocation) String() string {
 func (*ApplicationLocation) ProtoMessage() {}
 
 func (x *ApplicationLocation) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[7]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[8]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1017,7 +1095,7 @@ func (x *ApplicationLocation) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplicationLocation.ProtoReflect.Descriptor instead.
 func (*ApplicationLocation) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{7}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{8}
 }
 
 func (x *ApplicationLocation) GetService() string {
@@ -1062,7 +1140,7 @@ type ApplicationJoinAccept struct {
 func (x *ApplicationJoinAccept) Reset() {
 	*x = ApplicationJoinAccept{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[8]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[9]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1075,7 +1153,7 @@ func (x *ApplicationJoinAccept) String() string {
 func (*ApplicationJoinAccept) ProtoMessage() {}
 
 func (x *ApplicationJoinAccept) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[8]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[9]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1088,7 +1166,7 @@ func (x *ApplicationJoinAccept) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplicationJoinAccept.ProtoReflect.Descriptor instead.
 func (*ApplicationJoinAccept) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{8}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{9}
 }
 
 func (x *ApplicationJoinAccept) GetSessionKeyId() []byte {
@@ -1160,7 +1238,7 @@ type ApplicationDownlink struct {
 func (x *ApplicationDownlink) Reset() {
 	*x = ApplicationDownlink{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[9]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[10]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1173,7 +1251,7 @@ func (x *ApplicationDownlink) String() string {
 func (*ApplicationDownlink) ProtoMessage() {}
 
 func (x *ApplicationDownlink) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[9]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[10]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1186,7 +1264,7 @@ func (x *ApplicationDownlink) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplicationDownlink.ProtoReflect.Descriptor instead.
 func (*ApplicationDownlink) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{9}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{10}
 }
 
 func (x *ApplicationDownlink) GetSessionKeyId() []byte {
@@ -1277,7 +1355,7 @@ type ApplicationDownlinks struct {
 func (x *ApplicationDownlinks) Reset() {
 	*x = ApplicationDownlinks{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[10]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[11]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1290,7 +1368,7 @@ func (x *ApplicationDownlinks) String() string {
 func (*ApplicationDownlinks) ProtoMessage() {}
 
 func (x *ApplicationDownlinks) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[10]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[11]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1303,7 +1381,7 @@ func (x *ApplicationDownlinks) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplicationDownlinks.ProtoReflect.Descriptor instead.
 func (*ApplicationDownlinks) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{10}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{11}
 }
 
 func (x *ApplicationDownlinks) GetDownlinks() []*ApplicationDownlink {
@@ -1325,7 +1403,7 @@ type ApplicationDownlinkFailed struct {
 func (x *ApplicationDownlinkFailed) Reset() {
 	*x = ApplicationDownlinkFailed{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[11]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[12]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1338,7 +1416,7 @@ func (x *ApplicationDownlinkFailed) String() string {
 func (*ApplicationDownlinkFailed) ProtoMessage() {}
 
 func (x *ApplicationDownlinkFailed) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[11]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[12]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1351,7 +1429,7 @@ func (x *ApplicationDownlinkFailed) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplicationDownlinkFailed.ProtoReflect.Descriptor instead.
 func (*ApplicationDownlinkFailed) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{11}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{12}
 }
 
 func (x *ApplicationDownlinkFailed) GetDownlink() *ApplicationDownlink {
@@ -1381,7 +1459,7 @@ type ApplicationInvalidatedDownlinks struct {
 func (x *ApplicationInvalidatedDownlinks) Reset() {
 	*x = ApplicationInvalidatedDownlinks{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[12]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[13]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1394,7 +1472,7 @@ func (x *ApplicationInvalidatedDownlinks) String() string {
 func (*ApplicationInvalidatedDownlinks) ProtoMessage() {}
 
 func (x *ApplicationInvalidatedDownlinks) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[12]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[13]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1407,7 +1485,7 @@ func (x *ApplicationInvalidatedDownlinks) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplicationInvalidatedDownlinks.ProtoReflect.Descriptor instead.
 func (*ApplicationInvalidatedDownlinks) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{12}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{13}
 }
 
 func (x *ApplicationInvalidatedDownlinks) GetDownlinks() []*ApplicationDownlink {
@@ -1447,7 +1525,7 @@ type DownlinkQueueOperationErrorDetails struct {
 func (x *DownlinkQueueOperationErrorDetails) Reset() {
 	*x = DownlinkQueueOperationErrorDetails{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[13]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[14]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1460,7 +1538,7 @@ func (x *DownlinkQueueOperationErrorDetails) String() string {
 func (*DownlinkQueueOperationErrorDetails) ProtoMessage() {}
 
 func (x *DownlinkQueueOperationErrorDetails) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[13]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[14]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1473,7 +1551,7 @@ func (x *DownlinkQueueOperationErrorDetails) ProtoReflect() protoreflect.Message
 
 // Deprecated: Use DownlinkQueueOperationErrorDetails.ProtoReflect.Descriptor instead.
 func (*DownlinkQueueOperationErrorDetails) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{13}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{14}
 }
 
 func (x *DownlinkQueueOperationErrorDetails) GetDevAddr() []byte {
@@ -1530,7 +1608,7 @@ type ApplicationServiceData struct {
 func (x *ApplicationServiceData) Reset() {
 	*x = ApplicationServiceData{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[14]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[15]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1543,7 +1621,7 @@ func (x *ApplicationServiceData) String() string {
 func (*ApplicationServiceData) ProtoMessage() {}
 
 func (x *ApplicationServiceData) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[14]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[15]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1556,7 +1634,7 @@ func (x *ApplicationServiceData) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplicationServiceData.ProtoReflect.Descriptor instead.
 func (*ApplicationServiceData) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{14}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{15}
 }
 
 func (x *ApplicationServiceData) GetService() string {
@@ -1604,7 +1682,7 @@ type ApplicationUp struct {
 func (x *ApplicationUp) Reset() {
 	*x = ApplicationUp{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[15]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[16]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1617,7 +1695,7 @@ func (x *ApplicationUp) String() string {
 func (*ApplicationUp) ProtoMessage() {}
 
 func (x *ApplicationUp) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[15]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[16]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1630,7 +1708,7 @@ func (x *ApplicationUp) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplicationUp.ProtoReflect.Descriptor instead.
 func (*ApplicationUp) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{15}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{16}
 }
 
 func (x *ApplicationUp) GetEndDeviceIds() *EndDeviceIdentifiers {
@@ -1833,7 +1911,7 @@ type MessagePayloadFormatters struct {
 func (x *MessagePayloadFormatters) Reset() {
 	*x = MessagePayloadFormatters{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[16]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[17]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1846,7 +1924,7 @@ func (x *MessagePayloadFormatters) String() string {
 func (*MessagePayloadFormatters) ProtoMessage() {}
 
 func (x *MessagePayloadFormatters) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[16]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[17]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1859,7 +1937,7 @@ func (x *MessagePayloadFormatters) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use MessagePayloadFormatters.ProtoReflect.Descriptor instead.
 func (*MessagePayloadFormatters) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{16}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{17}
 }
 
 func (x *MessagePayloadFormatters) GetUpFormatter() PayloadFormatter {
@@ -1902,7 +1980,7 @@ type DownlinkQueueRequest struct {
 func (x *DownlinkQueueRequest) Reset() {
 	*x = DownlinkQueueRequest{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[17]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[18]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1915,7 +1993,7 @@ func (x *DownlinkQueueRequest) String() string {
 func (*DownlinkQueueRequest) ProtoMessage() {}
 
 func (x *DownlinkQueueRequest) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[17]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[18]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1928,7 +2006,7 @@ func (x *DownlinkQueueRequest) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use DownlinkQueueRequest.ProtoReflect.Descriptor instead.
 func (*DownlinkQueueRequest) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{17}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{18}
 }
 
 func (x *DownlinkQueueRequest) GetEndDeviceIds() *EndDeviceIdentifiers {
@@ -1966,7 +2044,7 @@ type ApplicationDownlink_ClassBC struct {
 func (x *ApplicationDownlink_ClassBC) Reset() {
 	*x = ApplicationDownlink_ClassBC{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[21]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[22]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -1979,7 +2057,7 @@ func (x *ApplicationDownlink_ClassBC) String() string {
 func (*ApplicationDownlink_ClassBC) ProtoMessage() {}
 
 func (x *ApplicationDownlink_ClassBC) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[21]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[22]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -1992,7 +2070,7 @@ func (x *ApplicationDownlink_ClassBC) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use ApplicationDownlink_ClassBC.ProtoReflect.Descriptor instead.
 func (*ApplicationDownlink_ClassBC) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{9, 0}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{10, 0}
 }
 
 func (x *ApplicationDownlink_ClassBC) GetGateways() []*ClassBCGatewayIdentifiers {
@@ -2024,7 +2102,7 @@ type ApplicationDownlink_ConfirmedRetry struct {
 func (x *ApplicationDownlink_ConfirmedRetry) Reset() {
 	*x = ApplicationDownlink_ConfirmedRetry{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[22]
+		mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[23]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -2037,7 +2115,7 @@ func (x *ApplicationDownlink_ConfirmedRetry) String() string {
 func (*ApplicationDownlink_ConfirmedRetry) ProtoMessage() {}
 
 func (x *ApplicationDownlink_ConfirmedRetry) ProtoReflect() protoreflect.Message {
-	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[22]
+	mi := &file_ttn_lorawan_v3_messages_proto_msgTypes[23]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -2050,7 +2128,7 @@ func (x *ApplicationDownlink_ConfirmedRetry) ProtoReflect() protoreflect.Message
 
 // Deprecated: Use ApplicationDownlink_ConfirmedRetry.ProtoReflect.Descriptor instead.
 func (*ApplicationDownlink_ConfirmedRetry) Descriptor() ([]byte, []int) {
-	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{9, 1}
+	return file_ttn_lorawan_v3_messages_proto_rawDescGZIP(), []int{10, 1}
 }
 
 func (x *ApplicationDownlink_ConfirmedRetry) GetAttempt() uint32 {
@@ -2200,7 +2278,18 @@ var file_ttn_lorawan_v3_messages_proto_rawDesc = []byte{
 	0x2e, 0x76, 0x33, 0x2e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
 	0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x07, 0x6d, 0x65, 0x73,
 	0x73, 0x61, 0x67, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x62, 0x61, 0x6e, 0x64, 0x5f, 0x69, 0x64, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x22, 0x95, 0x09,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x61, 0x6e, 0x64, 0x49, 0x64, 0x22, 0xad, 0x01,
+	0x0a, 0x15, 0x4c, 0x61, 0x73, 0x74, 0x42, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x50, 0x65, 0x72,
+	0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x13, 0x0a, 0x05, 0x66, 0x5f, 0x63, 0x6e, 0x74,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x66, 0x43, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x05,
+	0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f,
+	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x6c,
+	0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0f, 0xfa, 0x42, 0x0c, 0x0a, 0x0a, 0x1d,
+	0x00, 0x00, 0x80, 0x3f, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+	0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+	0x70, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x22, 0xf4, 0x09,
 	0x0a, 0x11, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x6c,
 	0x69, 0x6e, 0x6b, 0x12, 0x2e, 0x0a, 0x0e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b,
 	0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x08, 0xfa, 0x42, 0x05,
@@ -2268,389 +2357,395 @@ var file_ttn_lorawan_v3_messages_proto_rawDesc = []byte{
 	0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
 	0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x65, 0x6e,
 	0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
-	0x49, 0x64, 0x73, 0x1a, 0x56, 0x0a, 0x0e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
-	0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
-	0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x08, 0xf2, 0xaa, 0x19,
-	0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xb4, 0x07, 0x0a, 0x1b, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63,
-	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x72, 0x6d, 0x61,
-	0x6c, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x0e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
-	0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x08, 0xfa,
-	0x42, 0x05, 0x7a, 0x03, 0x18, 0x80, 0x10, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
-	0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x0d, 0xfa, 0x42, 0x0a, 0x2a, 0x08, 0x18, 0xff, 0x01, 0x28,
-	0x01, 0x38, 0xe0, 0x01, 0x52, 0x05, 0x66, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x13, 0x0a, 0x05, 0x66,
-	0x5f, 0x63, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x66, 0x43, 0x6e, 0x74,
-	0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18,
-	0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x66, 0x72, 0x6d, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61,
-	0x64, 0x12, 0x50, 0x0a, 0x12, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f,
-	0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
-	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
-	0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01,
-	0x52, 0x11, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x50, 0x61, 0x79, 0x6c,
-	0x6f, 0x61, 0x64, 0x12, 0x3e, 0x0a, 0x1b, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65,
-	0x64, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e,
-	0x67, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x19, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c,
-	0x69, 0x7a, 0x65, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x61, 0x72, 0x6e, 0x69,
-	0x6e, 0x67, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x78, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61,
-	0x74, 0x61, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
-	0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x78, 0x4d, 0x65, 0x74, 0x61,
-	0x64, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x72, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
-	0x12, 0x40, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x08, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
-	0x2e, 0x76, 0x33, 0x2e, 0x54, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x08,
-	0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e,
-	0x67, 0x73, 0x12, 0x45, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61,
-	0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
-	0x61, 0x6d, 0x70, 0x42, 0x08, 0xfa, 0x42, 0x05, 0xb2, 0x01, 0x02, 0x08, 0x01, 0x52, 0x0a, 0x72,
-	0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e,
-	0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f,
-	0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x73, 0x75,
-	0x6d, 0x65, 0x64, 0x5f, 0x61, 0x69, 0x72, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
-	0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x63, 0x6f,
-	0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x41, 0x69, 0x72, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x58, 0x0a,
-	0x09, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b,
-	0x32, 0x3a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
-	0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x6c,
-	0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x2e, 0x4c, 0x6f,
-	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6c, 0x6f,
-	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, 0x0a, 0x0b, 0x76, 0x65, 0x72, 0x73, 0x69,
-	0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74,
-	0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e,
-	0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64,
-	0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69,
-	0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x43, 0x0a, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b,
-	0x5f, 0x69, 0x64, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e,
-	0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x65, 0x74, 0x77,
-	0x6f, 0x72, 0x6b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x0a,
-	0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x73, 0x1a, 0x56, 0x0a, 0x0e, 0x4c, 0x6f,
-	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
-	0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e,
-	0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e,
-	0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c,
-	0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
-	0x38, 0x01, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x22, 0xc5, 0x02, 0x0a,
-	0x13, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x63, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3e,
-	0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
-	0x33, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a,
-	0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x8a,
-	0x01, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
-	0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
-	0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x35, 0xfa, 0x42, 0x32, 0x9a, 0x01, 0x2f,
-	0x10, 0x0a, 0x22, 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30,
-	0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d,
-	0x39, 0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x2a, 0x05, 0x72, 0x03, 0x18, 0xc8, 0x01, 0x52,
-	0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x41,
-	0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
-	0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
-	0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x49, 0x64, 0x73, 0x12, 0x5d, 0x0a, 0x17, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x62, 0x61, 0x74, 0x74,
+	0x65, 0x72, 0x79, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x14,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+	0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x42, 0x61, 0x74, 0x74, 0x65, 0x72,
+	0x79, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x52, 0x15, 0x6c, 0x61, 0x73,
+	0x74, 0x42, 0x61, 0x74, 0x74, 0x65, 0x72, 0x79, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61,
+	0x67, 0x65, 0x1a, 0x56, 0x0a, 0x0e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45,
+	0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+	0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
 	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04,
-	0x08, 0x01, 0x10, 0x00, 0x22, 0xd4, 0x02, 0x0a, 0x15, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x6f, 0x69, 0x6e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x2e,
-	0x0a, 0x0e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x7a, 0x03, 0x18, 0x80, 0x10,
-	0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x37,
-	0x0a, 0x09, 0x61, 0x70, 0x70, 0x5f, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x1b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
-	0x76, 0x33, 0x2e, 0x4b, 0x65, 0x79, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x52, 0x07,
-	0x61, 0x70, 0x70, 0x53, 0x4b, 0x65, 0x79, 0x12, 0x58, 0x0a, 0x15, 0x69, 0x6e, 0x76, 0x61, 0x6c,
-	0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73,
-	0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
-	0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
-	0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x14, 0x69, 0x6e, 0x76,
-	0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b,
-	0x73, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x73,
-	0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x70, 0x65, 0x6e, 0x64,
-	0x69, 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x0b, 0x72, 0x65,
-	0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
-	0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0xfa, 0x42, 0x05,
-	0xb2, 0x01, 0x02, 0x08, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41,
-	0x74, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x22, 0xd5, 0x09, 0x0a, 0x13,
-	0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c,
-	0x69, 0x6e, 0x6b, 0x12, 0xcd, 0x01, 0x0a, 0x0e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
-	0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xa6, 0x01, 0xfa,
-	0x42, 0x05, 0x7a, 0x03, 0x18, 0x80, 0x10, 0xf2, 0xaa, 0x19, 0x99, 0x01, 0x1a, 0x4e, 0x67, 0x69,
-	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x65, 0x54, 0x68, 0x69, 0x6e,
-	0x67, 0x73, 0x49, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x66, 0x6c, 0x61, 0x67, 0x73,
-	0x2f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4e, 0x65, 0x77,
-	0x48, 0x65, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x22, 0x47, 0x67, 0x69,
-	0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x65, 0x54, 0x68, 0x69, 0x6e,
-	0x67, 0x73, 0x49, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x66, 0x6c, 0x61, 0x67, 0x73,
-	0x2f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x47, 0x65, 0x74,
-	0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65,
-	0x79, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x06, 0x66, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0d, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x2a, 0x06, 0x18, 0xff, 0x01, 0x38, 0xe0, 0x01,
-	0x52, 0x05, 0x66, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x13, 0x0a, 0x05, 0x66, 0x5f, 0x63, 0x6e, 0x74,
-	0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x66, 0x43, 0x6e, 0x74, 0x12, 0xc8, 0x01, 0x0a,
-	0x0b, 0x66, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01,
-	0x28, 0x0c, 0x42, 0xa6, 0x01, 0xfa, 0x42, 0x05, 0x7a, 0x03, 0x18, 0xff, 0x01, 0xf2, 0xaa, 0x19,
-	0x99, 0x01, 0x1a, 0x4e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54,
-	0x68, 0x65, 0x54, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x49, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69,
-	0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f,
-	0x2d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x70, 0x6c, 0x75, 0x67,
-	0x69, 0x6e, 0x2e, 0x4e, 0x65, 0x77, 0x48, 0x65, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x46, 0x6c,
-	0x61, 0x67, 0x22, 0x47, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54,
-	0x68, 0x65, 0x54, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x49, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69,
-	0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f,
-	0x2d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x70, 0x6c, 0x75, 0x67,
-	0x69, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x66, 0x72, 0x6d,
-	0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x40, 0x0a, 0x0f, 0x64, 0x65, 0x63, 0x6f, 0x64,
-	0x65, 0x64, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
-	0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0e, 0x64, 0x65, 0x63, 0x6f, 0x64,
-	0x65, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x38, 0x0a, 0x18, 0x64, 0x65, 0x63,
-	0x6f, 0x64, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x77, 0x61, 0x72,
-	0x6e, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x16, 0x64, 0x65, 0x63,
-	0x6f, 0x64, 0x65, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x61, 0x72, 0x6e, 0x69,
-	0x6e, 0x67, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64,
-	0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65,
-	0x64, 0x12, 0x47, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x62, 0x5f, 0x63, 0x18, 0x07,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
-	0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
-	0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x42,
-	0x43, 0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x42, 0x43, 0x12, 0x48, 0x0a, 0x08, 0x70, 0x72,
-	0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74,
-	0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x78,
-	0x53, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79,
-	0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f,
-	0x72, 0x69, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74,
-	0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0c, 0xfa,
-	0x42, 0x09, 0x92, 0x01, 0x06, 0x22, 0x04, 0x72, 0x02, 0x18, 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x72,
-	0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x5b, 0x0a, 0x0f, 0x63,
-	0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x79, 0x18, 0x0b,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
-	0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
-	0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72,
-	0x6d, 0x65, 0x64, 0x52, 0x65, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72,
-	0x6d, 0x65, 0x64, 0x52, 0x65, 0x74, 0x72, 0x79, 0x1a, 0x9b, 0x01, 0x0a, 0x07, 0x43, 0x6c, 0x61,
-	0x73, 0x73, 0x42, 0x43, 0x12, 0x45, 0x0a, 0x08, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73,
-	0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
-	0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x42, 0x43, 0x47,
-	0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72,
-	0x73, 0x52, 0x08, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0x3f, 0x0a, 0x0d, 0x61,
-	0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c,
-	0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x3a, 0x08, 0xf2, 0xaa,
-	0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x1a, 0x80, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
-	0x72, 0x6d, 0x65, 0x64, 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x74, 0x74,
-	0x65, 0x6d, 0x70, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, 0x74, 0x74, 0x65,
-	0x6d, 0x70, 0x74, 0x12, 0x4a, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x6d,
-	0x70, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
-	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74,
-	0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x18, 0x64,
-	0x20, 0x00, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x3a,
-	0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08,
-	0x01, 0x10, 0x01, 0x22, 0x59, 0x0a, 0x14, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x41, 0x0a, 0x09, 0x64,
-	0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23,
-	0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
-	0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c,
-	0x69, 0x6e, 0x6b, 0x52, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x22, 0xae,
-	0x01, 0x0a, 0x19, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f,
-	0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x49, 0x0a, 0x08,
-	0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23,
-	0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
-	0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c,
-	0x69, 0x6e, 0x6b, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x64,
-	0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x3c, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
-	0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44, 0x65, 0x74,
-	0x61, 0x69, 0x6c, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05,
-	0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x22,
-	0xc5, 0x01, 0x0a, 0x1f, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49,
-	0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
-	0x6e, 0x6b, 0x73, 0x12, 0x41, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73,
-	0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
-	0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
-	0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x09, 0x64, 0x6f, 0x77,
-	0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x25, 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x66,
-	0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52,
-	0x0c, 0x6c, 0x61, 0x73, 0x74, 0x46, 0x43, 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x12, 0x2e, 0x0a,
+	0x08, 0x01, 0x10, 0x01, 0x22, 0xb4, 0x07, 0x0a, 0x1b, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c,
+	0x69, 0x7a, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x0e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
+	0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x08, 0xfa, 0x42,
+	0x05, 0x7a, 0x03, 0x18, 0x80, 0x10, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b,
+	0x65, 0x79, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x0d, 0x42, 0x0d, 0xfa, 0x42, 0x0a, 0x2a, 0x08, 0x18, 0xff, 0x01, 0x28, 0x01,
+	0x38, 0xe0, 0x01, 0x52, 0x05, 0x66, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x13, 0x0a, 0x05, 0x66, 0x5f,
+	0x63, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x66, 0x43, 0x6e, 0x74, 0x12,
+	0x1f, 0x0a, 0x0b, 0x66, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x66, 0x72, 0x6d, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
+	0x12, 0x50, 0x0a, 0x12, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x70,
+	0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67,
+	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53,
+	0x74, 0x72, 0x75, 0x63, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52,
+	0x11, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f,
+	0x61, 0x64, 0x12, 0x3e, 0x0a, 0x1b, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64,
+	0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67,
+	0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x19, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69,
+	0x7a, 0x65, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e,
+	0x67, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x78, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+	0x61, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f,
+	0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64,
+	0x61, 0x74, 0x61, 0x52, 0x0a, 0x72, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12,
+	0x40, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+	0x76, 0x33, 0x2e, 0x54, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x08, 0xfa,
+	0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67,
+	0x73, 0x12, 0x45, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74,
+	0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
+	0x6d, 0x70, 0x42, 0x08, 0xfa, 0x42, 0x05, 0xb2, 0x01, 0x02, 0x08, 0x01, 0x52, 0x0a, 0x72, 0x65,
+	0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x66,
+	0x69, 0x72, 0x6d, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6e,
+	0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x12, 0x44, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d,
+	0x65, 0x64, 0x5f, 0x61, 0x69, 0x72, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x63, 0x6f, 0x6e,
+	0x73, 0x75, 0x6d, 0x65, 0x64, 0x41, 0x69, 0x72, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x58, 0x0a, 0x09,
+	0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x3a, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+	0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x6c, 0x69,
+	0x6e, 0x6b, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x2e, 0x4c, 0x6f, 0x63,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x6c, 0x6f, 0x63,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, 0x0a, 0x0b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
+	0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x74,
+	0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x64,
+	0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x65,
+	0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
+	0x6e, 0x49, 0x64, 0x73, 0x12, 0x43, 0x0a, 0x0b, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f,
+	0x69, 0x64, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+	0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f,
+	0x72, 0x6b, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x52, 0x0a, 0x6e,
+	0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x73, 0x1a, 0x56, 0x0a, 0x0e, 0x4c, 0x6f, 0x63,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
+	0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a,
+	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x74,
+	0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x6f,
+	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
+	0x01, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x22, 0xc5, 0x02, 0x0a, 0x13,
+	0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x63, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x3e, 0x0a,
+	0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x18, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+	0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01,
+	0x02, 0x10, 0x01, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x8a, 0x01,
+	0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x33, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+	0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c,
+	0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
+	0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x35, 0xfa, 0x42, 0x32, 0x9a, 0x01, 0x2f, 0x10,
+	0x0a, 0x22, 0x24, 0x72, 0x22, 0x18, 0x24, 0x32, 0x1e, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d,
+	0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x2d, 0x5d, 0x3f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39,
+	0x5d, 0x29, 0x7b, 0x32, 0x2c, 0x7d, 0x24, 0x2a, 0x05, 0x72, 0x03, 0x18, 0xc8, 0x01, 0x52, 0x0a,
+	0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x41, 0x74,
+	0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
+	0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
+	0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
+	0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08,
+	0x01, 0x10, 0x00, 0x22, 0xd4, 0x02, 0x0a, 0x15, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x4a, 0x6f, 0x69, 0x6e, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x12, 0x2e, 0x0a,
 	0x0e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x7a, 0x03, 0x18, 0x80, 0x10, 0x52,
-	0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x3a, 0x08, 0xf2,
-	0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x22, 0x91, 0x05, 0x0a, 0x22, 0x44, 0x6f, 0x77, 0x6e,
-	0x6c, 0x69, 0x6e, 0x6b, 0x51, 0x75, 0x65, 0x75, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0xc8,
-	0x01, 0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
-	0x0c, 0x42, 0xac, 0x01, 0x92, 0x41, 0x19, 0x4a, 0x0a, 0x22, 0x32, 0x36, 0x30, 0x30, 0x41, 0x42,
-	0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
-	0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x04, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a, 0x3f,
+	0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x7a, 0x03, 0x18, 0x80, 0x10, 0x52,
+	0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x37, 0x0a,
+	0x09, 0x61, 0x70, 0x70, 0x5f, 0x73, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x1b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+	0x33, 0x2e, 0x4b, 0x65, 0x79, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x52, 0x07, 0x61,
+	0x70, 0x70, 0x53, 0x4b, 0x65, 0x79, 0x12, 0x58, 0x0a, 0x15, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69,
+	0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18,
+	0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+	0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x14, 0x69, 0x6e, 0x76, 0x61,
+	0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73,
+	0x12, 0x27, 0x0a, 0x0f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x73, 0x73,
+	0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x70, 0x65, 0x6e, 0x64, 0x69,
+	0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x45, 0x0a, 0x0b, 0x72, 0x65, 0x63,
+	0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
+	0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, 0xfa, 0x42, 0x05, 0xb2,
+	0x01, 0x02, 0x08, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41, 0x74,
+	0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x22, 0xd5, 0x09, 0x0a, 0x13, 0x41,
+	0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
+	0x6e, 0x6b, 0x12, 0xcd, 0x01, 0x0a, 0x0e, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b,
+	0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xa6, 0x01, 0xfa, 0x42,
+	0x05, 0x7a, 0x03, 0x18, 0x80, 0x10, 0xf2, 0xaa, 0x19, 0x99, 0x01, 0x1a, 0x4e, 0x67, 0x69, 0x74,
+	0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x65, 0x54, 0x68, 0x69, 0x6e, 0x67,
+	0x73, 0x49, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2f,
+	0x66, 0x6c, 0x61, 0x67, 0x73, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x4e, 0x65, 0x77, 0x48,
+	0x65, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x22, 0x47, 0x67, 0x69, 0x74,
+	0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x65, 0x54, 0x68, 0x69, 0x6e, 0x67,
+	0x73, 0x49, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69, 0x65, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2f,
+	0x66, 0x6c, 0x61, 0x67, 0x73, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x42,
+	0x79, 0x74, 0x65, 0x73, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79,
+	0x49, 0x64, 0x12, 0x22, 0x0a, 0x06, 0x66, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0d, 0x42, 0x0b, 0xfa, 0x42, 0x08, 0x2a, 0x06, 0x18, 0xff, 0x01, 0x38, 0xe0, 0x01, 0x52,
+	0x05, 0x66, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x13, 0x0a, 0x05, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x66, 0x43, 0x6e, 0x74, 0x12, 0xc8, 0x01, 0x0a, 0x0b,
+	0x66, 0x72, 0x6d, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28,
+	0x0c, 0x42, 0xa6, 0x01, 0xfa, 0x42, 0x05, 0x7a, 0x03, 0x18, 0xff, 0x01, 0xf2, 0xaa, 0x19, 0x99,
+	0x01, 0x1a, 0x4e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68,
+	0x65, 0x54, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x49, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69, 0x65,
+	0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d,
+	0x66, 0x6c, 0x61, 0x67, 0x73, 0x2f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x70, 0x6c, 0x75, 0x67, 0x69,
+	0x6e, 0x2e, 0x4e, 0x65, 0x77, 0x48, 0x65, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x46, 0x6c, 0x61,
+	0x67, 0x22, 0x47, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68,
+	0x65, 0x54, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x49, 0x6e, 0x64, 0x75, 0x73, 0x74, 0x72, 0x69, 0x65,
+	0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d,
+	0x66, 0x6c, 0x61, 0x67, 0x73, 0x2f, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x70, 0x6c, 0x75, 0x67, 0x69,
+	0x6e, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x0a, 0x66, 0x72, 0x6d, 0x50,
+	0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x40, 0x0a, 0x0f, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65,
+	0x64, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0e, 0x64, 0x65, 0x63, 0x6f, 0x64, 0x65,
+	0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x38, 0x0a, 0x18, 0x64, 0x65, 0x63, 0x6f,
+	0x64, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x77, 0x61, 0x72, 0x6e,
+	0x69, 0x6e, 0x67, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x16, 0x64, 0x65, 0x63, 0x6f,
+	0x64, 0x65, 0x64, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e,
+	0x67, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x18,
+	0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64,
+	0x12, 0x47, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x62, 0x5f, 0x63, 0x18, 0x07, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+	0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x42, 0x43,
+	0x52, 0x07, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x42, 0x43, 0x12, 0x48, 0x0a, 0x08, 0x70, 0x72, 0x69,
+	0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x74, 0x74,
+	0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x78, 0x53,
+	0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x42,
+	0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72,
+	0x69, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x0f, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0c, 0xfa, 0x42,
+	0x09, 0x92, 0x01, 0x06, 0x22, 0x04, 0x72, 0x02, 0x18, 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x72, 0x72,
+	0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x5b, 0x0a, 0x0f, 0x63, 0x6f,
+	0x6e, 0x66, 0x69, 0x72, 0x6d, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x79, 0x18, 0x0b, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
+	0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d,
+	0x65, 0x64, 0x52, 0x65, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d,
+	0x65, 0x64, 0x52, 0x65, 0x74, 0x72, 0x79, 0x1a, 0x9b, 0x01, 0x0a, 0x07, 0x43, 0x6c, 0x61, 0x73,
+	0x73, 0x42, 0x43, 0x12, 0x45, 0x0a, 0x08, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x18,
+	0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+	0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x42, 0x43, 0x47, 0x61,
+	0x74, 0x65, 0x77, 0x61, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73,
+	0x52, 0x08, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x73, 0x12, 0x3f, 0x0a, 0x0d, 0x61, 0x62,
+	0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x61,
+	0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x3a, 0x08, 0xf2, 0xaa, 0x19,
+	0x04, 0x08, 0x01, 0x10, 0x01, 0x1a, 0x80, 0x01, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72,
+	0x6d, 0x65, 0x64, 0x52, 0x65, 0x74, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x74, 0x74, 0x65,
+	0x6d, 0x70, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x61, 0x74, 0x74, 0x65, 0x6d,
+	0x70, 0x74, 0x12, 0x4a, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x5f, 0x61, 0x74, 0x74, 0x65, 0x6d, 0x70,
+	0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33,
+	0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x2a, 0x04, 0x18, 0x64, 0x20,
+	0x00, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x41, 0x74, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x73, 0x3a, 0x08,
+	0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01,
+	0x10, 0x01, 0x22, 0x59, 0x0a, 0x14, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x41, 0x0a, 0x09, 0x64, 0x6f,
+	0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e,
+	0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41,
+	0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
+	0x6e, 0x6b, 0x52, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x22, 0xae, 0x01,
+	0x0a, 0x19, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77,
+	0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x49, 0x0a, 0x08, 0x64,
+	0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e,
+	0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41,
+	0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
+	0x6e, 0x6b, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x64, 0x6f,
+	0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x3c, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+	0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44, 0x65, 0x74, 0x61,
+	0x69, 0x6c, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x65,
+	0x72, 0x72, 0x6f, 0x72, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x22, 0xc5,
+	0x01, 0x0a, 0x1f, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e,
+	0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e,
+	0x6b, 0x73, 0x12, 0x41, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18,
+	0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+	0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x52, 0x09, 0x64, 0x6f, 0x77, 0x6e,
+	0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x25, 0x0a, 0x0f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x66, 0x5f,
+	0x63, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c,
+	0x6c, 0x61, 0x73, 0x74, 0x46, 0x43, 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x12, 0x2e, 0x0a, 0x0e,
+	0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x03,
+	0x20, 0x01, 0x28, 0x0c, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x7a, 0x03, 0x18, 0x80, 0x10, 0x52, 0x0c,
+	0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x3a, 0x08, 0xf2, 0xaa,
+	0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x22, 0x91, 0x05, 0x0a, 0x22, 0x44, 0x6f, 0x77, 0x6e, 0x6c,
+	0x69, 0x6e, 0x6b, 0x51, 0x75, 0x65, 0x75, 0x65, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x12, 0xc8, 0x01,
+	0x0a, 0x08, 0x64, 0x65, 0x76, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
+	0x42, 0xac, 0x01, 0x92, 0x41, 0x19, 0x4a, 0x0a, 0x22, 0x32, 0x36, 0x30, 0x30, 0x41, 0x42, 0x43,
+	0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xfa,
+	0x42, 0x06, 0x7a, 0x04, 0x68, 0x04, 0x70, 0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a, 0x3f, 0x67,
+	0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77,
+	0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63,
+	0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d,
+	0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x3f,
 	0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74,
 	0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61,
 	0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e,
-	0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12,
-	0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65,
-	0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74,
-	0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73,
-	0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x34, 0x42, 0x79, 0x74, 0x65, 0x73,
-	0x52, 0x07, 0x64, 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x12, 0x2e, 0x0a, 0x0e, 0x73, 0x65, 0x73,
-	0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
-	0x0c, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x7a, 0x03, 0x18, 0x80, 0x10, 0x52, 0x0c, 0x73, 0x65, 0x73,
-	0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0e, 0x6d, 0x69, 0x6e,
-	0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x0d, 0x52, 0x0b, 0x6d, 0x69, 0x6e, 0x46, 0x43, 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x12, 0xd7,
-	0x01, 0x0a, 0x10, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x76, 0x5f, 0x61,
-	0x64, 0x64, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xac, 0x01, 0x92, 0x41, 0x19, 0x4a,
-	0x0a, 0x22, 0x32, 0x36, 0x30, 0x30, 0x41, 0x42, 0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2,
-	0x02, 0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x04, 0x70,
-	0x01, 0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68,
+	0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x34, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52,
+	0x07, 0x64, 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x12, 0x2e, 0x0a, 0x0e, 0x73, 0x65, 0x73, 0x73,
+	0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c,
+	0x42, 0x08, 0xfa, 0x42, 0x05, 0x7a, 0x03, 0x18, 0x80, 0x10, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73,
+	0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0e, 0x6d, 0x69, 0x6e, 0x5f,
+	0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d,
+	0x52, 0x0b, 0x6d, 0x69, 0x6e, 0x46, 0x43, 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x12, 0xd7, 0x01,
+	0x0a, 0x10, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x65, 0x76, 0x5f, 0x61, 0x64,
+	0x64, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x42, 0xac, 0x01, 0x92, 0x41, 0x19, 0x4a, 0x0a,
+	0x22, 0x32, 0x36, 0x30, 0x30, 0x41, 0x42, 0x43, 0x44, 0x22, 0x9a, 0x02, 0x01, 0x07, 0xa2, 0x02,
+	0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xfa, 0x42, 0x06, 0x7a, 0x04, 0x68, 0x04, 0x70, 0x01,
+	0xea, 0xaa, 0x19, 0x82, 0x01, 0x0a, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69,
+	0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61,
+	0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67,
+	0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48, 0x45,
+	0x58, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68,
 	0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72,
 	0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b,
-	0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x61, 0x72, 0x73, 0x68, 0x61, 0x6c, 0x48,
-	0x45, 0x58, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x3f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74,
-	0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f,
-	0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70,
-	0x6b, 0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68,
-	0x61, 0x6c, 0x34, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x0e, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e,
-	0x67, 0x44, 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x12, 0x3d, 0x0a, 0x16, 0x70, 0x65, 0x6e, 0x64,
-	0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f,
-	0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x7a, 0x03, 0x18,
-	0x80, 0x10, 0x52, 0x13, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69,
-	0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x16, 0x70, 0x65, 0x6e, 0x64, 0x69,
-	0x6e, 0x67, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77,
-	0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67,
-	0x4d, 0x69, 0x6e, 0x46, 0x43, 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x22, 0x69, 0x0a, 0x16, 0x41,
-	0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
-	0x2b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
-	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
-	0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x08, 0xf2, 0xaa,
-	0x19, 0x04, 0x08, 0x01, 0x10, 0x00, 0x22, 0x94, 0x09, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x69,
-	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x12, 0x54, 0x0a, 0x0e, 0x65, 0x6e, 0x64, 0x5f,
-	0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
-	0x33, 0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74,
-	0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01,
-	0x52, 0x0c, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x35,
-	0x0a, 0x0f, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64,
-	0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0c, 0xfa, 0x42, 0x09, 0x92, 0x01, 0x06, 0x22,
-	0x04, 0x72, 0x02, 0x18, 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65,
-	0x64, 0x5f, 0x61, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
-	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d,
-	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64,
-	0x41, 0x74, 0x12, 0x4a, 0x0a, 0x0e, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6d, 0x65, 0x73,
-	0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x74, 0x6e,
-	0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c,
-	0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x48, 0x00, 0x52,
-	0x0d, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x5a,
-	0x0a, 0x11, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69,
-	0x7a, 0x65, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+	0x67, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x55, 0x6e, 0x6d, 0x61, 0x72, 0x73, 0x68, 0x61,
+	0x6c, 0x34, 0x42, 0x79, 0x74, 0x65, 0x73, 0x52, 0x0e, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67,
+	0x44, 0x65, 0x76, 0x41, 0x64, 0x64, 0x72, 0x12, 0x3d, 0x0a, 0x16, 0x70, 0x65, 0x6e, 0x64, 0x69,
+	0x6e, 0x67, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69,
+	0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x7a, 0x03, 0x18, 0x80,
+	0x10, 0x52, 0x13, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f,
+	0x6e, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x16, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e,
+	0x67, 0x5f, 0x6d, 0x69, 0x6e, 0x5f, 0x66, 0x5f, 0x63, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x77, 0x6e,
+	0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x4d,
+	0x69, 0x6e, 0x46, 0x43, 0x6e, 0x74, 0x44, 0x6f, 0x77, 0x6e, 0x22, 0x69, 0x0a, 0x16, 0x41, 0x70,
+	0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x44, 0x61, 0x74, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2b,
+	0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67,
+	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53,
+	0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x08, 0xf2, 0xaa, 0x19,
+	0x04, 0x08, 0x01, 0x10, 0x00, 0x22, 0x94, 0x09, 0x0a, 0x0d, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x12, 0x54, 0x0a, 0x0e, 0x65, 0x6e, 0x64, 0x5f, 0x64,
+	0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x24, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+	0x2e, 0x45, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69,
+	0x66, 0x69, 0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52,
+	0x0c, 0x65, 0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x35, 0x0a,
+	0x0f, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73,
+	0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0c, 0xfa, 0x42, 0x09, 0x92, 0x01, 0x06, 0x22, 0x04,
+	0x72, 0x02, 0x18, 0x64, 0x52, 0x0e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x49, 0x64, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64,
+	0x5f, 0x61, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65,
+	0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x41,
+	0x74, 0x12, 0x4a, 0x0a, 0x0e, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
 	0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69,
-	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x72, 0x6d,
-	0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x48, 0x00, 0x52, 0x10, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b,
-	0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x0b, 0x6a, 0x6f,
-	0x69, 0x6e, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x25, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
-	0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x6f, 0x69, 0x6e,
-	0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x6a, 0x6f, 0x69, 0x6e, 0x41, 0x63,
-	0x63, 0x65, 0x70, 0x74, 0x12, 0x48, 0x0a, 0x0c, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b,
-	0x5f, 0x61, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e,
-	0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c,
-	0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x48,
-	0x00, 0x52, 0x0b, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x63, 0x6b, 0x12, 0x4a,
-	0x0a, 0x0d, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x61, 0x63, 0x6b, 0x18,
-	0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
-	0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x48, 0x00, 0x52, 0x0c, 0x64, 0x6f,
-	0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4e, 0x61, 0x63, 0x6b, 0x12, 0x4a, 0x0a, 0x0d, 0x64, 0x6f,
-	0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
-	0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f,
-	0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x48, 0x00, 0x52, 0x0c, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
-	0x6e, 0x6b, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x54, 0x0a, 0x0f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
-	0x6e, 0x6b, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x29, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
-	0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e,
-	0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x6f,
-	0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x4e, 0x0a, 0x0f,
-	0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x18,
-	0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
-	0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x6f,
-	0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x51, 0x75, 0x65, 0x75, 0x65, 0x64, 0x12, 0x6f, 0x0a, 0x1a,
-	0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x69,
-	0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b,
-	0x32, 0x2f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
-	0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x76,
-	0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b,
-	0x73, 0x48, 0x00, 0x52, 0x18, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x51, 0x75, 0x65,
-	0x75, 0x65, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x4e, 0x0a,
-	0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64,
-	0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72,
-	0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
-	0x69, 0x6f, 0x6e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x6c,
-	0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x12, 0x4b, 0x0a,
-	0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0d, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61,
-	0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x0b, 0x73,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69,
-	0x6d, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73,
-	0x69, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01,
-	0x10, 0x00, 0x42, 0x09, 0x0a, 0x02, 0x75, 0x70, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x22, 0xcc, 0x02,
-	0x0a, 0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64,
-	0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x73, 0x12, 0x4d, 0x0a, 0x0c, 0x75, 0x70,
-	0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e,
-	0x32, 0x20, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
-	0x33, 0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74,
-	0x65, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x75, 0x70,
-	0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x16, 0x75, 0x70, 0x5f,
-	0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65,
-	0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x72, 0x04,
-	0x18, 0x80, 0xc0, 0x02, 0x52, 0x14, 0x75, 0x70, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65,
-	0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x51, 0x0a, 0x0e, 0x64, 0x6f,
-	0x77, 0x6e, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01,
-	0x28, 0x0e, 0x32, 0x20, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
-	0x2e, 0x76, 0x33, 0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61,
-	0x74, 0x74, 0x65, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0d,
-	0x64, 0x6f, 0x77, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x12, 0x43, 0x0a,
-	0x18, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x5f,
-	0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42,
-	0x09, 0xfa, 0x42, 0x06, 0x72, 0x04, 0x18, 0x80, 0xc0, 0x02, 0x52, 0x16, 0x64, 0x6f, 0x77, 0x6e,
-	0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
-	0x65, 0x72, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xbb, 0x01, 0x0a,
-	0x14, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x51, 0x75, 0x65, 0x75, 0x65, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x54, 0x0a, 0x0e, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76,
-	0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e,
-	0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45,
-	0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69,
-	0x65, 0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x65,
-	0x6e, 0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x4d, 0x0a, 0x09, 0x64,
-	0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23,
+	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x48, 0x00, 0x52, 0x0d,
+	0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x5a, 0x0a,
+	0x11, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a,
+	0x65, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c,
+	0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4e, 0x6f, 0x72, 0x6d, 0x61,
+	0x6c, 0x69, 0x7a, 0x65, 0x64, 0x48, 0x00, 0x52, 0x10, 0x75, 0x70, 0x6c, 0x69, 0x6e, 0x6b, 0x4e,
+	0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x48, 0x0a, 0x0b, 0x6a, 0x6f, 0x69,
+	0x6e, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25,
+	0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
+	0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x6f, 0x69, 0x6e, 0x41,
+	0x63, 0x63, 0x65, 0x70, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x6a, 0x6f, 0x69, 0x6e, 0x41, 0x63, 0x63,
+	0x65, 0x70, 0x74, 0x12, 0x48, 0x0a, 0x0c, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f,
+	0x61, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e,
+	0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69,
+	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x48, 0x00,
+	0x52, 0x0b, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x41, 0x63, 0x6b, 0x12, 0x4a, 0x0a,
+	0x0d, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x6e, 0x61, 0x63, 0x6b, 0x18, 0x06,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+	0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x48, 0x00, 0x52, 0x0c, 0x64, 0x6f, 0x77,
+	0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x4e, 0x61, 0x63, 0x6b, 0x12, 0x4a, 0x0a, 0x0d, 0x64, 0x6f, 0x77,
+	0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76,
+	0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77,
+	0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x48, 0x00, 0x52, 0x0c, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e,
+	0x6b, 0x53, 0x65, 0x6e, 0x74, 0x12, 0x54, 0x0a, 0x0f, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e,
+	0x6b, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29,
 	0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e,
 	0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c,
-	0x69, 0x6e, 0x6b, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x92, 0x01, 0x04, 0x10, 0xa0, 0x8d, 0x06, 0x52,
-	0x09, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x2a, 0xa3, 0x01, 0x0a, 0x10, 0x50,
-	0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x12,
-	0x12, 0x0a, 0x0e, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x4e,
-	0x45, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52,
-	0x5f, 0x52, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x4f, 0x52, 0x59, 0x10, 0x01, 0x12, 0x1a, 0x0a,
-	0x16, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52, 0x5f, 0x47, 0x52, 0x50, 0x43, 0x5f,
-	0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x4f, 0x52,
-	0x4d, 0x41, 0x54, 0x54, 0x45, 0x52, 0x5f, 0x4a, 0x41, 0x56, 0x41, 0x53, 0x43, 0x52, 0x49, 0x50,
-	0x54, 0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52,
-	0x5f, 0x43, 0x41, 0x59, 0x45, 0x4e, 0x4e, 0x45, 0x4c, 0x50, 0x50, 0x10, 0x04, 0x1a, 0x11, 0xea,
-	0xaa, 0x19, 0x0d, 0x18, 0x01, 0x2a, 0x09, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52,
-	0x42, 0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73,
-	0x2e, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
-	0x2d, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74,
-	0x6e, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x69, 0x6e, 0x6b, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x6f, 0x77,
+	0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x4e, 0x0a, 0x0f, 0x64,
+	0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x18, 0x09,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77,
+	0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x48, 0x00, 0x52, 0x0e, 0x64, 0x6f, 0x77,
+	0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x51, 0x75, 0x65, 0x75, 0x65, 0x64, 0x12, 0x6f, 0x0a, 0x1a, 0x64,
+	0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x71, 0x75, 0x65, 0x75, 0x65, 0x5f, 0x69, 0x6e,
+	0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32,
+	0x2f, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+	0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x76, 0x61,
+	0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73,
+	0x48, 0x00, 0x52, 0x18, 0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x51, 0x75, 0x65, 0x75,
+	0x65, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x12, 0x4e, 0x0a, 0x0f,
+	0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x18,
+	0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61,
+	0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x6c, 0x6f,
+	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x12, 0x4b, 0x0a, 0x0c,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0d, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x26, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e,
+	0x2e, 0x76, 0x33, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53,
+	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x6d,
+	0x75, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x69,
+	0x6d, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10,
+	0x00, 0x42, 0x09, 0x0a, 0x02, 0x75, 0x70, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x22, 0xcc, 0x02, 0x0a,
+	0x18, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x46,
+	0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x73, 0x12, 0x4d, 0x0a, 0x0c, 0x75, 0x70, 0x5f,
+	0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
+	0x20, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33,
+	0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65,
+	0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x75, 0x70, 0x46,
+	0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x16, 0x75, 0x70, 0x5f, 0x66,
+	0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
+	0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xfa, 0x42, 0x06, 0x72, 0x04, 0x18,
+	0x80, 0xc0, 0x02, 0x52, 0x14, 0x75, 0x70, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72,
+	0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x51, 0x0a, 0x0e, 0x64, 0x6f, 0x77,
+	0x6e, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x0e, 0x32, 0x20, 0x2e, 0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e,
+	0x76, 0x33, 0x2e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74,
+	0x74, 0x65, 0x72, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0d, 0x64,
+	0x6f, 0x77, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x12, 0x43, 0x0a, 0x18,
+	0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x70,
+	0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09,
+	0xfa, 0x42, 0x06, 0x72, 0x04, 0x18, 0x80, 0xc0, 0x02, 0x52, 0x16, 0x64, 0x6f, 0x77, 0x6e, 0x46,
+	0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,
+	0x72, 0x3a, 0x08, 0xf2, 0xaa, 0x19, 0x04, 0x08, 0x01, 0x10, 0x01, 0x22, 0xbb, 0x01, 0x0a, 0x14,
+	0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x51, 0x75, 0x65, 0x75, 0x65, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x54, 0x0a, 0x0e, 0x65, 0x6e, 0x64, 0x5f, 0x64, 0x65, 0x76, 0x69,
+	0x63, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x74,
+	0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e,
+	0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65,
+	0x72, 0x73, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x65, 0x6e,
+	0x64, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x73, 0x12, 0x4d, 0x0a, 0x09, 0x64, 0x6f,
+	0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e,
+	0x74, 0x74, 0x6e, 0x2e, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2e, 0x76, 0x33, 0x2e, 0x41,
+	0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x6f, 0x77, 0x6e, 0x6c, 0x69,
+	0x6e, 0x6b, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x92, 0x01, 0x04, 0x10, 0xa0, 0x8d, 0x06, 0x52, 0x09,
+	0x64, 0x6f, 0x77, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x2a, 0xa3, 0x01, 0x0a, 0x10, 0x50, 0x61,
+	0x79, 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x12, 0x12,
+	0x0a, 0x0e, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x4e, 0x45,
+	0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52, 0x5f,
+	0x52, 0x45, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x4f, 0x52, 0x59, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16,
+	0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52, 0x5f, 0x47, 0x52, 0x50, 0x43, 0x5f, 0x53,
+	0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x4f, 0x52, 0x4d,
+	0x41, 0x54, 0x54, 0x45, 0x52, 0x5f, 0x4a, 0x41, 0x56, 0x41, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54,
+	0x10, 0x03, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52, 0x5f,
+	0x43, 0x41, 0x59, 0x45, 0x4e, 0x4e, 0x45, 0x4c, 0x50, 0x50, 0x10, 0x04, 0x1a, 0x11, 0xea, 0xaa,
+	0x19, 0x0d, 0x18, 0x01, 0x2a, 0x09, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x54, 0x45, 0x52, 0x42,
+	0x31, 0x5a, 0x2f, 0x67, 0x6f, 0x2e, 0x74, 0x68, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x73, 0x2e,
+	0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6f, 0x72, 0x61, 0x77, 0x61, 0x6e, 0x2d,
+	0x73, 0x74, 0x61, 0x63, 0x6b, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x74, 0x74, 0x6e,
+	0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -2666,7 +2761,7 @@ func file_ttn_lorawan_v3_messages_proto_rawDescGZIP() []byte {
 }
 
 var file_ttn_lorawan_v3_messages_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
-var file_ttn_lorawan_v3_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 23)
+var file_ttn_lorawan_v3_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 24)
 var file_ttn_lorawan_v3_messages_proto_goTypes = []interface{}{
 	(PayloadFormatter)(0),                      // 0: ttn.lorawan.v3.PayloadFormatter
 	(TxAcknowledgment_Result)(0),               // 1: ttn.lorawan.v3.TxAcknowledgment.Result
@@ -2675,118 +2770,123 @@ var file_ttn_lorawan_v3_messages_proto_goTypes = []interface{}{
 	(*TxAcknowledgment)(nil),                   // 4: ttn.lorawan.v3.TxAcknowledgment
 	(*GatewayTxAcknowledgment)(nil),            // 5: ttn.lorawan.v3.GatewayTxAcknowledgment
 	(*GatewayUplinkMessage)(nil),               // 6: ttn.lorawan.v3.GatewayUplinkMessage
-	(*ApplicationUplink)(nil),                  // 7: ttn.lorawan.v3.ApplicationUplink
-	(*ApplicationUplinkNormalized)(nil),        // 8: ttn.lorawan.v3.ApplicationUplinkNormalized
-	(*ApplicationLocation)(nil),                // 9: ttn.lorawan.v3.ApplicationLocation
-	(*ApplicationJoinAccept)(nil),              // 10: ttn.lorawan.v3.ApplicationJoinAccept
-	(*ApplicationDownlink)(nil),                // 11: ttn.lorawan.v3.ApplicationDownlink
-	(*ApplicationDownlinks)(nil),               // 12: ttn.lorawan.v3.ApplicationDownlinks
-	(*ApplicationDownlinkFailed)(nil),          // 13: ttn.lorawan.v3.ApplicationDownlinkFailed
-	(*ApplicationInvalidatedDownlinks)(nil),    // 14: ttn.lorawan.v3.ApplicationInvalidatedDownlinks
-	(*DownlinkQueueOperationErrorDetails)(nil), // 15: ttn.lorawan.v3.DownlinkQueueOperationErrorDetails
-	(*ApplicationServiceData)(nil),             // 16: ttn.lorawan.v3.ApplicationServiceData
-	(*ApplicationUp)(nil),                      // 17: ttn.lorawan.v3.ApplicationUp
-	(*MessagePayloadFormatters)(nil),           // 18: ttn.lorawan.v3.MessagePayloadFormatters
-	(*DownlinkQueueRequest)(nil),               // 19: ttn.lorawan.v3.DownlinkQueueRequest
-	nil,                                        // 20: ttn.lorawan.v3.ApplicationUplink.LocationsEntry
-	nil,                                        // 21: ttn.lorawan.v3.ApplicationUplinkNormalized.LocationsEntry
-	nil,                                        // 22: ttn.lorawan.v3.ApplicationLocation.AttributesEntry
-	(*ApplicationDownlink_ClassBC)(nil),        // 23: ttn.lorawan.v3.ApplicationDownlink.ClassBC
-	(*ApplicationDownlink_ConfirmedRetry)(nil), // 24: ttn.lorawan.v3.ApplicationDownlink.ConfirmedRetry
-	(*Message)(nil),                            // 25: ttn.lorawan.v3.Message
-	(*TxSettings)(nil),                         // 26: ttn.lorawan.v3.TxSettings
-	(*RxMetadata)(nil),                         // 27: ttn.lorawan.v3.RxMetadata
-	(*timestamppb.Timestamp)(nil),              // 28: google.protobuf.Timestamp
-	(*durationpb.Duration)(nil),                // 29: google.protobuf.Duration
-	(*wrapperspb.BoolValue)(nil),               // 30: google.protobuf.BoolValue
-	(*EndDeviceIdentifiers)(nil),               // 31: ttn.lorawan.v3.EndDeviceIdentifiers
-	(*TxRequest)(nil),                          // 32: ttn.lorawan.v3.TxRequest
-	(*GatewayIdentifiers)(nil),                 // 33: ttn.lorawan.v3.GatewayIdentifiers
-	(*structpb.Struct)(nil),                    // 34: google.protobuf.Struct
-	(*KeyEnvelope)(nil),                        // 35: ttn.lorawan.v3.KeyEnvelope
-	(*EndDeviceVersionIdentifiers)(nil),        // 36: ttn.lorawan.v3.EndDeviceVersionIdentifiers
-	(*NetworkIdentifiers)(nil),                 // 37: ttn.lorawan.v3.NetworkIdentifiers
-	(*Location)(nil),                           // 38: ttn.lorawan.v3.Location
-	(TxSchedulePriority)(0),                    // 39: ttn.lorawan.v3.TxSchedulePriority
-	(*ErrorDetails)(nil),                       // 40: ttn.lorawan.v3.ErrorDetails
-	(*ClassBCGatewayIdentifiers)(nil),          // 41: ttn.lorawan.v3.ClassBCGatewayIdentifiers
-	(*wrapperspb.UInt32Value)(nil),             // 42: google.protobuf.UInt32Value
+	(*LastBatteryPercentage)(nil),              // 7: ttn.lorawan.v3.LastBatteryPercentage
+	(*ApplicationUplink)(nil),                  // 8: ttn.lorawan.v3.ApplicationUplink
+	(*ApplicationUplinkNormalized)(nil),        // 9: ttn.lorawan.v3.ApplicationUplinkNormalized
+	(*ApplicationLocation)(nil),                // 10: ttn.lorawan.v3.ApplicationLocation
+	(*ApplicationJoinAccept)(nil),              // 11: ttn.lorawan.v3.ApplicationJoinAccept
+	(*ApplicationDownlink)(nil),                // 12: ttn.lorawan.v3.ApplicationDownlink
+	(*ApplicationDownlinks)(nil),               // 13: ttn.lorawan.v3.ApplicationDownlinks
+	(*ApplicationDownlinkFailed)(nil),          // 14: ttn.lorawan.v3.ApplicationDownlinkFailed
+	(*ApplicationInvalidatedDownlinks)(nil),    // 15: ttn.lorawan.v3.ApplicationInvalidatedDownlinks
+	(*DownlinkQueueOperationErrorDetails)(nil), // 16: ttn.lorawan.v3.DownlinkQueueOperationErrorDetails
+	(*ApplicationServiceData)(nil),             // 17: ttn.lorawan.v3.ApplicationServiceData
+	(*ApplicationUp)(nil),                      // 18: ttn.lorawan.v3.ApplicationUp
+	(*MessagePayloadFormatters)(nil),           // 19: ttn.lorawan.v3.MessagePayloadFormatters
+	(*DownlinkQueueRequest)(nil),               // 20: ttn.lorawan.v3.DownlinkQueueRequest
+	nil,                                        // 21: ttn.lorawan.v3.ApplicationUplink.LocationsEntry
+	nil,                                        // 22: ttn.lorawan.v3.ApplicationUplinkNormalized.LocationsEntry
+	nil,                                        // 23: ttn.lorawan.v3.ApplicationLocation.AttributesEntry
+	(*ApplicationDownlink_ClassBC)(nil),        // 24: ttn.lorawan.v3.ApplicationDownlink.ClassBC
+	(*ApplicationDownlink_ConfirmedRetry)(nil), // 25: ttn.lorawan.v3.ApplicationDownlink.ConfirmedRetry
+	(*Message)(nil),                            // 26: ttn.lorawan.v3.Message
+	(*TxSettings)(nil),                         // 27: ttn.lorawan.v3.TxSettings
+	(*RxMetadata)(nil),                         // 28: ttn.lorawan.v3.RxMetadata
+	(*timestamppb.Timestamp)(nil),              // 29: google.protobuf.Timestamp
+	(*durationpb.Duration)(nil),                // 30: google.protobuf.Duration
+	(*wrapperspb.BoolValue)(nil),               // 31: google.protobuf.BoolValue
+	(*EndDeviceIdentifiers)(nil),               // 32: ttn.lorawan.v3.EndDeviceIdentifiers
+	(*TxRequest)(nil),                          // 33: ttn.lorawan.v3.TxRequest
+	(*GatewayIdentifiers)(nil),                 // 34: ttn.lorawan.v3.GatewayIdentifiers
+	(*wrapperspb.FloatValue)(nil),              // 35: google.protobuf.FloatValue
+	(*structpb.Struct)(nil),                    // 36: google.protobuf.Struct
+	(*KeyEnvelope)(nil),                        // 37: ttn.lorawan.v3.KeyEnvelope
+	(*EndDeviceVersionIdentifiers)(nil),        // 38: ttn.lorawan.v3.EndDeviceVersionIdentifiers
+	(*NetworkIdentifiers)(nil),                 // 39: ttn.lorawan.v3.NetworkIdentifiers
+	(*Location)(nil),                           // 40: ttn.lorawan.v3.Location
+	(TxSchedulePriority)(0),                    // 41: ttn.lorawan.v3.TxSchedulePriority
+	(*ErrorDetails)(nil),                       // 42: ttn.lorawan.v3.ErrorDetails
+	(*ClassBCGatewayIdentifiers)(nil),          // 43: ttn.lorawan.v3.ClassBCGatewayIdentifiers
+	(*wrapperspb.UInt32Value)(nil),             // 44: google.protobuf.UInt32Value
 }
 var file_ttn_lorawan_v3_messages_proto_depIdxs = []int32{
-	25, // 0: ttn.lorawan.v3.UplinkMessage.payload:type_name -> ttn.lorawan.v3.Message
-	26, // 1: ttn.lorawan.v3.UplinkMessage.settings:type_name -> ttn.lorawan.v3.TxSettings
-	27, // 2: ttn.lorawan.v3.UplinkMessage.rx_metadata:type_name -> ttn.lorawan.v3.RxMetadata
-	28, // 3: ttn.lorawan.v3.UplinkMessage.received_at:type_name -> google.protobuf.Timestamp
-	29, // 4: ttn.lorawan.v3.UplinkMessage.consumed_airtime:type_name -> google.protobuf.Duration
-	30, // 5: ttn.lorawan.v3.UplinkMessage.crc_status:type_name -> google.protobuf.BoolValue
-	25, // 6: ttn.lorawan.v3.DownlinkMessage.payload:type_name -> ttn.lorawan.v3.Message
-	31, // 7: ttn.lorawan.v3.DownlinkMessage.end_device_ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
-	32, // 8: ttn.lorawan.v3.DownlinkMessage.request:type_name -> ttn.lorawan.v3.TxRequest
-	26, // 9: ttn.lorawan.v3.DownlinkMessage.scheduled:type_name -> ttn.lorawan.v3.TxSettings
+	26, // 0: ttn.lorawan.v3.UplinkMessage.payload:type_name -> ttn.lorawan.v3.Message
+	27, // 1: ttn.lorawan.v3.UplinkMessage.settings:type_name -> ttn.lorawan.v3.TxSettings
+	28, // 2: ttn.lorawan.v3.UplinkMessage.rx_metadata:type_name -> ttn.lorawan.v3.RxMetadata
+	29, // 3: ttn.lorawan.v3.UplinkMessage.received_at:type_name -> google.protobuf.Timestamp
+	30, // 4: ttn.lorawan.v3.UplinkMessage.consumed_airtime:type_name -> google.protobuf.Duration
+	31, // 5: ttn.lorawan.v3.UplinkMessage.crc_status:type_name -> google.protobuf.BoolValue
+	26, // 6: ttn.lorawan.v3.DownlinkMessage.payload:type_name -> ttn.lorawan.v3.Message
+	32, // 7: ttn.lorawan.v3.DownlinkMessage.end_device_ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
+	33, // 8: ttn.lorawan.v3.DownlinkMessage.request:type_name -> ttn.lorawan.v3.TxRequest
+	27, // 9: ttn.lorawan.v3.DownlinkMessage.scheduled:type_name -> ttn.lorawan.v3.TxSettings
 	1,  // 10: ttn.lorawan.v3.TxAcknowledgment.result:type_name -> ttn.lorawan.v3.TxAcknowledgment.Result
 	3,  // 11: ttn.lorawan.v3.TxAcknowledgment.downlink_message:type_name -> ttn.lorawan.v3.DownlinkMessage
-	33, // 12: ttn.lorawan.v3.GatewayTxAcknowledgment.gateway_ids:type_name -> ttn.lorawan.v3.GatewayIdentifiers
+	34, // 12: ttn.lorawan.v3.GatewayTxAcknowledgment.gateway_ids:type_name -> ttn.lorawan.v3.GatewayIdentifiers
 	4,  // 13: ttn.lorawan.v3.GatewayTxAcknowledgment.tx_ack:type_name -> ttn.lorawan.v3.TxAcknowledgment
 	2,  // 14: ttn.lorawan.v3.GatewayUplinkMessage.message:type_name -> ttn.lorawan.v3.UplinkMessage
-	34, // 15: ttn.lorawan.v3.ApplicationUplink.decoded_payload:type_name -> google.protobuf.Struct
-	34, // 16: ttn.lorawan.v3.ApplicationUplink.normalized_payload:type_name -> google.protobuf.Struct
-	27, // 17: ttn.lorawan.v3.ApplicationUplink.rx_metadata:type_name -> ttn.lorawan.v3.RxMetadata
-	26, // 18: ttn.lorawan.v3.ApplicationUplink.settings:type_name -> ttn.lorawan.v3.TxSettings
-	28, // 19: ttn.lorawan.v3.ApplicationUplink.received_at:type_name -> google.protobuf.Timestamp
-	35, // 20: ttn.lorawan.v3.ApplicationUplink.app_s_key:type_name -> ttn.lorawan.v3.KeyEnvelope
-	29, // 21: ttn.lorawan.v3.ApplicationUplink.consumed_airtime:type_name -> google.protobuf.Duration
-	20, // 22: ttn.lorawan.v3.ApplicationUplink.locations:type_name -> ttn.lorawan.v3.ApplicationUplink.LocationsEntry
-	36, // 23: ttn.lorawan.v3.ApplicationUplink.version_ids:type_name -> ttn.lorawan.v3.EndDeviceVersionIdentifiers
-	37, // 24: ttn.lorawan.v3.ApplicationUplink.network_ids:type_name -> ttn.lorawan.v3.NetworkIdentifiers
-	34, // 25: ttn.lorawan.v3.ApplicationUplinkNormalized.normalized_payload:type_name -> google.protobuf.Struct
-	27, // 26: ttn.lorawan.v3.ApplicationUplinkNormalized.rx_metadata:type_name -> ttn.lorawan.v3.RxMetadata
-	26, // 27: ttn.lorawan.v3.ApplicationUplinkNormalized.settings:type_name -> ttn.lorawan.v3.TxSettings
-	28, // 28: ttn.lorawan.v3.ApplicationUplinkNormalized.received_at:type_name -> google.protobuf.Timestamp
-	29, // 29: ttn.lorawan.v3.ApplicationUplinkNormalized.consumed_airtime:type_name -> google.protobuf.Duration
-	21, // 30: ttn.lorawan.v3.ApplicationUplinkNormalized.locations:type_name -> ttn.lorawan.v3.ApplicationUplinkNormalized.LocationsEntry
-	36, // 31: ttn.lorawan.v3.ApplicationUplinkNormalized.version_ids:type_name -> ttn.lorawan.v3.EndDeviceVersionIdentifiers
-	37, // 32: ttn.lorawan.v3.ApplicationUplinkNormalized.network_ids:type_name -> ttn.lorawan.v3.NetworkIdentifiers
-	38, // 33: ttn.lorawan.v3.ApplicationLocation.location:type_name -> ttn.lorawan.v3.Location
-	22, // 34: ttn.lorawan.v3.ApplicationLocation.attributes:type_name -> ttn.lorawan.v3.ApplicationLocation.AttributesEntry
-	35, // 35: ttn.lorawan.v3.ApplicationJoinAccept.app_s_key:type_name -> ttn.lorawan.v3.KeyEnvelope
-	11, // 36: ttn.lorawan.v3.ApplicationJoinAccept.invalidated_downlinks:type_name -> ttn.lorawan.v3.ApplicationDownlink
-	28, // 37: ttn.lorawan.v3.ApplicationJoinAccept.received_at:type_name -> google.protobuf.Timestamp
-	34, // 38: ttn.lorawan.v3.ApplicationDownlink.decoded_payload:type_name -> google.protobuf.Struct
-	23, // 39: ttn.lorawan.v3.ApplicationDownlink.class_b_c:type_name -> ttn.lorawan.v3.ApplicationDownlink.ClassBC
-	39, // 40: ttn.lorawan.v3.ApplicationDownlink.priority:type_name -> ttn.lorawan.v3.TxSchedulePriority
-	24, // 41: ttn.lorawan.v3.ApplicationDownlink.confirmed_retry:type_name -> ttn.lorawan.v3.ApplicationDownlink.ConfirmedRetry
-	11, // 42: ttn.lorawan.v3.ApplicationDownlinks.downlinks:type_name -> ttn.lorawan.v3.ApplicationDownlink
-	11, // 43: ttn.lorawan.v3.ApplicationDownlinkFailed.downlink:type_name -> ttn.lorawan.v3.ApplicationDownlink
-	40, // 44: ttn.lorawan.v3.ApplicationDownlinkFailed.error:type_name -> ttn.lorawan.v3.ErrorDetails
-	11, // 45: ttn.lorawan.v3.ApplicationInvalidatedDownlinks.downlinks:type_name -> ttn.lorawan.v3.ApplicationDownlink
-	34, // 46: ttn.lorawan.v3.ApplicationServiceData.data:type_name -> google.protobuf.Struct
-	31, // 47: ttn.lorawan.v3.ApplicationUp.end_device_ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
-	28, // 48: ttn.lorawan.v3.ApplicationUp.received_at:type_name -> google.protobuf.Timestamp
-	7,  // 49: ttn.lorawan.v3.ApplicationUp.uplink_message:type_name -> ttn.lorawan.v3.ApplicationUplink
-	8,  // 50: ttn.lorawan.v3.ApplicationUp.uplink_normalized:type_name -> ttn.lorawan.v3.ApplicationUplinkNormalized
-	10, // 51: ttn.lorawan.v3.ApplicationUp.join_accept:type_name -> ttn.lorawan.v3.ApplicationJoinAccept
-	11, // 52: ttn.lorawan.v3.ApplicationUp.downlink_ack:type_name -> ttn.lorawan.v3.ApplicationDownlink
-	11, // 53: ttn.lorawan.v3.ApplicationUp.downlink_nack:type_name -> ttn.lorawan.v3.ApplicationDownlink
-	11, // 54: ttn.lorawan.v3.ApplicationUp.downlink_sent:type_name -> ttn.lorawan.v3.ApplicationDownlink
-	13, // 55: ttn.lorawan.v3.ApplicationUp.downlink_failed:type_name -> ttn.lorawan.v3.ApplicationDownlinkFailed
-	11, // 56: ttn.lorawan.v3.ApplicationUp.downlink_queued:type_name -> ttn.lorawan.v3.ApplicationDownlink
-	14, // 57: ttn.lorawan.v3.ApplicationUp.downlink_queue_invalidated:type_name -> ttn.lorawan.v3.ApplicationInvalidatedDownlinks
-	9,  // 58: ttn.lorawan.v3.ApplicationUp.location_solved:type_name -> ttn.lorawan.v3.ApplicationLocation
-	16, // 59: ttn.lorawan.v3.ApplicationUp.service_data:type_name -> ttn.lorawan.v3.ApplicationServiceData
-	0,  // 60: ttn.lorawan.v3.MessagePayloadFormatters.up_formatter:type_name -> ttn.lorawan.v3.PayloadFormatter
-	0,  // 61: ttn.lorawan.v3.MessagePayloadFormatters.down_formatter:type_name -> ttn.lorawan.v3.PayloadFormatter
-	31, // 62: ttn.lorawan.v3.DownlinkQueueRequest.end_device_ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
-	11, // 63: ttn.lorawan.v3.DownlinkQueueRequest.downlinks:type_name -> ttn.lorawan.v3.ApplicationDownlink
-	38, // 64: ttn.lorawan.v3.ApplicationUplink.LocationsEntry.value:type_name -> ttn.lorawan.v3.Location
-	38, // 65: ttn.lorawan.v3.ApplicationUplinkNormalized.LocationsEntry.value:type_name -> ttn.lorawan.v3.Location
-	41, // 66: ttn.lorawan.v3.ApplicationDownlink.ClassBC.gateways:type_name -> ttn.lorawan.v3.ClassBCGatewayIdentifiers
-	28, // 67: ttn.lorawan.v3.ApplicationDownlink.ClassBC.absolute_time:type_name -> google.protobuf.Timestamp
-	42, // 68: ttn.lorawan.v3.ApplicationDownlink.ConfirmedRetry.max_attempts:type_name -> google.protobuf.UInt32Value
-	69, // [69:69] is the sub-list for method output_type
-	69, // [69:69] is the sub-list for method input_type
-	69, // [69:69] is the sub-list for extension type_name
-	69, // [69:69] is the sub-list for extension extendee
-	0,  // [0:69] is the sub-list for field type_name
+	35, // 15: ttn.lorawan.v3.LastBatteryPercentage.value:type_name -> google.protobuf.FloatValue
+	29, // 16: ttn.lorawan.v3.LastBatteryPercentage.received_at:type_name -> google.protobuf.Timestamp
+	36, // 17: ttn.lorawan.v3.ApplicationUplink.decoded_payload:type_name -> google.protobuf.Struct
+	36, // 18: ttn.lorawan.v3.ApplicationUplink.normalized_payload:type_name -> google.protobuf.Struct
+	28, // 19: ttn.lorawan.v3.ApplicationUplink.rx_metadata:type_name -> ttn.lorawan.v3.RxMetadata
+	27, // 20: ttn.lorawan.v3.ApplicationUplink.settings:type_name -> ttn.lorawan.v3.TxSettings
+	29, // 21: ttn.lorawan.v3.ApplicationUplink.received_at:type_name -> google.protobuf.Timestamp
+	37, // 22: ttn.lorawan.v3.ApplicationUplink.app_s_key:type_name -> ttn.lorawan.v3.KeyEnvelope
+	30, // 23: ttn.lorawan.v3.ApplicationUplink.consumed_airtime:type_name -> google.protobuf.Duration
+	21, // 24: ttn.lorawan.v3.ApplicationUplink.locations:type_name -> ttn.lorawan.v3.ApplicationUplink.LocationsEntry
+	38, // 25: ttn.lorawan.v3.ApplicationUplink.version_ids:type_name -> ttn.lorawan.v3.EndDeviceVersionIdentifiers
+	39, // 26: ttn.lorawan.v3.ApplicationUplink.network_ids:type_name -> ttn.lorawan.v3.NetworkIdentifiers
+	7,  // 27: ttn.lorawan.v3.ApplicationUplink.last_battery_percentage:type_name -> ttn.lorawan.v3.LastBatteryPercentage
+	36, // 28: ttn.lorawan.v3.ApplicationUplinkNormalized.normalized_payload:type_name -> google.protobuf.Struct
+	28, // 29: ttn.lorawan.v3.ApplicationUplinkNormalized.rx_metadata:type_name -> ttn.lorawan.v3.RxMetadata
+	27, // 30: ttn.lorawan.v3.ApplicationUplinkNormalized.settings:type_name -> ttn.lorawan.v3.TxSettings
+	29, // 31: ttn.lorawan.v3.ApplicationUplinkNormalized.received_at:type_name -> google.protobuf.Timestamp
+	30, // 32: ttn.lorawan.v3.ApplicationUplinkNormalized.consumed_airtime:type_name -> google.protobuf.Duration
+	22, // 33: ttn.lorawan.v3.ApplicationUplinkNormalized.locations:type_name -> ttn.lorawan.v3.ApplicationUplinkNormalized.LocationsEntry
+	38, // 34: ttn.lorawan.v3.ApplicationUplinkNormalized.version_ids:type_name -> ttn.lorawan.v3.EndDeviceVersionIdentifiers
+	39, // 35: ttn.lorawan.v3.ApplicationUplinkNormalized.network_ids:type_name -> ttn.lorawan.v3.NetworkIdentifiers
+	40, // 36: ttn.lorawan.v3.ApplicationLocation.location:type_name -> ttn.lorawan.v3.Location
+	23, // 37: ttn.lorawan.v3.ApplicationLocation.attributes:type_name -> ttn.lorawan.v3.ApplicationLocation.AttributesEntry
+	37, // 38: ttn.lorawan.v3.ApplicationJoinAccept.app_s_key:type_name -> ttn.lorawan.v3.KeyEnvelope
+	12, // 39: ttn.lorawan.v3.ApplicationJoinAccept.invalidated_downlinks:type_name -> ttn.lorawan.v3.ApplicationDownlink
+	29, // 40: ttn.lorawan.v3.ApplicationJoinAccept.received_at:type_name -> google.protobuf.Timestamp
+	36, // 41: ttn.lorawan.v3.ApplicationDownlink.decoded_payload:type_name -> google.protobuf.Struct
+	24, // 42: ttn.lorawan.v3.ApplicationDownlink.class_b_c:type_name -> ttn.lorawan.v3.ApplicationDownlink.ClassBC
+	41, // 43: ttn.lorawan.v3.ApplicationDownlink.priority:type_name -> ttn.lorawan.v3.TxSchedulePriority
+	25, // 44: ttn.lorawan.v3.ApplicationDownlink.confirmed_retry:type_name -> ttn.lorawan.v3.ApplicationDownlink.ConfirmedRetry
+	12, // 45: ttn.lorawan.v3.ApplicationDownlinks.downlinks:type_name -> ttn.lorawan.v3.ApplicationDownlink
+	12, // 46: ttn.lorawan.v3.ApplicationDownlinkFailed.downlink:type_name -> ttn.lorawan.v3.ApplicationDownlink
+	42, // 47: ttn.lorawan.v3.ApplicationDownlinkFailed.error:type_name -> ttn.lorawan.v3.ErrorDetails
+	12, // 48: ttn.lorawan.v3.ApplicationInvalidatedDownlinks.downlinks:type_name -> ttn.lorawan.v3.ApplicationDownlink
+	36, // 49: ttn.lorawan.v3.ApplicationServiceData.data:type_name -> google.protobuf.Struct
+	32, // 50: ttn.lorawan.v3.ApplicationUp.end_device_ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
+	29, // 51: ttn.lorawan.v3.ApplicationUp.received_at:type_name -> google.protobuf.Timestamp
+	8,  // 52: ttn.lorawan.v3.ApplicationUp.uplink_message:type_name -> ttn.lorawan.v3.ApplicationUplink
+	9,  // 53: ttn.lorawan.v3.ApplicationUp.uplink_normalized:type_name -> ttn.lorawan.v3.ApplicationUplinkNormalized
+	11, // 54: ttn.lorawan.v3.ApplicationUp.join_accept:type_name -> ttn.lorawan.v3.ApplicationJoinAccept
+	12, // 55: ttn.lorawan.v3.ApplicationUp.downlink_ack:type_name -> ttn.lorawan.v3.ApplicationDownlink
+	12, // 56: ttn.lorawan.v3.ApplicationUp.downlink_nack:type_name -> ttn.lorawan.v3.ApplicationDownlink
+	12, // 57: ttn.lorawan.v3.ApplicationUp.downlink_sent:type_name -> ttn.lorawan.v3.ApplicationDownlink
+	14, // 58: ttn.lorawan.v3.ApplicationUp.downlink_failed:type_name -> ttn.lorawan.v3.ApplicationDownlinkFailed
+	12, // 59: ttn.lorawan.v3.ApplicationUp.downlink_queued:type_name -> ttn.lorawan.v3.ApplicationDownlink
+	15, // 60: ttn.lorawan.v3.ApplicationUp.downlink_queue_invalidated:type_name -> ttn.lorawan.v3.ApplicationInvalidatedDownlinks
+	10, // 61: ttn.lorawan.v3.ApplicationUp.location_solved:type_name -> ttn.lorawan.v3.ApplicationLocation
+	17, // 62: ttn.lorawan.v3.ApplicationUp.service_data:type_name -> ttn.lorawan.v3.ApplicationServiceData
+	0,  // 63: ttn.lorawan.v3.MessagePayloadFormatters.up_formatter:type_name -> ttn.lorawan.v3.PayloadFormatter
+	0,  // 64: ttn.lorawan.v3.MessagePayloadFormatters.down_formatter:type_name -> ttn.lorawan.v3.PayloadFormatter
+	32, // 65: ttn.lorawan.v3.DownlinkQueueRequest.end_device_ids:type_name -> ttn.lorawan.v3.EndDeviceIdentifiers
+	12, // 66: ttn.lorawan.v3.DownlinkQueueRequest.downlinks:type_name -> ttn.lorawan.v3.ApplicationDownlink
+	40, // 67: ttn.lorawan.v3.ApplicationUplink.LocationsEntry.value:type_name -> ttn.lorawan.v3.Location
+	40, // 68: ttn.lorawan.v3.ApplicationUplinkNormalized.LocationsEntry.value:type_name -> ttn.lorawan.v3.Location
+	43, // 69: ttn.lorawan.v3.ApplicationDownlink.ClassBC.gateways:type_name -> ttn.lorawan.v3.ClassBCGatewayIdentifiers
+	29, // 70: ttn.lorawan.v3.ApplicationDownlink.ClassBC.absolute_time:type_name -> google.protobuf.Timestamp
+	44, // 71: ttn.lorawan.v3.ApplicationDownlink.ConfirmedRetry.max_attempts:type_name -> google.protobuf.UInt32Value
+	72, // [72:72] is the sub-list for method output_type
+	72, // [72:72] is the sub-list for method input_type
+	72, // [72:72] is the sub-list for extension type_name
+	72, // [72:72] is the sub-list for extension extendee
+	0,  // [0:72] is the sub-list for field type_name
 }
 
 func init() { file_ttn_lorawan_v3_messages_proto_init() }
@@ -2861,7 +2961,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			}
 		}
 		file_ttn_lorawan_v3_messages_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ApplicationUplink); i {
+			switch v := v.(*LastBatteryPercentage); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -2873,7 +2973,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			}
 		}
 		file_ttn_lorawan_v3_messages_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ApplicationUplinkNormalized); i {
+			switch v := v.(*ApplicationUplink); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -2885,7 +2985,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			}
 		}
 		file_ttn_lorawan_v3_messages_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ApplicationLocation); i {
+			switch v := v.(*ApplicationUplinkNormalized); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -2897,7 +2997,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			}
 		}
 		file_ttn_lorawan_v3_messages_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ApplicationJoinAccept); i {
+			switch v := v.(*ApplicationLocation); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -2909,7 +3009,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			}
 		}
 		file_ttn_lorawan_v3_messages_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ApplicationDownlink); i {
+			switch v := v.(*ApplicationJoinAccept); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -2921,7 +3021,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			}
 		}
 		file_ttn_lorawan_v3_messages_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ApplicationDownlinks); i {
+			switch v := v.(*ApplicationDownlink); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -2933,7 +3033,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			}
 		}
 		file_ttn_lorawan_v3_messages_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ApplicationDownlinkFailed); i {
+			switch v := v.(*ApplicationDownlinks); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -2945,7 +3045,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			}
 		}
 		file_ttn_lorawan_v3_messages_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ApplicationInvalidatedDownlinks); i {
+			switch v := v.(*ApplicationDownlinkFailed); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -2957,7 +3057,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			}
 		}
 		file_ttn_lorawan_v3_messages_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*DownlinkQueueOperationErrorDetails); i {
+			switch v := v.(*ApplicationInvalidatedDownlinks); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -2969,7 +3069,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			}
 		}
 		file_ttn_lorawan_v3_messages_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ApplicationServiceData); i {
+			switch v := v.(*DownlinkQueueOperationErrorDetails); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -2981,7 +3081,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			}
 		}
 		file_ttn_lorawan_v3_messages_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*ApplicationUp); i {
+			switch v := v.(*ApplicationServiceData); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -2993,7 +3093,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			}
 		}
 		file_ttn_lorawan_v3_messages_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*MessagePayloadFormatters); i {
+			switch v := v.(*ApplicationUp); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -3005,6 +3105,18 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			}
 		}
 		file_ttn_lorawan_v3_messages_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MessagePayloadFormatters); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ttn_lorawan_v3_messages_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*DownlinkQueueRequest); i {
 			case 0:
 				return &v.state
@@ -3016,7 +3128,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 				return nil
 			}
 		}
-		file_ttn_lorawan_v3_messages_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
+		file_ttn_lorawan_v3_messages_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ApplicationDownlink_ClassBC); i {
 			case 0:
 				return &v.state
@@ -3028,7 +3140,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 				return nil
 			}
 		}
-		file_ttn_lorawan_v3_messages_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+		file_ttn_lorawan_v3_messages_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*ApplicationDownlink_ConfirmedRetry); i {
 			case 0:
 				return &v.state
@@ -3045,7 +3157,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 		(*DownlinkMessage_Request)(nil),
 		(*DownlinkMessage_Scheduled)(nil),
 	}
-	file_ttn_lorawan_v3_messages_proto_msgTypes[15].OneofWrappers = []interface{}{
+	file_ttn_lorawan_v3_messages_proto_msgTypes[16].OneofWrappers = []interface{}{
 		(*ApplicationUp_UplinkMessage)(nil),
 		(*ApplicationUp_UplinkNormalized)(nil),
 		(*ApplicationUp_JoinAccept)(nil),
@@ -3064,7 +3176,7 @@ func file_ttn_lorawan_v3_messages_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_ttn_lorawan_v3_messages_proto_rawDesc,
 			NumEnums:      2,
-			NumMessages:   23,
+			NumMessages:   24,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
diff --git a/pkg/ttnpb/messages.pb.paths.fm.go b/pkg/ttnpb/messages.pb.paths.fm.go
index a214a23716..0dfa9d1d44 100644
--- a/pkg/ttnpb/messages.pb.paths.fm.go
+++ b/pkg/ttnpb/messages.pb.paths.fm.go
@@ -545,6 +545,17 @@ var GatewayUplinkMessageFieldPathsTopLevel = []string{
 	"band_id",
 	"message",
 }
+var LastBatteryPercentageFieldPathsNested = []string{
+	"f_cnt",
+	"received_at",
+	"value",
+}
+
+var LastBatteryPercentageFieldPathsTopLevel = []string{
+	"f_cnt",
+	"received_at",
+	"value",
+}
 var ApplicationUplinkFieldPathsNested = []string{
 	"app_s_key",
 	"app_s_key.encrypted_key",
@@ -558,6 +569,10 @@ var ApplicationUplinkFieldPathsNested = []string{
 	"f_port",
 	"frm_payload",
 	"last_a_f_cnt_down",
+	"last_battery_percentage",
+	"last_battery_percentage.f_cnt",
+	"last_battery_percentage.received_at",
+	"last_battery_percentage.value",
 	"locations",
 	"network_ids",
 	"network_ids.cluster_address",
@@ -612,6 +627,7 @@ var ApplicationUplinkFieldPathsTopLevel = []string{
 	"f_port",
 	"frm_payload",
 	"last_a_f_cnt_down",
+	"last_battery_percentage",
 	"locations",
 	"network_ids",
 	"normalized_payload",
@@ -979,6 +995,10 @@ var ApplicationUpFieldPathsNested = []string{
 	"up.uplink_message.f_port",
 	"up.uplink_message.frm_payload",
 	"up.uplink_message.last_a_f_cnt_down",
+	"up.uplink_message.last_battery_percentage",
+	"up.uplink_message.last_battery_percentage.f_cnt",
+	"up.uplink_message.last_battery_percentage.received_at",
+	"up.uplink_message.last_battery_percentage.value",
 	"up.uplink_message.locations",
 	"up.uplink_message.network_ids",
 	"up.uplink_message.network_ids.cluster_address",
diff --git a/pkg/ttnpb/messages.pb.setters.fm.go b/pkg/ttnpb/messages.pb.setters.fm.go
index 7e790005fd..8cfbcff174 100644
--- a/pkg/ttnpb/messages.pb.setters.fm.go
+++ b/pkg/ttnpb/messages.pb.setters.fm.go
@@ -471,6 +471,45 @@ func (dst *GatewayUplinkMessage) SetFields(src *GatewayUplinkMessage, paths ...s
 	return nil
 }
 
+func (dst *LastBatteryPercentage) SetFields(src *LastBatteryPercentage, paths ...string) error {
+	for name, subs := range _processPaths(paths) {
+		switch name {
+		case "f_cnt":
+			if len(subs) > 0 {
+				return fmt.Errorf("'f_cnt' has no subfields, but %s were specified", subs)
+			}
+			if src != nil {
+				dst.FCnt = src.FCnt
+			} else {
+				var zero uint32
+				dst.FCnt = zero
+			}
+		case "value":
+			if len(subs) > 0 {
+				return fmt.Errorf("'value' has no subfields, but %s were specified", subs)
+			}
+			if src != nil {
+				dst.Value = src.Value
+			} else {
+				dst.Value = nil
+			}
+		case "received_at":
+			if len(subs) > 0 {
+				return fmt.Errorf("'received_at' has no subfields, but %s were specified", subs)
+			}
+			if src != nil {
+				dst.ReceivedAt = src.ReceivedAt
+			} else {
+				dst.ReceivedAt = nil
+			}
+
+		default:
+			return fmt.Errorf("invalid field: '%s'", name)
+		}
+	}
+	return nil
+}
+
 func (dst *ApplicationUplink) SetFields(src *ApplicationUplink, paths ...string) error {
 	for name, subs := range _processPaths(paths) {
 		switch name {
@@ -714,6 +753,31 @@ func (dst *ApplicationUplink) SetFields(src *ApplicationUplink, paths ...string)
 					dst.NetworkIds = nil
 				}
 			}
+		case "last_battery_percentage":
+			if len(subs) > 0 {
+				var newDst, newSrc *LastBatteryPercentage
+				if (src == nil || src.LastBatteryPercentage == nil) && dst.LastBatteryPercentage == nil {
+					continue
+				}
+				if src != nil {
+					newSrc = src.LastBatteryPercentage
+				}
+				if dst.LastBatteryPercentage != nil {
+					newDst = dst.LastBatteryPercentage
+				} else {
+					newDst = &LastBatteryPercentage{}
+					dst.LastBatteryPercentage = newDst
+				}
+				if err := newDst.SetFields(newSrc, subs...); err != nil {
+					return err
+				}
+			} else {
+				if src != nil {
+					dst.LastBatteryPercentage = src.LastBatteryPercentage
+				} else {
+					dst.LastBatteryPercentage = nil
+				}
+			}
 
 		default:
 			return fmt.Errorf("invalid field: '%s'", name)
diff --git a/pkg/ttnpb/messages.pb.validate.go b/pkg/ttnpb/messages.pb.validate.go
index fafe2734b0..481207135a 100644
--- a/pkg/ttnpb/messages.pb.validate.go
+++ b/pkg/ttnpb/messages.pb.validate.go
@@ -718,6 +718,114 @@ var _ interface {
 	ErrorName() string
 } = GatewayUplinkMessageValidationError{}
 
+// ValidateFields checks the field values on LastBatteryPercentage with the
+// rules defined in the proto definition for this message. If any rules are
+// violated, an error is returned.
+func (m *LastBatteryPercentage) ValidateFields(paths ...string) error {
+	if m == nil {
+		return nil
+	}
+
+	if len(paths) == 0 {
+		paths = LastBatteryPercentageFieldPathsNested
+	}
+
+	for name, subs := range _processPaths(append(paths[:0:0], paths...)) {
+		_ = subs
+		switch name {
+		case "f_cnt":
+			// no validation rules for FCnt
+		case "value":
+
+			if wrapper := m.GetValue(); wrapper != nil {
+
+				if val := wrapper.GetValue(); val < 0 || val > 1 {
+					return LastBatteryPercentageValidationError{
+						field:  "value",
+						reason: "value must be inside range [0, 1]",
+					}
+				}
+
+			}
+
+		case "received_at":
+
+			if v, ok := interface{}(m.GetReceivedAt()).(interface{ ValidateFields(...string) error }); ok {
+				if err := v.ValidateFields(subs...); err != nil {
+					return LastBatteryPercentageValidationError{
+						field:  "received_at",
+						reason: "embedded message failed validation",
+						cause:  err,
+					}
+				}
+			}
+
+		default:
+			return LastBatteryPercentageValidationError{
+				field:  name,
+				reason: "invalid field path",
+			}
+		}
+	}
+	return nil
+}
+
+// LastBatteryPercentageValidationError is the validation error returned by
+// LastBatteryPercentage.ValidateFields if the designated constraints aren't met.
+type LastBatteryPercentageValidationError struct {
+	field  string
+	reason string
+	cause  error
+	key    bool
+}
+
+// Field function returns field value.
+func (e LastBatteryPercentageValidationError) Field() string { return e.field }
+
+// Reason function returns reason value.
+func (e LastBatteryPercentageValidationError) Reason() string { return e.reason }
+
+// Cause function returns cause value.
+func (e LastBatteryPercentageValidationError) Cause() error { return e.cause }
+
+// Key function returns key value.
+func (e LastBatteryPercentageValidationError) Key() bool { return e.key }
+
+// ErrorName returns error name.
+func (e LastBatteryPercentageValidationError) ErrorName() string {
+	return "LastBatteryPercentageValidationError"
+}
+
+// Error satisfies the builtin error interface
+func (e LastBatteryPercentageValidationError) Error() string {
+	cause := ""
+	if e.cause != nil {
+		cause = fmt.Sprintf(" | caused by: %v", e.cause)
+	}
+
+	key := ""
+	if e.key {
+		key = "key for "
+	}
+
+	return fmt.Sprintf(
+		"invalid %sLastBatteryPercentage.%s: %s%s",
+		key,
+		e.field,
+		e.reason,
+		cause)
+}
+
+var _ error = LastBatteryPercentageValidationError{}
+
+var _ interface {
+	Field() string
+	Reason() string
+	Key() bool
+	Cause() error
+	ErrorName() string
+} = LastBatteryPercentageValidationError{}
+
 // ValidateFields checks the field values on ApplicationUplink with the rules
 // defined in the proto definition for this message. If any rules are
 // violated, an error is returned.
@@ -916,6 +1024,18 @@ func (m *ApplicationUplink) ValidateFields(paths ...string) error {
 				}
 			}
 
+		case "last_battery_percentage":
+
+			if v, ok := interface{}(m.GetLastBatteryPercentage()).(interface{ ValidateFields(...string) error }); ok {
+				if err := v.ValidateFields(subs...); err != nil {
+					return ApplicationUplinkValidationError{
+						field:  "last_battery_percentage",
+						reason: "embedded message failed validation",
+						cause:  err,
+					}
+				}
+			}
+
 		default:
 			return ApplicationUplinkValidationError{
 				field:  name,
diff --git a/pkg/ttnpb/messages_flags.pb.go b/pkg/ttnpb/messages_flags.pb.go
index 45c12c6541..ead7ad98e1 100644
--- a/pkg/ttnpb/messages_flags.pb.go
+++ b/pkg/ttnpb/messages_flags.pb.go
@@ -38,6 +38,8 @@ func AddSelectFlagsForApplicationUplink(flags *pflag.FlagSet, prefix string, hid
 	AddSelectFlagsForEndDeviceVersionIdentifiers(flags, flagsplugin.Prefix("version-ids", prefix), hidden)
 	flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("network-ids", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("network-ids", prefix), true), flagsplugin.WithHidden(hidden)))
 	AddSelectFlagsForNetworkIdentifiers(flags, flagsplugin.Prefix("network-ids", prefix), hidden)
+	flags.AddFlag(flagsplugin.NewBoolFlag(flagsplugin.Prefix("last-battery-percentage", prefix), flagsplugin.SelectDesc(flagsplugin.Prefix("last-battery-percentage", prefix), true), flagsplugin.WithHidden(hidden)))
+	// NOTE: last_battery_percentage (LastBatteryPercentage) does not seem to have select flags.
 }
 
 // SelectFromFlags outputs the fieldmask paths forApplicationUplink message from select flags.
@@ -157,6 +159,12 @@ func PathsFromSelectFlagsForApplicationUplink(flags *pflag.FlagSet, prefix strin
 	} else {
 		paths = append(paths, selectPaths...)
 	}
+	if val, selected, err := flagsplugin.GetBool(flags, flagsplugin.Prefix("last_battery_percentage", prefix)); err != nil {
+		return nil, err
+	} else if selected && val {
+		paths = append(paths, flagsplugin.Prefix("last_battery_percentage", prefix))
+	}
+	// NOTE: last_battery_percentage (LastBatteryPercentage) does not seem to have select flags.
 	return paths, nil
 }
 
@@ -181,6 +189,7 @@ func AddSetFlagsForApplicationUplink(flags *pflag.FlagSet, prefix string, hidden
 	// FIXME: Skipping Locations because maps with message value types are currently not supported.
 	AddSetFlagsForEndDeviceVersionIdentifiers(flags, flagsplugin.Prefix("version-ids", prefix), hidden)
 	AddSetFlagsForNetworkIdentifiers(flags, flagsplugin.Prefix("network-ids", prefix), hidden)
+	// FIXME: Skipping LastBatteryPercentage because it does not seem to implement AddSetFlags.
 }
 
 // SetFromFlags sets the ApplicationUplink message from flags.
@@ -295,6 +304,7 @@ func (m *ApplicationUplink) SetFromFlags(flags *pflag.FlagSet, prefix string) (p
 			paths = append(paths, setPaths...)
 		}
 	}
+	// FIXME: Skipping LastBatteryPercentage because it does not seem to implement AddSetFlags.
 	return paths, nil
 }
 
diff --git a/pkg/ttnpb/messages_json.pb.go b/pkg/ttnpb/messages_json.pb.go
index 8b69bcf8b3..d73f3c4f35 100644
--- a/pkg/ttnpb/messages_json.pb.go
+++ b/pkg/ttnpb/messages_json.pb.go
@@ -719,6 +719,12 @@ func (x *ApplicationUplink) MarshalProtoJSON(s *jsonplugin.MarshalState) {
 		s.WriteObjectField("network_ids")
 		x.NetworkIds.MarshalProtoJSON(s.WithField("network_ids"))
 	}
+	if x.LastBatteryPercentage != nil || s.HasField("last_battery_percentage") {
+		s.WriteMoreIf(&wroteField)
+		s.WriteObjectField("last_battery_percentage")
+		// NOTE: LastBatteryPercentage does not seem to implement MarshalProtoJSON.
+		golang.MarshalMessage(s, x.LastBatteryPercentage)
+	}
 	s.WriteObjectEnd()
 }
 
@@ -881,6 +887,16 @@ func (x *ApplicationUplink) UnmarshalProtoJSON(s *jsonplugin.UnmarshalState) {
 			}
 			x.NetworkIds = &NetworkIdentifiers{}
 			x.NetworkIds.UnmarshalProtoJSON(s.WithField("network_ids", true))
+		case "last_battery_percentage", "lastBatteryPercentage":
+			s.AddField("last_battery_percentage")
+			if s.ReadNil() {
+				x.LastBatteryPercentage = nil
+				return
+			}
+			// NOTE: LastBatteryPercentage does not seem to implement UnmarshalProtoJSON.
+			var v LastBatteryPercentage
+			golang.UnmarshalMessage(s, &v)
+			x.LastBatteryPercentage = &v
 		}
 	})
 }
diff --git a/sdk/js/generated/api-definition.json b/sdk/js/generated/api-definition.json
index 27bf4962ff..2e234ff95c 100644
--- a/sdk/js/generated/api-definition.json
+++ b/sdk/js/generated/api-definition.json
@@ -877,6 +877,10 @@
         "up.uplink_message.f_port",
         "up.uplink_message.frm_payload",
         "up.uplink_message.last_a_f_cnt_down",
+        "up.uplink_message.last_battery_percentage",
+        "up.uplink_message.last_battery_percentage.f_cnt",
+        "up.uplink_message.last_battery_percentage.received_at",
+        "up.uplink_message.last_battery_percentage.value",
         "up.uplink_message.locations",
         "up.uplink_message.network_ids",
         "up.uplink_message.network_ids.cluster_address",
diff --git a/sdk/js/generated/api.json b/sdk/js/generated/api.json
index 5ceb4fcecf..4bfd6d89ab 100644
--- a/sdk/js/generated/api.json
+++ b/sdk/js/generated/api.json
@@ -39591,6 +39591,18 @@
               "isoneof": false,
               "oneofdecl": "",
               "defaultValue": ""
+            },
+            {
+              "name": "last_battery_percentage",
+              "description": "Last battery percentage of the end device.\nReceived via the DevStatus MAC command at last_dev_status_received_at or earlier.\nSet by the Network Server while handling the message.",
+              "label": "",
+              "type": "LastBatteryPercentage",
+              "longType": "LastBatteryPercentage",
+              "fullType": "ttn.lorawan.v3.LastBatteryPercentage",
+              "ismap": false,
+              "isoneof": false,
+              "oneofdecl": "",
+              "defaultValue": ""
             }
           ]
         },
@@ -40256,6 +40268,66 @@
             }
           ]
         },
+        {
+          "name": "LastBatteryPercentage",
+          "longName": "LastBatteryPercentage",
+          "fullName": "ttn.lorawan.v3.LastBatteryPercentage",
+          "description": "",
+          "hasExtensions": false,
+          "hasFields": true,
+          "hasOneofs": false,
+          "extensions": [],
+          "fields": [
+            {
+              "name": "f_cnt",
+              "description": "Frame counter value of last uplink containing DevStatusAns.",
+              "label": "",
+              "type": "uint32",
+              "longType": "uint32",
+              "fullType": "uint32",
+              "ismap": false,
+              "isoneof": false,
+              "oneofdecl": "",
+              "defaultValue": ""
+            },
+            {
+              "name": "value",
+              "description": "The battery percentage of the end device.\nThe value is defined in the [0, 100] interval.",
+              "label": "",
+              "type": "FloatValue",
+              "longType": "google.protobuf.FloatValue",
+              "fullType": "google.protobuf.FloatValue",
+              "ismap": false,
+              "isoneof": false,
+              "oneofdecl": "",
+              "defaultValue": "",
+              "options": {
+                "validate.rules": [
+                  {
+                    "name": "float.lte",
+                    "value": 1
+                  },
+                  {
+                    "name": "float.gte",
+                    "value": 0
+                  }
+                ]
+              }
+            },
+            {
+              "name": "received_at",
+              "description": "Time when last DevStatus MAC command was received.",
+              "label": "",
+              "type": "Timestamp",
+              "longType": "google.protobuf.Timestamp",
+              "fullType": "google.protobuf.Timestamp",
+              "ismap": false,
+              "isoneof": false,
+              "oneofdecl": "",
+              "defaultValue": ""
+            }
+          ]
+        },
         {
           "name": "MessagePayloadFormatters",
           "longName": "MessagePayloadFormatters",

From 4fc2b5beca096b32f247aeca6cbde92874d6f1ef Mon Sep 17 00:00:00 2001
From: Imre Halasz <imre.halasz@thethingsindustries.com>
Date: Wed, 18 Dec 2024 15:54:29 +0100
Subject: [PATCH 2/4] ns: Add `LastBatteryPercentage` to the
 `ApplicationUplink` message

---
 pkg/networkserver/grpc_gsns.go | 35 +++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/pkg/networkserver/grpc_gsns.go b/pkg/networkserver/grpc_gsns.go
index a0f6b96016..7fd6c41a0d 100644
--- a/pkg/networkserver/grpc_gsns.go
+++ b/pkg/networkserver/grpc_gsns.go
@@ -904,6 +904,18 @@ const (
 	initialDeduplicationRound = iota
 )
 
+func lastBatteryPercentage(dev *ttnpb.EndDevice) *ttnpb.LastBatteryPercentage {
+	if dev.MacState == nil || dev.BatteryPercentage == nil || dev.LastDevStatusReceivedAt == nil {
+		return nil
+	}
+
+	return &ttnpb.LastBatteryPercentage{
+		FCnt:       dev.MacState.LastDevStatusFCntUp,
+		Value:      dev.BatteryPercentage,
+		ReceivedAt: dev.LastDevStatusReceivedAt,
+	}
+}
+
 func (ns *NetworkServer) handleDataUplink(ctx context.Context, up *ttnpb.UplinkMessage) (err error) {
 	defer trace.StartRegion(ctx, "handle data uplink").End()
 
@@ -1149,17 +1161,18 @@ func (ns *NetworkServer) handleDataUplink(ctx context.Context, up *ttnpb.UplinkM
 			CorrelationIds: up.CorrelationIds,
 			Up: &ttnpb.ApplicationUp_UplinkMessage{
 				UplinkMessage: &ttnpb.ApplicationUplink{
-					Confirmed:       up.Payload.MHdr.MType == ttnpb.MType_CONFIRMED_UP,
-					FCnt:            pld.FullFCnt,
-					FPort:           pld.FPort,
-					FrmPayload:      frmPayload,
-					RxMetadata:      up.RxMetadata,
-					SessionKeyId:    stored.Session.Keys.SessionKeyId,
-					Settings:        up.Settings,
-					ReceivedAt:      up.ReceivedAt,
-					ConsumedAirtime: up.ConsumedAirtime,
-					PacketErrorRate: mac.LossRate(stored.MacState, matched.phy),
-					NetworkIds:      ns.networkIdentifiers(ctx),
+					Confirmed:             up.Payload.MHdr.MType == ttnpb.MType_CONFIRMED_UP,
+					FCnt:                  pld.FullFCnt,
+					FPort:                 pld.FPort,
+					FrmPayload:            frmPayload,
+					RxMetadata:            up.RxMetadata,
+					SessionKeyId:          stored.Session.Keys.SessionKeyId,
+					Settings:              up.Settings,
+					ReceivedAt:            up.ReceivedAt,
+					ConsumedAirtime:       up.ConsumedAirtime,
+					PacketErrorRate:       mac.LossRate(stored.MacState, matched.phy),
+					NetworkIds:            ns.networkIdentifiers(ctx),
+					LastBatteryPercentage: lastBatteryPercentage(stored),
 				},
 			},
 		})

From ad82414b790ce66558325503f11815f0c30bbb91 Mon Sep 17 00:00:00 2001
From: Imre Halasz <imre.halasz@thethingsindustries.com>
Date: Thu, 19 Dec 2024 11:03:04 +0100
Subject: [PATCH 3/4] dev: Update CHANGELOG

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 60d650cbcc..3e250c656a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@ For details about compatibility between different releases, see the **Commitment
 ### Added
 
 - Add recvTime field to the decodeUplink input in payload formatters
+- Add the latest battery percentage of the end device in the `ApplicationUplink` message.
 
 ### Changed
 

From d63d032d36bb01d633441d66352d5ea01474c9d1 Mon Sep 17 00:00:00 2001
From: Imre Halasz <imre.halasz@thethingsindustries.com>
Date: Tue, 21 Jan 2025 14:57:24 +0100
Subject: [PATCH 4/4] ns: Convert `LastBatteryPercentage` value to [0, 100]
 interval

---
 api/ttn/lorawan/v3/api.md         | 2 +-
 api/ttn/lorawan/v3/messages.proto | 2 +-
 pkg/networkserver/grpc_gsns.go    | 3 ++-
 pkg/ttnpb/messages.pb.go          | 2 +-
 pkg/ttnpb/messages.pb.validate.go | 4 ++--
 sdk/js/generated/api.json         | 2 +-
 6 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/api/ttn/lorawan/v3/api.md b/api/ttn/lorawan/v3/api.md
index e20c978f2d..1ee06e0ed6 100644
--- a/api/ttn/lorawan/v3/api.md
+++ b/api/ttn/lorawan/v3/api.md
@@ -8954,7 +8954,7 @@ ncrc: [scheduled.advanced]
 
 | Field | Validations |
 | ----- | ----------- |
-| `value` | <p>`float.lte`: `1`</p><p>`float.gte`: `0`</p> |
+| `value` | <p>`float.lte`: `100`</p><p>`float.gte`: `0`</p> |
 
 ### <a name="ttn.lorawan.v3.MessagePayloadFormatters">Message `MessagePayloadFormatters`</a>
 
diff --git a/api/ttn/lorawan/v3/messages.proto b/api/ttn/lorawan/v3/messages.proto
index 4bd951ffb8..84b69891d3 100644
--- a/api/ttn/lorawan/v3/messages.proto
+++ b/api/ttn/lorawan/v3/messages.proto
@@ -193,7 +193,7 @@ message LastBatteryPercentage {
   // The value is defined in the [0, 100] interval.
   google.protobuf.FloatValue value = 2 [(validate.rules).float = {
     gte: 0,
-    lte: 1
+    lte: 100
   }];
   // Time when last DevStatus MAC command was received.
   google.protobuf.Timestamp received_at = 3;
diff --git a/pkg/networkserver/grpc_gsns.go b/pkg/networkserver/grpc_gsns.go
index 7fd6c41a0d..53f731e140 100644
--- a/pkg/networkserver/grpc_gsns.go
+++ b/pkg/networkserver/grpc_gsns.go
@@ -43,6 +43,7 @@ import (
 	"google.golang.org/protobuf/types/known/durationpb"
 	"google.golang.org/protobuf/types/known/emptypb"
 	"google.golang.org/protobuf/types/known/timestamppb"
+	"google.golang.org/protobuf/types/known/wrapperspb"
 )
 
 const (
@@ -911,7 +912,7 @@ func lastBatteryPercentage(dev *ttnpb.EndDevice) *ttnpb.LastBatteryPercentage {
 
 	return &ttnpb.LastBatteryPercentage{
 		FCnt:       dev.MacState.LastDevStatusFCntUp,
-		Value:      dev.BatteryPercentage,
+		Value:      wrapperspb.Float(dev.BatteryPercentage.Value * 100),
 		ReceivedAt: dev.LastDevStatusReceivedAt,
 	}
 }
diff --git a/pkg/ttnpb/messages.pb.go b/pkg/ttnpb/messages.pb.go
index 518c13f878..0d65cc1b9f 100644
--- a/pkg/ttnpb/messages.pb.go
+++ b/pkg/ttnpb/messages.pb.go
@@ -2285,7 +2285,7 @@ var file_ttn_lorawan_v3_messages_proto_rawDesc = []byte{
 	0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f,
 	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x6c,
 	0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0f, 0xfa, 0x42, 0x0c, 0x0a, 0x0a, 0x1d,
-	0x00, 0x00, 0x80, 0x3f, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
+	0x00, 0x00, 0xc8, 0x42, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
 	0x12, 0x3b, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18,
 	0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
 	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
diff --git a/pkg/ttnpb/messages.pb.validate.go b/pkg/ttnpb/messages.pb.validate.go
index 481207135a..e12c1ee3fd 100644
--- a/pkg/ttnpb/messages.pb.validate.go
+++ b/pkg/ttnpb/messages.pb.validate.go
@@ -739,10 +739,10 @@ func (m *LastBatteryPercentage) ValidateFields(paths ...string) error {
 
 			if wrapper := m.GetValue(); wrapper != nil {
 
-				if val := wrapper.GetValue(); val < 0 || val > 1 {
+				if val := wrapper.GetValue(); val < 0 || val > 100 {
 					return LastBatteryPercentageValidationError{
 						field:  "value",
-						reason: "value must be inside range [0, 1]",
+						reason: "value must be inside range [0, 100]",
 					}
 				}
 
diff --git a/sdk/js/generated/api.json b/sdk/js/generated/api.json
index 4bfd6d89ab..f953f176c2 100644
--- a/sdk/js/generated/api.json
+++ b/sdk/js/generated/api.json
@@ -40305,7 +40305,7 @@
                 "validate.rules": [
                   {
                     "name": "float.lte",
-                    "value": 1
+                    "value": 100
                   },
                   {
                     "name": "float.gte",