From 80ce68559a611c1a5c99b492d74c0258e0656aed Mon Sep 17 00:00:00 2001 From: sen-trustero Date: Thu, 2 Oct 2025 16:30:51 -0700 Subject: [PATCH 1/2] multipart meta to file --- docs/receptor_v1/receptor.md | 18 + go/examples/multipart_usage/main.go | 4 +- go/receptor_sdk/cmd/report.go | 23 +- go/receptor_sdk/multipartkit/builder.go | 14 +- go/receptor_sdk/receptor.go | 1 + go/receptor_v1/receptor.pb.go | 537 ++++++++++++------------ proto/receptor_v1/receptor.proto | 3 + 7 files changed, 328 insertions(+), 272 deletions(-) diff --git a/docs/receptor_v1/receptor.md b/docs/receptor_v1/receptor.md index 4033680..ea51a73 100644 --- a/docs/receptor_v1/receptor.md +++ b/docs/receptor_v1/receptor.md @@ -6,6 +6,7 @@ - [receptor_v1/receptor.proto](#receptor_v1_receptor-proto) - [Credential](#receptor_v1-Credential) - [Document](#receptor_v1-Document) + - [Document.MetadataEntry](#receptor_v1-Document-MetadataEntry) - [Documents](#receptor_v1-Documents) - [Evidence](#receptor_v1-Evidence) - [Finding](#receptor_v1-Finding) @@ -77,6 +78,23 @@ Document is an unstructured evidence provided as a MIME document. | stream_file_path | [string](#string) | | Filepath for streaming large evidence - should be accessible by the server. | | file_name | [string](#string) | | Filename is the name of the document | | last_modified | [google.protobuf.Timestamp](#google-protobuf-Timestamp) | | Last modified date of the document at the source | +| metadata | [Document.MetadataEntry](#receptor_v1-Document-MetadataEntry) | repeated | Metadata is a map of key-value pairs that provide additional information about the document. | + + + + + + + + +### Document.MetadataEntry + + + +| Field | Type | Label | Description | +| ----- | ---- | ----- | ----------- | +| key | [string](#string) | | | +| value | [string](#string) | | | diff --git a/go/examples/multipart_usage/main.go b/go/examples/multipart_usage/main.go index 9f0754a..c51c213 100644 --- a/go/examples/multipart_usage/main.go +++ b/go/examples/multipart_usage/main.go @@ -30,13 +30,13 @@ func main() { boundary := builder.GetBoundary() // Add a file part - err = builder.AddFile("test1.csv", "test1.csv", "application/csv") + err = builder.AddFile("test1.csv", "test1.csv", "application/csv", map[string]string{"Author": "Trustero Engi."}) if err != nil { log.Fatalf("Failed to add file part: %v", err) } // Add another file part - err = builder.AddFile("test2.docx", "test2.docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document") + err = builder.AddFile("test2.docx", "test2.docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", map[string]string{"Author": "Trustero Engi."}) if err != nil { log.Fatalf("Failed to add file part: %v", err) } diff --git a/go/receptor_sdk/cmd/report.go b/go/receptor_sdk/cmd/report.go index 3ec63ec..4c131c8 100644 --- a/go/receptor_sdk/cmd/report.go +++ b/go/receptor_sdk/cmd/report.go @@ -95,12 +95,13 @@ func reportEvidence(rc receptor_v1.ReceptorClient, finding *receptor_v1.Finding, Evidences: []*receptor_v1.Evidence{&reportEvidence}, } // create a new finding from current finding and add evidence - paths := []string{} + paths := []FilePathsInfo{} for _, doc := range *evidence.Document { newDoc := receptor_v1.Document{ Body: doc.Body, Mime: doc.Mime, FileName: doc.FileName, + Metadata: doc.Metadata, } if doc.LastModified != nil { newDoc.LastModified = doc.LastModified @@ -108,7 +109,10 @@ func reportEvidence(rc receptor_v1.ReceptorClient, finding *receptor_v1.Finding, reportEvidence.EvidenceType = &receptor_v1.Evidence_Doc{ Doc: &newDoc, } - paths = append(paths, doc.StreamFilePath) + paths = append(paths, FilePathsInfo{ + Path: doc.StreamFilePath, + Metadata: doc.Metadata, + }) } contentType, streamFile, err := multipartEvidence(&reportFinding, paths) @@ -412,7 +416,12 @@ func assertStruct(rowType reflect.Type) (err error) { return } -func multipartEvidence(finding *receptor_v1.Finding, streamFilePaths []string) (contentType string, evidencePath string, err error) { +type FilePathsInfo struct { + Path string + Metadata map[string]string +} + +func multipartEvidence(finding *receptor_v1.Finding, streamFilePathsInfo []FilePathsInfo) (contentType string, evidencePath string, err error) { if len(finding.Evidences) == 0 { err = errors.New("no evidence found") log.Error().Msg("no evidence found") @@ -468,11 +477,11 @@ func multipartEvidence(finding *receptor_v1.Finding, streamFilePaths []string) ( } // 3. Part3 : evidence paths - for _, streamFilePath := range streamFilePaths { - if streamFilePath != "" { - err = builder.AddFile(evidence.Caption, streamFilePath, mime) + for _, streamFilePathInfo := range streamFilePathsInfo { + if streamFilePathInfo.Path != "" { + err = builder.AddFile(evidence.Caption, streamFilePathInfo.Path, mime, streamFilePathInfo.Metadata) if err != nil { - log.Err(err).Msgf("failed to add stream file: %s", streamFilePath) + log.Err(err).Msgf("failed to add stream file: %s", streamFilePathInfo.Path) } } } diff --git a/go/receptor_sdk/multipartkit/builder.go b/go/receptor_sdk/multipartkit/builder.go index b1d00b4..28d86a3 100644 --- a/go/receptor_sdk/multipartkit/builder.go +++ b/go/receptor_sdk/multipartkit/builder.go @@ -128,7 +128,7 @@ func (mb *MultipartBuilder) addSingleOrMultipleProtobuf(partName string, pbs []p } // AddFile writes the content of a file as a part of the multipart stream with Content-Size and Content-Hash headers. -func (mb *MultipartBuilder) AddFile(partName, filePath, contentType string) error { +func (mb *MultipartBuilder) AddFile(partName, filePath, contentType string, contentMeta map[string]string) error { file, err := os.Open(filePath) if err != nil { return fmt.Errorf("failed to open file: %v", err) @@ -155,13 +155,19 @@ func (mb *MultipartBuilder) AddFile(partName, filePath, contentType string) erro return fmt.Errorf("failed to seek file: %v", err) } - // Create the part with all headers, including Content-Hash - partWriter, err := mb.writer.CreatePart(map[string][]string{ + headers := map[string][]string{ "Content-Disposition": {fmt.Sprintf(`file; name="%s"; filename="%s"`, partName, partName)}, "Content-Type": {contentType}, "Content-Size": {fmt.Sprintf("%d", fileInfo.Size())}, "Content-Hash": {contentHash}, - }) + } + + // Inject key-value pairs from contentMeta into headers + for key, value := range contentMeta { + headers[key] = []string{value} + } + + partWriter, err := mb.writer.CreatePart(headers) if err != nil { return fmt.Errorf("failed to create multipart part: %v", err) } diff --git a/go/receptor_sdk/receptor.go b/go/receptor_sdk/receptor.go index 3c1fc02..bf00d06 100644 --- a/go/receptor_sdk/receptor.go +++ b/go/receptor_sdk/receptor.go @@ -155,6 +155,7 @@ type Document struct { StreamFilePath string // Path to the file containing the evidence FileName string // Name of the document LastModified *timestamppb.Timestamp // Last modified date of the document at the provider source + Metadata map[string]string // Additional metadata about the document } // Config with Field struct defines the json shape of the custom configurations for receptors that the app can use diff --git a/go/receptor_v1/receptor.pb.go b/go/receptor_v1/receptor.pb.go index 842dd87..93d2cd5 100644 --- a/go/receptor_v1/receptor.pb.go +++ b/go/receptor_v1/receptor.pb.go @@ -549,6 +549,8 @@ type Document struct { FileName string `protobuf:"bytes,5,opt,name=file_name,json=fileName,proto3" json:"file_name,omitempty"` // Last modified date of the document at the source LastModified *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=last_modified,json=lastModified,proto3" json:"last_modified,omitempty"` + // Metadata is a map of key-value pairs that provide additional information about the document. + Metadata map[string]string `protobuf:"bytes,7,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Document) Reset() { @@ -618,6 +620,13 @@ func (x *Document) GetLastModified() *timestamppb.Timestamp { return nil } +func (x *Document) GetMetadata() map[string]string { + if x != nil { + return x.Metadata + } + return nil +} + type Documents struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1816,7 +1825,7 @@ var file_receptor_v1_receptor_proto_rawDesc = []byte{ 0x0a, 0x07, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, - 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0xba, 0x01, 0x0a, 0x08, 0x44, 0x6f, 0x63, + 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0xb8, 0x02, 0x0a, 0x08, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x28, 0x0a, @@ -1828,223 +1837,231 @@ var file_receptor_v1_receptor_proto_rawDesc = []byte{ 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x06, 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, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, - 0x69, 0x66, 0x69, 0x65, 0x64, 0x22, 0x36, 0x0a, 0x09, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x12, 0x29, 0x0a, 0x04, 0x64, 0x6f, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x44, - 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x64, 0x6f, 0x63, 0x73, 0x22, 0xed, 0x02, - 0x0a, 0x06, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, - 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x54, - 0x0a, 0x11, 0x63, 0x6f, 0x6c, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x72, 0x65, 0x63, 0x65, - 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x43, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x3f, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, + 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 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, 0x22, 0x36, 0x0a, 0x09, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x12, 0x29, 0x0a, 0x04, 0x64, 0x6f, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x44, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x04, 0x64, 0x6f, 0x63, 0x73, 0x22, 0xed, 0x02, 0x0a, 0x06, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, + 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x54, 0x0a, 0x11, + 0x63, 0x6f, 0x6c, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, + 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x43, 0x6f, 0x6c, + 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6c, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6f, 0x6c, 0x5f, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x63, + 0x6f, 0x6c, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x3b, + 0x0a, 0x08, 0x63, 0x6f, 0x6c, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x20, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x43, 0x6f, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x07, 0x63, 0x6f, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x1a, 0x42, 0x0a, 0x14, 0x43, 0x6f, 0x6c, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6c, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6f, 0x6c, 0x5f, 0x64, 0x69, 0x73, 0x70, - 0x6c, 0x61, 0x79, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0f, 0x63, 0x6f, 0x6c, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4f, 0x72, 0x64, 0x65, 0x72, - 0x12, 0x3b, 0x0a, 0x08, 0x63, 0x6f, 0x6c, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, - 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x43, 0x6f, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x63, 0x6f, 0x6c, 0x54, 0x61, 0x67, 0x73, 0x1a, 0x42, 0x0a, - 0x14, 0x43, 0x6f, 0x6c, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 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, 0x1a, 0x3a, 0x0a, 0x0c, 0x43, 0x6f, 0x6c, 0x54, 0x61, 0x67, 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, 0x22, 0xb0, 0x01, - 0x0a, 0x03, 0x52, 0x6f, 0x77, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x10, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, - 0x52, 0x6f, 0x77, 0x2e, 0x43, 0x6f, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x63, - 0x6f, 0x6c, 0x73, 0x1a, 0x4b, 0x0a, 0x09, 0x43, 0x6f, 0x6c, 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, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x88, 0x04, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x64, 0x6f, - 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, - 0x48, 0x00, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x21, 0x0a, 0x0b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x02, 0x48, 0x00, 0x52, 0x0a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x33, 0x32, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, - 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x75, 0x69, 0x6e, 0x74, - 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, - 0x52, 0x0b, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, - 0x0c, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x04, 0x48, 0x00, 0x52, 0x0b, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x45, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 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, 0x48, 0x00, 0x52, - 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x45, 0x0a, 0x11, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x63, - 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, - 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, - 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x45, 0x0a, 0x11, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, - 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, - 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x74, - 0x72, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0c, 0x0a, - 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x24, 0x0a, 0x0a, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x73, 0x22, 0x3f, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, - 0x31, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x53, 0x74, - 0x72, 0x75, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x73, 0x22, 0x9c, 0x01, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x53, 0x74, 0x72, - 0x75, 0x63, 0x74, 0x12, 0x3d, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, - 0x31, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x1a, 0x4d, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, 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, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, - 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0xa8, 0x01, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x74, - 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, - 0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, - 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x38, 0x0a, 0x18, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x61, - 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, - 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x69, - 0x74, 0x79, 0x52, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0xe1, 0x01, 0x0a, - 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x21, - 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x12, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x10, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, - 0x22, 0xc4, 0x01, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, - 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x63, - 0x65, 0x70, 0x74, 0x6f, 0x72, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, - 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x2e, 0x0a, - 0x13, 0x69, 0x73, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x76, - 0x61, 0x6c, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, 0x73, 0x43, 0x72, - 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x18, 0x0a, - 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x63, 0x65, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x63, - 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3b, 0x0a, 0x0b, 0x52, 0x65, 0x63, 0x65, 0x70, - 0x74, 0x6f, 0x72, 0x4f, 0x49, 0x44, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, - 0x6f, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x49, 0x64, 0x22, 0xd2, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, - 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, - 0x0a, 0x12, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x63, 0x65, - 0x70, 0x74, 0x6f, 0x72, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, - 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x38, 0x0a, 0x18, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, - 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x19, - 0x0a, 0x08, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x49, 0x64, 0x22, 0xa8, 0x01, 0x0a, 0x09, 0x4a, 0x6f, - 0x62, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x63, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x72, 0x61, 0x63, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x16, - 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, - 0x6f, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x48, 0x0a, 0x0b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, - 0x75, 0x6e, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x0a, - 0x0b, 0x69, 0x73, 0x5f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x22, 0x28, - 0x0a, 0x0e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2a, 0xeb, 0x02, 0x0a, 0x12, 0x45, 0x76, 0x69, - 0x64, 0x65, 0x6e, 0x63, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x0d, 0x0a, 0x09, 0x45, 0x56, 0x49, 0x44, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x10, 0x00, 0x12, 0x0c, - 0x0a, 0x08, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x53, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, - 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x49, 0x45, 0x53, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x4f, - 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x44, 0x4f, 0x43, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, - 0x1a, 0x0a, 0x16, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, - 0x59, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x43, - 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x44, 0x55, 0x52, 0x45, - 0x53, 0x10, 0x05, 0x12, 0x25, 0x0a, 0x21, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x43, - 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x44, 0x55, 0x52, 0x45, - 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x06, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, - 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x45, 0x56, 0x49, 0x44, 0x45, 0x4e, 0x43, 0x45, 0x5f, 0x4d, - 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x07, 0x12, 0x12, 0x0a, 0x0e, 0x45, 0x56, 0x49, 0x44, - 0x45, 0x4e, 0x43, 0x45, 0x53, 0x5f, 0x4d, 0x45, 0x54, 0x41, 0x10, 0x08, 0x12, 0x22, 0x0a, 0x1e, - 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x44, 0x4f, 0x43, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, - 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x09, - 0x12, 0x18, 0x0a, 0x14, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x44, 0x4f, 0x43, 0x55, 0x4d, - 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x45, 0x54, 0x41, 0x10, 0x0a, 0x12, 0x26, 0x0a, 0x22, 0x43, 0x4f, - 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x44, 0x55, 0x52, 0x45, 0x5f, - 0x45, 0x56, 0x49, 0x44, 0x45, 0x4e, 0x43, 0x45, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, - 0x10, 0x0b, 0x12, 0x22, 0x0a, 0x1e, 0x57, 0x4f, 0x52, 0x4b, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x54, - 0x41, 0x53, 0x4b, 0x5f, 0x45, 0x56, 0x49, 0x44, 0x45, 0x4e, 0x43, 0x45, 0x5f, 0x4d, 0x41, 0x50, - 0x50, 0x49, 0x4e, 0x47, 0x10, 0x0c, 0x32, 0xf4, 0x03, 0x0a, 0x08, 0x52, 0x65, 0x63, 0x65, 0x70, - 0x74, 0x6f, 0x72, 0x12, 0x3b, 0x0a, 0x08, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, - 0x17, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x12, 0x50, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x4f, 0x49, 0x44, 0x1a, 0x22, - 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, - 0x65, 0x70, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x48, 0x0a, 0x0a, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, - 0x12, 0x1c, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x1a, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3c, 0x0a, 0x06, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, - 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x1a, 0x1c, 0x2e, 0x67, + 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, 0x1a, + 0x3a, 0x0a, 0x0c, 0x43, 0x6f, 0x6c, 0x54, 0x61, 0x67, 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, 0x22, 0xb0, 0x01, 0x0a, 0x03, + 0x52, 0x6f, 0x77, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x52, 0x6f, + 0x77, 0x2e, 0x43, 0x6f, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x63, 0x6f, 0x6c, + 0x73, 0x1a, 0x4b, 0x0a, 0x09, 0x43, 0x6f, 0x6c, 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, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x88, + 0x04, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x64, 0x6f, 0x75, 0x62, + 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, + 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, + 0x0b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x02, 0x48, 0x00, 0x52, 0x0a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x21, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x21, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x36, + 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0b, + 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x75, + 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x04, 0x48, 0x00, 0x52, 0x0b, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x1f, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x45, 0x0a, 0x0f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 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, 0x48, 0x00, 0x52, 0x0e, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x45, 0x0a, + 0x11, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, + 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, + 0x74, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x45, 0x0a, 0x11, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x6c, + 0x69, 0x73, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x24, 0x0a, 0x0a, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, + 0x3f, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x31, 0x0a, + 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x22, 0x9c, 0x01, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x12, 0x3d, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x1a, 0x4d, 0x0a, 0x0b, 0x46, 0x69, 0x65, 0x6c, 0x64, 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, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0xa8, 0x01, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x69, 0x74, + 0x69, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x63, 0x65, + 0x70, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x38, 0x0a, 0x18, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, + 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x52, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0xe1, 0x01, 0x0a, 0x0d, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x21, 0x0a, 0x0c, + 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x1f, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x30, 0x0a, 0x14, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, + 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xc4, + 0x01, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x2c, 0x0a, + 0x12, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x63, 0x65, 0x70, + 0x74, 0x6f, 0x72, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x2e, 0x0a, 0x13, 0x69, + 0x73, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, 0x73, 0x43, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x63, 0x65, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3b, 0x0a, 0x0b, 0x52, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, + 0x72, 0x4f, 0x49, 0x44, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, + 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x10, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x49, 0x64, 0x22, 0xd2, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x12, + 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, + 0x6f, 0x72, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x38, 0x0a, 0x18, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, + 0x76, 0x69, 0x64, 0x65, 0x72, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x08, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x49, 0x64, 0x22, 0xa8, 0x01, 0x0a, 0x09, 0x4a, 0x6f, 0x62, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x72, 0x61, 0x63, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, + 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x10, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x22, 0x48, 0x0a, 0x0b, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x75, 0x6e, + 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, + 0x73, 0x5f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0a, 0x69, 0x73, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x22, 0x28, 0x0a, 0x0e, + 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2a, 0xeb, 0x02, 0x0a, 0x12, 0x45, 0x76, 0x69, 0x64, 0x65, + 0x6e, 0x63, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0d, 0x0a, + 0x09, 0x45, 0x56, 0x49, 0x44, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, + 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x53, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x50, 0x4f, + 0x4c, 0x49, 0x43, 0x49, 0x45, 0x53, 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x4f, 0x4c, 0x49, + 0x43, 0x59, 0x5f, 0x44, 0x4f, 0x43, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, 0x1a, 0x0a, + 0x16, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, + 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x4f, 0x4e, + 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x44, 0x55, 0x52, 0x45, 0x53, 0x10, + 0x05, 0x12, 0x25, 0x0a, 0x21, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x43, 0x4f, 0x4e, + 0x54, 0x52, 0x4f, 0x4c, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x44, 0x55, 0x52, 0x45, 0x5f, 0x4d, + 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x06, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4f, 0x4e, 0x54, + 0x52, 0x4f, 0x4c, 0x5f, 0x45, 0x56, 0x49, 0x44, 0x45, 0x4e, 0x43, 0x45, 0x5f, 0x4d, 0x41, 0x50, + 0x50, 0x49, 0x4e, 0x47, 0x10, 0x07, 0x12, 0x12, 0x0a, 0x0e, 0x45, 0x56, 0x49, 0x44, 0x45, 0x4e, + 0x43, 0x45, 0x53, 0x5f, 0x4d, 0x45, 0x54, 0x41, 0x10, 0x08, 0x12, 0x22, 0x0a, 0x1e, 0x50, 0x4f, + 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x44, 0x4f, 0x43, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x4f, + 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x09, 0x12, 0x18, + 0x0a, 0x14, 0x50, 0x4f, 0x4c, 0x49, 0x43, 0x59, 0x5f, 0x44, 0x4f, 0x43, 0x55, 0x4d, 0x45, 0x4e, + 0x54, 0x5f, 0x4d, 0x45, 0x54, 0x41, 0x10, 0x0a, 0x12, 0x26, 0x0a, 0x22, 0x43, 0x4f, 0x4e, 0x54, + 0x52, 0x4f, 0x4c, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x44, 0x55, 0x52, 0x45, 0x5f, 0x45, 0x56, + 0x49, 0x44, 0x45, 0x4e, 0x43, 0x45, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x10, 0x0b, + 0x12, 0x22, 0x0a, 0x1e, 0x57, 0x4f, 0x52, 0x4b, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x54, 0x41, 0x53, + 0x4b, 0x5f, 0x45, 0x56, 0x49, 0x44, 0x45, 0x4e, 0x43, 0x45, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, + 0x4e, 0x47, 0x10, 0x0c, 0x32, 0xf4, 0x03, 0x0a, 0x08, 0x52, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, + 0x72, 0x12, 0x3b, 0x0a, 0x08, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x17, 0x2e, + 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x50, + 0x0a, 0x10, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x18, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x4f, 0x49, 0x44, 0x1a, 0x22, 0x2e, 0x72, + 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x70, + 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x48, 0x0a, 0x0a, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x65, 0x64, 0x12, 0x1c, + 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x4e, 0x6f, - 0x74, 0x69, 0x66, 0x79, 0x12, 0x16, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, - 0x76, 0x31, 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x1a, 0x16, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4e, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, - 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x16, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, - 0x70, 0x6f, 0x72, 0x74, 0x12, 0x18, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x1a, 0x1b, - 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, - 0x6f, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x42, 0x28, 0x5a, - 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x72, 0x65, 0x63, 0x65, - 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3c, 0x0a, 0x06, 0x52, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x12, 0x14, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, + 0x76, 0x31, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x4e, 0x6f, 0x74, 0x69, + 0x66, 0x79, 0x12, 0x16, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, + 0x2e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x12, 0x4e, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, + 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x12, 0x47, 0x0a, 0x0c, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x12, 0x18, 0x2e, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x1a, 0x1b, 0x2e, 0x72, + 0x65, 0x63, 0x65, 0x70, 0x74, 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x42, 0x28, 0x5a, 0x26, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x72, 0x65, 0x63, 0x65, 0x70, 0x74, + 0x6f, 0x72, 0x5f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2060,7 +2077,7 @@ func file_receptor_v1_receptor_proto_rawDescGZIP() []byte { } var file_receptor_v1_receptor_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_receptor_v1_receptor_proto_msgTypes = make([]protoimpl.MessageInfo, 24) +var file_receptor_v1_receptor_proto_msgTypes = make([]protoimpl.MessageInfo, 25) var file_receptor_v1_receptor_proto_goTypes = []interface{}{ (EvidenceObjectType)(0), // 0: receptor_v1.EvidenceObjectType (*Finding)(nil), // 1: receptor_v1.Finding @@ -2083,13 +2100,14 @@ var file_receptor_v1_receptor_proto_goTypes = []interface{}{ (*JobResult)(nil), // 18: receptor_v1.JobResult (*ReportChunk)(nil), // 19: receptor_v1.ReportChunk (*ReportResponse)(nil), // 20: receptor_v1.ReportResponse - nil, // 21: receptor_v1.Struct.ColDisplayNamesEntry - nil, // 22: receptor_v1.Struct.ColTagsEntry - nil, // 23: receptor_v1.Row.ColsEntry - nil, // 24: receptor_v1.StructStruct.FieldsEntry - (*timestamppb.Timestamp)(nil), // 25: google.protobuf.Timestamp - (*emptypb.Empty)(nil), // 26: google.protobuf.Empty - (*wrapperspb.StringValue)(nil), // 27: google.protobuf.StringValue + nil, // 21: receptor_v1.Document.MetadataEntry + nil, // 22: receptor_v1.Struct.ColDisplayNamesEntry + nil, // 23: receptor_v1.Struct.ColTagsEntry + nil, // 24: receptor_v1.Row.ColsEntry + nil, // 25: receptor_v1.StructStruct.FieldsEntry + (*timestamppb.Timestamp)(nil), // 26: google.protobuf.Timestamp + (*emptypb.Empty)(nil), // 27: google.protobuf.Empty + (*wrapperspb.StringValue)(nil), // 28: google.protobuf.StringValue } var file_receptor_v1_receptor_proto_depIdxs = []int32{ 14, // 0: receptor_v1.Finding.entities:type_name -> receptor_v1.ServiceEntity @@ -2098,42 +2116,43 @@ var file_receptor_v1_receptor_proto_depIdxs = []int32{ 5, // 3: receptor_v1.Evidence.doc:type_name -> receptor_v1.Document 7, // 4: receptor_v1.Evidence.struct:type_name -> receptor_v1.Struct 6, // 5: receptor_v1.Evidence.docs:type_name -> receptor_v1.Documents - 25, // 6: receptor_v1.Evidence.relevant_date:type_name -> google.protobuf.Timestamp + 26, // 6: receptor_v1.Evidence.relevant_date:type_name -> google.protobuf.Timestamp 0, // 7: receptor_v1.Evidence.evidence_object_type:type_name -> receptor_v1.EvidenceObjectType 3, // 8: receptor_v1.Sources.sources:type_name -> receptor_v1.Source - 25, // 9: receptor_v1.Document.last_modified:type_name -> google.protobuf.Timestamp - 5, // 10: receptor_v1.Documents.docs:type_name -> receptor_v1.Document - 8, // 11: receptor_v1.Struct.rows:type_name -> receptor_v1.Row - 21, // 12: receptor_v1.Struct.col_display_names:type_name -> receptor_v1.Struct.ColDisplayNamesEntry - 22, // 13: receptor_v1.Struct.col_tags:type_name -> receptor_v1.Struct.ColTagsEntry - 23, // 14: receptor_v1.Row.cols:type_name -> receptor_v1.Row.ColsEntry - 25, // 15: receptor_v1.Value.timestamp_value:type_name -> google.protobuf.Timestamp - 10, // 16: receptor_v1.Value.string_list_value:type_name -> receptor_v1.StringList - 11, // 17: receptor_v1.Value.struct_list_value:type_name -> receptor_v1.StructList - 12, // 18: receptor_v1.StructList.values:type_name -> receptor_v1.StructStruct - 24, // 19: receptor_v1.StructStruct.fields:type_name -> receptor_v1.StructStruct.FieldsEntry - 14, // 20: receptor_v1.ServiceEntities.entities:type_name -> receptor_v1.ServiceEntity - 9, // 21: receptor_v1.Row.ColsEntry.value:type_name -> receptor_v1.Value - 9, // 22: receptor_v1.StructStruct.FieldsEntry.value:type_name -> receptor_v1.Value - 15, // 23: receptor_v1.Receptor.Verified:input_type -> receptor_v1.Credential - 16, // 24: receptor_v1.Receptor.GetConfiguration:input_type -> receptor_v1.ReceptorOID - 13, // 25: receptor_v1.Receptor.Discovered:input_type -> receptor_v1.ServiceEntities - 1, // 26: receptor_v1.Receptor.Report:input_type -> receptor_v1.Finding - 18, // 27: receptor_v1.Receptor.Notify:input_type -> receptor_v1.JobResult - 17, // 28: receptor_v1.Receptor.SetConfiguration:input_type -> receptor_v1.ReceptorConfiguration - 19, // 29: receptor_v1.Receptor.StreamReport:input_type -> receptor_v1.ReportChunk - 26, // 30: receptor_v1.Receptor.Verified:output_type -> google.protobuf.Empty - 17, // 31: receptor_v1.Receptor.GetConfiguration:output_type -> receptor_v1.ReceptorConfiguration - 27, // 32: receptor_v1.Receptor.Discovered:output_type -> google.protobuf.StringValue - 27, // 33: receptor_v1.Receptor.Report:output_type -> google.protobuf.StringValue - 26, // 34: receptor_v1.Receptor.Notify:output_type -> google.protobuf.Empty - 26, // 35: receptor_v1.Receptor.SetConfiguration:output_type -> google.protobuf.Empty - 20, // 36: receptor_v1.Receptor.StreamReport:output_type -> receptor_v1.ReportResponse - 30, // [30:37] is the sub-list for method output_type - 23, // [23:30] is the sub-list for method input_type - 23, // [23:23] is the sub-list for extension type_name - 23, // [23:23] is the sub-list for extension extendee - 0, // [0:23] is the sub-list for field type_name + 26, // 9: receptor_v1.Document.last_modified:type_name -> google.protobuf.Timestamp + 21, // 10: receptor_v1.Document.metadata:type_name -> receptor_v1.Document.MetadataEntry + 5, // 11: receptor_v1.Documents.docs:type_name -> receptor_v1.Document + 8, // 12: receptor_v1.Struct.rows:type_name -> receptor_v1.Row + 22, // 13: receptor_v1.Struct.col_display_names:type_name -> receptor_v1.Struct.ColDisplayNamesEntry + 23, // 14: receptor_v1.Struct.col_tags:type_name -> receptor_v1.Struct.ColTagsEntry + 24, // 15: receptor_v1.Row.cols:type_name -> receptor_v1.Row.ColsEntry + 26, // 16: receptor_v1.Value.timestamp_value:type_name -> google.protobuf.Timestamp + 10, // 17: receptor_v1.Value.string_list_value:type_name -> receptor_v1.StringList + 11, // 18: receptor_v1.Value.struct_list_value:type_name -> receptor_v1.StructList + 12, // 19: receptor_v1.StructList.values:type_name -> receptor_v1.StructStruct + 25, // 20: receptor_v1.StructStruct.fields:type_name -> receptor_v1.StructStruct.FieldsEntry + 14, // 21: receptor_v1.ServiceEntities.entities:type_name -> receptor_v1.ServiceEntity + 9, // 22: receptor_v1.Row.ColsEntry.value:type_name -> receptor_v1.Value + 9, // 23: receptor_v1.StructStruct.FieldsEntry.value:type_name -> receptor_v1.Value + 15, // 24: receptor_v1.Receptor.Verified:input_type -> receptor_v1.Credential + 16, // 25: receptor_v1.Receptor.GetConfiguration:input_type -> receptor_v1.ReceptorOID + 13, // 26: receptor_v1.Receptor.Discovered:input_type -> receptor_v1.ServiceEntities + 1, // 27: receptor_v1.Receptor.Report:input_type -> receptor_v1.Finding + 18, // 28: receptor_v1.Receptor.Notify:input_type -> receptor_v1.JobResult + 17, // 29: receptor_v1.Receptor.SetConfiguration:input_type -> receptor_v1.ReceptorConfiguration + 19, // 30: receptor_v1.Receptor.StreamReport:input_type -> receptor_v1.ReportChunk + 27, // 31: receptor_v1.Receptor.Verified:output_type -> google.protobuf.Empty + 17, // 32: receptor_v1.Receptor.GetConfiguration:output_type -> receptor_v1.ReceptorConfiguration + 28, // 33: receptor_v1.Receptor.Discovered:output_type -> google.protobuf.StringValue + 28, // 34: receptor_v1.Receptor.Report:output_type -> google.protobuf.StringValue + 27, // 35: receptor_v1.Receptor.Notify:output_type -> google.protobuf.Empty + 27, // 36: receptor_v1.Receptor.SetConfiguration:output_type -> google.protobuf.Empty + 20, // 37: receptor_v1.Receptor.StreamReport:output_type -> receptor_v1.ReportResponse + 31, // [31:38] is the sub-list for method output_type + 24, // [24:31] is the sub-list for method input_type + 24, // [24:24] is the sub-list for extension type_name + 24, // [24:24] is the sub-list for extension extendee + 0, // [0:24] is the sub-list for field type_name } func init() { file_receptor_v1_receptor_proto_init() } @@ -2407,7 +2426,7 @@ func file_receptor_v1_receptor_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_receptor_v1_receptor_proto_rawDesc, NumEnums: 1, - NumMessages: 24, + NumMessages: 25, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/receptor_v1/receptor.proto b/proto/receptor_v1/receptor.proto index f6f2e77..dfb74db 100644 --- a/proto/receptor_v1/receptor.proto +++ b/proto/receptor_v1/receptor.proto @@ -177,6 +177,9 @@ message Document { // Last modified date of the document at the source google.protobuf.Timestamp last_modified = 6; + + // Metadata is a map of key-value pairs that provide additional information about the document. + map metadata = 7; } message Documents { From 0eddc9b75874c0e605d0b89aba2b548bb49215a9 Mon Sep 17 00:00:00 2001 From: sen-trustero Date: Sun, 5 Oct 2025 10:33:39 -0700 Subject: [PATCH 2/2] clean up multifile multipart messages --- go/receptor_sdk/cmd/report.go | 91 +++++++++++++++++-------- go/receptor_sdk/multipartkit/builder.go | 17 +++-- 2 files changed, 75 insertions(+), 33 deletions(-) diff --git a/go/receptor_sdk/cmd/report.go b/go/receptor_sdk/cmd/report.go index 4c131c8..3cc9923 100644 --- a/go/receptor_sdk/cmd/report.go +++ b/go/receptor_sdk/cmd/report.go @@ -51,10 +51,9 @@ func report(rc receptor_v1.ReceptorClient, credentials interface{}, config inter if err != nil { log.Err(err).Msg("failed to report evidence") // Continue on to next batch even after an error - finding.Evidences = []*receptor_v1.Evidence{} // Empty every time for new evidence continue } - finding.Evidences = []*receptor_v1.Evidence{} // Empty every time for new evidence + } return @@ -68,7 +67,6 @@ func reportEvidence(rc receptor_v1.ReceptorClient, finding *receptor_v1.Finding, ColDisplayOrder: []string{}, ColTags: map[string]string{}, } - reportEvidence := receptor_v1.Evidence{ Caption: evidence.Caption, Description: evidence.Description, @@ -88,14 +86,14 @@ func reportEvidence(rc receptor_v1.ReceptorClient, finding *receptor_v1.Finding, } if evidence.Document != nil && len(*evidence.Document) > 0 { - // we can skip entitities for document evidence + paths := []FilePathsInfo{} + evidenceDocuments := receptor_v1.Documents{} + evidenceDocuments.Docs = []*receptor_v1.Document{} reportFinding := receptor_v1.Finding{ ReceptorType: finding.ReceptorType, ServiceProviderAccount: finding.ServiceProviderAccount, - Evidences: []*receptor_v1.Evidence{&reportEvidence}, } - // create a new finding from current finding and add evidence - paths := []FilePathsInfo{} + for _, doc := range *evidence.Document { newDoc := receptor_v1.Document{ Body: doc.Body, @@ -106,17 +104,39 @@ func reportEvidence(rc receptor_v1.ReceptorClient, finding *receptor_v1.Finding, if doc.LastModified != nil { newDoc.LastModified = doc.LastModified } + evidenceDocuments.Docs = append(evidenceDocuments.Docs, &newDoc) + // add to paths only if it is NOT bytes + if len(doc.Body) == 0 { + paths = append(paths, FilePathsInfo{ + Path: doc.StreamFilePath, + Metadata: doc.Metadata, + }) + } + } + if len(evidenceDocuments.Docs) == 1 { // single document reportEvidence.EvidenceType = &receptor_v1.Evidence_Doc{ - Doc: &newDoc, + Doc: evidenceDocuments.Docs[0], } - paths = append(paths, FilePathsInfo{ - Path: doc.StreamFilePath, - Metadata: doc.Metadata, + } else if len(evidenceDocuments.Docs) > 1 { + reportEvidence.EvidenceType = &receptor_v1.Evidence_Docs{ + Docs: &evidenceDocuments, + } + } + //extract sources and add to multipart and remove from finding + sources := []*receptor_v1.Source{} + for _, source := range evidence.Sources { + sources = append(sources, &receptor_v1.Source{ + RawApiRequest: source.RawApiRequest, + RawApiResponse: source.RawApiResponse, }) } + reportEvidence.Sources = []*receptor_v1.Source{} + + reportFinding.Evidences = append(reportFinding.Evidences, &reportEvidence) - contentType, streamFile, err := multipartEvidence(&reportFinding, paths) + contentType, streamFile, err := multipartEvidence(&reportFinding, paths, sources) + // have the streamFile from receptor - remove the temp evidence files for _, doc := range *evidence.Document { os.Remove(doc.StreamFilePath) } @@ -176,7 +196,7 @@ func reportEvidence(rc receptor_v1.ReceptorClient, finding *receptor_v1.Finding, for idx, row := range evidence.Rows { if idx == 0 { if entityIdFieldName, rowFieldNames, err = ExtractMetaData(row, &reportStruct); err != nil { - return // fail to extract metadata, likely an invalid row type + return // failed to extract metadata, likely an invalid row type } } reportStruct.Rows = append(reportStruct.Rows, RowToStructRow(row, entityIdFieldName, rowFieldNames)) @@ -185,10 +205,10 @@ func reportEvidence(rc receptor_v1.ReceptorClient, finding *receptor_v1.Finding, // Append to Finding finding.Evidences = append(finding.Evidences, &reportEvidence) } + } + // report all structured evidence at once _, err = rc.Report(context.Background(), finding) - finding.Evidences = []*receptor_v1.Evidence{} // Empty every time for new evidence - return } @@ -421,7 +441,7 @@ type FilePathsInfo struct { Metadata map[string]string } -func multipartEvidence(finding *receptor_v1.Finding, streamFilePathsInfo []FilePathsInfo) (contentType string, evidencePath string, err error) { +func multipartEvidence(finding *receptor_v1.Finding, streamFilePathsInfo []FilePathsInfo, sources []*receptor_v1.Source) (contentType string, evidencePath string, err error) { if len(finding.Evidences) == 0 { err = errors.New("no evidence found") log.Error().Msg("no evidence found") @@ -429,10 +449,12 @@ func multipartEvidence(finding *receptor_v1.Finding, streamFilePathsInfo []FileP } evidence := finding.Evidences[0] - if evidence.GetDoc() == nil { - err = errors.New("evidence doc is nil") - log.Error().Msg("evidence doc is nil") + + if evidence.EvidenceType == nil { + err = errors.New("evidence doc(s) is nil") + log.Error().Msg("evidence doc(s) is nil") } else { + // evidence should be protobuf of evidence + blob in a multipart/mixed // the mime of the part should be the mime from the evidence.doc.Mime dstFile, err := os.CreateTemp("", "multipart-evidence_*.tmp") @@ -440,9 +462,7 @@ func multipartEvidence(finding *receptor_v1.Finding, streamFilePathsInfo []FileP log.Err(err).Msg("failed to create multipart file") return "", "", err } - mime := evidence.GetDoc().GetMime() - body := evidence.GetDoc().GetBody() bufferSize := multipartkit.DefaultBufferSize // Initialize the multipart builder @@ -463,19 +483,32 @@ func multipartEvidence(finding *receptor_v1.Finding, streamFilePathsInfo []FileP contentType = fmt.Sprintf("%s; %s; boundary=%s", mulitpartPrefix, mime, boundary) // 1. Part1 : protobuf of Finding without evidence - err = builder.AddProtobuf("receptor_v1.Finding", finding) + + err = builder.AddProtobuf("receptor_v1.Finding", finding) // need to remove evidences from this finding ... if err != nil { log.Error().Msgf("failed to add protobuf message: %v", err) } // 2. Part2 : evidence blob - if len(body) > 0 { - err = builder.AddBytes(evidence.Caption, evidence.Caption, mime, body) - if err != nil { - log.Err(err).Msgf("failed to add blob part: %s", evidence.Caption) - } + docs := []*receptor_v1.Document{} + + switch evidenceDocType := evidence.EvidenceType.(type) { + case *receptor_v1.Evidence_Doc: + log.Info().Msgf("%v", evidenceDocType.Doc.Mime) + docs = append(docs, evidenceDocType.Doc) + case *receptor_v1.Evidence_Docs: + log.Info().Msg("docs...") + docs = evidence.GetDocs().Docs } + for _, doc := range docs { + if len(doc.Body) > 0 { + err = builder.AddBytes(evidence.Caption, evidence.Caption, mime, doc.GetBody(), doc.GetMetadata()) + if err != nil { + log.Err(err).Msgf("failed to add blob part: %s", evidence.Caption) + } + } + } // 3. Part3 : evidence paths for _, streamFilePathInfo := range streamFilePathsInfo { if streamFilePathInfo.Path != "" { @@ -488,11 +521,13 @@ func multipartEvidence(finding *receptor_v1.Finding, streamFilePathsInfo []FileP // 4. Part4 : Sources err = builder.AddProtobuf("receptor_v1.Sources", &receptor_v1.Sources{ - Sources: evidence.Sources, + Sources: sources, }) if err != nil { log.Error().Msgf("failed to add sources part: %v", err) } + // clear evidences from the temp finding + finding.Evidences = []*receptor_v1.Evidence{} return contentType, dstFile.Name(), nil } diff --git a/go/receptor_sdk/multipartkit/builder.go b/go/receptor_sdk/multipartkit/builder.go index 28d86a3..f5d607d 100644 --- a/go/receptor_sdk/multipartkit/builder.go +++ b/go/receptor_sdk/multipartkit/builder.go @@ -155,6 +155,7 @@ func (mb *MultipartBuilder) AddFile(partName, filePath, contentType string, cont return fmt.Errorf("failed to seek file: %v", err) } + // common headers headers := map[string][]string{ "Content-Disposition": {fmt.Sprintf(`file; name="%s"; filename="%s"`, partName, partName)}, "Content-Type": {contentType}, @@ -181,7 +182,7 @@ func (mb *MultipartBuilder) AddFile(partName, filePath, contentType string, cont } // AddBytes writes a file (provided as bytes) into the multipart builder with the given filename and MIME type. -func (mb *MultipartBuilder) AddBytes(partName, fileName, contentType string, data []byte) error { +func (mb *MultipartBuilder) AddBytes(partName, fileName, contentType string, data []byte, contentMeta map[string]string) error { reader := bytes.NewReader(data) // Compute the hash for the provided byte array @@ -192,14 +193,20 @@ func (mb *MultipartBuilder) AddBytes(partName, fileName, contentType string, dat // Rewind the reader after calculating the hash reader.Seek(0, io.SeekStart) - - // Create the part with all headers, including Content-Hash - partWriter, err := mb.writer.CreatePart(map[string][]string{ + headers := map[string][]string{ "Content-Disposition": {fmt.Sprintf(`file; name="%s"; filename="%s"`, partName, fileName)}, "Content-Type": {contentType}, "Content-Length": {fmt.Sprintf("%d", len(data))}, "Content-Hash": {contentHash}, - }) + } + + // Inject key-value pairs from contentMeta into headers + for key, value := range contentMeta { + headers[key] = []string{value} + } + + // Create the part with all headers, including Content-Hash + partWriter, err := mb.writer.CreatePart(headers) if err != nil { return fmt.Errorf("failed to create multipart part: %v", err) }