From 852c2f6a1c2b17dff06d7302b3c6580b042d1328 Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Fri, 20 Feb 2026 13:23:25 -0800 Subject: [PATCH 01/62] feat(runtime): add GenerateTemplate RPC handler for YAML generation Adds a new GenerateTemplate RPC endpoint that serves as the single source of truth for YAML format generation. Replaces frontend imperative YAML builders with a centralized backend handler. - Add EnvVarName field to PropertySpec for custom env var name mapping - Populate EnvVarName values across 14 driver specs (S3, GCS, Azure, ClickHouse, Postgres, BigQuery, Snowflake, Redshift, MotherDuck, Athena, MySQL, Druid, Pinot, Salesforce) - Define GenerateTemplate proto messages with validation annotations - Implement handler: auth check, driver validation, property validation, DuckDB rewrite for object/file stores and sqlite - Add comprehensive YAML renderers for connectors and models with precise formatting via yaml.Node tree construction - Implement env var conflict resolution with _1, _2 suffix appending - Add 54 passing test cases covering all drivers, error scenarios, and edge cases Frontend migration to use this RPC will follow as a separate step. Co-Authored-By: Claude Opus 4.6 --- .mcp.json | 16 - proto/gen/rill/admin/v1/openapi.yaml | 2 +- proto/gen/rill/admin/v1/public.openapi.yaml | 2 +- proto/gen/rill/runtime/v1/api.pb.go | 3781 +++++++++-------- proto/gen/rill/runtime/v1/api.pb.gw.go | 111 + proto/gen/rill/runtime/v1/api.pb.validate.go | 285 ++ proto/gen/rill/runtime/v1/api_grpc.pb.go | 40 + .../gen/rill/runtime/v1/runtime.swagger.yaml | 49 + proto/rill/runtime/v1/api.proto | 25 + runtime/drivers/athena/athena.go | 2 + runtime/drivers/azure/azure.go | 15 +- runtime/drivers/bigquery/bigquery.go | 1 + runtime/drivers/clickhouse/clickhouse.go | 2 + runtime/drivers/connectors.go | 5 +- runtime/drivers/druid/druid.go | 2 + runtime/drivers/duckdb/duckdb.go | 1 + runtime/drivers/gcs/gcs.go | 3 + runtime/drivers/mysql/mysql.go | 2 + runtime/drivers/pinot/pinot.go | 2 + runtime/drivers/postgres/postgres.go | 2 + runtime/drivers/redshift/redshift.go | 2 + runtime/drivers/s3/s3.go | 3 + runtime/drivers/salesforce/salesforce.go | 16 +- runtime/drivers/snowflake/snowflake.go | 2 + runtime/server/generate_template.go | 445 ++ runtime/server/generate_template_test.go | 884 ++++ .../src/proto/gen/rill/runtime/v1/api_pb.ts | 120 + .../src/runtime-client/gen/index.schemas.ts | 20 + .../gen/runtime-service/runtime-service.ts | 90 + 29 files changed, 4121 insertions(+), 1809 deletions(-) delete mode 100644 .mcp.json create mode 100644 runtime/server/generate_template.go create mode 100644 runtime/server/generate_template_test.go diff --git a/.mcp.json b/.mcp.json deleted file mode 100644 index 7fd7caa0ba1..00000000000 --- a/.mcp.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "mcpServers": { - "linear": { - "type": "http", - "url": "https://mcp.linear.app/mcp" - }, - "slack": { - "type": "stdio", - "command": "npx", - "args": ["-y", "slack-mcp-server"], - "env": { - "SLACK_MCP_XOXP_TOKEN": "${SLACK_MCP_XOXP_TOKEN}" - } - } - } -} diff --git a/proto/gen/rill/admin/v1/openapi.yaml b/proto/gen/rill/admin/v1/openapi.yaml index 84d1f47bbcb..83a805c9d31 100644 --- a/proto/gen/rill/admin/v1/openapi.yaml +++ b/proto/gen/rill/admin/v1/openapi.yaml @@ -2316,7 +2316,7 @@ externalDocs: info: description: Rill Admin API enables programmatic management of Rill Cloud resources, including organizations, projects, and user access. It provides endpoints for creating, updating, and deleting these resources, as well as managing authentication and permissions. title: Rill Admin API - version: v0.81.1 + version: v0.81.4 openapi: 3.0.3 paths: /v1/ai/complete: diff --git a/proto/gen/rill/admin/v1/public.openapi.yaml b/proto/gen/rill/admin/v1/public.openapi.yaml index 72b11511be7..b3e28d02e13 100644 --- a/proto/gen/rill/admin/v1/public.openapi.yaml +++ b/proto/gen/rill/admin/v1/public.openapi.yaml @@ -2316,7 +2316,7 @@ externalDocs: info: description: Rill Admin API enables programmatic management of Rill Cloud resources, including organizations, projects, and user access. It provides endpoints for creating, updating, and deleting these resources, as well as managing authentication and permissions. title: Rill Admin API - version: v0.81.1 + version: v0.81.4 openapi: 3.0.3 paths: /v1/ai/complete: {} diff --git a/proto/gen/rill/runtime/v1/api.pb.go b/proto/gen/rill/runtime/v1/api.pb.go index b3ada72f620..0707e164c1f 100644 --- a/proto/gen/rill/runtime/v1/api.pb.go +++ b/proto/gen/rill/runtime/v1/api.pb.go @@ -238,7 +238,7 @@ func (x ConnectorDriver_Property_Type) Number() protoreflect.EnumNumber { // Deprecated: Use ConnectorDriver_Property_Type.Descriptor instead. func (ConnectorDriver_Property_Type) EnumDescriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{71, 0, 0} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{73, 0, 0} } // Request message for RuntimeService.Ping @@ -3371,6 +3371,158 @@ func (x *GenerateRendererResponse) GetRendererProperties() *structpb.Struct { return nil } +type GenerateTemplateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"` + ResourceType string `protobuf:"bytes,2,opt,name=resource_type,json=resourceType,proto3" json:"resource_type,omitempty"` + Driver string `protobuf:"bytes,3,opt,name=driver,proto3" json:"driver,omitempty"` + Properties *structpb.Struct `protobuf:"bytes,4,opt,name=properties,proto3" json:"properties,omitempty"` + ConnectorName string `protobuf:"bytes,5,opt,name=connector_name,json=connectorName,proto3" json:"connector_name,omitempty"` +} + +func (x *GenerateTemplateRequest) Reset() { + *x = GenerateTemplateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_rill_runtime_v1_api_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GenerateTemplateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenerateTemplateRequest) ProtoMessage() {} + +func (x *GenerateTemplateRequest) ProtoReflect() protoreflect.Message { + mi := &file_rill_runtime_v1_api_proto_msgTypes[51] + 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 GenerateTemplateRequest.ProtoReflect.Descriptor instead. +func (*GenerateTemplateRequest) Descriptor() ([]byte, []int) { + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{51} +} + +func (x *GenerateTemplateRequest) GetInstanceId() string { + if x != nil { + return x.InstanceId + } + return "" +} + +func (x *GenerateTemplateRequest) GetResourceType() string { + if x != nil { + return x.ResourceType + } + return "" +} + +func (x *GenerateTemplateRequest) GetDriver() string { + if x != nil { + return x.Driver + } + return "" +} + +func (x *GenerateTemplateRequest) GetProperties() *structpb.Struct { + if x != nil { + return x.Properties + } + return nil +} + +func (x *GenerateTemplateRequest) GetConnectorName() string { + if x != nil { + return x.ConnectorName + } + return "" +} + +type GenerateTemplateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Blob string `protobuf:"bytes,1,opt,name=blob,proto3" json:"blob,omitempty"` + EnvVars map[string]string `protobuf:"bytes,2,rep,name=env_vars,json=envVars,proto3" json:"env_vars,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Actual resource type used; may differ from request when driver is rewritten + ResourceType string `protobuf:"bytes,3,opt,name=resource_type,json=resourceType,proto3" json:"resource_type,omitempty"` + // Actual driver used; may differ from request when rewritten to duckdb + Driver string `protobuf:"bytes,4,opt,name=driver,proto3" json:"driver,omitempty"` +} + +func (x *GenerateTemplateResponse) Reset() { + *x = GenerateTemplateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_rill_runtime_v1_api_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GenerateTemplateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenerateTemplateResponse) ProtoMessage() {} + +func (x *GenerateTemplateResponse) ProtoReflect() protoreflect.Message { + mi := &file_rill_runtime_v1_api_proto_msgTypes[52] + 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 GenerateTemplateResponse.ProtoReflect.Descriptor instead. +func (*GenerateTemplateResponse) Descriptor() ([]byte, []int) { + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{52} +} + +func (x *GenerateTemplateResponse) GetBlob() string { + if x != nil { + return x.Blob + } + return "" +} + +func (x *GenerateTemplateResponse) GetEnvVars() map[string]string { + if x != nil { + return x.EnvVars + } + return nil +} + +func (x *GenerateTemplateResponse) GetResourceType() string { + if x != nil { + return x.ResourceType + } + return "" +} + +func (x *GenerateTemplateResponse) GetDriver() string { + if x != nil { + return x.Driver + } + return "" +} + type QueryResolverRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3386,7 +3538,7 @@ type QueryResolverRequest struct { func (x *QueryResolverRequest) Reset() { *x = QueryResolverRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[51] + mi := &file_rill_runtime_v1_api_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3399,7 +3551,7 @@ func (x *QueryResolverRequest) String() string { func (*QueryResolverRequest) ProtoMessage() {} func (x *QueryResolverRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[51] + mi := &file_rill_runtime_v1_api_proto_msgTypes[53] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3412,7 +3564,7 @@ func (x *QueryResolverRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryResolverRequest.ProtoReflect.Descriptor instead. func (*QueryResolverRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{51} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{53} } func (x *QueryResolverRequest) GetInstanceId() string { @@ -3463,7 +3615,7 @@ type QueryResolverResponse struct { func (x *QueryResolverResponse) Reset() { *x = QueryResolverResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[52] + mi := &file_rill_runtime_v1_api_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3476,7 +3628,7 @@ func (x *QueryResolverResponse) String() string { func (*QueryResolverResponse) ProtoMessage() {} func (x *QueryResolverResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[52] + mi := &file_rill_runtime_v1_api_proto_msgTypes[54] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3489,7 +3641,7 @@ func (x *QueryResolverResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryResolverResponse.ProtoReflect.Descriptor instead. func (*QueryResolverResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{52} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{54} } func (x *QueryResolverResponse) GetMeta() *structpb.Struct { @@ -3527,7 +3679,7 @@ type Log struct { func (x *Log) Reset() { *x = Log{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[53] + mi := &file_rill_runtime_v1_api_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3540,7 +3692,7 @@ func (x *Log) String() string { func (*Log) ProtoMessage() {} func (x *Log) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[53] + mi := &file_rill_runtime_v1_api_proto_msgTypes[55] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3553,7 +3705,7 @@ func (x *Log) ProtoReflect() protoreflect.Message { // Deprecated: Use Log.ProtoReflect.Descriptor instead. func (*Log) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{53} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{55} } func (x *Log) GetLevel() LogLevel { @@ -3600,7 +3752,7 @@ type ModelPartition struct { func (x *ModelPartition) Reset() { *x = ModelPartition{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[54] + mi := &file_rill_runtime_v1_api_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3613,7 +3765,7 @@ func (x *ModelPartition) String() string { func (*ModelPartition) ProtoMessage() {} func (x *ModelPartition) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[54] + mi := &file_rill_runtime_v1_api_proto_msgTypes[56] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3626,7 +3778,7 @@ func (x *ModelPartition) ProtoReflect() protoreflect.Message { // Deprecated: Use ModelPartition.ProtoReflect.Descriptor instead. func (*ModelPartition) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{54} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{56} } func (x *ModelPartition) GetKey() string { @@ -3685,7 +3837,7 @@ type GetLogsRequest struct { func (x *GetLogsRequest) Reset() { *x = GetLogsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[55] + mi := &file_rill_runtime_v1_api_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3698,7 +3850,7 @@ func (x *GetLogsRequest) String() string { func (*GetLogsRequest) ProtoMessage() {} func (x *GetLogsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[55] + mi := &file_rill_runtime_v1_api_proto_msgTypes[57] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3711,7 +3863,7 @@ func (x *GetLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetLogsRequest.ProtoReflect.Descriptor instead. func (*GetLogsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{55} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{57} } func (x *GetLogsRequest) GetInstanceId() string { @@ -3753,7 +3905,7 @@ type GetLogsResponse struct { func (x *GetLogsResponse) Reset() { *x = GetLogsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[56] + mi := &file_rill_runtime_v1_api_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3766,7 +3918,7 @@ func (x *GetLogsResponse) String() string { func (*GetLogsResponse) ProtoMessage() {} func (x *GetLogsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[56] + mi := &file_rill_runtime_v1_api_proto_msgTypes[58] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3779,7 +3931,7 @@ func (x *GetLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetLogsResponse.ProtoReflect.Descriptor instead. func (*GetLogsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{56} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{58} } func (x *GetLogsResponse) GetLogs() []*Log { @@ -3803,7 +3955,7 @@ type WatchLogsRequest struct { func (x *WatchLogsRequest) Reset() { *x = WatchLogsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[57] + mi := &file_rill_runtime_v1_api_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3816,7 +3968,7 @@ func (x *WatchLogsRequest) String() string { func (*WatchLogsRequest) ProtoMessage() {} func (x *WatchLogsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[57] + mi := &file_rill_runtime_v1_api_proto_msgTypes[59] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3829,7 +3981,7 @@ func (x *WatchLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchLogsRequest.ProtoReflect.Descriptor instead. func (*WatchLogsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{57} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{59} } func (x *WatchLogsRequest) GetInstanceId() string { @@ -3871,7 +4023,7 @@ type WatchLogsResponse struct { func (x *WatchLogsResponse) Reset() { *x = WatchLogsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[58] + mi := &file_rill_runtime_v1_api_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3884,7 +4036,7 @@ func (x *WatchLogsResponse) String() string { func (*WatchLogsResponse) ProtoMessage() {} func (x *WatchLogsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[58] + mi := &file_rill_runtime_v1_api_proto_msgTypes[60] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3897,7 +4049,7 @@ func (x *WatchLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchLogsResponse.ProtoReflect.Descriptor instead. func (*WatchLogsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{58} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{60} } func (x *WatchLogsResponse) GetLog() *Log { @@ -3925,7 +4077,7 @@ type ListResourcesRequest struct { func (x *ListResourcesRequest) Reset() { *x = ListResourcesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[59] + mi := &file_rill_runtime_v1_api_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3938,7 +4090,7 @@ func (x *ListResourcesRequest) String() string { func (*ListResourcesRequest) ProtoMessage() {} func (x *ListResourcesRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[59] + mi := &file_rill_runtime_v1_api_proto_msgTypes[61] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3951,7 +4103,7 @@ func (x *ListResourcesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListResourcesRequest.ProtoReflect.Descriptor instead. func (*ListResourcesRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{59} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{61} } func (x *ListResourcesRequest) GetInstanceId() string { @@ -3993,7 +4145,7 @@ type ListResourcesResponse struct { func (x *ListResourcesResponse) Reset() { *x = ListResourcesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[60] + mi := &file_rill_runtime_v1_api_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4006,7 +4158,7 @@ func (x *ListResourcesResponse) String() string { func (*ListResourcesResponse) ProtoMessage() {} func (x *ListResourcesResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[60] + mi := &file_rill_runtime_v1_api_proto_msgTypes[62] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4019,7 +4171,7 @@ func (x *ListResourcesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListResourcesResponse.ProtoReflect.Descriptor instead. func (*ListResourcesResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{60} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{62} } func (x *ListResourcesResponse) GetResources() []*Resource { @@ -4042,7 +4194,7 @@ type WatchResourcesRequest struct { func (x *WatchResourcesRequest) Reset() { *x = WatchResourcesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[61] + mi := &file_rill_runtime_v1_api_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4055,7 +4207,7 @@ func (x *WatchResourcesRequest) String() string { func (*WatchResourcesRequest) ProtoMessage() {} func (x *WatchResourcesRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[61] + mi := &file_rill_runtime_v1_api_proto_msgTypes[63] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4068,7 +4220,7 @@ func (x *WatchResourcesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchResourcesRequest.ProtoReflect.Descriptor instead. func (*WatchResourcesRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{61} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{63} } func (x *WatchResourcesRequest) GetInstanceId() string { @@ -4105,7 +4257,7 @@ type WatchResourcesResponse struct { func (x *WatchResourcesResponse) Reset() { *x = WatchResourcesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[62] + mi := &file_rill_runtime_v1_api_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4118,7 +4270,7 @@ func (x *WatchResourcesResponse) String() string { func (*WatchResourcesResponse) ProtoMessage() {} func (x *WatchResourcesResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[62] + mi := &file_rill_runtime_v1_api_proto_msgTypes[64] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4131,7 +4283,7 @@ func (x *WatchResourcesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchResourcesResponse.ProtoReflect.Descriptor instead. func (*WatchResourcesResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{62} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{64} } func (x *WatchResourcesResponse) GetEvent() ResourceEvent { @@ -4168,7 +4320,7 @@ type GetResourceRequest struct { func (x *GetResourceRequest) Reset() { *x = GetResourceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[63] + mi := &file_rill_runtime_v1_api_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4181,7 +4333,7 @@ func (x *GetResourceRequest) String() string { func (*GetResourceRequest) ProtoMessage() {} func (x *GetResourceRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[63] + mi := &file_rill_runtime_v1_api_proto_msgTypes[65] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4194,7 +4346,7 @@ func (x *GetResourceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetResourceRequest.ProtoReflect.Descriptor instead. func (*GetResourceRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{63} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{65} } func (x *GetResourceRequest) GetInstanceId() string { @@ -4229,7 +4381,7 @@ type GetResourceResponse struct { func (x *GetResourceResponse) Reset() { *x = GetResourceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[64] + mi := &file_rill_runtime_v1_api_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4242,7 +4394,7 @@ func (x *GetResourceResponse) String() string { func (*GetResourceResponse) ProtoMessage() {} func (x *GetResourceResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[64] + mi := &file_rill_runtime_v1_api_proto_msgTypes[66] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4255,7 +4407,7 @@ func (x *GetResourceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetResourceResponse.ProtoReflect.Descriptor instead. func (*GetResourceResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{64} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{66} } func (x *GetResourceResponse) GetResource() *Resource { @@ -4277,7 +4429,7 @@ type GetExploreRequest struct { func (x *GetExploreRequest) Reset() { *x = GetExploreRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[65] + mi := &file_rill_runtime_v1_api_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4290,7 +4442,7 @@ func (x *GetExploreRequest) String() string { func (*GetExploreRequest) ProtoMessage() {} func (x *GetExploreRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[65] + mi := &file_rill_runtime_v1_api_proto_msgTypes[67] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4303,7 +4455,7 @@ func (x *GetExploreRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetExploreRequest.ProtoReflect.Descriptor instead. func (*GetExploreRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{65} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{67} } func (x *GetExploreRequest) GetInstanceId() string { @@ -4332,7 +4484,7 @@ type GetExploreResponse struct { func (x *GetExploreResponse) Reset() { *x = GetExploreResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[66] + mi := &file_rill_runtime_v1_api_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4345,7 +4497,7 @@ func (x *GetExploreResponse) String() string { func (*GetExploreResponse) ProtoMessage() {} func (x *GetExploreResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[66] + mi := &file_rill_runtime_v1_api_proto_msgTypes[68] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4358,7 +4510,7 @@ func (x *GetExploreResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetExploreResponse.ProtoReflect.Descriptor instead. func (*GetExploreResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{66} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{68} } func (x *GetExploreResponse) GetExplore() *Resource { @@ -4391,7 +4543,7 @@ type GetModelPartitionsRequest struct { func (x *GetModelPartitionsRequest) Reset() { *x = GetModelPartitionsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[67] + mi := &file_rill_runtime_v1_api_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4404,7 +4556,7 @@ func (x *GetModelPartitionsRequest) String() string { func (*GetModelPartitionsRequest) ProtoMessage() {} func (x *GetModelPartitionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[67] + mi := &file_rill_runtime_v1_api_proto_msgTypes[69] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4417,7 +4569,7 @@ func (x *GetModelPartitionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetModelPartitionsRequest.ProtoReflect.Descriptor instead. func (*GetModelPartitionsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{67} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{69} } func (x *GetModelPartitionsRequest) GetInstanceId() string { @@ -4474,7 +4626,7 @@ type GetModelPartitionsResponse struct { func (x *GetModelPartitionsResponse) Reset() { *x = GetModelPartitionsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[68] + mi := &file_rill_runtime_v1_api_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4487,7 +4639,7 @@ func (x *GetModelPartitionsResponse) String() string { func (*GetModelPartitionsResponse) ProtoMessage() {} func (x *GetModelPartitionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[68] + mi := &file_rill_runtime_v1_api_proto_msgTypes[70] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4500,7 +4652,7 @@ func (x *GetModelPartitionsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetModelPartitionsResponse.ProtoReflect.Descriptor instead. func (*GetModelPartitionsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{68} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{70} } func (x *GetModelPartitionsResponse) GetPartitions() []*ModelPartition { @@ -4543,7 +4695,7 @@ type CreateTriggerRequest struct { func (x *CreateTriggerRequest) Reset() { *x = CreateTriggerRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[69] + mi := &file_rill_runtime_v1_api_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4556,7 +4708,7 @@ func (x *CreateTriggerRequest) String() string { func (*CreateTriggerRequest) ProtoMessage() {} func (x *CreateTriggerRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[69] + mi := &file_rill_runtime_v1_api_proto_msgTypes[71] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4569,7 +4721,7 @@ func (x *CreateTriggerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateTriggerRequest.ProtoReflect.Descriptor instead. func (*CreateTriggerRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{69} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{71} } func (x *CreateTriggerRequest) GetInstanceId() string { @@ -4623,7 +4775,7 @@ type CreateTriggerResponse struct { func (x *CreateTriggerResponse) Reset() { *x = CreateTriggerResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[70] + mi := &file_rill_runtime_v1_api_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4636,7 +4788,7 @@ func (x *CreateTriggerResponse) String() string { func (*CreateTriggerResponse) ProtoMessage() {} func (x *CreateTriggerResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[70] + mi := &file_rill_runtime_v1_api_proto_msgTypes[72] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4649,7 +4801,7 @@ func (x *CreateTriggerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateTriggerResponse.ProtoReflect.Descriptor instead. func (*CreateTriggerResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{70} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{72} } // ConnectorDriver represents a connector driver available in the runtime. @@ -4687,7 +4839,7 @@ type ConnectorDriver struct { func (x *ConnectorDriver) Reset() { *x = ConnectorDriver{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[71] + mi := &file_rill_runtime_v1_api_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4700,7 +4852,7 @@ func (x *ConnectorDriver) String() string { func (*ConnectorDriver) ProtoMessage() {} func (x *ConnectorDriver) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[71] + mi := &file_rill_runtime_v1_api_proto_msgTypes[73] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4713,7 +4865,7 @@ func (x *ConnectorDriver) ProtoReflect() protoreflect.Message { // Deprecated: Use ConnectorDriver.ProtoReflect.Descriptor instead. func (*ConnectorDriver) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{71} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{73} } func (x *ConnectorDriver) GetName() string { @@ -4868,7 +5020,7 @@ type AnalyzedConnector struct { func (x *AnalyzedConnector) Reset() { *x = AnalyzedConnector{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[72] + mi := &file_rill_runtime_v1_api_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4881,7 +5033,7 @@ func (x *AnalyzedConnector) String() string { func (*AnalyzedConnector) ProtoMessage() {} func (x *AnalyzedConnector) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[72] + mi := &file_rill_runtime_v1_api_proto_msgTypes[74] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4894,7 +5046,7 @@ func (x *AnalyzedConnector) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalyzedConnector.ProtoReflect.Descriptor instead. func (*AnalyzedConnector) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{72} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{74} } func (x *AnalyzedConnector) GetName() string { @@ -4984,7 +5136,7 @@ type ListConnectorDriversRequest struct { func (x *ListConnectorDriversRequest) Reset() { *x = ListConnectorDriversRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[73] + mi := &file_rill_runtime_v1_api_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4997,7 +5149,7 @@ func (x *ListConnectorDriversRequest) String() string { func (*ListConnectorDriversRequest) ProtoMessage() {} func (x *ListConnectorDriversRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[73] + mi := &file_rill_runtime_v1_api_proto_msgTypes[75] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5010,7 +5162,7 @@ func (x *ListConnectorDriversRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListConnectorDriversRequest.ProtoReflect.Descriptor instead. func (*ListConnectorDriversRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{73} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{75} } // Response message for RuntimeService.ListConnectorDrivers @@ -5025,7 +5177,7 @@ type ListConnectorDriversResponse struct { func (x *ListConnectorDriversResponse) Reset() { *x = ListConnectorDriversResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[74] + mi := &file_rill_runtime_v1_api_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5038,7 +5190,7 @@ func (x *ListConnectorDriversResponse) String() string { func (*ListConnectorDriversResponse) ProtoMessage() {} func (x *ListConnectorDriversResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[74] + mi := &file_rill_runtime_v1_api_proto_msgTypes[76] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5051,7 +5203,7 @@ func (x *ListConnectorDriversResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListConnectorDriversResponse.ProtoReflect.Descriptor instead. func (*ListConnectorDriversResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{74} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{76} } func (x *ListConnectorDriversResponse) GetConnectors() []*ConnectorDriver { @@ -5073,7 +5225,7 @@ type AnalyzeConnectorsRequest struct { func (x *AnalyzeConnectorsRequest) Reset() { *x = AnalyzeConnectorsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[75] + mi := &file_rill_runtime_v1_api_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5086,7 +5238,7 @@ func (x *AnalyzeConnectorsRequest) String() string { func (*AnalyzeConnectorsRequest) ProtoMessage() {} func (x *AnalyzeConnectorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[75] + mi := &file_rill_runtime_v1_api_proto_msgTypes[77] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5099,7 +5251,7 @@ func (x *AnalyzeConnectorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalyzeConnectorsRequest.ProtoReflect.Descriptor instead. func (*AnalyzeConnectorsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{75} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{77} } func (x *AnalyzeConnectorsRequest) GetInstanceId() string { @@ -5121,7 +5273,7 @@ type AnalyzeConnectorsResponse struct { func (x *AnalyzeConnectorsResponse) Reset() { *x = AnalyzeConnectorsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[76] + mi := &file_rill_runtime_v1_api_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5134,7 +5286,7 @@ func (x *AnalyzeConnectorsResponse) String() string { func (*AnalyzeConnectorsResponse) ProtoMessage() {} func (x *AnalyzeConnectorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[76] + mi := &file_rill_runtime_v1_api_proto_msgTypes[78] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5147,7 +5299,7 @@ func (x *AnalyzeConnectorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalyzeConnectorsResponse.ProtoReflect.Descriptor instead. func (*AnalyzeConnectorsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{76} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{78} } func (x *AnalyzeConnectorsResponse) GetConnectors() []*AnalyzedConnector { @@ -5169,7 +5321,7 @@ type ListNotifierConnectorsRequest struct { func (x *ListNotifierConnectorsRequest) Reset() { *x = ListNotifierConnectorsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[77] + mi := &file_rill_runtime_v1_api_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5182,7 +5334,7 @@ func (x *ListNotifierConnectorsRequest) String() string { func (*ListNotifierConnectorsRequest) ProtoMessage() {} func (x *ListNotifierConnectorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[77] + mi := &file_rill_runtime_v1_api_proto_msgTypes[79] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5195,7 +5347,7 @@ func (x *ListNotifierConnectorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListNotifierConnectorsRequest.ProtoReflect.Descriptor instead. func (*ListNotifierConnectorsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{77} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{79} } func (x *ListNotifierConnectorsRequest) GetInstanceId() string { @@ -5218,7 +5370,7 @@ type ListNotifierConnectorsResponse struct { func (x *ListNotifierConnectorsResponse) Reset() { *x = ListNotifierConnectorsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[78] + mi := &file_rill_runtime_v1_api_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5231,7 +5383,7 @@ func (x *ListNotifierConnectorsResponse) String() string { func (*ListNotifierConnectorsResponse) ProtoMessage() {} func (x *ListNotifierConnectorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[78] + mi := &file_rill_runtime_v1_api_proto_msgTypes[80] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5244,7 +5396,7 @@ func (x *ListNotifierConnectorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListNotifierConnectorsResponse.ProtoReflect.Descriptor instead. func (*ListNotifierConnectorsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{78} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{80} } func (x *ListNotifierConnectorsResponse) GetConnectors() []*Connector { @@ -5272,7 +5424,7 @@ type Conversation struct { func (x *Conversation) Reset() { *x = Conversation{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[79] + mi := &file_rill_runtime_v1_api_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5285,7 +5437,7 @@ func (x *Conversation) String() string { func (*Conversation) ProtoMessage() {} func (x *Conversation) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[79] + mi := &file_rill_runtime_v1_api_proto_msgTypes[81] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5298,7 +5450,7 @@ func (x *Conversation) ProtoReflect() protoreflect.Message { // Deprecated: Use Conversation.ProtoReflect.Descriptor instead. func (*Conversation) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{79} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{81} } func (x *Conversation) GetId() string { @@ -5372,7 +5524,7 @@ type Message struct { func (x *Message) Reset() { *x = Message{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[80] + mi := &file_rill_runtime_v1_api_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5385,7 +5537,7 @@ func (x *Message) String() string { func (*Message) ProtoMessage() {} func (x *Message) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[80] + mi := &file_rill_runtime_v1_api_proto_msgTypes[82] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5398,7 +5550,7 @@ func (x *Message) ProtoReflect() protoreflect.Message { // Deprecated: Use Message.ProtoReflect.Descriptor instead. func (*Message) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{80} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{82} } func (x *Message) GetId() string { @@ -5509,7 +5661,7 @@ type AnalystAgentContext struct { func (x *AnalystAgentContext) Reset() { *x = AnalystAgentContext{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[81] + mi := &file_rill_runtime_v1_api_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5522,7 +5674,7 @@ func (x *AnalystAgentContext) String() string { func (*AnalystAgentContext) ProtoMessage() {} func (x *AnalystAgentContext) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[81] + mi := &file_rill_runtime_v1_api_proto_msgTypes[83] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5535,7 +5687,7 @@ func (x *AnalystAgentContext) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalystAgentContext.ProtoReflect.Descriptor instead. func (*AnalystAgentContext) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{81} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{83} } func (x *AnalystAgentContext) GetExplore() string { @@ -5618,7 +5770,7 @@ type DeveloperAgentContext struct { func (x *DeveloperAgentContext) Reset() { *x = DeveloperAgentContext{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[82] + mi := &file_rill_runtime_v1_api_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5631,7 +5783,7 @@ func (x *DeveloperAgentContext) String() string { func (*DeveloperAgentContext) ProtoMessage() {} func (x *DeveloperAgentContext) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[82] + mi := &file_rill_runtime_v1_api_proto_msgTypes[84] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5644,7 +5796,7 @@ func (x *DeveloperAgentContext) ProtoReflect() protoreflect.Message { // Deprecated: Use DeveloperAgentContext.ProtoReflect.Descriptor instead. func (*DeveloperAgentContext) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{82} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{84} } func (x *DeveloperAgentContext) GetInitProject() bool { @@ -5681,7 +5833,7 @@ type FeedbackAgentContext struct { func (x *FeedbackAgentContext) Reset() { *x = FeedbackAgentContext{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[83] + mi := &file_rill_runtime_v1_api_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5694,7 +5846,7 @@ func (x *FeedbackAgentContext) String() string { func (*FeedbackAgentContext) ProtoMessage() {} func (x *FeedbackAgentContext) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[83] + mi := &file_rill_runtime_v1_api_proto_msgTypes[85] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5707,7 +5859,7 @@ func (x *FeedbackAgentContext) ProtoReflect() protoreflect.Message { // Deprecated: Use FeedbackAgentContext.ProtoReflect.Descriptor instead. func (*FeedbackAgentContext) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{83} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{85} } func (x *FeedbackAgentContext) GetTargetMessageId() string { @@ -5752,7 +5904,7 @@ type ListConversationsRequest struct { func (x *ListConversationsRequest) Reset() { *x = ListConversationsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[84] + mi := &file_rill_runtime_v1_api_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5765,7 +5917,7 @@ func (x *ListConversationsRequest) String() string { func (*ListConversationsRequest) ProtoMessage() {} func (x *ListConversationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[84] + mi := &file_rill_runtime_v1_api_proto_msgTypes[86] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5778,7 +5930,7 @@ func (x *ListConversationsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListConversationsRequest.ProtoReflect.Descriptor instead. func (*ListConversationsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{84} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{86} } func (x *ListConversationsRequest) GetInstanceId() string { @@ -5807,7 +5959,7 @@ type ListConversationsResponse struct { func (x *ListConversationsResponse) Reset() { *x = ListConversationsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[85] + mi := &file_rill_runtime_v1_api_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5820,7 +5972,7 @@ func (x *ListConversationsResponse) String() string { func (*ListConversationsResponse) ProtoMessage() {} func (x *ListConversationsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[85] + mi := &file_rill_runtime_v1_api_proto_msgTypes[87] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5833,7 +5985,7 @@ func (x *ListConversationsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListConversationsResponse.ProtoReflect.Descriptor instead. func (*ListConversationsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{85} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{87} } func (x *ListConversationsResponse) GetConversations() []*Conversation { @@ -5856,7 +6008,7 @@ type GetConversationRequest struct { func (x *GetConversationRequest) Reset() { *x = GetConversationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[86] + mi := &file_rill_runtime_v1_api_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5869,7 +6021,7 @@ func (x *GetConversationRequest) String() string { func (*GetConversationRequest) ProtoMessage() {} func (x *GetConversationRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[86] + mi := &file_rill_runtime_v1_api_proto_msgTypes[88] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5882,7 +6034,7 @@ func (x *GetConversationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetConversationRequest.ProtoReflect.Descriptor instead. func (*GetConversationRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{86} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{88} } func (x *GetConversationRequest) GetInstanceId() string { @@ -5913,7 +6065,7 @@ type GetConversationResponse struct { func (x *GetConversationResponse) Reset() { *x = GetConversationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[87] + mi := &file_rill_runtime_v1_api_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5926,7 +6078,7 @@ func (x *GetConversationResponse) String() string { func (*GetConversationResponse) ProtoMessage() {} func (x *GetConversationResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[87] + mi := &file_rill_runtime_v1_api_proto_msgTypes[89] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5939,7 +6091,7 @@ func (x *GetConversationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetConversationResponse.ProtoReflect.Descriptor instead. func (*GetConversationResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{87} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{89} } func (x *GetConversationResponse) GetConversation() *Conversation { @@ -5980,7 +6132,7 @@ type ShareConversationRequest struct { func (x *ShareConversationRequest) Reset() { *x = ShareConversationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[88] + mi := &file_rill_runtime_v1_api_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5993,7 +6145,7 @@ func (x *ShareConversationRequest) String() string { func (*ShareConversationRequest) ProtoMessage() {} func (x *ShareConversationRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[88] + mi := &file_rill_runtime_v1_api_proto_msgTypes[90] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6006,7 +6158,7 @@ func (x *ShareConversationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShareConversationRequest.ProtoReflect.Descriptor instead. func (*ShareConversationRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{88} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{90} } func (x *ShareConversationRequest) GetInstanceId() string { @@ -6040,7 +6192,7 @@ type ShareConversationResponse struct { func (x *ShareConversationResponse) Reset() { *x = ShareConversationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[89] + mi := &file_rill_runtime_v1_api_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6053,7 +6205,7 @@ func (x *ShareConversationResponse) String() string { func (*ShareConversationResponse) ProtoMessage() {} func (x *ShareConversationResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[89] + mi := &file_rill_runtime_v1_api_proto_msgTypes[91] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6066,7 +6218,7 @@ func (x *ShareConversationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShareConversationResponse.ProtoReflect.Descriptor instead. func (*ShareConversationResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{89} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{91} } // Request message for RuntimeService.ForkConversation @@ -6082,7 +6234,7 @@ type ForkConversationRequest struct { func (x *ForkConversationRequest) Reset() { *x = ForkConversationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[90] + mi := &file_rill_runtime_v1_api_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6095,7 +6247,7 @@ func (x *ForkConversationRequest) String() string { func (*ForkConversationRequest) ProtoMessage() {} func (x *ForkConversationRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[90] + mi := &file_rill_runtime_v1_api_proto_msgTypes[92] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6108,7 +6260,7 @@ func (x *ForkConversationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ForkConversationRequest.ProtoReflect.Descriptor instead. func (*ForkConversationRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{90} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{92} } func (x *ForkConversationRequest) GetInstanceId() string { @@ -6137,7 +6289,7 @@ type ForkConversationResponse struct { func (x *ForkConversationResponse) Reset() { *x = ForkConversationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[91] + mi := &file_rill_runtime_v1_api_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6150,7 +6302,7 @@ func (x *ForkConversationResponse) String() string { func (*ForkConversationResponse) ProtoMessage() {} func (x *ForkConversationResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[91] + mi := &file_rill_runtime_v1_api_proto_msgTypes[93] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6163,7 +6315,7 @@ func (x *ForkConversationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ForkConversationResponse.ProtoReflect.Descriptor instead. func (*ForkConversationResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{91} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{93} } func (x *ForkConversationResponse) GetConversationId() string { @@ -6185,7 +6337,7 @@ type ListToolsRequest struct { func (x *ListToolsRequest) Reset() { *x = ListToolsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[92] + mi := &file_rill_runtime_v1_api_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6198,7 +6350,7 @@ func (x *ListToolsRequest) String() string { func (*ListToolsRequest) ProtoMessage() {} func (x *ListToolsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[92] + mi := &file_rill_runtime_v1_api_proto_msgTypes[94] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6211,7 +6363,7 @@ func (x *ListToolsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListToolsRequest.ProtoReflect.Descriptor instead. func (*ListToolsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{92} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{94} } func (x *ListToolsRequest) GetInstanceId() string { @@ -6233,7 +6385,7 @@ type ListToolsResponse struct { func (x *ListToolsResponse) Reset() { *x = ListToolsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[93] + mi := &file_rill_runtime_v1_api_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6246,7 +6398,7 @@ func (x *ListToolsResponse) String() string { func (*ListToolsResponse) ProtoMessage() {} func (x *ListToolsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[93] + mi := &file_rill_runtime_v1_api_proto_msgTypes[95] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6259,7 +6411,7 @@ func (x *ListToolsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListToolsResponse.ProtoReflect.Descriptor instead. func (*ListToolsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{93} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{95} } func (x *ListToolsResponse) GetTools() []*v1.Tool { @@ -6298,7 +6450,7 @@ type CompleteRequest struct { func (x *CompleteRequest) Reset() { *x = CompleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[94] + mi := &file_rill_runtime_v1_api_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6311,7 +6463,7 @@ func (x *CompleteRequest) String() string { func (*CompleteRequest) ProtoMessage() {} func (x *CompleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[94] + mi := &file_rill_runtime_v1_api_proto_msgTypes[96] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6324,7 +6476,7 @@ func (x *CompleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CompleteRequest.ProtoReflect.Descriptor instead. func (*CompleteRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{94} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{96} } func (x *CompleteRequest) GetInstanceId() string { @@ -6389,7 +6541,7 @@ type CompleteResponse struct { func (x *CompleteResponse) Reset() { *x = CompleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[95] + mi := &file_rill_runtime_v1_api_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6402,7 +6554,7 @@ func (x *CompleteResponse) String() string { func (*CompleteResponse) ProtoMessage() {} func (x *CompleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[95] + mi := &file_rill_runtime_v1_api_proto_msgTypes[97] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6415,7 +6567,7 @@ func (x *CompleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CompleteResponse.ProtoReflect.Descriptor instead. func (*CompleteResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{95} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{97} } func (x *CompleteResponse) GetConversationId() string { @@ -6461,7 +6613,7 @@ type CompleteStreamingRequest struct { func (x *CompleteStreamingRequest) Reset() { *x = CompleteStreamingRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[96] + mi := &file_rill_runtime_v1_api_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6474,7 +6626,7 @@ func (x *CompleteStreamingRequest) String() string { func (*CompleteStreamingRequest) ProtoMessage() {} func (x *CompleteStreamingRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[96] + mi := &file_rill_runtime_v1_api_proto_msgTypes[98] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6487,7 +6639,7 @@ func (x *CompleteStreamingRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CompleteStreamingRequest.ProtoReflect.Descriptor instead. func (*CompleteStreamingRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{96} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{98} } func (x *CompleteStreamingRequest) GetInstanceId() string { @@ -6552,7 +6704,7 @@ type CompleteStreamingResponse struct { func (x *CompleteStreamingResponse) Reset() { *x = CompleteStreamingResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[97] + mi := &file_rill_runtime_v1_api_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6565,7 +6717,7 @@ func (x *CompleteStreamingResponse) String() string { func (*CompleteStreamingResponse) ProtoMessage() {} func (x *CompleteStreamingResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[97] + mi := &file_rill_runtime_v1_api_proto_msgTypes[99] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6578,7 +6730,7 @@ func (x *CompleteStreamingResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CompleteStreamingResponse.ProtoReflect.Descriptor instead. func (*CompleteStreamingResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{97} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{99} } func (x *CompleteStreamingResponse) GetConversationId() string { @@ -6613,7 +6765,7 @@ type IssueDevJWTRequest struct { func (x *IssueDevJWTRequest) Reset() { *x = IssueDevJWTRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[98] + mi := &file_rill_runtime_v1_api_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6626,7 +6778,7 @@ func (x *IssueDevJWTRequest) String() string { func (*IssueDevJWTRequest) ProtoMessage() {} func (x *IssueDevJWTRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[98] + mi := &file_rill_runtime_v1_api_proto_msgTypes[100] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6639,7 +6791,7 @@ func (x *IssueDevJWTRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use IssueDevJWTRequest.ProtoReflect.Descriptor instead. func (*IssueDevJWTRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{98} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{100} } func (x *IssueDevJWTRequest) GetName() string { @@ -6689,7 +6841,7 @@ type IssueDevJWTResponse struct { func (x *IssueDevJWTResponse) Reset() { *x = IssueDevJWTResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[99] + mi := &file_rill_runtime_v1_api_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6702,7 +6854,7 @@ func (x *IssueDevJWTResponse) String() string { func (*IssueDevJWTResponse) ProtoMessage() {} func (x *IssueDevJWTResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[99] + mi := &file_rill_runtime_v1_api_proto_msgTypes[101] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6715,7 +6867,7 @@ func (x *IssueDevJWTResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use IssueDevJWTResponse.ProtoReflect.Descriptor instead. func (*IssueDevJWTResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{99} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{101} } func (x *IssueDevJWTResponse) GetJwt() string { @@ -6737,7 +6889,7 @@ type AnalyzeVariablesRequest struct { func (x *AnalyzeVariablesRequest) Reset() { *x = AnalyzeVariablesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[100] + mi := &file_rill_runtime_v1_api_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6750,7 +6902,7 @@ func (x *AnalyzeVariablesRequest) String() string { func (*AnalyzeVariablesRequest) ProtoMessage() {} func (x *AnalyzeVariablesRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[100] + mi := &file_rill_runtime_v1_api_proto_msgTypes[102] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6763,7 +6915,7 @@ func (x *AnalyzeVariablesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalyzeVariablesRequest.ProtoReflect.Descriptor instead. func (*AnalyzeVariablesRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{100} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{102} } func (x *AnalyzeVariablesRequest) GetInstanceId() string { @@ -6785,7 +6937,7 @@ type AnalyzeVariablesResponse struct { func (x *AnalyzeVariablesResponse) Reset() { *x = AnalyzeVariablesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[101] + mi := &file_rill_runtime_v1_api_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6798,7 +6950,7 @@ func (x *AnalyzeVariablesResponse) String() string { func (*AnalyzeVariablesResponse) ProtoMessage() {} func (x *AnalyzeVariablesResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[101] + mi := &file_rill_runtime_v1_api_proto_msgTypes[103] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6811,7 +6963,7 @@ func (x *AnalyzeVariablesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalyzeVariablesResponse.ProtoReflect.Descriptor instead. func (*AnalyzeVariablesResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{101} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{103} } func (x *AnalyzeVariablesResponse) GetVariables() []*AnalyzedVariable { @@ -6837,7 +6989,7 @@ type AnalyzedVariable struct { func (x *AnalyzedVariable) Reset() { *x = AnalyzedVariable{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[102] + mi := &file_rill_runtime_v1_api_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6850,7 +7002,7 @@ func (x *AnalyzedVariable) String() string { func (*AnalyzedVariable) ProtoMessage() {} func (x *AnalyzedVariable) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[102] + mi := &file_rill_runtime_v1_api_proto_msgTypes[104] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6863,7 +7015,7 @@ func (x *AnalyzedVariable) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalyzedVariable.ProtoReflect.Descriptor instead. func (*AnalyzedVariable) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{102} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{104} } func (x *AnalyzedVariable) GetName() string { @@ -6900,7 +7052,7 @@ type ListGitCommitsRequest struct { func (x *ListGitCommitsRequest) Reset() { *x = ListGitCommitsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[103] + mi := &file_rill_runtime_v1_api_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6913,7 +7065,7 @@ func (x *ListGitCommitsRequest) String() string { func (*ListGitCommitsRequest) ProtoMessage() {} func (x *ListGitCommitsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[103] + mi := &file_rill_runtime_v1_api_proto_msgTypes[105] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6926,7 +7078,7 @@ func (x *ListGitCommitsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListGitCommitsRequest.ProtoReflect.Descriptor instead. func (*ListGitCommitsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{103} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{105} } func (x *ListGitCommitsRequest) GetInstanceId() string { @@ -6962,7 +7114,7 @@ type ListGitCommitsResponse struct { func (x *ListGitCommitsResponse) Reset() { *x = ListGitCommitsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[104] + mi := &file_rill_runtime_v1_api_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6975,7 +7127,7 @@ func (x *ListGitCommitsResponse) String() string { func (*ListGitCommitsResponse) ProtoMessage() {} func (x *ListGitCommitsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[104] + mi := &file_rill_runtime_v1_api_proto_msgTypes[106] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6988,7 +7140,7 @@ func (x *ListGitCommitsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListGitCommitsResponse.ProtoReflect.Descriptor instead. func (*ListGitCommitsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{104} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{106} } func (x *ListGitCommitsResponse) GetCommits() []*GitCommit { @@ -7020,7 +7172,7 @@ type GitCommit struct { func (x *GitCommit) Reset() { *x = GitCommit{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[105] + mi := &file_rill_runtime_v1_api_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7033,7 +7185,7 @@ func (x *GitCommit) String() string { func (*GitCommit) ProtoMessage() {} func (x *GitCommit) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[105] + mi := &file_rill_runtime_v1_api_proto_msgTypes[107] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7046,7 +7198,7 @@ func (x *GitCommit) ProtoReflect() protoreflect.Message { // Deprecated: Use GitCommit.ProtoReflect.Descriptor instead. func (*GitCommit) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{105} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{107} } func (x *GitCommit) GetCommitSha() string { @@ -7095,7 +7247,7 @@ type GitStatusRequest struct { func (x *GitStatusRequest) Reset() { *x = GitStatusRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[106] + mi := &file_rill_runtime_v1_api_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7108,7 +7260,7 @@ func (x *GitStatusRequest) String() string { func (*GitStatusRequest) ProtoMessage() {} func (x *GitStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[106] + mi := &file_rill_runtime_v1_api_proto_msgTypes[108] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7121,7 +7273,7 @@ func (x *GitStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GitStatusRequest.ProtoReflect.Descriptor instead. func (*GitStatusRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{106} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{108} } func (x *GitStatusRequest) GetInstanceId() string { @@ -7153,7 +7305,7 @@ type GitStatusResponse struct { func (x *GitStatusResponse) Reset() { *x = GitStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[107] + mi := &file_rill_runtime_v1_api_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7166,7 +7318,7 @@ func (x *GitStatusResponse) String() string { func (*GitStatusResponse) ProtoMessage() {} func (x *GitStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[107] + mi := &file_rill_runtime_v1_api_proto_msgTypes[109] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7179,7 +7331,7 @@ func (x *GitStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GitStatusResponse.ProtoReflect.Descriptor instead. func (*GitStatusResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{107} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{109} } func (x *GitStatusResponse) GetBranch() string { @@ -7235,7 +7387,7 @@ type ListGitBranchesRequest struct { func (x *ListGitBranchesRequest) Reset() { *x = ListGitBranchesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[108] + mi := &file_rill_runtime_v1_api_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7248,7 +7400,7 @@ func (x *ListGitBranchesRequest) String() string { func (*ListGitBranchesRequest) ProtoMessage() {} func (x *ListGitBranchesRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[108] + mi := &file_rill_runtime_v1_api_proto_msgTypes[110] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7261,7 +7413,7 @@ func (x *ListGitBranchesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListGitBranchesRequest.ProtoReflect.Descriptor instead. func (*ListGitBranchesRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{108} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{110} } func (x *ListGitBranchesRequest) GetInstanceId() string { @@ -7283,7 +7435,7 @@ type ListGitBranchesResponse struct { func (x *ListGitBranchesResponse) Reset() { *x = ListGitBranchesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[109] + mi := &file_rill_runtime_v1_api_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7296,7 +7448,7 @@ func (x *ListGitBranchesResponse) String() string { func (*ListGitBranchesResponse) ProtoMessage() {} func (x *ListGitBranchesResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[109] + mi := &file_rill_runtime_v1_api_proto_msgTypes[111] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7309,7 +7461,7 @@ func (x *ListGitBranchesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListGitBranchesResponse.ProtoReflect.Descriptor instead. func (*ListGitBranchesResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{109} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{111} } func (x *ListGitBranchesResponse) GetCurrentBranch() string { @@ -7339,7 +7491,7 @@ type GitBranch struct { func (x *GitBranch) Reset() { *x = GitBranch{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[110] + mi := &file_rill_runtime_v1_api_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7352,7 +7504,7 @@ func (x *GitBranch) String() string { func (*GitBranch) ProtoMessage() {} func (x *GitBranch) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[110] + mi := &file_rill_runtime_v1_api_proto_msgTypes[112] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7365,7 +7517,7 @@ func (x *GitBranch) ProtoReflect() protoreflect.Message { // Deprecated: Use GitBranch.ProtoReflect.Descriptor instead. func (*GitBranch) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{110} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{112} } func (x *GitBranch) GetName() string { @@ -7401,7 +7553,7 @@ type GitCommitRequest struct { func (x *GitCommitRequest) Reset() { *x = GitCommitRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[111] + mi := &file_rill_runtime_v1_api_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7414,7 +7566,7 @@ func (x *GitCommitRequest) String() string { func (*GitCommitRequest) ProtoMessage() {} func (x *GitCommitRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[111] + mi := &file_rill_runtime_v1_api_proto_msgTypes[113] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7427,7 +7579,7 @@ func (x *GitCommitRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GitCommitRequest.ProtoReflect.Descriptor instead. func (*GitCommitRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{111} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{113} } func (x *GitCommitRequest) GetInstanceId() string { @@ -7455,7 +7607,7 @@ type GitCommitResponse struct { func (x *GitCommitResponse) Reset() { *x = GitCommitResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[112] + mi := &file_rill_runtime_v1_api_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7468,7 +7620,7 @@ func (x *GitCommitResponse) String() string { func (*GitCommitResponse) ProtoMessage() {} func (x *GitCommitResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[112] + mi := &file_rill_runtime_v1_api_proto_msgTypes[114] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7481,7 +7633,7 @@ func (x *GitCommitResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GitCommitResponse.ProtoReflect.Descriptor instead. func (*GitCommitResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{112} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{114} } func (x *GitCommitResponse) GetCommitSha() string { @@ -7504,7 +7656,7 @@ type RestoreGitCommitRequest struct { func (x *RestoreGitCommitRequest) Reset() { *x = RestoreGitCommitRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[113] + mi := &file_rill_runtime_v1_api_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7517,7 +7669,7 @@ func (x *RestoreGitCommitRequest) String() string { func (*RestoreGitCommitRequest) ProtoMessage() {} func (x *RestoreGitCommitRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[113] + mi := &file_rill_runtime_v1_api_proto_msgTypes[115] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7530,7 +7682,7 @@ func (x *RestoreGitCommitRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreGitCommitRequest.ProtoReflect.Descriptor instead. func (*RestoreGitCommitRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{113} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{115} } func (x *RestoreGitCommitRequest) GetInstanceId() string { @@ -7559,7 +7711,7 @@ type RestoreGitCommitResponse struct { func (x *RestoreGitCommitResponse) Reset() { *x = RestoreGitCommitResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[114] + mi := &file_rill_runtime_v1_api_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7572,7 +7724,7 @@ func (x *RestoreGitCommitResponse) String() string { func (*RestoreGitCommitResponse) ProtoMessage() {} func (x *RestoreGitCommitResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[114] + mi := &file_rill_runtime_v1_api_proto_msgTypes[116] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7585,7 +7737,7 @@ func (x *RestoreGitCommitResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreGitCommitResponse.ProtoReflect.Descriptor instead. func (*RestoreGitCommitResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{114} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{116} } func (x *RestoreGitCommitResponse) GetNewCommitSha() string { @@ -7609,7 +7761,7 @@ type GitMergeToBranchRequest struct { func (x *GitMergeToBranchRequest) Reset() { *x = GitMergeToBranchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[115] + mi := &file_rill_runtime_v1_api_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7622,7 +7774,7 @@ func (x *GitMergeToBranchRequest) String() string { func (*GitMergeToBranchRequest) ProtoMessage() {} func (x *GitMergeToBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[115] + mi := &file_rill_runtime_v1_api_proto_msgTypes[117] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7635,7 +7787,7 @@ func (x *GitMergeToBranchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GitMergeToBranchRequest.ProtoReflect.Descriptor instead. func (*GitMergeToBranchRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{115} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{117} } func (x *GitMergeToBranchRequest) GetInstanceId() string { @@ -7671,7 +7823,7 @@ type GitMergeToBranchResponse struct { func (x *GitMergeToBranchResponse) Reset() { *x = GitMergeToBranchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[116] + mi := &file_rill_runtime_v1_api_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7684,7 +7836,7 @@ func (x *GitMergeToBranchResponse) String() string { func (*GitMergeToBranchResponse) ProtoMessage() {} func (x *GitMergeToBranchResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[116] + mi := &file_rill_runtime_v1_api_proto_msgTypes[118] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7697,7 +7849,7 @@ func (x *GitMergeToBranchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GitMergeToBranchResponse.ProtoReflect.Descriptor instead. func (*GitMergeToBranchResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{116} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{118} } func (x *GitMergeToBranchResponse) GetOutput() string { @@ -7721,7 +7873,7 @@ type GitSwitchBranchRequest struct { func (x *GitSwitchBranchRequest) Reset() { *x = GitSwitchBranchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[117] + mi := &file_rill_runtime_v1_api_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7734,7 +7886,7 @@ func (x *GitSwitchBranchRequest) String() string { func (*GitSwitchBranchRequest) ProtoMessage() {} func (x *GitSwitchBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[117] + mi := &file_rill_runtime_v1_api_proto_msgTypes[119] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7747,7 +7899,7 @@ func (x *GitSwitchBranchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GitSwitchBranchRequest.ProtoReflect.Descriptor instead. func (*GitSwitchBranchRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{117} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{119} } func (x *GitSwitchBranchRequest) GetInstanceId() string { @@ -7787,7 +7939,7 @@ type GitSwitchBranchResponse struct { func (x *GitSwitchBranchResponse) Reset() { *x = GitSwitchBranchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[118] + mi := &file_rill_runtime_v1_api_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7800,7 +7952,7 @@ func (x *GitSwitchBranchResponse) String() string { func (*GitSwitchBranchResponse) ProtoMessage() {} func (x *GitSwitchBranchResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[118] + mi := &file_rill_runtime_v1_api_proto_msgTypes[120] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7813,7 +7965,7 @@ func (x *GitSwitchBranchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GitSwitchBranchResponse.ProtoReflect.Descriptor instead. func (*GitSwitchBranchResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{118} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{120} } type GitPullRequest struct { @@ -7828,7 +7980,7 @@ type GitPullRequest struct { func (x *GitPullRequest) Reset() { *x = GitPullRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[119] + mi := &file_rill_runtime_v1_api_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7841,7 +7993,7 @@ func (x *GitPullRequest) String() string { func (*GitPullRequest) ProtoMessage() {} func (x *GitPullRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[119] + mi := &file_rill_runtime_v1_api_proto_msgTypes[121] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7854,7 +8006,7 @@ func (x *GitPullRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GitPullRequest.ProtoReflect.Descriptor instead. func (*GitPullRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{119} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{121} } func (x *GitPullRequest) GetInstanceId() string { @@ -7883,7 +8035,7 @@ type GitPullResponse struct { func (x *GitPullResponse) Reset() { *x = GitPullResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[120] + mi := &file_rill_runtime_v1_api_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7896,7 +8048,7 @@ func (x *GitPullResponse) String() string { func (*GitPullResponse) ProtoMessage() {} func (x *GitPullResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[120] + mi := &file_rill_runtime_v1_api_proto_msgTypes[122] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7909,7 +8061,7 @@ func (x *GitPullResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GitPullResponse.ProtoReflect.Descriptor instead. func (*GitPullResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{120} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{122} } func (x *GitPullResponse) GetOutput() string { @@ -7932,7 +8084,7 @@ type GitPushRequest struct { func (x *GitPushRequest) Reset() { *x = GitPushRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[121] + mi := &file_rill_runtime_v1_api_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7945,7 +8097,7 @@ func (x *GitPushRequest) String() string { func (*GitPushRequest) ProtoMessage() {} func (x *GitPushRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[121] + mi := &file_rill_runtime_v1_api_proto_msgTypes[123] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7958,7 +8110,7 @@ func (x *GitPushRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GitPushRequest.ProtoReflect.Descriptor instead. func (*GitPushRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{121} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{123} } func (x *GitPushRequest) GetInstanceId() string { @@ -7991,7 +8143,7 @@ type GitPushResponse struct { func (x *GitPushResponse) Reset() { *x = GitPushResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[122] + mi := &file_rill_runtime_v1_api_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8004,7 +8156,7 @@ func (x *GitPushResponse) String() string { func (*GitPushResponse) ProtoMessage() {} func (x *GitPushResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[122] + mi := &file_rill_runtime_v1_api_proto_msgTypes[124] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8017,7 +8169,7 @@ func (x *GitPushResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GitPushResponse.ProtoReflect.Descriptor instead. func (*GitPushResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{122} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{124} } // Property represents the spec of one of the driver's config properties @@ -8053,7 +8205,7 @@ type ConnectorDriver_Property struct { func (x *ConnectorDriver_Property) Reset() { *x = ConnectorDriver_Property{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[131] + mi := &file_rill_runtime_v1_api_proto_msgTypes[134] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8066,7 +8218,7 @@ func (x *ConnectorDriver_Property) String() string { func (*ConnectorDriver_Property) ProtoMessage() {} func (x *ConnectorDriver_Property) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[131] + mi := &file_rill_runtime_v1_api_proto_msgTypes[134] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8079,7 +8231,7 @@ func (x *ConnectorDriver_Property) ProtoReflect() protoreflect.Message { // Deprecated: Use ConnectorDriver_Property.ProtoReflect.Descriptor instead. func (*ConnectorDriver_Property) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{71, 0} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{73, 0} } func (x *ConnectorDriver_Property) GetKey() string { @@ -8657,1261 +8809,1305 @@ var file_rill_runtime_v1_api_proto_rawDesc = []byte{ 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, 0x12, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, - 0x22, 0xf1, 0x01, 0x0a, 0x14, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, - 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, - 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, - 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 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, 0x12, 0x72, 0x65, - 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, - 0x12, 0x3c, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x72, 0x67, - 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x22, 0xa4, 0x02, 0x0a, 0x17, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, + 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x3c, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x17, + 0xfa, 0x42, 0x14, 0x72, 0x12, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x30, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, + 0x61, 0x2d, 0x7a, 0x5d, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5f, 0x5d, 0x2a, 0x24, 0x52, + 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x37, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x04, 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, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, + 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xfa, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x12, 0x51, 0x0a, 0x08, 0x65, 0x6e, 0x76, 0x5f, + 0x76, 0x61, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x1a, 0x3a, 0x0a, 0x0c, 0x45, 0x6e, 0x76, 0x56, + 0x61, 0x72, 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, 0xf1, 0x01, 0x0a, 0x14, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, + 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, + 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x65, + 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x18, 0x03, 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, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x41, 0x72, 0x67, 0x73, 0x12, 0x14, - 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, - 0x69, 0x6d, 0x69, 0x74, 0x22, 0xa6, 0x01, 0x0a, 0x15, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, - 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, - 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 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, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x33, 0x0a, 0x06, 0x73, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, - 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x12, 0x2b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 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, 0x22, 0xa3, 0x01, - 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, - 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, - 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, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x12, 0x21, 0x0a, 0x0c, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6a, 0x73, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, - 0x6f, 0x61, 0x64, 0x22, 0xfb, 0x01, 0x0a, 0x0e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, - 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 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, 0x12, 0x38, 0x0a, 0x09, 0x77, 0x61, 0x74, 0x65, 0x72, 0x6d, 0x61, - 0x72, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x69, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, + 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x04, 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, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x41, 0x72, + 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0xa6, 0x01, 0x0a, 0x15, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 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, 0x6d, 0x65, 0x74, 0x61, 0x12, + 0x33, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x12, 0x2b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, + 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, 0x22, 0xa3, 0x01, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, + 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, + 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x02, 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, 0x09, 0x77, 0x61, 0x74, 0x65, 0x72, 0x6d, 0x61, 0x72, 0x6b, 0x12, - 0x3b, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x04, - 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, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x14, 0x0a, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x5f, 0x6d, 0x73, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x4d, - 0x73, 0x22, 0xa8, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, - 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x12, 0x26, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x05, 0x42, 0x10, 0xfa, 0x42, 0x0d, 0x1a, 0x0b, 0x28, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x01, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x2f, 0x0a, 0x05, 0x6c, - 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, - 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x3b, 0x0a, 0x0f, - 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x28, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0xb1, 0x01, 0x0a, 0x10, 0x57, 0x61, - 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, - 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, - 0x16, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x12, 0x33, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6c, 0x61, - 0x79, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x10, 0xfa, - 0x42, 0x0d, 0x1a, 0x0b, 0x28, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x52, - 0x0b, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x2f, 0x0a, 0x05, - 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, - 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x3b, 0x0a, - 0x11, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x26, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x22, 0x91, 0x01, 0x0a, 0x14, 0x4c, - 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x30, 0x0a, 0x14, - 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x68, - 0x65, 0x63, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x73, 0x6b, 0x69, 0x70, - 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x22, 0x50, - 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x22, 0x64, 0x0a, 0x15, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, - 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x16, - 0x0a, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, - 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x22, 0xb8, 0x01, 0x0a, 0x16, 0x57, 0x61, 0x74, 0x63, 0x68, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x34, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x79, + 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6a, 0x73, 0x6f, 0x6e, + 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xfb, 0x01, 0x0a, 0x0e, 0x4d, 0x6f, 0x64, 0x65, + 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 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, 0x12, 0x38, 0x0a, 0x09, 0x77, 0x61, 0x74, + 0x65, 0x72, 0x6d, 0x61, 0x72, 0x6b, 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, 0x09, 0x77, 0x61, 0x74, 0x65, 0x72, 0x6d, + 0x61, 0x72, 0x6b, 0x12, 0x3b, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x5f, + 0x6f, 0x6e, 0x18, 0x04, 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, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x4f, 0x6e, + 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, + 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x65, 0x6c, 0x61, 0x70, + 0x73, 0x65, 0x64, 0x4d, 0x73, 0x22, 0xa8, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x31, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x14, - 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x68, - 0x65, 0x63, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x73, 0x6b, 0x69, 0x70, - 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x22, 0x4c, - 0x0a, 0x13, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x48, 0x0a, 0x11, - 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x45, 0x78, - 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, - 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x73, 0x63, + 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x73, + 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x26, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x10, 0xfa, 0x42, 0x0d, 0x1a, 0x0b, 0x28, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, + 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, - 0x72, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, - 0x65, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x52, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, - 0x22, 0xce, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, - 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, - 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, - 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, - 0x18, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x07, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x65, 0x64, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, - 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x0a, 0xfa, 0x42, - 0x07, 0x2a, 0x05, 0x18, 0x90, 0x4e, 0x40, 0x01, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, - 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x22, 0x85, 0x01, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, - 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x3f, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x74, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, - 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xf7, 0x01, 0x0a, 0x14, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, + 0x22, 0x3b, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0xb1, 0x01, + 0x0a, 0x10, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x12, 0x3c, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x54, - 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x12, 0x16, - 0x0a, 0x06, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, - 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x6c, 0x6c, 0x5f, - 0x66, 0x75, 0x6c, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x61, 0x6c, 0x6c, 0x46, - 0x75, 0x6c, 0x6c, 0x22, 0x17, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, - 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x96, 0x0a, 0x0a, - 0x0f, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x56, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, - 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, - 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x56, 0x0a, 0x11, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, - 0x74, 0x79, 0x52, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, - 0x74, 0x69, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, - 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x6f, 0x63, - 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6f, 0x63, - 0x73, 0x55, 0x72, 0x6c, 0x12, 0x2f, 0x0a, 0x13, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x79, 0x12, 0x2d, 0x0a, 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x11, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x61, 0x74, - 0x61, 0x6c, 0x6f, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, - 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x29, 0x0a, - 0x10, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x61, 0x64, 0x6d, 0x69, - 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6d, 0x70, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x61, 0x69, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0c, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x41, 0x69, 0x12, 0x30, 0x0a, - 0x14, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x73, 0x71, 0x6c, 0x5f, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x6d, 0x70, - 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x71, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, - 0x27, 0x0a, 0x0f, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x6f, 0x6c, - 0x61, 0x70, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x6c, 0x61, 0x70, 0x12, 0x36, 0x0a, 0x17, 0x69, 0x6d, 0x70, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x69, 0x6d, 0x70, 0x6c, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, - 0x12, 0x32, 0x0a, 0x15, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x66, - 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x13, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2f, 0x0a, 0x13, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4e, 0x6f, 0x74, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x31, 0x0a, 0x14, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x5f, 0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x18, 0x14, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x57, - 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x1a, 0xda, 0x03, 0x0a, 0x08, 0x50, 0x72, 0x6f, - 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x42, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, - 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, - 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, - 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, - 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, - 0x64, 0x6f, 0x63, 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x64, 0x6f, 0x63, 0x73, 0x55, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x6e, 0x74, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x69, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, - 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, - 0x6c, 0x64, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x6c, 0x61, 0x63, - 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, - 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, - 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x22, 0x77, 0x0a, 0x04, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x10, 0x02, 0x12, 0x0f, 0x0a, - 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x0d, - 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x16, 0x0a, - 0x12, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x49, 0x4f, - 0x4e, 0x41, 0x4c, 0x10, 0x05, 0x22, 0x8d, 0x05, 0x0a, 0x11, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, - 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x38, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, - 0x72, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x18, 0x03, 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, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, - 0x65, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x04, 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, 0x0c, 0x70, 0x72, 0x65, 0x73, - 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3e, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 0x0d, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x50, 0x0a, 0x0a, 0x65, 0x6e, 0x76, 0x5f, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, - 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x2e, 0x45, 0x6e, 0x76, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x09, 0x65, 0x6e, 0x76, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x0b, 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, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x68, 0x61, 0x73, 0x5f, - 0x61, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x68, 0x61, 0x73, 0x41, 0x6e, 0x6f, 0x6e, 0x79, - 0x6d, 0x6f, 0x75, 0x73, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x36, 0x0a, 0x07, 0x75, 0x73, - 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, + 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x12, 0x33, 0x0a, 0x0c, 0x72, + 0x65, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x05, 0x42, 0x10, 0xfa, 0x42, 0x0d, 0x1a, 0x0b, 0x28, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x01, 0x52, 0x0b, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, + 0x12, 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, + 0x6c, 0x22, 0x3b, 0x0a, 0x11, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x22, 0x91, + 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, + 0x12, 0x30, 0x0a, 0x14, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, + 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x73, 0x22, 0x50, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x09, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x15, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, + 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, + 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x22, 0xb8, 0x01, 0x0a, 0x16, 0x57, + 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, + 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x31, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x06, 0x75, 0x73, 0x65, 0x64, - 0x42, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x3c, 0x0a, 0x0e, 0x45, 0x6e, 0x76, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 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, 0x1d, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x22, 0x60, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x3b, 0x0a, 0x18, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, - 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x49, 0x64, 0x22, 0x5f, 0x0a, 0x19, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x42, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x73, 0x22, 0x40, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x30, 0x0a, 0x14, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, + 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, + 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x73, 0x22, 0x4c, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x22, 0x48, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x5c, 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, - 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, + 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x12, 0x47, + 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x33, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x07, 0x65, + 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x56, 0x69, 0x65, 0x77, 0x22, 0xce, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, + 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x65, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x65, 0x6e, 0x64, + 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x65, 0x64, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x65, 0x64, 0x12, 0x27, 0x0a, + 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x2a, 0x05, 0x18, 0x90, 0x4e, 0x40, 0x01, 0x52, 0x08, 0x70, 0x61, + 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x85, 0x01, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, + 0x65, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, + 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xf7, 0x01, + 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x6f, + 0x64, 0x65, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x06, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, + 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x19, 0x0a, 0x08, + 0x61, 0x6c, 0x6c, 0x5f, 0x66, 0x75, 0x6c, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x61, 0x6c, 0x6c, 0x46, 0x75, 0x6c, 0x6c, 0x22, 0x17, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x96, 0x0a, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, + 0x69, 0x76, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x56, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, + 0x72, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x10, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, + 0x12, 0x56, 0x0a, 0x11, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, + 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, + 0x08, 0x64, 0x6f, 0x63, 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x64, 0x6f, 0x63, 0x73, 0x55, 0x72, 0x6c, 0x12, 0x2f, 0x0a, 0x13, 0x69, 0x6d, 0x70, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x12, 0x2d, 0x0a, 0x12, 0x69, 0x6d, 0x70, + 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6d, 0x70, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x0c, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0e, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x70, + 0x6f, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, + 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6d, 0x70, + 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x23, 0x0a, 0x0d, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x61, 0x69, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x41, + 0x69, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, + 0x73, 0x71, 0x6c, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x71, 0x6c, 0x53, 0x74, + 0x6f, 0x72, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x5f, 0x6f, 0x6c, 0x61, 0x70, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6d, + 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x6c, 0x61, 0x70, 0x12, 0x36, 0x0a, 0x17, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x69, + 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x12, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x46, + 0x69, 0x6c, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2f, 0x0a, 0x13, 0x69, 0x6d, 0x70, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, + 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x31, 0x0a, 0x14, 0x69, 0x6d, 0x70, + 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, + 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x1a, 0xda, 0x03, 0x0a, + 0x08, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x42, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x19, 0x0a, 0x08, 0x64, 0x6f, 0x63, 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x64, 0x6f, 0x63, 0x73, 0x55, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x68, + 0x69, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x69, 0x6e, 0x74, 0x12, + 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, + 0x22, 0x77, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, + 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x10, 0x01, 0x12, + 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x10, + 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, + 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, + 0x04, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x52, 0x4d, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x05, 0x22, 0x8d, 0x05, 0x0a, 0x11, 0x41, 0x6e, + 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, + 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, + 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x2f, 0x0a, + 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 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, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, + 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, + 0x04, 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, 0x0c, + 0x70, 0x72, 0x65, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3e, 0x0a, 0x0e, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 0x0d, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x50, 0x0a, 0x0a, + 0x65, 0x6e, 0x76, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x31, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x45, 0x6e, 0x76, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x09, 0x65, 0x6e, 0x76, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, + 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x0b, + 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, 0x0d, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x14, + 0x68, 0x61, 0x73, 0x5f, 0x61, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x68, 0x61, 0x73, 0x41, + 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x36, + 0x0a, 0x07, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x06, + 0x75, 0x73, 0x65, 0x64, 0x42, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x3c, 0x0a, 0x0e, 0x45, + 0x6e, 0x76, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 0x1d, 0x0a, 0x1b, 0x4c, 0x69, 0x73, + 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x60, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x73, 0x22, 0x9a, 0x02, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x6f, 0x6e, 0x18, 0x04, 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, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4f, 0x6e, - 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x05, - 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, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x34, 0x0a, 0x08, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x73, 0x22, 0xf8, 0x02, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, - 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 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, 0x09, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x6f, 0x6e, 0x18, 0x04, 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, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x4f, 0x6e, - 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x6f, 0x6f, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x6f, - 0x6f, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x61, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x6c, - 0x6f, 0x63, 0x6b, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0xac, 0x04, 0x0a, - 0x13, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x78, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, - 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, - 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x73, 0x18, 0x06, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x73, 0x12, 0x31, 0x0a, - 0x05, 0x77, 0x68, 0x65, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, - 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x77, 0x68, 0x65, 0x72, 0x65, - 0x12, 0x72, 0x0a, 0x16, 0x77, 0x68, 0x65, 0x72, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x6d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x3d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x57, 0x68, 0x65, 0x72, 0x65, 0x50, 0x65, 0x72, 0x4d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x13, 0x77, 0x68, 0x65, 0x72, 0x65, 0x50, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, - 0x56, 0x69, 0x65, 0x77, 0x12, 0x39, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x0a, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x3b, 0x0a, 0x18, 0x41, 0x6e, + 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x5f, 0x0a, 0x19, 0x41, 0x6e, 0x61, 0x6c, 0x79, + 0x7a, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, + 0x7a, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x0a, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x40, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, + 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x5c, 0x0a, 0x1e, 0x4c, 0x69, + 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0a, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x0a, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x9a, 0x02, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, + 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x04, 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, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, + 0x6f, 0x6e, 0x18, 0x05, 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, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, - 0x35, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x65, 0x6e, 0x64, 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, 0x52, 0x07, 0x74, - 0x69, 0x6d, 0x65, 0x45, 0x6e, 0x64, 0x1a, 0x63, 0x0a, 0x18, 0x57, 0x68, 0x65, 0x72, 0x65, 0x50, - 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x66, 0x0a, 0x15, 0x44, - 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x78, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x69, 0x74, 0x5f, 0x70, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x69, 0x74, - 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x50, - 0x61, 0x74, 0x68, 0x22, 0x9a, 0x01, 0x0a, 0x14, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x2a, 0x0a, 0x11, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, - 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x61, 0x74, 0x65, - 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, - 0x22, 0x83, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, + 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, + 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0xf8, 0x02, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x39, + 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 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, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x04, 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, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, + 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x6f, 0x6f, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x74, 0x6f, 0x6f, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x61, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x22, 0xac, 0x04, 0x0a, 0x13, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6c, + 0x6f, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, + 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x61, + 0x6e, 0x76, 0x61, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x43, 0x6f, 0x6d, 0x70, + 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x69, 0x6d, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, + 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, + 0x73, 0x12, 0x31, 0x0a, 0x05, 0x77, 0x68, 0x65, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x77, + 0x68, 0x65, 0x72, 0x65, 0x12, 0x72, 0x0a, 0x16, 0x77, 0x68, 0x65, 0x72, 0x65, 0x5f, 0x70, 0x65, + 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x18, 0x0c, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, + 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x57, 0x68, 0x65, 0x72, 0x65, + 0x50, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x13, 0x77, 0x68, 0x65, 0x72, 0x65, 0x50, 0x65, 0x72, 0x4d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x12, 0x39, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, + 0x5f, 0x73, 0x74, 0x61, 0x72, 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, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x65, 0x6e, 0x64, 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, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x45, 0x6e, 0x64, 0x1a, 0x63, 0x0a, 0x18, 0x57, 0x68, + 0x65, 0x72, 0x65, 0x50, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, + 0x77, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x66, 0x0a, 0x15, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x69, 0x74, + 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, + 0x69, 0x6e, 0x69, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x46, + 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22, 0x9a, 0x01, 0x0a, 0x14, 0x46, 0x65, 0x65, 0x64, + 0x62, 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, + 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x61, + 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, + 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, + 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, + 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x83, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, + 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, + 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, + 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x74, 0x65, + 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, + 0x65, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x22, 0x60, 0x0a, 0x19, 0x4c, 0x69, + 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x63, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7c, 0x0a, 0x16, + 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, + 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, + 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0xad, 0x01, 0x0a, 0x17, 0x47, + 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x63, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, + 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x69, 0x73, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0xb1, 0x01, 0x0a, 0x18, 0x53, + 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, + 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, + 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, + 0x72, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x5f, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x22, 0x1b, + 0x0a, 0x19, 0x53, 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x86, 0x01, 0x0a, 0x17, + 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, + 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, + 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, + 0x72, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x43, 0x0a, 0x18, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x33, 0x0a, 0x10, 0x4c, 0x69, 0x73, + 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, - 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, - 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x50, - 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x22, 0x60, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x76, 0x65, - 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7c, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x43, - 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x3b, + 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x61, 0x69, 0x2e, 0x76, 0x31, 0x2e, + 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x22, 0xf4, 0x03, 0x0a, 0x0f, + 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, + 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x12, 0x4e, 0x0a, 0x05, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xfa, 0x42, 0x35, 0x72, + 0x33, 0x52, 0x0d, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x52, 0x0f, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x52, 0x0e, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0xd0, 0x01, 0x01, 0x52, 0x05, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x15, 0x61, + 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, + 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x52, 0x13, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, + 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, + 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x15, + 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x5b, 0x0a, 0x16, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, + 0x6b, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, + 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x14, 0x66, 0x65, + 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x22, 0x71, 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, + 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0xfd, 0x03, 0x0a, 0x18, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0xad, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, - 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x69, - 0x73, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, - 0x73, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0xb1, 0x01, 0x0a, 0x18, 0x53, 0x68, 0x61, 0x72, 0x65, - 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, - 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, - 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x30, - 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, - 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, - 0x12, 0x28, 0x0a, 0x10, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x75, 0x6e, 0x74, 0x69, - 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x22, 0x1b, 0x0a, 0x19, 0x53, 0x68, - 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x86, 0x01, 0x0a, 0x17, 0x46, 0x6f, 0x72, 0x6b, - 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, - 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, - 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x30, - 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, - 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, - 0x22, 0x43, 0x0a, 0x18, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, - 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x33, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6f, - 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x3b, 0x0a, 0x11, 0x4c, 0x69, - 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x26, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x61, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, - 0x52, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x22, 0xf4, 0x03, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, - 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, - 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, - 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, - 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x12, 0x4e, 0x0a, 0x05, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xfa, 0x42, 0x35, 0x72, 0x33, 0x52, 0x0d, 0x61, - 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x0f, 0x64, 0x65, - 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x0e, 0x66, - 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0xd0, 0x01, 0x01, - 0x52, 0x05, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x15, 0x61, 0x6e, 0x61, 0x6c, 0x79, - 0x73, 0x74, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x13, 0x61, 0x6e, - 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, - 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x15, 0x64, 0x65, 0x76, 0x65, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x12, 0x4e, + 0x0a, 0x05, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xfa, + 0x42, 0x35, 0x72, 0x33, 0x52, 0x0d, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x52, 0x0f, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x52, 0x0e, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0xd0, 0x01, 0x01, 0x52, 0x05, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x58, + 0x0a, 0x15, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x52, 0x13, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x64, 0x65, 0x76, 0x65, + 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x12, 0x5b, 0x0a, 0x16, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, - 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x14, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, - 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x71, - 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x74, 0x52, 0x15, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x5b, 0x0a, 0x16, 0x66, 0x65, 0x65, 0x64, + 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x62, + 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, + 0x14, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x78, 0x0a, 0x19, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x08, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, + 0xb7, 0x01, 0x0a, 0x12, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x05, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, + 0x6d, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, + 0x12, 0x37, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 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, 0x0a, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x27, 0x0a, 0x13, 0x49, 0x73, 0x73, + 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x6a, 0x77, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6a, + 0x77, 0x74, 0x22, 0x3a, 0x0a, 0x17, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, + 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x5b, + 0x0a, 0x18, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x09, 0x76, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x73, 0x22, 0xfd, 0x03, 0x0a, 0x18, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, - 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, - 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x12, 0x4e, 0x0a, 0x05, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xfa, 0x42, 0x35, 0x72, 0x33, - 0x52, 0x0d, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x52, - 0x0f, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x52, 0x0e, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0xd0, 0x01, 0x01, 0x52, 0x05, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x15, 0x61, 0x6e, - 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, - 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, - 0x13, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x78, 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, - 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, - 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, - 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x15, 0x64, - 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, - 0x74, 0x65, 0x78, 0x74, 0x12, 0x5b, 0x0a, 0x16, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, - 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x0d, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x41, - 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x14, 0x66, 0x65, 0x65, - 0x64, 0x62, 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x22, 0x78, 0x0a, 0x19, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, - 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xb7, 0x01, 0x0a, 0x12, - 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x1d, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, - 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x16, - 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x37, 0x0a, 0x0a, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 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, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x27, 0x0a, 0x13, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, - 0x76, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, - 0x6a, 0x77, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6a, 0x77, 0x74, 0x22, 0x3a, - 0x0a, 0x17, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x5b, 0x0a, 0x18, 0x41, 0x6e, - 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, - 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, - 0x79, 0x7a, 0x65, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x09, 0x76, 0x61, - 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x10, 0x41, 0x6e, 0x61, 0x6c, - 0x79, 0x7a, 0x65, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x79, - 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x06, 0x75, 0x73, 0x65, 0x64, 0x42, 0x79, 0x22, 0x8e, 0x01, - 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, - 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, - 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, - 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x76, - 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x43, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x26, - 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, - 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xc7, 0x01, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, - 0x68, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x53, 0x68, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x3d, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x04, 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, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x22, 0x4d, 0x0a, 0x10, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, - 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, - 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, - 0xdc, 0x01, 0x0a, 0x11, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1d, 0x0a, - 0x0a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, - 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x5f, 0x67, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0a, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x47, 0x69, 0x74, 0x12, 0x23, 0x0a, - 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x74, - 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x0d, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x53, - 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, + 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, + 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x10, + 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x75, 0x73, 0x65, + 0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x06, 0x75, 0x73, 0x65, 0x64, 0x42, + 0x79, 0x22, 0x8e, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, + 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, + 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x22, 0x76, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x07, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, + 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xc7, 0x01, 0x0a, 0x09, 0x47, + 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x3d, 0x0a, 0x0c, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x04, 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, 0x0b, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x22, 0x4d, 0x0a, 0x10, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x49, 0x64, 0x22, 0x78, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x42, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, - 0x0a, 0x0e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x36, 0x0a, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x52, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x22, 0x77, 0x0a, - 0x09, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, - 0x0a, 0x0e, 0x68, 0x61, 0x73, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x68, 0x61, 0x73, 0x44, 0x65, 0x70, 0x6c, 0x6f, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x13, 0x65, 0x64, 0x69, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x12, 0x65, 0x64, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x70, 0x6c, - 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x74, 0x0a, 0x10, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, - 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x32, 0x0a, 0x11, - 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61, - 0x22, 0x7c, 0x0a, 0x17, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, - 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, - 0x5f, 0x73, 0x68, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, - 0x02, 0x10, 0x01, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61, 0x22, 0x40, - 0x0a, 0x18, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x65, - 0x77, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61, - 0x22, 0x82, 0x01, 0x0a, 0x17, 0x47, 0x69, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x42, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, + 0x65, 0x49, 0x64, 0x22, 0xdc, 0x01, 0x0a, 0x11, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x75, 0x72, 0x6c, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, 0x72, 0x6c, + 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x5f, 0x67, 0x69, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x47, 0x69, + 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, + 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x73, 0x22, 0x53, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, - 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, - 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x32, 0x0a, 0x18, 0x47, 0x69, 0x74, 0x4d, 0x65, 0x72, 0x67, - 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0xb5, 0x01, 0x0a, 0x16, 0x47, 0x69, - 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, - 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, - 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, - 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, - 0x30, 0x0a, 0x14, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, - 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, - 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x73, 0x22, 0x19, 0x0a, 0x17, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x42, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x70, 0x0a, 0x0e, - 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x78, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x47, + 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x36, 0x0a, 0x08, 0x62, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, + 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, + 0x73, 0x22, 0x77, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x68, 0x61, 0x73, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x68, 0x61, 0x73, 0x44, + 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x13, 0x65, 0x64, 0x69, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x65, 0x64, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x74, 0x0a, 0x10, 0x47, 0x69, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x69, 0x73, - 0x63, 0x61, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0c, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x29, - 0x0a, 0x0f, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x88, 0x01, 0x0a, 0x0e, 0x47, 0x69, - 0x74, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, - 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, - 0x6f, 0x72, 0x63, 0x65, 0x22, 0x11, 0x0a, 0x0f, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x54, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x45, 0x56, 0x45, - 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, - 0x12, 0x14, 0x0a, 0x10, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x57, - 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x45, - 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x02, 0x2a, 0x8c, 0x01, - 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x19, 0x0a, 0x15, 0x4c, 0x4f, - 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, - 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, - 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f, - 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x08, 0x12, 0x12, - 0x0a, 0x0e, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x57, 0x41, 0x52, 0x4e, - 0x10, 0x0c, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x10, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, - 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x14, 0x2a, 0x64, 0x0a, 0x0d, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x0a, - 0x1a, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, - 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, - 0x14, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, - 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x45, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, - 0x10, 0x02, 0x32, 0xc7, 0x3c, 0x0a, 0x0e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, - 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x5d, 0x0a, 0x06, - 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, - 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x8d, 0x01, 0x0a, 0x0e, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x26, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x75, 0x0a, 0x0d, 0x4c, - 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x25, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x73, 0x12, 0x7d, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x7d, 0x12, 0x7b, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a, 0x22, - 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x83, - 0x01, 0x0a, 0x0c, 0x45, 0x64, 0x69, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, - 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x32, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x89, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x32, 0x0a, 0x11, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, + 0x73, 0x68, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x53, 0x68, 0x61, 0x22, 0x7c, 0x0a, 0x17, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, + 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, + 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0a, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, + 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, + 0x68, 0x61, 0x22, 0x40, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, + 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, + 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x53, 0x68, 0x61, 0x22, 0x82, 0x01, 0x0a, 0x17, 0x47, 0x69, 0x74, 0x4d, 0x65, 0x72, 0x67, + 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, + 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, + 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x32, 0x0a, 0x18, 0x47, 0x69, 0x74, + 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0xb5, 0x01, + 0x0a, 0x16, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, + 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, + 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x12, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x70, 0x0a, 0x0e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, + 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, + 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x23, 0x0a, + 0x0d, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x4c, 0x6f, 0x63, + 0x61, 0x6c, 0x22, 0x29, 0x0a, 0x0f, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x88, 0x01, + 0x0a, 0x0e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, + 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, + 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x11, 0x0a, 0x0f, 0x47, 0x69, 0x74, 0x50, + 0x75, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x54, 0x0a, 0x09, 0x46, + 0x69, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x49, 0x4c, 0x45, + 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x45, 0x56, 0x45, + 0x4e, 0x54, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x46, 0x49, + 0x4c, 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, + 0x02, 0x2a, 0x8c, 0x01, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x19, + 0x0a, 0x15, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, + 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x04, 0x12, 0x12, + 0x0a, 0x0e, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x49, 0x4e, 0x46, 0x4f, + 0x10, 0x08, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, + 0x57, 0x41, 0x52, 0x4e, 0x10, 0x0c, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, + 0x56, 0x45, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x10, 0x12, 0x13, 0x0a, 0x0f, 0x4c, + 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x14, + 0x2a, 0x64, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x56, + 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x56, + 0x45, 0x4e, 0x54, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x52, + 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, + 0x4c, 0x45, 0x54, 0x45, 0x10, 0x02, 0x32, 0xeb, 0x3d, 0x0a, 0x0e, 0x52, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x04, 0x50, 0x69, 0x6e, + 0x67, 0x12, 0x1c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x69, 0x6e, 0x67, + 0x12, 0x5d, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1e, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, + 0x8d, 0x01, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, + 0x74, 0x68, 0x12, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x76, 0x31, + 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, + 0x75, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, + 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x7d, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x7b, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, - 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, - 0x12, 0x91, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x3a, 0x01, 0x2a, 0x22, 0x29, 0x2f, 0x76, 0x31, 0x2f, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2d, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x12, 0x7d, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, - 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, - 0x12, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, - 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x12, 0x88, 0x01, 0x0a, 0x0a, 0x57, 0x61, 0x74, 0x63, 0x68, 0x46, 0x69, 0x6c, - 0x65, 0x73, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x46, 0x69, - 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, - 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x30, 0x01, 0x12, 0x7d, - 0x0a, 0x07, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, - 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, + 0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x73, 0x12, 0x83, 0x01, 0x0a, 0x0c, 0x45, 0x64, 0x69, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x64, 0x69, 0x74, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x32, 0x1b, 0x2f, 0x76, 0x31, + 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x89, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x91, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x3a, 0x01, 0x2a, 0x22, 0x29, 0x2f, + 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x6c, 0x6f, 0x61, + 0x64, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x7d, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, + 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, + 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x23, 0x12, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x80, 0x01, - 0x0a, 0x07, 0x50, 0x75, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x74, 0x46, - 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x74, - 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, 0x2a, 0x22, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, + 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x88, 0x01, 0x0a, 0x0a, 0x57, 0x61, 0x74, 0x63, + 0x68, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x46, 0x69, + 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, + 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x96, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x79, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, + 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, + 0x30, 0x01, 0x12, 0x7d, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x3a, - 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x64, 0x69, 0x72, 0x12, 0x86, 0x01, 0x0a, 0x0a, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, + 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x80, 0x01, 0x0a, 0x07, 0x50, 0x75, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x50, 0x75, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x75, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, 0x2a, 0x22, 0x27, 0x2f, 0x76, 0x31, + 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x96, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x64, 0x69, 0x72, 0x12, 0x86, 0x01, + 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x2a, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x65, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x46, 0x69, 0x6c, - 0x65, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x2a, 0x27, 0x2f, + 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, + 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x52, 0x65, 0x6e, 0x61, 0x6d, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x46, 0x69, - 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x2d, 0x3a, 0x01, 0x2a, 0x22, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, - 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x71, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, - 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x73, 0x12, 0x9b, 0x01, 0x0a, 0x0d, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, 0x78, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, 0x78, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, - 0x70, 0x61, 0x63, 0x6b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x3a, 0x01, 0x2a, 0x22, 0x30, - 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, - 0x73, 0x2f, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x2d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x12, 0x93, 0x01, 0x0a, 0x0b, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x33, 0x3a, 0x01, 0x2a, 0x22, 0x2e, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, - 0x2d, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x12, 0xc0, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x6e, 0x65, 0x72, - 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x46, 0x69, - 0x6c, 0x65, 0x12, 0x2f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x65, - 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x3c, 0x3a, 0x01, 0x2a, - 0x22, 0x37, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, - 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, - 0x6c, 0x65, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65, 0x77, 0x12, 0xab, 0x01, 0x0a, 0x12, 0x47, 0x65, - 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x46, 0x69, 0x6c, 0x65, - 0x12, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x76, 0x61, - 0x73, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x46, 0x69, 0x6c, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x36, 0x3a, 0x01, 0x2a, 0x22, 0x31, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x61, + 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x3a, 0x01, 0x2a, 0x22, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x71, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x9b, 0x01, 0x0a, 0x0d, 0x55, 0x6e, 0x70, 0x61, 0x63, + 0x6b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x63, + 0x6b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x3a, + 0x01, 0x2a, 0x22, 0x30, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, + 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x2d, 0x65, 0x78, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x0b, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x61, + 0x63, 0x6b, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x3a, 0x01, 0x2a, 0x22, 0x2e, 0x2f, 0x76, 0x31, 0x2f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x75, 0x6e, + 0x70, 0x61, 0x63, 0x6b, 0x2d, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x12, 0xc0, 0x01, 0x0a, 0x17, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, + 0x65, 0x77, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x2f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x46, 0x69, 0x6c, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x46, 0x69, 0x6c, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x3c, 0x3a, 0x01, 0x2a, 0x22, 0x37, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, - 0x2d, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x12, 0xa1, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x28, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x3a, 0x01, 0x2a, 0x22, 0x2d, 0x2f, 0x76, - 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0xa1, 0x01, 0x0a, 0x10, - 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, + 0x2d, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65, 0x77, 0x12, 0xab, 0x01, + 0x0a, 0x12, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, + 0x46, 0x69, 0x6c, 0x65, 0x12, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, + 0x61, 0x6e, 0x76, 0x61, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x76, 0x61, + 0x73, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3c, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x36, 0x3a, 0x01, 0x2a, 0x22, 0x31, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x2d, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x12, 0xa1, 0x01, 0x0a, 0x10, + 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6e, 0x64, 0x65, - 0x72, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x52, 0x65, 0x73, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x3a, 0x01, 0x2a, 0x22, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x65, - 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2f, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x12, - 0x95, 0x01, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, - 0x72, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x3a, 0x01, 0x2a, 0x22, 0x2a, 0x2f, 0x76, 0x31, - 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x72, - 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x76, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, - 0x67, 0x73, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, - 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x12, - 0x84, 0x01, 0x0a, 0x09, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x21, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x76, - 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x2f, 0x77, - 0x61, 0x74, 0x63, 0x68, 0x30, 0x01, 0x12, 0x8d, 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, - 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x9a, 0x01, 0x0a, 0x0e, 0x57, 0x61, 0x74, 0x63, 0x68, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, - 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x2d, 0x2f, 0x77, 0x61, 0x74, 0x63, - 0x68, 0x30, 0x01, 0x12, 0x86, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x8c, 0x01, 0x0a, - 0x0a, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x12, 0x22, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x76, - 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x2f, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x12, 0xac, 0x01, 0x0a, 0x12, - 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, - 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, + 0xa1, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x65, 0x72, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3d, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x37, 0x12, 0x35, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, - 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x7b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x7d, 0x2f, - 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x8e, 0x01, 0x0a, 0x0d, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, - 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, 0x22, 0x23, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x74, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x12, 0x90, 0x01, 0x0a, 0x14, - 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, - 0x76, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x12, 0xa2, - 0x01, 0x0a, 0x11, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x73, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x30, 0x12, 0x2e, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, + 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x32, 0x3a, 0x01, 0x2a, 0x22, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2f, 0x72, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x65, 0x72, 0x12, 0xa1, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x3a, 0x01, 0x2a, 0x22, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2f, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x95, 0x01, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, + 0x3a, 0x01, 0x2a, 0x22, 0x2a, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, - 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x61, 0x6e, 0x61, 0x6c, - 0x79, 0x7a, 0x65, 0x12, 0xb3, 0x01, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, - 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x12, 0x30, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, + 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, + 0x76, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x7d, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x84, 0x01, 0x0a, 0x09, 0x57, 0x61, 0x74, 0x63, + 0x68, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, + 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x30, 0x01, 0x12, 0x8d, + 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x2f, - 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, 0x12, 0xa0, 0x01, 0x0a, 0x11, 0x4c, 0x69, - 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x12, 0x2c, + 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x9a, + 0x01, 0x0a, 0x0e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x12, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x76, 0x31, 0x2f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x2f, 0x2d, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x30, 0x01, 0x12, 0x86, 0x01, 0x0a, 0x0b, + 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x23, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, - 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xac, 0x01, 0x0a, - 0x0f, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, - 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x46, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x40, 0x12, 0x3e, 0x2f, 0x76, 0x31, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x12, 0x8c, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, + 0x6f, 0x72, 0x65, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, + 0x6c, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x65, 0x78, 0x70, 0x6c, + 0x6f, 0x72, 0x65, 0x12, 0xac, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x6c, + 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, + 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x3d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x37, 0x12, 0x35, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x76, 0x65, - 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0xbb, 0x01, 0x0a, 0x11, - 0x53, 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, - 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x49, - 0x3a, 0x01, 0x2a, 0x22, 0x44, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, + 0x7b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x7d, 0x2f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x8e, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, + 0x67, 0x67, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, + 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, 0x22, 0x23, + 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x74, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x12, 0x90, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x15, 0x12, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x12, 0xa2, 0x01, 0x0a, 0x11, 0x41, 0x6e, 0x61, 0x6c, 0x79, + 0x7a, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x29, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, + 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x12, 0x2e, 0x2f, 0x76, 0x31, + 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x73, 0x2f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x12, 0xb3, 0x01, 0x0a, 0x16, + 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x12, + 0x30, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x73, 0x12, 0xa0, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x12, 0x2c, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xac, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x40, 0x12, 0x3e, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x12, 0xb7, 0x01, 0x0a, 0x10, 0x46, 0x6f, - 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x6b, 0x43, - 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x48, 0x3a, 0x01, 0x2a, 0x22, 0x43, - 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, - 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x63, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, - 0x6f, 0x72, 0x6b, 0x12, 0x80, 0x01, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, - 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, - 0x12, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, - 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, - 0x2f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x83, 0x01, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x6c, - 0x65, 0x74, 0x65, 0x12, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, - 0x3a, 0x01, 0x2a, 0x22, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, - 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0xa7, 0x01, 0x0a, - 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, - 0x6e, 0x67, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, + 0x69, 0x64, 0x7d, 0x12, 0xbb, 0x01, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, 0x61, 0x72, + 0x65, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x4f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x49, 0x3a, 0x01, 0x2a, 0x22, 0x44, 0x2f, 0x76, 0x31, + 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x68, 0x61, 0x72, + 0x65, 0x12, 0xb7, 0x01, 0x0a, 0x10, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x48, 0x3a, 0x01, 0x2a, 0x22, 0x43, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x6f, 0x72, 0x6b, 0x12, 0x80, 0x01, 0x0a, 0x09, + 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x83, + 0x01, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x20, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, - 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x33, 0x3a, 0x01, 0x2a, 0x22, 0x2e, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2f, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x30, 0x01, 0x12, 0x70, 0x0a, 0x0b, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, - 0x65, 0x76, 0x4a, 0x57, 0x54, 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, - 0x4a, 0x57, 0x54, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x73, - 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x76, 0x31, - 0x2f, 0x64, 0x65, 0x76, 0x2d, 0x6a, 0x77, 0x74, 0x12, 0x9e, 0x01, 0x0a, 0x10, 0x41, 0x6e, 0x61, - 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x2e, + 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, 0x2a, 0x22, 0x27, 0x2f, 0x76, 0x31, + 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x12, 0xa7, 0x01, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x3a, 0x01, 0x2a, 0x22, 0x2e, 0x2f, 0x76, + 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x30, 0x01, 0x12, 0x70, + 0x0a, 0x0b, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, - 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x76, 0x31, 0x2f, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, - 0x73, 0x2f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x12, 0x92, 0x01, 0x0a, 0x0e, 0x4c, 0x69, - 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, + 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x2d, 0x6a, 0x77, 0x74, + 0x12, 0x9e, 0x01, 0x0a, 0x10, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, + 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, + 0x65, 0x12, 0x92, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, - 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x82, - 0x01, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x2e, 0x72, + 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, + 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x82, 0x01, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x96, 0x01, 0x0a, 0x0f, + 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x12, + 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, + 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x76, 0x31, 0x2f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x62, 0x72, 0x61, 0x6e, + 0x63, 0x68, 0x65, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x2b, 0x3a, 0x01, 0x2a, 0x22, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0xa8, 0x01, 0x0a, + 0x10, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, 0x3a, 0x01, + 0x2a, 0x22, 0x34, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, + 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, + 0x69, 0x74, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x7b, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x7d, 0x12, 0x99, 0x01, 0x0a, 0x10, 0x47, 0x69, 0x74, 0x4d, + 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x76, 0x31, - 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x96, 0x01, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x42, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, - 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x67, 0x69, 0x74, 0x2f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x12, 0x85, 0x01, 0x0a, - 0x09, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x3a, 0x01, 0x2a, 0x22, 0x26, 0x2f, 0x76, + 0x69, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x4d, 0x65, 0x72, 0x67, + 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x12, 0xa8, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, - 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, 0x3a, 0x01, 0x2a, 0x22, 0x34, 0x2f, 0x76, 0x31, 0x2f, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x2f, 0x7b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x7d, 0x12, - 0x99, 0x01, 0x0a, 0x10, 0x47, 0x69, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x42, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, - 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x69, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x12, 0xa0, 0x01, 0x0a, 0x0f, - 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, - 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x77, - 0x69, 0x74, 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x3a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x34, 0x3a, 0x01, 0x2a, 0x22, 0x2f, 0x2f, - 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x62, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x2f, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x12, 0x7d, - 0x0a, 0x07, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, - 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, - 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x70, 0x75, 0x6c, 0x6c, 0x12, 0x7d, 0x0a, - 0x07, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, 0x75, - 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, - 0x75, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x70, 0x75, 0x73, 0x68, 0x42, 0xbb, 0x01, 0x0a, - 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x41, 0x70, 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x69, 0x6c, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x76, 0x31, 0xa2, 0x02, - 0x03, 0x52, 0x52, 0x58, 0xaa, 0x02, 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x2e, 0x52, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x1b, 0x52, 0x69, 0x6c, 0x6c, 0x5c, - 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, 0x52, 0x69, 0x6c, 0x6c, 0x3a, 0x3a, 0x52, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x6d, 0x65, + 0x72, 0x67, 0x65, 0x12, 0xa0, 0x01, 0x0a, 0x0f, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, + 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, + 0x74, 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, + 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x34, 0x3a, 0x01, 0x2a, 0x22, 0x2f, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x2f, + 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x12, 0x7d, 0x0a, 0x07, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, + 0x6c, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, + 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, + 0x2f, 0x70, 0x75, 0x6c, 0x6c, 0x12, 0x7d, 0x0a, 0x07, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, + 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, + 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, + 0x70, 0x75, 0x73, 0x68, 0x42, 0xbb, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x41, 0x70, + 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x69, + 0x6c, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72, 0x69, 0x6c, + 0x6c, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x52, 0x58, 0xaa, 0x02, 0x0f, 0x52, + 0x69, 0x6c, 0x6c, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, + 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, + 0xe2, 0x02, 0x1b, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, + 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x11, 0x52, 0x69, 0x6c, 0x6c, 0x3a, 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3a, + 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -9927,7 +10123,7 @@ func file_rill_runtime_v1_api_proto_rawDescGZIP() []byte { } var file_rill_runtime_v1_api_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_rill_runtime_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 134) +var file_rill_runtime_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 137) var file_rill_runtime_v1_api_proto_goTypes = []any{ (FileEvent)(0), // 0: rill.runtime.v1.FileEvent (LogLevel)(0), // 1: rill.runtime.v1.LogLevel @@ -9984,308 +10180,315 @@ var file_rill_runtime_v1_api_proto_goTypes = []any{ (*GenerateResolverResponse)(nil), // 52: rill.runtime.v1.GenerateResolverResponse (*GenerateRendererRequest)(nil), // 53: rill.runtime.v1.GenerateRendererRequest (*GenerateRendererResponse)(nil), // 54: rill.runtime.v1.GenerateRendererResponse - (*QueryResolverRequest)(nil), // 55: rill.runtime.v1.QueryResolverRequest - (*QueryResolverResponse)(nil), // 56: rill.runtime.v1.QueryResolverResponse - (*Log)(nil), // 57: rill.runtime.v1.Log - (*ModelPartition)(nil), // 58: rill.runtime.v1.ModelPartition - (*GetLogsRequest)(nil), // 59: rill.runtime.v1.GetLogsRequest - (*GetLogsResponse)(nil), // 60: rill.runtime.v1.GetLogsResponse - (*WatchLogsRequest)(nil), // 61: rill.runtime.v1.WatchLogsRequest - (*WatchLogsResponse)(nil), // 62: rill.runtime.v1.WatchLogsResponse - (*ListResourcesRequest)(nil), // 63: rill.runtime.v1.ListResourcesRequest - (*ListResourcesResponse)(nil), // 64: rill.runtime.v1.ListResourcesResponse - (*WatchResourcesRequest)(nil), // 65: rill.runtime.v1.WatchResourcesRequest - (*WatchResourcesResponse)(nil), // 66: rill.runtime.v1.WatchResourcesResponse - (*GetResourceRequest)(nil), // 67: rill.runtime.v1.GetResourceRequest - (*GetResourceResponse)(nil), // 68: rill.runtime.v1.GetResourceResponse - (*GetExploreRequest)(nil), // 69: rill.runtime.v1.GetExploreRequest - (*GetExploreResponse)(nil), // 70: rill.runtime.v1.GetExploreResponse - (*GetModelPartitionsRequest)(nil), // 71: rill.runtime.v1.GetModelPartitionsRequest - (*GetModelPartitionsResponse)(nil), // 72: rill.runtime.v1.GetModelPartitionsResponse - (*CreateTriggerRequest)(nil), // 73: rill.runtime.v1.CreateTriggerRequest - (*CreateTriggerResponse)(nil), // 74: rill.runtime.v1.CreateTriggerResponse - (*ConnectorDriver)(nil), // 75: rill.runtime.v1.ConnectorDriver - (*AnalyzedConnector)(nil), // 76: rill.runtime.v1.AnalyzedConnector - (*ListConnectorDriversRequest)(nil), // 77: rill.runtime.v1.ListConnectorDriversRequest - (*ListConnectorDriversResponse)(nil), // 78: rill.runtime.v1.ListConnectorDriversResponse - (*AnalyzeConnectorsRequest)(nil), // 79: rill.runtime.v1.AnalyzeConnectorsRequest - (*AnalyzeConnectorsResponse)(nil), // 80: rill.runtime.v1.AnalyzeConnectorsResponse - (*ListNotifierConnectorsRequest)(nil), // 81: rill.runtime.v1.ListNotifierConnectorsRequest - (*ListNotifierConnectorsResponse)(nil), // 82: rill.runtime.v1.ListNotifierConnectorsResponse - (*Conversation)(nil), // 83: rill.runtime.v1.Conversation - (*Message)(nil), // 84: rill.runtime.v1.Message - (*AnalystAgentContext)(nil), // 85: rill.runtime.v1.AnalystAgentContext - (*DeveloperAgentContext)(nil), // 86: rill.runtime.v1.DeveloperAgentContext - (*FeedbackAgentContext)(nil), // 87: rill.runtime.v1.FeedbackAgentContext - (*ListConversationsRequest)(nil), // 88: rill.runtime.v1.ListConversationsRequest - (*ListConversationsResponse)(nil), // 89: rill.runtime.v1.ListConversationsResponse - (*GetConversationRequest)(nil), // 90: rill.runtime.v1.GetConversationRequest - (*GetConversationResponse)(nil), // 91: rill.runtime.v1.GetConversationResponse - (*ShareConversationRequest)(nil), // 92: rill.runtime.v1.ShareConversationRequest - (*ShareConversationResponse)(nil), // 93: rill.runtime.v1.ShareConversationResponse - (*ForkConversationRequest)(nil), // 94: rill.runtime.v1.ForkConversationRequest - (*ForkConversationResponse)(nil), // 95: rill.runtime.v1.ForkConversationResponse - (*ListToolsRequest)(nil), // 96: rill.runtime.v1.ListToolsRequest - (*ListToolsResponse)(nil), // 97: rill.runtime.v1.ListToolsResponse - (*CompleteRequest)(nil), // 98: rill.runtime.v1.CompleteRequest - (*CompleteResponse)(nil), // 99: rill.runtime.v1.CompleteResponse - (*CompleteStreamingRequest)(nil), // 100: rill.runtime.v1.CompleteStreamingRequest - (*CompleteStreamingResponse)(nil), // 101: rill.runtime.v1.CompleteStreamingResponse - (*IssueDevJWTRequest)(nil), // 102: rill.runtime.v1.IssueDevJWTRequest - (*IssueDevJWTResponse)(nil), // 103: rill.runtime.v1.IssueDevJWTResponse - (*AnalyzeVariablesRequest)(nil), // 104: rill.runtime.v1.AnalyzeVariablesRequest - (*AnalyzeVariablesResponse)(nil), // 105: rill.runtime.v1.AnalyzeVariablesResponse - (*AnalyzedVariable)(nil), // 106: rill.runtime.v1.AnalyzedVariable - (*ListGitCommitsRequest)(nil), // 107: rill.runtime.v1.ListGitCommitsRequest - (*ListGitCommitsResponse)(nil), // 108: rill.runtime.v1.ListGitCommitsResponse - (*GitCommit)(nil), // 109: rill.runtime.v1.GitCommit - (*GitStatusRequest)(nil), // 110: rill.runtime.v1.GitStatusRequest - (*GitStatusResponse)(nil), // 111: rill.runtime.v1.GitStatusResponse - (*ListGitBranchesRequest)(nil), // 112: rill.runtime.v1.ListGitBranchesRequest - (*ListGitBranchesResponse)(nil), // 113: rill.runtime.v1.ListGitBranchesResponse - (*GitBranch)(nil), // 114: rill.runtime.v1.GitBranch - (*GitCommitRequest)(nil), // 115: rill.runtime.v1.GitCommitRequest - (*GitCommitResponse)(nil), // 116: rill.runtime.v1.GitCommitResponse - (*RestoreGitCommitRequest)(nil), // 117: rill.runtime.v1.RestoreGitCommitRequest - (*RestoreGitCommitResponse)(nil), // 118: rill.runtime.v1.RestoreGitCommitResponse - (*GitMergeToBranchRequest)(nil), // 119: rill.runtime.v1.GitMergeToBranchRequest - (*GitMergeToBranchResponse)(nil), // 120: rill.runtime.v1.GitMergeToBranchResponse - (*GitSwitchBranchRequest)(nil), // 121: rill.runtime.v1.GitSwitchBranchRequest - (*GitSwitchBranchResponse)(nil), // 122: rill.runtime.v1.GitSwitchBranchResponse - (*GitPullRequest)(nil), // 123: rill.runtime.v1.GitPullRequest - (*GitPullResponse)(nil), // 124: rill.runtime.v1.GitPullResponse - (*GitPushRequest)(nil), // 125: rill.runtime.v1.GitPushRequest - (*GitPushResponse)(nil), // 126: rill.runtime.v1.GitPushResponse - nil, // 127: rill.runtime.v1.HealthResponse.InstancesHealthEntry - nil, // 128: rill.runtime.v1.InstanceHealth.MetricsViewErrorsEntry - nil, // 129: rill.runtime.v1.Instance.VariablesEntry - nil, // 130: rill.runtime.v1.Instance.ProjectVariablesEntry - nil, // 131: rill.runtime.v1.Instance.FeatureFlagsEntry - nil, // 132: rill.runtime.v1.Instance.AnnotationsEntry - nil, // 133: rill.runtime.v1.CreateInstanceRequest.VariablesEntry - nil, // 134: rill.runtime.v1.CreateInstanceRequest.AnnotationsEntry - (*ConnectorDriver_Property)(nil), // 135: rill.runtime.v1.ConnectorDriver.Property - nil, // 136: rill.runtime.v1.AnalyzedConnector.EnvConfigEntry - nil, // 137: rill.runtime.v1.AnalystAgentContext.WherePerMetricsViewEntry - (*timestamppb.Timestamp)(nil), // 138: google.protobuf.Timestamp - (*structpb.Struct)(nil), // 139: google.protobuf.Struct - (*StructType)(nil), // 140: rill.runtime.v1.StructType - (*Resource)(nil), // 141: rill.runtime.v1.Resource - (*ResourceName)(nil), // 142: rill.runtime.v1.ResourceName - (*RefreshModelTrigger)(nil), // 143: rill.runtime.v1.RefreshModelTrigger - (*v1.ContentBlock)(nil), // 144: rill.ai.v1.ContentBlock - (*Expression)(nil), // 145: rill.runtime.v1.Expression - (*v1.Tool)(nil), // 146: rill.ai.v1.Tool + (*GenerateTemplateRequest)(nil), // 55: rill.runtime.v1.GenerateTemplateRequest + (*GenerateTemplateResponse)(nil), // 56: rill.runtime.v1.GenerateTemplateResponse + (*QueryResolverRequest)(nil), // 57: rill.runtime.v1.QueryResolverRequest + (*QueryResolverResponse)(nil), // 58: rill.runtime.v1.QueryResolverResponse + (*Log)(nil), // 59: rill.runtime.v1.Log + (*ModelPartition)(nil), // 60: rill.runtime.v1.ModelPartition + (*GetLogsRequest)(nil), // 61: rill.runtime.v1.GetLogsRequest + (*GetLogsResponse)(nil), // 62: rill.runtime.v1.GetLogsResponse + (*WatchLogsRequest)(nil), // 63: rill.runtime.v1.WatchLogsRequest + (*WatchLogsResponse)(nil), // 64: rill.runtime.v1.WatchLogsResponse + (*ListResourcesRequest)(nil), // 65: rill.runtime.v1.ListResourcesRequest + (*ListResourcesResponse)(nil), // 66: rill.runtime.v1.ListResourcesResponse + (*WatchResourcesRequest)(nil), // 67: rill.runtime.v1.WatchResourcesRequest + (*WatchResourcesResponse)(nil), // 68: rill.runtime.v1.WatchResourcesResponse + (*GetResourceRequest)(nil), // 69: rill.runtime.v1.GetResourceRequest + (*GetResourceResponse)(nil), // 70: rill.runtime.v1.GetResourceResponse + (*GetExploreRequest)(nil), // 71: rill.runtime.v1.GetExploreRequest + (*GetExploreResponse)(nil), // 72: rill.runtime.v1.GetExploreResponse + (*GetModelPartitionsRequest)(nil), // 73: rill.runtime.v1.GetModelPartitionsRequest + (*GetModelPartitionsResponse)(nil), // 74: rill.runtime.v1.GetModelPartitionsResponse + (*CreateTriggerRequest)(nil), // 75: rill.runtime.v1.CreateTriggerRequest + (*CreateTriggerResponse)(nil), // 76: rill.runtime.v1.CreateTriggerResponse + (*ConnectorDriver)(nil), // 77: rill.runtime.v1.ConnectorDriver + (*AnalyzedConnector)(nil), // 78: rill.runtime.v1.AnalyzedConnector + (*ListConnectorDriversRequest)(nil), // 79: rill.runtime.v1.ListConnectorDriversRequest + (*ListConnectorDriversResponse)(nil), // 80: rill.runtime.v1.ListConnectorDriversResponse + (*AnalyzeConnectorsRequest)(nil), // 81: rill.runtime.v1.AnalyzeConnectorsRequest + (*AnalyzeConnectorsResponse)(nil), // 82: rill.runtime.v1.AnalyzeConnectorsResponse + (*ListNotifierConnectorsRequest)(nil), // 83: rill.runtime.v1.ListNotifierConnectorsRequest + (*ListNotifierConnectorsResponse)(nil), // 84: rill.runtime.v1.ListNotifierConnectorsResponse + (*Conversation)(nil), // 85: rill.runtime.v1.Conversation + (*Message)(nil), // 86: rill.runtime.v1.Message + (*AnalystAgentContext)(nil), // 87: rill.runtime.v1.AnalystAgentContext + (*DeveloperAgentContext)(nil), // 88: rill.runtime.v1.DeveloperAgentContext + (*FeedbackAgentContext)(nil), // 89: rill.runtime.v1.FeedbackAgentContext + (*ListConversationsRequest)(nil), // 90: rill.runtime.v1.ListConversationsRequest + (*ListConversationsResponse)(nil), // 91: rill.runtime.v1.ListConversationsResponse + (*GetConversationRequest)(nil), // 92: rill.runtime.v1.GetConversationRequest + (*GetConversationResponse)(nil), // 93: rill.runtime.v1.GetConversationResponse + (*ShareConversationRequest)(nil), // 94: rill.runtime.v1.ShareConversationRequest + (*ShareConversationResponse)(nil), // 95: rill.runtime.v1.ShareConversationResponse + (*ForkConversationRequest)(nil), // 96: rill.runtime.v1.ForkConversationRequest + (*ForkConversationResponse)(nil), // 97: rill.runtime.v1.ForkConversationResponse + (*ListToolsRequest)(nil), // 98: rill.runtime.v1.ListToolsRequest + (*ListToolsResponse)(nil), // 99: rill.runtime.v1.ListToolsResponse + (*CompleteRequest)(nil), // 100: rill.runtime.v1.CompleteRequest + (*CompleteResponse)(nil), // 101: rill.runtime.v1.CompleteResponse + (*CompleteStreamingRequest)(nil), // 102: rill.runtime.v1.CompleteStreamingRequest + (*CompleteStreamingResponse)(nil), // 103: rill.runtime.v1.CompleteStreamingResponse + (*IssueDevJWTRequest)(nil), // 104: rill.runtime.v1.IssueDevJWTRequest + (*IssueDevJWTResponse)(nil), // 105: rill.runtime.v1.IssueDevJWTResponse + (*AnalyzeVariablesRequest)(nil), // 106: rill.runtime.v1.AnalyzeVariablesRequest + (*AnalyzeVariablesResponse)(nil), // 107: rill.runtime.v1.AnalyzeVariablesResponse + (*AnalyzedVariable)(nil), // 108: rill.runtime.v1.AnalyzedVariable + (*ListGitCommitsRequest)(nil), // 109: rill.runtime.v1.ListGitCommitsRequest + (*ListGitCommitsResponse)(nil), // 110: rill.runtime.v1.ListGitCommitsResponse + (*GitCommit)(nil), // 111: rill.runtime.v1.GitCommit + (*GitStatusRequest)(nil), // 112: rill.runtime.v1.GitStatusRequest + (*GitStatusResponse)(nil), // 113: rill.runtime.v1.GitStatusResponse + (*ListGitBranchesRequest)(nil), // 114: rill.runtime.v1.ListGitBranchesRequest + (*ListGitBranchesResponse)(nil), // 115: rill.runtime.v1.ListGitBranchesResponse + (*GitBranch)(nil), // 116: rill.runtime.v1.GitBranch + (*GitCommitRequest)(nil), // 117: rill.runtime.v1.GitCommitRequest + (*GitCommitResponse)(nil), // 118: rill.runtime.v1.GitCommitResponse + (*RestoreGitCommitRequest)(nil), // 119: rill.runtime.v1.RestoreGitCommitRequest + (*RestoreGitCommitResponse)(nil), // 120: rill.runtime.v1.RestoreGitCommitResponse + (*GitMergeToBranchRequest)(nil), // 121: rill.runtime.v1.GitMergeToBranchRequest + (*GitMergeToBranchResponse)(nil), // 122: rill.runtime.v1.GitMergeToBranchResponse + (*GitSwitchBranchRequest)(nil), // 123: rill.runtime.v1.GitSwitchBranchRequest + (*GitSwitchBranchResponse)(nil), // 124: rill.runtime.v1.GitSwitchBranchResponse + (*GitPullRequest)(nil), // 125: rill.runtime.v1.GitPullRequest + (*GitPullResponse)(nil), // 126: rill.runtime.v1.GitPullResponse + (*GitPushRequest)(nil), // 127: rill.runtime.v1.GitPushRequest + (*GitPushResponse)(nil), // 128: rill.runtime.v1.GitPushResponse + nil, // 129: rill.runtime.v1.HealthResponse.InstancesHealthEntry + nil, // 130: rill.runtime.v1.InstanceHealth.MetricsViewErrorsEntry + nil, // 131: rill.runtime.v1.Instance.VariablesEntry + nil, // 132: rill.runtime.v1.Instance.ProjectVariablesEntry + nil, // 133: rill.runtime.v1.Instance.FeatureFlagsEntry + nil, // 134: rill.runtime.v1.Instance.AnnotationsEntry + nil, // 135: rill.runtime.v1.CreateInstanceRequest.VariablesEntry + nil, // 136: rill.runtime.v1.CreateInstanceRequest.AnnotationsEntry + nil, // 137: rill.runtime.v1.GenerateTemplateResponse.EnvVarsEntry + (*ConnectorDriver_Property)(nil), // 138: rill.runtime.v1.ConnectorDriver.Property + nil, // 139: rill.runtime.v1.AnalyzedConnector.EnvConfigEntry + nil, // 140: rill.runtime.v1.AnalystAgentContext.WherePerMetricsViewEntry + (*timestamppb.Timestamp)(nil), // 141: google.protobuf.Timestamp + (*structpb.Struct)(nil), // 142: google.protobuf.Struct + (*StructType)(nil), // 143: rill.runtime.v1.StructType + (*Resource)(nil), // 144: rill.runtime.v1.Resource + (*ResourceName)(nil), // 145: rill.runtime.v1.ResourceName + (*RefreshModelTrigger)(nil), // 146: rill.runtime.v1.RefreshModelTrigger + (*v1.ContentBlock)(nil), // 147: rill.ai.v1.ContentBlock + (*Expression)(nil), // 148: rill.runtime.v1.Expression + (*v1.Tool)(nil), // 149: rill.ai.v1.Tool } var file_rill_runtime_v1_api_proto_depIdxs = []int32{ - 138, // 0: rill.runtime.v1.PingResponse.time:type_name -> google.protobuf.Timestamp - 127, // 1: rill.runtime.v1.HealthResponse.instances_health:type_name -> rill.runtime.v1.HealthResponse.InstancesHealthEntry + 141, // 0: rill.runtime.v1.PingResponse.time:type_name -> google.protobuf.Timestamp + 129, // 1: rill.runtime.v1.HealthResponse.instances_health:type_name -> rill.runtime.v1.HealthResponse.InstancesHealthEntry 10, // 2: rill.runtime.v1.InstanceHealthResponse.instance_health:type_name -> rill.runtime.v1.InstanceHealth - 128, // 3: rill.runtime.v1.InstanceHealth.metrics_view_errors:type_name -> rill.runtime.v1.InstanceHealth.MetricsViewErrorsEntry - 138, // 4: rill.runtime.v1.Instance.created_on:type_name -> google.protobuf.Timestamp - 138, // 5: rill.runtime.v1.Instance.updated_on:type_name -> google.protobuf.Timestamp + 130, // 3: rill.runtime.v1.InstanceHealth.metrics_view_errors:type_name -> rill.runtime.v1.InstanceHealth.MetricsViewErrorsEntry + 141, // 4: rill.runtime.v1.Instance.created_on:type_name -> google.protobuf.Timestamp + 141, // 5: rill.runtime.v1.Instance.updated_on:type_name -> google.protobuf.Timestamp 12, // 6: rill.runtime.v1.Instance.connectors:type_name -> rill.runtime.v1.Connector 12, // 7: rill.runtime.v1.Instance.project_connectors:type_name -> rill.runtime.v1.Connector - 129, // 8: rill.runtime.v1.Instance.variables:type_name -> rill.runtime.v1.Instance.VariablesEntry - 130, // 9: rill.runtime.v1.Instance.project_variables:type_name -> rill.runtime.v1.Instance.ProjectVariablesEntry - 131, // 10: rill.runtime.v1.Instance.feature_flags:type_name -> rill.runtime.v1.Instance.FeatureFlagsEntry - 132, // 11: rill.runtime.v1.Instance.annotations:type_name -> rill.runtime.v1.Instance.AnnotationsEntry - 139, // 12: rill.runtime.v1.Connector.config:type_name -> google.protobuf.Struct - 139, // 13: rill.runtime.v1.Connector.provision_args:type_name -> google.protobuf.Struct + 131, // 8: rill.runtime.v1.Instance.variables:type_name -> rill.runtime.v1.Instance.VariablesEntry + 132, // 9: rill.runtime.v1.Instance.project_variables:type_name -> rill.runtime.v1.Instance.ProjectVariablesEntry + 133, // 10: rill.runtime.v1.Instance.feature_flags:type_name -> rill.runtime.v1.Instance.FeatureFlagsEntry + 134, // 11: rill.runtime.v1.Instance.annotations:type_name -> rill.runtime.v1.Instance.AnnotationsEntry + 142, // 12: rill.runtime.v1.Connector.config:type_name -> google.protobuf.Struct + 142, // 13: rill.runtime.v1.Connector.provision_args:type_name -> google.protobuf.Struct 11, // 14: rill.runtime.v1.ListInstancesResponse.instances:type_name -> rill.runtime.v1.Instance 11, // 15: rill.runtime.v1.GetInstanceResponse.instance:type_name -> rill.runtime.v1.Instance 12, // 16: rill.runtime.v1.CreateInstanceRequest.connectors:type_name -> rill.runtime.v1.Connector - 133, // 17: rill.runtime.v1.CreateInstanceRequest.variables:type_name -> rill.runtime.v1.CreateInstanceRequest.VariablesEntry - 134, // 18: rill.runtime.v1.CreateInstanceRequest.annotations:type_name -> rill.runtime.v1.CreateInstanceRequest.AnnotationsEntry + 135, // 17: rill.runtime.v1.CreateInstanceRequest.variables:type_name -> rill.runtime.v1.CreateInstanceRequest.VariablesEntry + 136, // 18: rill.runtime.v1.CreateInstanceRequest.annotations:type_name -> rill.runtime.v1.CreateInstanceRequest.AnnotationsEntry 11, // 19: rill.runtime.v1.CreateInstanceResponse.instance:type_name -> rill.runtime.v1.Instance 12, // 20: rill.runtime.v1.EditInstanceRequest.connectors:type_name -> rill.runtime.v1.Connector 11, // 21: rill.runtime.v1.EditInstanceResponse.instance:type_name -> rill.runtime.v1.Instance 27, // 22: rill.runtime.v1.ListFilesResponse.files:type_name -> rill.runtime.v1.DirEntry 0, // 23: rill.runtime.v1.WatchFilesResponse.event:type_name -> rill.runtime.v1.FileEvent - 138, // 24: rill.runtime.v1.GetFileResponse.updated_on:type_name -> google.protobuf.Timestamp + 141, // 24: rill.runtime.v1.GetFileResponse.updated_on:type_name -> google.protobuf.Timestamp 40, // 25: rill.runtime.v1.ListExamplesResponse.examples:type_name -> rill.runtime.v1.Example - 139, // 26: rill.runtime.v1.GenerateResolverResponse.resolver_properties:type_name -> google.protobuf.Struct - 139, // 27: rill.runtime.v1.GenerateRendererRequest.resolver_properties:type_name -> google.protobuf.Struct - 139, // 28: rill.runtime.v1.GenerateRendererResponse.renderer_properties:type_name -> google.protobuf.Struct - 139, // 29: rill.runtime.v1.QueryResolverRequest.resolver_properties:type_name -> google.protobuf.Struct - 139, // 30: rill.runtime.v1.QueryResolverRequest.resolver_args:type_name -> google.protobuf.Struct - 139, // 31: rill.runtime.v1.QueryResolverResponse.meta:type_name -> google.protobuf.Struct - 140, // 32: rill.runtime.v1.QueryResolverResponse.schema:type_name -> rill.runtime.v1.StructType - 139, // 33: rill.runtime.v1.QueryResolverResponse.data:type_name -> google.protobuf.Struct - 1, // 34: rill.runtime.v1.Log.level:type_name -> rill.runtime.v1.LogLevel - 138, // 35: rill.runtime.v1.Log.time:type_name -> google.protobuf.Timestamp - 139, // 36: rill.runtime.v1.ModelPartition.data:type_name -> google.protobuf.Struct - 138, // 37: rill.runtime.v1.ModelPartition.watermark:type_name -> google.protobuf.Timestamp - 138, // 38: rill.runtime.v1.ModelPartition.executed_on:type_name -> google.protobuf.Timestamp - 1, // 39: rill.runtime.v1.GetLogsRequest.level:type_name -> rill.runtime.v1.LogLevel - 57, // 40: rill.runtime.v1.GetLogsResponse.logs:type_name -> rill.runtime.v1.Log - 1, // 41: rill.runtime.v1.WatchLogsRequest.level:type_name -> rill.runtime.v1.LogLevel - 57, // 42: rill.runtime.v1.WatchLogsResponse.log:type_name -> rill.runtime.v1.Log - 141, // 43: rill.runtime.v1.ListResourcesResponse.resources:type_name -> rill.runtime.v1.Resource - 2, // 44: rill.runtime.v1.WatchResourcesResponse.event:type_name -> rill.runtime.v1.ResourceEvent - 142, // 45: rill.runtime.v1.WatchResourcesResponse.name:type_name -> rill.runtime.v1.ResourceName - 141, // 46: rill.runtime.v1.WatchResourcesResponse.resource:type_name -> rill.runtime.v1.Resource - 142, // 47: rill.runtime.v1.GetResourceRequest.name:type_name -> rill.runtime.v1.ResourceName - 141, // 48: rill.runtime.v1.GetResourceResponse.resource:type_name -> rill.runtime.v1.Resource - 141, // 49: rill.runtime.v1.GetExploreResponse.explore:type_name -> rill.runtime.v1.Resource - 141, // 50: rill.runtime.v1.GetExploreResponse.metrics_view:type_name -> rill.runtime.v1.Resource - 58, // 51: rill.runtime.v1.GetModelPartitionsResponse.partitions:type_name -> rill.runtime.v1.ModelPartition - 142, // 52: rill.runtime.v1.CreateTriggerRequest.resources:type_name -> rill.runtime.v1.ResourceName - 143, // 53: rill.runtime.v1.CreateTriggerRequest.models:type_name -> rill.runtime.v1.RefreshModelTrigger - 135, // 54: rill.runtime.v1.ConnectorDriver.config_properties:type_name -> rill.runtime.v1.ConnectorDriver.Property - 135, // 55: rill.runtime.v1.ConnectorDriver.source_properties:type_name -> rill.runtime.v1.ConnectorDriver.Property - 75, // 56: rill.runtime.v1.AnalyzedConnector.driver:type_name -> rill.runtime.v1.ConnectorDriver - 139, // 57: rill.runtime.v1.AnalyzedConnector.config:type_name -> google.protobuf.Struct - 139, // 58: rill.runtime.v1.AnalyzedConnector.preset_config:type_name -> google.protobuf.Struct - 139, // 59: rill.runtime.v1.AnalyzedConnector.project_config:type_name -> google.protobuf.Struct - 136, // 60: rill.runtime.v1.AnalyzedConnector.env_config:type_name -> rill.runtime.v1.AnalyzedConnector.EnvConfigEntry - 139, // 61: rill.runtime.v1.AnalyzedConnector.provision_args:type_name -> google.protobuf.Struct - 142, // 62: rill.runtime.v1.AnalyzedConnector.used_by:type_name -> rill.runtime.v1.ResourceName - 75, // 63: rill.runtime.v1.ListConnectorDriversResponse.connectors:type_name -> rill.runtime.v1.ConnectorDriver - 76, // 64: rill.runtime.v1.AnalyzeConnectorsResponse.connectors:type_name -> rill.runtime.v1.AnalyzedConnector - 12, // 65: rill.runtime.v1.ListNotifierConnectorsResponse.connectors:type_name -> rill.runtime.v1.Connector - 138, // 66: rill.runtime.v1.Conversation.created_on:type_name -> google.protobuf.Timestamp - 138, // 67: rill.runtime.v1.Conversation.updated_on:type_name -> google.protobuf.Timestamp - 84, // 68: rill.runtime.v1.Conversation.messages:type_name -> rill.runtime.v1.Message - 138, // 69: rill.runtime.v1.Message.created_on:type_name -> google.protobuf.Timestamp - 138, // 70: rill.runtime.v1.Message.updated_on:type_name -> google.protobuf.Timestamp - 144, // 71: rill.runtime.v1.Message.content:type_name -> rill.ai.v1.ContentBlock - 145, // 72: rill.runtime.v1.AnalystAgentContext.where:type_name -> rill.runtime.v1.Expression - 137, // 73: rill.runtime.v1.AnalystAgentContext.where_per_metrics_view:type_name -> rill.runtime.v1.AnalystAgentContext.WherePerMetricsViewEntry - 138, // 74: rill.runtime.v1.AnalystAgentContext.time_start:type_name -> google.protobuf.Timestamp - 138, // 75: rill.runtime.v1.AnalystAgentContext.time_end:type_name -> google.protobuf.Timestamp - 83, // 76: rill.runtime.v1.ListConversationsResponse.conversations:type_name -> rill.runtime.v1.Conversation - 83, // 77: rill.runtime.v1.GetConversationResponse.conversation:type_name -> rill.runtime.v1.Conversation - 84, // 78: rill.runtime.v1.GetConversationResponse.messages:type_name -> rill.runtime.v1.Message - 146, // 79: rill.runtime.v1.ListToolsResponse.tools:type_name -> rill.ai.v1.Tool - 85, // 80: rill.runtime.v1.CompleteRequest.analyst_agent_context:type_name -> rill.runtime.v1.AnalystAgentContext - 86, // 81: rill.runtime.v1.CompleteRequest.developer_agent_context:type_name -> rill.runtime.v1.DeveloperAgentContext - 87, // 82: rill.runtime.v1.CompleteRequest.feedback_agent_context:type_name -> rill.runtime.v1.FeedbackAgentContext - 84, // 83: rill.runtime.v1.CompleteResponse.messages:type_name -> rill.runtime.v1.Message - 85, // 84: rill.runtime.v1.CompleteStreamingRequest.analyst_agent_context:type_name -> rill.runtime.v1.AnalystAgentContext - 86, // 85: rill.runtime.v1.CompleteStreamingRequest.developer_agent_context:type_name -> rill.runtime.v1.DeveloperAgentContext - 87, // 86: rill.runtime.v1.CompleteStreamingRequest.feedback_agent_context:type_name -> rill.runtime.v1.FeedbackAgentContext - 84, // 87: rill.runtime.v1.CompleteStreamingResponse.message:type_name -> rill.runtime.v1.Message - 139, // 88: rill.runtime.v1.IssueDevJWTRequest.attributes:type_name -> google.protobuf.Struct - 106, // 89: rill.runtime.v1.AnalyzeVariablesResponse.variables:type_name -> rill.runtime.v1.AnalyzedVariable - 142, // 90: rill.runtime.v1.AnalyzedVariable.used_by:type_name -> rill.runtime.v1.ResourceName - 109, // 91: rill.runtime.v1.ListGitCommitsResponse.commits:type_name -> rill.runtime.v1.GitCommit - 138, // 92: rill.runtime.v1.GitCommit.committed_on:type_name -> google.protobuf.Timestamp - 114, // 93: rill.runtime.v1.ListGitBranchesResponse.branches:type_name -> rill.runtime.v1.GitBranch - 10, // 94: rill.runtime.v1.HealthResponse.InstancesHealthEntry.value:type_name -> rill.runtime.v1.InstanceHealth - 3, // 95: rill.runtime.v1.ConnectorDriver.Property.type:type_name -> rill.runtime.v1.ConnectorDriver.Property.Type - 145, // 96: rill.runtime.v1.AnalystAgentContext.WherePerMetricsViewEntry.value:type_name -> rill.runtime.v1.Expression - 4, // 97: rill.runtime.v1.RuntimeService.Ping:input_type -> rill.runtime.v1.PingRequest - 6, // 98: rill.runtime.v1.RuntimeService.Health:input_type -> rill.runtime.v1.HealthRequest - 8, // 99: rill.runtime.v1.RuntimeService.InstanceHealth:input_type -> rill.runtime.v1.InstanceHealthRequest - 13, // 100: rill.runtime.v1.RuntimeService.ListInstances:input_type -> rill.runtime.v1.ListInstancesRequest - 15, // 101: rill.runtime.v1.RuntimeService.GetInstance:input_type -> rill.runtime.v1.GetInstanceRequest - 17, // 102: rill.runtime.v1.RuntimeService.CreateInstance:input_type -> rill.runtime.v1.CreateInstanceRequest - 21, // 103: rill.runtime.v1.RuntimeService.EditInstance:input_type -> rill.runtime.v1.EditInstanceRequest - 19, // 104: rill.runtime.v1.RuntimeService.DeleteInstance:input_type -> rill.runtime.v1.DeleteInstanceRequest - 23, // 105: rill.runtime.v1.RuntimeService.ReloadConfig:input_type -> rill.runtime.v1.ReloadConfigRequest - 25, // 106: rill.runtime.v1.RuntimeService.ListFiles:input_type -> rill.runtime.v1.ListFilesRequest - 28, // 107: rill.runtime.v1.RuntimeService.WatchFiles:input_type -> rill.runtime.v1.WatchFilesRequest - 30, // 108: rill.runtime.v1.RuntimeService.GetFile:input_type -> rill.runtime.v1.GetFileRequest - 32, // 109: rill.runtime.v1.RuntimeService.PutFile:input_type -> rill.runtime.v1.PutFileRequest - 34, // 110: rill.runtime.v1.RuntimeService.CreateDirectory:input_type -> rill.runtime.v1.CreateDirectoryRequest - 36, // 111: rill.runtime.v1.RuntimeService.DeleteFile:input_type -> rill.runtime.v1.DeleteFileRequest - 38, // 112: rill.runtime.v1.RuntimeService.RenameFile:input_type -> rill.runtime.v1.RenameFileRequest - 41, // 113: rill.runtime.v1.RuntimeService.ListExamples:input_type -> rill.runtime.v1.ListExamplesRequest - 43, // 114: rill.runtime.v1.RuntimeService.UnpackExample:input_type -> rill.runtime.v1.UnpackExampleRequest - 45, // 115: rill.runtime.v1.RuntimeService.UnpackEmpty:input_type -> rill.runtime.v1.UnpackEmptyRequest - 47, // 116: rill.runtime.v1.RuntimeService.GenerateMetricsViewFile:input_type -> rill.runtime.v1.GenerateMetricsViewFileRequest - 49, // 117: rill.runtime.v1.RuntimeService.GenerateCanvasFile:input_type -> rill.runtime.v1.GenerateCanvasFileRequest - 51, // 118: rill.runtime.v1.RuntimeService.GenerateResolver:input_type -> rill.runtime.v1.GenerateResolverRequest - 53, // 119: rill.runtime.v1.RuntimeService.GenerateRenderer:input_type -> rill.runtime.v1.GenerateRendererRequest - 55, // 120: rill.runtime.v1.RuntimeService.QueryResolver:input_type -> rill.runtime.v1.QueryResolverRequest - 59, // 121: rill.runtime.v1.RuntimeService.GetLogs:input_type -> rill.runtime.v1.GetLogsRequest - 61, // 122: rill.runtime.v1.RuntimeService.WatchLogs:input_type -> rill.runtime.v1.WatchLogsRequest - 63, // 123: rill.runtime.v1.RuntimeService.ListResources:input_type -> rill.runtime.v1.ListResourcesRequest - 65, // 124: rill.runtime.v1.RuntimeService.WatchResources:input_type -> rill.runtime.v1.WatchResourcesRequest - 67, // 125: rill.runtime.v1.RuntimeService.GetResource:input_type -> rill.runtime.v1.GetResourceRequest - 69, // 126: rill.runtime.v1.RuntimeService.GetExplore:input_type -> rill.runtime.v1.GetExploreRequest - 71, // 127: rill.runtime.v1.RuntimeService.GetModelPartitions:input_type -> rill.runtime.v1.GetModelPartitionsRequest - 73, // 128: rill.runtime.v1.RuntimeService.CreateTrigger:input_type -> rill.runtime.v1.CreateTriggerRequest - 77, // 129: rill.runtime.v1.RuntimeService.ListConnectorDrivers:input_type -> rill.runtime.v1.ListConnectorDriversRequest - 79, // 130: rill.runtime.v1.RuntimeService.AnalyzeConnectors:input_type -> rill.runtime.v1.AnalyzeConnectorsRequest - 81, // 131: rill.runtime.v1.RuntimeService.ListNotifierConnectors:input_type -> rill.runtime.v1.ListNotifierConnectorsRequest - 88, // 132: rill.runtime.v1.RuntimeService.ListConversations:input_type -> rill.runtime.v1.ListConversationsRequest - 90, // 133: rill.runtime.v1.RuntimeService.GetConversation:input_type -> rill.runtime.v1.GetConversationRequest - 92, // 134: rill.runtime.v1.RuntimeService.ShareConversation:input_type -> rill.runtime.v1.ShareConversationRequest - 94, // 135: rill.runtime.v1.RuntimeService.ForkConversation:input_type -> rill.runtime.v1.ForkConversationRequest - 96, // 136: rill.runtime.v1.RuntimeService.ListTools:input_type -> rill.runtime.v1.ListToolsRequest - 98, // 137: rill.runtime.v1.RuntimeService.Complete:input_type -> rill.runtime.v1.CompleteRequest - 100, // 138: rill.runtime.v1.RuntimeService.CompleteStreaming:input_type -> rill.runtime.v1.CompleteStreamingRequest - 102, // 139: rill.runtime.v1.RuntimeService.IssueDevJWT:input_type -> rill.runtime.v1.IssueDevJWTRequest - 104, // 140: rill.runtime.v1.RuntimeService.AnalyzeVariables:input_type -> rill.runtime.v1.AnalyzeVariablesRequest - 107, // 141: rill.runtime.v1.RuntimeService.ListGitCommits:input_type -> rill.runtime.v1.ListGitCommitsRequest - 110, // 142: rill.runtime.v1.RuntimeService.GitStatus:input_type -> rill.runtime.v1.GitStatusRequest - 112, // 143: rill.runtime.v1.RuntimeService.ListGitBranches:input_type -> rill.runtime.v1.ListGitBranchesRequest - 115, // 144: rill.runtime.v1.RuntimeService.GitCommit:input_type -> rill.runtime.v1.GitCommitRequest - 117, // 145: rill.runtime.v1.RuntimeService.RestoreGitCommit:input_type -> rill.runtime.v1.RestoreGitCommitRequest - 119, // 146: rill.runtime.v1.RuntimeService.GitMergeToBranch:input_type -> rill.runtime.v1.GitMergeToBranchRequest - 121, // 147: rill.runtime.v1.RuntimeService.GitSwitchBranch:input_type -> rill.runtime.v1.GitSwitchBranchRequest - 123, // 148: rill.runtime.v1.RuntimeService.GitPull:input_type -> rill.runtime.v1.GitPullRequest - 125, // 149: rill.runtime.v1.RuntimeService.GitPush:input_type -> rill.runtime.v1.GitPushRequest - 5, // 150: rill.runtime.v1.RuntimeService.Ping:output_type -> rill.runtime.v1.PingResponse - 7, // 151: rill.runtime.v1.RuntimeService.Health:output_type -> rill.runtime.v1.HealthResponse - 9, // 152: rill.runtime.v1.RuntimeService.InstanceHealth:output_type -> rill.runtime.v1.InstanceHealthResponse - 14, // 153: rill.runtime.v1.RuntimeService.ListInstances:output_type -> rill.runtime.v1.ListInstancesResponse - 16, // 154: rill.runtime.v1.RuntimeService.GetInstance:output_type -> rill.runtime.v1.GetInstanceResponse - 18, // 155: rill.runtime.v1.RuntimeService.CreateInstance:output_type -> rill.runtime.v1.CreateInstanceResponse - 22, // 156: rill.runtime.v1.RuntimeService.EditInstance:output_type -> rill.runtime.v1.EditInstanceResponse - 20, // 157: rill.runtime.v1.RuntimeService.DeleteInstance:output_type -> rill.runtime.v1.DeleteInstanceResponse - 24, // 158: rill.runtime.v1.RuntimeService.ReloadConfig:output_type -> rill.runtime.v1.ReloadConfigResponse - 26, // 159: rill.runtime.v1.RuntimeService.ListFiles:output_type -> rill.runtime.v1.ListFilesResponse - 29, // 160: rill.runtime.v1.RuntimeService.WatchFiles:output_type -> rill.runtime.v1.WatchFilesResponse - 31, // 161: rill.runtime.v1.RuntimeService.GetFile:output_type -> rill.runtime.v1.GetFileResponse - 33, // 162: rill.runtime.v1.RuntimeService.PutFile:output_type -> rill.runtime.v1.PutFileResponse - 35, // 163: rill.runtime.v1.RuntimeService.CreateDirectory:output_type -> rill.runtime.v1.CreateDirectoryResponse - 37, // 164: rill.runtime.v1.RuntimeService.DeleteFile:output_type -> rill.runtime.v1.DeleteFileResponse - 39, // 165: rill.runtime.v1.RuntimeService.RenameFile:output_type -> rill.runtime.v1.RenameFileResponse - 42, // 166: rill.runtime.v1.RuntimeService.ListExamples:output_type -> rill.runtime.v1.ListExamplesResponse - 44, // 167: rill.runtime.v1.RuntimeService.UnpackExample:output_type -> rill.runtime.v1.UnpackExampleResponse - 46, // 168: rill.runtime.v1.RuntimeService.UnpackEmpty:output_type -> rill.runtime.v1.UnpackEmptyResponse - 48, // 169: rill.runtime.v1.RuntimeService.GenerateMetricsViewFile:output_type -> rill.runtime.v1.GenerateMetricsViewFileResponse - 50, // 170: rill.runtime.v1.RuntimeService.GenerateCanvasFile:output_type -> rill.runtime.v1.GenerateCanvasFileResponse - 52, // 171: rill.runtime.v1.RuntimeService.GenerateResolver:output_type -> rill.runtime.v1.GenerateResolverResponse - 54, // 172: rill.runtime.v1.RuntimeService.GenerateRenderer:output_type -> rill.runtime.v1.GenerateRendererResponse - 56, // 173: rill.runtime.v1.RuntimeService.QueryResolver:output_type -> rill.runtime.v1.QueryResolverResponse - 60, // 174: rill.runtime.v1.RuntimeService.GetLogs:output_type -> rill.runtime.v1.GetLogsResponse - 62, // 175: rill.runtime.v1.RuntimeService.WatchLogs:output_type -> rill.runtime.v1.WatchLogsResponse - 64, // 176: rill.runtime.v1.RuntimeService.ListResources:output_type -> rill.runtime.v1.ListResourcesResponse - 66, // 177: rill.runtime.v1.RuntimeService.WatchResources:output_type -> rill.runtime.v1.WatchResourcesResponse - 68, // 178: rill.runtime.v1.RuntimeService.GetResource:output_type -> rill.runtime.v1.GetResourceResponse - 70, // 179: rill.runtime.v1.RuntimeService.GetExplore:output_type -> rill.runtime.v1.GetExploreResponse - 72, // 180: rill.runtime.v1.RuntimeService.GetModelPartitions:output_type -> rill.runtime.v1.GetModelPartitionsResponse - 74, // 181: rill.runtime.v1.RuntimeService.CreateTrigger:output_type -> rill.runtime.v1.CreateTriggerResponse - 78, // 182: rill.runtime.v1.RuntimeService.ListConnectorDrivers:output_type -> rill.runtime.v1.ListConnectorDriversResponse - 80, // 183: rill.runtime.v1.RuntimeService.AnalyzeConnectors:output_type -> rill.runtime.v1.AnalyzeConnectorsResponse - 82, // 184: rill.runtime.v1.RuntimeService.ListNotifierConnectors:output_type -> rill.runtime.v1.ListNotifierConnectorsResponse - 89, // 185: rill.runtime.v1.RuntimeService.ListConversations:output_type -> rill.runtime.v1.ListConversationsResponse - 91, // 186: rill.runtime.v1.RuntimeService.GetConversation:output_type -> rill.runtime.v1.GetConversationResponse - 93, // 187: rill.runtime.v1.RuntimeService.ShareConversation:output_type -> rill.runtime.v1.ShareConversationResponse - 95, // 188: rill.runtime.v1.RuntimeService.ForkConversation:output_type -> rill.runtime.v1.ForkConversationResponse - 97, // 189: rill.runtime.v1.RuntimeService.ListTools:output_type -> rill.runtime.v1.ListToolsResponse - 99, // 190: rill.runtime.v1.RuntimeService.Complete:output_type -> rill.runtime.v1.CompleteResponse - 101, // 191: rill.runtime.v1.RuntimeService.CompleteStreaming:output_type -> rill.runtime.v1.CompleteStreamingResponse - 103, // 192: rill.runtime.v1.RuntimeService.IssueDevJWT:output_type -> rill.runtime.v1.IssueDevJWTResponse - 105, // 193: rill.runtime.v1.RuntimeService.AnalyzeVariables:output_type -> rill.runtime.v1.AnalyzeVariablesResponse - 108, // 194: rill.runtime.v1.RuntimeService.ListGitCommits:output_type -> rill.runtime.v1.ListGitCommitsResponse - 111, // 195: rill.runtime.v1.RuntimeService.GitStatus:output_type -> rill.runtime.v1.GitStatusResponse - 113, // 196: rill.runtime.v1.RuntimeService.ListGitBranches:output_type -> rill.runtime.v1.ListGitBranchesResponse - 116, // 197: rill.runtime.v1.RuntimeService.GitCommit:output_type -> rill.runtime.v1.GitCommitResponse - 118, // 198: rill.runtime.v1.RuntimeService.RestoreGitCommit:output_type -> rill.runtime.v1.RestoreGitCommitResponse - 120, // 199: rill.runtime.v1.RuntimeService.GitMergeToBranch:output_type -> rill.runtime.v1.GitMergeToBranchResponse - 122, // 200: rill.runtime.v1.RuntimeService.GitSwitchBranch:output_type -> rill.runtime.v1.GitSwitchBranchResponse - 124, // 201: rill.runtime.v1.RuntimeService.GitPull:output_type -> rill.runtime.v1.GitPullResponse - 126, // 202: rill.runtime.v1.RuntimeService.GitPush:output_type -> rill.runtime.v1.GitPushResponse - 150, // [150:203] is the sub-list for method output_type - 97, // [97:150] is the sub-list for method input_type - 97, // [97:97] is the sub-list for extension type_name - 97, // [97:97] is the sub-list for extension extendee - 0, // [0:97] is the sub-list for field type_name + 142, // 26: rill.runtime.v1.GenerateResolverResponse.resolver_properties:type_name -> google.protobuf.Struct + 142, // 27: rill.runtime.v1.GenerateRendererRequest.resolver_properties:type_name -> google.protobuf.Struct + 142, // 28: rill.runtime.v1.GenerateRendererResponse.renderer_properties:type_name -> google.protobuf.Struct + 142, // 29: rill.runtime.v1.GenerateTemplateRequest.properties:type_name -> google.protobuf.Struct + 137, // 30: rill.runtime.v1.GenerateTemplateResponse.env_vars:type_name -> rill.runtime.v1.GenerateTemplateResponse.EnvVarsEntry + 142, // 31: rill.runtime.v1.QueryResolverRequest.resolver_properties:type_name -> google.protobuf.Struct + 142, // 32: rill.runtime.v1.QueryResolverRequest.resolver_args:type_name -> google.protobuf.Struct + 142, // 33: rill.runtime.v1.QueryResolverResponse.meta:type_name -> google.protobuf.Struct + 143, // 34: rill.runtime.v1.QueryResolverResponse.schema:type_name -> rill.runtime.v1.StructType + 142, // 35: rill.runtime.v1.QueryResolverResponse.data:type_name -> google.protobuf.Struct + 1, // 36: rill.runtime.v1.Log.level:type_name -> rill.runtime.v1.LogLevel + 141, // 37: rill.runtime.v1.Log.time:type_name -> google.protobuf.Timestamp + 142, // 38: rill.runtime.v1.ModelPartition.data:type_name -> google.protobuf.Struct + 141, // 39: rill.runtime.v1.ModelPartition.watermark:type_name -> google.protobuf.Timestamp + 141, // 40: rill.runtime.v1.ModelPartition.executed_on:type_name -> google.protobuf.Timestamp + 1, // 41: rill.runtime.v1.GetLogsRequest.level:type_name -> rill.runtime.v1.LogLevel + 59, // 42: rill.runtime.v1.GetLogsResponse.logs:type_name -> rill.runtime.v1.Log + 1, // 43: rill.runtime.v1.WatchLogsRequest.level:type_name -> rill.runtime.v1.LogLevel + 59, // 44: rill.runtime.v1.WatchLogsResponse.log:type_name -> rill.runtime.v1.Log + 144, // 45: rill.runtime.v1.ListResourcesResponse.resources:type_name -> rill.runtime.v1.Resource + 2, // 46: rill.runtime.v1.WatchResourcesResponse.event:type_name -> rill.runtime.v1.ResourceEvent + 145, // 47: rill.runtime.v1.WatchResourcesResponse.name:type_name -> rill.runtime.v1.ResourceName + 144, // 48: rill.runtime.v1.WatchResourcesResponse.resource:type_name -> rill.runtime.v1.Resource + 145, // 49: rill.runtime.v1.GetResourceRequest.name:type_name -> rill.runtime.v1.ResourceName + 144, // 50: rill.runtime.v1.GetResourceResponse.resource:type_name -> rill.runtime.v1.Resource + 144, // 51: rill.runtime.v1.GetExploreResponse.explore:type_name -> rill.runtime.v1.Resource + 144, // 52: rill.runtime.v1.GetExploreResponse.metrics_view:type_name -> rill.runtime.v1.Resource + 60, // 53: rill.runtime.v1.GetModelPartitionsResponse.partitions:type_name -> rill.runtime.v1.ModelPartition + 145, // 54: rill.runtime.v1.CreateTriggerRequest.resources:type_name -> rill.runtime.v1.ResourceName + 146, // 55: rill.runtime.v1.CreateTriggerRequest.models:type_name -> rill.runtime.v1.RefreshModelTrigger + 138, // 56: rill.runtime.v1.ConnectorDriver.config_properties:type_name -> rill.runtime.v1.ConnectorDriver.Property + 138, // 57: rill.runtime.v1.ConnectorDriver.source_properties:type_name -> rill.runtime.v1.ConnectorDriver.Property + 77, // 58: rill.runtime.v1.AnalyzedConnector.driver:type_name -> rill.runtime.v1.ConnectorDriver + 142, // 59: rill.runtime.v1.AnalyzedConnector.config:type_name -> google.protobuf.Struct + 142, // 60: rill.runtime.v1.AnalyzedConnector.preset_config:type_name -> google.protobuf.Struct + 142, // 61: rill.runtime.v1.AnalyzedConnector.project_config:type_name -> google.protobuf.Struct + 139, // 62: rill.runtime.v1.AnalyzedConnector.env_config:type_name -> rill.runtime.v1.AnalyzedConnector.EnvConfigEntry + 142, // 63: rill.runtime.v1.AnalyzedConnector.provision_args:type_name -> google.protobuf.Struct + 145, // 64: rill.runtime.v1.AnalyzedConnector.used_by:type_name -> rill.runtime.v1.ResourceName + 77, // 65: rill.runtime.v1.ListConnectorDriversResponse.connectors:type_name -> rill.runtime.v1.ConnectorDriver + 78, // 66: rill.runtime.v1.AnalyzeConnectorsResponse.connectors:type_name -> rill.runtime.v1.AnalyzedConnector + 12, // 67: rill.runtime.v1.ListNotifierConnectorsResponse.connectors:type_name -> rill.runtime.v1.Connector + 141, // 68: rill.runtime.v1.Conversation.created_on:type_name -> google.protobuf.Timestamp + 141, // 69: rill.runtime.v1.Conversation.updated_on:type_name -> google.protobuf.Timestamp + 86, // 70: rill.runtime.v1.Conversation.messages:type_name -> rill.runtime.v1.Message + 141, // 71: rill.runtime.v1.Message.created_on:type_name -> google.protobuf.Timestamp + 141, // 72: rill.runtime.v1.Message.updated_on:type_name -> google.protobuf.Timestamp + 147, // 73: rill.runtime.v1.Message.content:type_name -> rill.ai.v1.ContentBlock + 148, // 74: rill.runtime.v1.AnalystAgentContext.where:type_name -> rill.runtime.v1.Expression + 140, // 75: rill.runtime.v1.AnalystAgentContext.where_per_metrics_view:type_name -> rill.runtime.v1.AnalystAgentContext.WherePerMetricsViewEntry + 141, // 76: rill.runtime.v1.AnalystAgentContext.time_start:type_name -> google.protobuf.Timestamp + 141, // 77: rill.runtime.v1.AnalystAgentContext.time_end:type_name -> google.protobuf.Timestamp + 85, // 78: rill.runtime.v1.ListConversationsResponse.conversations:type_name -> rill.runtime.v1.Conversation + 85, // 79: rill.runtime.v1.GetConversationResponse.conversation:type_name -> rill.runtime.v1.Conversation + 86, // 80: rill.runtime.v1.GetConversationResponse.messages:type_name -> rill.runtime.v1.Message + 149, // 81: rill.runtime.v1.ListToolsResponse.tools:type_name -> rill.ai.v1.Tool + 87, // 82: rill.runtime.v1.CompleteRequest.analyst_agent_context:type_name -> rill.runtime.v1.AnalystAgentContext + 88, // 83: rill.runtime.v1.CompleteRequest.developer_agent_context:type_name -> rill.runtime.v1.DeveloperAgentContext + 89, // 84: rill.runtime.v1.CompleteRequest.feedback_agent_context:type_name -> rill.runtime.v1.FeedbackAgentContext + 86, // 85: rill.runtime.v1.CompleteResponse.messages:type_name -> rill.runtime.v1.Message + 87, // 86: rill.runtime.v1.CompleteStreamingRequest.analyst_agent_context:type_name -> rill.runtime.v1.AnalystAgentContext + 88, // 87: rill.runtime.v1.CompleteStreamingRequest.developer_agent_context:type_name -> rill.runtime.v1.DeveloperAgentContext + 89, // 88: rill.runtime.v1.CompleteStreamingRequest.feedback_agent_context:type_name -> rill.runtime.v1.FeedbackAgentContext + 86, // 89: rill.runtime.v1.CompleteStreamingResponse.message:type_name -> rill.runtime.v1.Message + 142, // 90: rill.runtime.v1.IssueDevJWTRequest.attributes:type_name -> google.protobuf.Struct + 108, // 91: rill.runtime.v1.AnalyzeVariablesResponse.variables:type_name -> rill.runtime.v1.AnalyzedVariable + 145, // 92: rill.runtime.v1.AnalyzedVariable.used_by:type_name -> rill.runtime.v1.ResourceName + 111, // 93: rill.runtime.v1.ListGitCommitsResponse.commits:type_name -> rill.runtime.v1.GitCommit + 141, // 94: rill.runtime.v1.GitCommit.committed_on:type_name -> google.protobuf.Timestamp + 116, // 95: rill.runtime.v1.ListGitBranchesResponse.branches:type_name -> rill.runtime.v1.GitBranch + 10, // 96: rill.runtime.v1.HealthResponse.InstancesHealthEntry.value:type_name -> rill.runtime.v1.InstanceHealth + 3, // 97: rill.runtime.v1.ConnectorDriver.Property.type:type_name -> rill.runtime.v1.ConnectorDriver.Property.Type + 148, // 98: rill.runtime.v1.AnalystAgentContext.WherePerMetricsViewEntry.value:type_name -> rill.runtime.v1.Expression + 4, // 99: rill.runtime.v1.RuntimeService.Ping:input_type -> rill.runtime.v1.PingRequest + 6, // 100: rill.runtime.v1.RuntimeService.Health:input_type -> rill.runtime.v1.HealthRequest + 8, // 101: rill.runtime.v1.RuntimeService.InstanceHealth:input_type -> rill.runtime.v1.InstanceHealthRequest + 13, // 102: rill.runtime.v1.RuntimeService.ListInstances:input_type -> rill.runtime.v1.ListInstancesRequest + 15, // 103: rill.runtime.v1.RuntimeService.GetInstance:input_type -> rill.runtime.v1.GetInstanceRequest + 17, // 104: rill.runtime.v1.RuntimeService.CreateInstance:input_type -> rill.runtime.v1.CreateInstanceRequest + 21, // 105: rill.runtime.v1.RuntimeService.EditInstance:input_type -> rill.runtime.v1.EditInstanceRequest + 19, // 106: rill.runtime.v1.RuntimeService.DeleteInstance:input_type -> rill.runtime.v1.DeleteInstanceRequest + 23, // 107: rill.runtime.v1.RuntimeService.ReloadConfig:input_type -> rill.runtime.v1.ReloadConfigRequest + 25, // 108: rill.runtime.v1.RuntimeService.ListFiles:input_type -> rill.runtime.v1.ListFilesRequest + 28, // 109: rill.runtime.v1.RuntimeService.WatchFiles:input_type -> rill.runtime.v1.WatchFilesRequest + 30, // 110: rill.runtime.v1.RuntimeService.GetFile:input_type -> rill.runtime.v1.GetFileRequest + 32, // 111: rill.runtime.v1.RuntimeService.PutFile:input_type -> rill.runtime.v1.PutFileRequest + 34, // 112: rill.runtime.v1.RuntimeService.CreateDirectory:input_type -> rill.runtime.v1.CreateDirectoryRequest + 36, // 113: rill.runtime.v1.RuntimeService.DeleteFile:input_type -> rill.runtime.v1.DeleteFileRequest + 38, // 114: rill.runtime.v1.RuntimeService.RenameFile:input_type -> rill.runtime.v1.RenameFileRequest + 41, // 115: rill.runtime.v1.RuntimeService.ListExamples:input_type -> rill.runtime.v1.ListExamplesRequest + 43, // 116: rill.runtime.v1.RuntimeService.UnpackExample:input_type -> rill.runtime.v1.UnpackExampleRequest + 45, // 117: rill.runtime.v1.RuntimeService.UnpackEmpty:input_type -> rill.runtime.v1.UnpackEmptyRequest + 47, // 118: rill.runtime.v1.RuntimeService.GenerateMetricsViewFile:input_type -> rill.runtime.v1.GenerateMetricsViewFileRequest + 49, // 119: rill.runtime.v1.RuntimeService.GenerateCanvasFile:input_type -> rill.runtime.v1.GenerateCanvasFileRequest + 51, // 120: rill.runtime.v1.RuntimeService.GenerateResolver:input_type -> rill.runtime.v1.GenerateResolverRequest + 53, // 121: rill.runtime.v1.RuntimeService.GenerateRenderer:input_type -> rill.runtime.v1.GenerateRendererRequest + 55, // 122: rill.runtime.v1.RuntimeService.GenerateTemplate:input_type -> rill.runtime.v1.GenerateTemplateRequest + 57, // 123: rill.runtime.v1.RuntimeService.QueryResolver:input_type -> rill.runtime.v1.QueryResolverRequest + 61, // 124: rill.runtime.v1.RuntimeService.GetLogs:input_type -> rill.runtime.v1.GetLogsRequest + 63, // 125: rill.runtime.v1.RuntimeService.WatchLogs:input_type -> rill.runtime.v1.WatchLogsRequest + 65, // 126: rill.runtime.v1.RuntimeService.ListResources:input_type -> rill.runtime.v1.ListResourcesRequest + 67, // 127: rill.runtime.v1.RuntimeService.WatchResources:input_type -> rill.runtime.v1.WatchResourcesRequest + 69, // 128: rill.runtime.v1.RuntimeService.GetResource:input_type -> rill.runtime.v1.GetResourceRequest + 71, // 129: rill.runtime.v1.RuntimeService.GetExplore:input_type -> rill.runtime.v1.GetExploreRequest + 73, // 130: rill.runtime.v1.RuntimeService.GetModelPartitions:input_type -> rill.runtime.v1.GetModelPartitionsRequest + 75, // 131: rill.runtime.v1.RuntimeService.CreateTrigger:input_type -> rill.runtime.v1.CreateTriggerRequest + 79, // 132: rill.runtime.v1.RuntimeService.ListConnectorDrivers:input_type -> rill.runtime.v1.ListConnectorDriversRequest + 81, // 133: rill.runtime.v1.RuntimeService.AnalyzeConnectors:input_type -> rill.runtime.v1.AnalyzeConnectorsRequest + 83, // 134: rill.runtime.v1.RuntimeService.ListNotifierConnectors:input_type -> rill.runtime.v1.ListNotifierConnectorsRequest + 90, // 135: rill.runtime.v1.RuntimeService.ListConversations:input_type -> rill.runtime.v1.ListConversationsRequest + 92, // 136: rill.runtime.v1.RuntimeService.GetConversation:input_type -> rill.runtime.v1.GetConversationRequest + 94, // 137: rill.runtime.v1.RuntimeService.ShareConversation:input_type -> rill.runtime.v1.ShareConversationRequest + 96, // 138: rill.runtime.v1.RuntimeService.ForkConversation:input_type -> rill.runtime.v1.ForkConversationRequest + 98, // 139: rill.runtime.v1.RuntimeService.ListTools:input_type -> rill.runtime.v1.ListToolsRequest + 100, // 140: rill.runtime.v1.RuntimeService.Complete:input_type -> rill.runtime.v1.CompleteRequest + 102, // 141: rill.runtime.v1.RuntimeService.CompleteStreaming:input_type -> rill.runtime.v1.CompleteStreamingRequest + 104, // 142: rill.runtime.v1.RuntimeService.IssueDevJWT:input_type -> rill.runtime.v1.IssueDevJWTRequest + 106, // 143: rill.runtime.v1.RuntimeService.AnalyzeVariables:input_type -> rill.runtime.v1.AnalyzeVariablesRequest + 109, // 144: rill.runtime.v1.RuntimeService.ListGitCommits:input_type -> rill.runtime.v1.ListGitCommitsRequest + 112, // 145: rill.runtime.v1.RuntimeService.GitStatus:input_type -> rill.runtime.v1.GitStatusRequest + 114, // 146: rill.runtime.v1.RuntimeService.ListGitBranches:input_type -> rill.runtime.v1.ListGitBranchesRequest + 117, // 147: rill.runtime.v1.RuntimeService.GitCommit:input_type -> rill.runtime.v1.GitCommitRequest + 119, // 148: rill.runtime.v1.RuntimeService.RestoreGitCommit:input_type -> rill.runtime.v1.RestoreGitCommitRequest + 121, // 149: rill.runtime.v1.RuntimeService.GitMergeToBranch:input_type -> rill.runtime.v1.GitMergeToBranchRequest + 123, // 150: rill.runtime.v1.RuntimeService.GitSwitchBranch:input_type -> rill.runtime.v1.GitSwitchBranchRequest + 125, // 151: rill.runtime.v1.RuntimeService.GitPull:input_type -> rill.runtime.v1.GitPullRequest + 127, // 152: rill.runtime.v1.RuntimeService.GitPush:input_type -> rill.runtime.v1.GitPushRequest + 5, // 153: rill.runtime.v1.RuntimeService.Ping:output_type -> rill.runtime.v1.PingResponse + 7, // 154: rill.runtime.v1.RuntimeService.Health:output_type -> rill.runtime.v1.HealthResponse + 9, // 155: rill.runtime.v1.RuntimeService.InstanceHealth:output_type -> rill.runtime.v1.InstanceHealthResponse + 14, // 156: rill.runtime.v1.RuntimeService.ListInstances:output_type -> rill.runtime.v1.ListInstancesResponse + 16, // 157: rill.runtime.v1.RuntimeService.GetInstance:output_type -> rill.runtime.v1.GetInstanceResponse + 18, // 158: rill.runtime.v1.RuntimeService.CreateInstance:output_type -> rill.runtime.v1.CreateInstanceResponse + 22, // 159: rill.runtime.v1.RuntimeService.EditInstance:output_type -> rill.runtime.v1.EditInstanceResponse + 20, // 160: rill.runtime.v1.RuntimeService.DeleteInstance:output_type -> rill.runtime.v1.DeleteInstanceResponse + 24, // 161: rill.runtime.v1.RuntimeService.ReloadConfig:output_type -> rill.runtime.v1.ReloadConfigResponse + 26, // 162: rill.runtime.v1.RuntimeService.ListFiles:output_type -> rill.runtime.v1.ListFilesResponse + 29, // 163: rill.runtime.v1.RuntimeService.WatchFiles:output_type -> rill.runtime.v1.WatchFilesResponse + 31, // 164: rill.runtime.v1.RuntimeService.GetFile:output_type -> rill.runtime.v1.GetFileResponse + 33, // 165: rill.runtime.v1.RuntimeService.PutFile:output_type -> rill.runtime.v1.PutFileResponse + 35, // 166: rill.runtime.v1.RuntimeService.CreateDirectory:output_type -> rill.runtime.v1.CreateDirectoryResponse + 37, // 167: rill.runtime.v1.RuntimeService.DeleteFile:output_type -> rill.runtime.v1.DeleteFileResponse + 39, // 168: rill.runtime.v1.RuntimeService.RenameFile:output_type -> rill.runtime.v1.RenameFileResponse + 42, // 169: rill.runtime.v1.RuntimeService.ListExamples:output_type -> rill.runtime.v1.ListExamplesResponse + 44, // 170: rill.runtime.v1.RuntimeService.UnpackExample:output_type -> rill.runtime.v1.UnpackExampleResponse + 46, // 171: rill.runtime.v1.RuntimeService.UnpackEmpty:output_type -> rill.runtime.v1.UnpackEmptyResponse + 48, // 172: rill.runtime.v1.RuntimeService.GenerateMetricsViewFile:output_type -> rill.runtime.v1.GenerateMetricsViewFileResponse + 50, // 173: rill.runtime.v1.RuntimeService.GenerateCanvasFile:output_type -> rill.runtime.v1.GenerateCanvasFileResponse + 52, // 174: rill.runtime.v1.RuntimeService.GenerateResolver:output_type -> rill.runtime.v1.GenerateResolverResponse + 54, // 175: rill.runtime.v1.RuntimeService.GenerateRenderer:output_type -> rill.runtime.v1.GenerateRendererResponse + 56, // 176: rill.runtime.v1.RuntimeService.GenerateTemplate:output_type -> rill.runtime.v1.GenerateTemplateResponse + 58, // 177: rill.runtime.v1.RuntimeService.QueryResolver:output_type -> rill.runtime.v1.QueryResolverResponse + 62, // 178: rill.runtime.v1.RuntimeService.GetLogs:output_type -> rill.runtime.v1.GetLogsResponse + 64, // 179: rill.runtime.v1.RuntimeService.WatchLogs:output_type -> rill.runtime.v1.WatchLogsResponse + 66, // 180: rill.runtime.v1.RuntimeService.ListResources:output_type -> rill.runtime.v1.ListResourcesResponse + 68, // 181: rill.runtime.v1.RuntimeService.WatchResources:output_type -> rill.runtime.v1.WatchResourcesResponse + 70, // 182: rill.runtime.v1.RuntimeService.GetResource:output_type -> rill.runtime.v1.GetResourceResponse + 72, // 183: rill.runtime.v1.RuntimeService.GetExplore:output_type -> rill.runtime.v1.GetExploreResponse + 74, // 184: rill.runtime.v1.RuntimeService.GetModelPartitions:output_type -> rill.runtime.v1.GetModelPartitionsResponse + 76, // 185: rill.runtime.v1.RuntimeService.CreateTrigger:output_type -> rill.runtime.v1.CreateTriggerResponse + 80, // 186: rill.runtime.v1.RuntimeService.ListConnectorDrivers:output_type -> rill.runtime.v1.ListConnectorDriversResponse + 82, // 187: rill.runtime.v1.RuntimeService.AnalyzeConnectors:output_type -> rill.runtime.v1.AnalyzeConnectorsResponse + 84, // 188: rill.runtime.v1.RuntimeService.ListNotifierConnectors:output_type -> rill.runtime.v1.ListNotifierConnectorsResponse + 91, // 189: rill.runtime.v1.RuntimeService.ListConversations:output_type -> rill.runtime.v1.ListConversationsResponse + 93, // 190: rill.runtime.v1.RuntimeService.GetConversation:output_type -> rill.runtime.v1.GetConversationResponse + 95, // 191: rill.runtime.v1.RuntimeService.ShareConversation:output_type -> rill.runtime.v1.ShareConversationResponse + 97, // 192: rill.runtime.v1.RuntimeService.ForkConversation:output_type -> rill.runtime.v1.ForkConversationResponse + 99, // 193: rill.runtime.v1.RuntimeService.ListTools:output_type -> rill.runtime.v1.ListToolsResponse + 101, // 194: rill.runtime.v1.RuntimeService.Complete:output_type -> rill.runtime.v1.CompleteResponse + 103, // 195: rill.runtime.v1.RuntimeService.CompleteStreaming:output_type -> rill.runtime.v1.CompleteStreamingResponse + 105, // 196: rill.runtime.v1.RuntimeService.IssueDevJWT:output_type -> rill.runtime.v1.IssueDevJWTResponse + 107, // 197: rill.runtime.v1.RuntimeService.AnalyzeVariables:output_type -> rill.runtime.v1.AnalyzeVariablesResponse + 110, // 198: rill.runtime.v1.RuntimeService.ListGitCommits:output_type -> rill.runtime.v1.ListGitCommitsResponse + 113, // 199: rill.runtime.v1.RuntimeService.GitStatus:output_type -> rill.runtime.v1.GitStatusResponse + 115, // 200: rill.runtime.v1.RuntimeService.ListGitBranches:output_type -> rill.runtime.v1.ListGitBranchesResponse + 118, // 201: rill.runtime.v1.RuntimeService.GitCommit:output_type -> rill.runtime.v1.GitCommitResponse + 120, // 202: rill.runtime.v1.RuntimeService.RestoreGitCommit:output_type -> rill.runtime.v1.RestoreGitCommitResponse + 122, // 203: rill.runtime.v1.RuntimeService.GitMergeToBranch:output_type -> rill.runtime.v1.GitMergeToBranchResponse + 124, // 204: rill.runtime.v1.RuntimeService.GitSwitchBranch:output_type -> rill.runtime.v1.GitSwitchBranchResponse + 126, // 205: rill.runtime.v1.RuntimeService.GitPull:output_type -> rill.runtime.v1.GitPullResponse + 128, // 206: rill.runtime.v1.RuntimeService.GitPush:output_type -> rill.runtime.v1.GitPushResponse + 153, // [153:207] is the sub-list for method output_type + 99, // [99:153] is the sub-list for method input_type + 99, // [99:99] is the sub-list for extension type_name + 99, // [99:99] is the sub-list for extension extendee + 0, // [0:99] is the sub-list for field type_name } func init() { file_rill_runtime_v1_api_proto_init() } @@ -10910,7 +11113,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[51].Exporter = func(v any, i int) any { - switch v := v.(*QueryResolverRequest); i { + switch v := v.(*GenerateTemplateRequest); i { case 0: return &v.state case 1: @@ -10922,7 +11125,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[52].Exporter = func(v any, i int) any { - switch v := v.(*QueryResolverResponse); i { + switch v := v.(*GenerateTemplateResponse); i { case 0: return &v.state case 1: @@ -10934,7 +11137,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[53].Exporter = func(v any, i int) any { - switch v := v.(*Log); i { + switch v := v.(*QueryResolverRequest); i { case 0: return &v.state case 1: @@ -10946,7 +11149,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[54].Exporter = func(v any, i int) any { - switch v := v.(*ModelPartition); i { + switch v := v.(*QueryResolverResponse); i { case 0: return &v.state case 1: @@ -10958,7 +11161,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[55].Exporter = func(v any, i int) any { - switch v := v.(*GetLogsRequest); i { + switch v := v.(*Log); i { case 0: return &v.state case 1: @@ -10970,7 +11173,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[56].Exporter = func(v any, i int) any { - switch v := v.(*GetLogsResponse); i { + switch v := v.(*ModelPartition); i { case 0: return &v.state case 1: @@ -10982,7 +11185,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[57].Exporter = func(v any, i int) any { - switch v := v.(*WatchLogsRequest); i { + switch v := v.(*GetLogsRequest); i { case 0: return &v.state case 1: @@ -10994,7 +11197,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[58].Exporter = func(v any, i int) any { - switch v := v.(*WatchLogsResponse); i { + switch v := v.(*GetLogsResponse); i { case 0: return &v.state case 1: @@ -11006,7 +11209,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[59].Exporter = func(v any, i int) any { - switch v := v.(*ListResourcesRequest); i { + switch v := v.(*WatchLogsRequest); i { case 0: return &v.state case 1: @@ -11018,7 +11221,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[60].Exporter = func(v any, i int) any { - switch v := v.(*ListResourcesResponse); i { + switch v := v.(*WatchLogsResponse); i { case 0: return &v.state case 1: @@ -11030,7 +11233,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[61].Exporter = func(v any, i int) any { - switch v := v.(*WatchResourcesRequest); i { + switch v := v.(*ListResourcesRequest); i { case 0: return &v.state case 1: @@ -11042,7 +11245,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[62].Exporter = func(v any, i int) any { - switch v := v.(*WatchResourcesResponse); i { + switch v := v.(*ListResourcesResponse); i { case 0: return &v.state case 1: @@ -11054,7 +11257,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[63].Exporter = func(v any, i int) any { - switch v := v.(*GetResourceRequest); i { + switch v := v.(*WatchResourcesRequest); i { case 0: return &v.state case 1: @@ -11066,7 +11269,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[64].Exporter = func(v any, i int) any { - switch v := v.(*GetResourceResponse); i { + switch v := v.(*WatchResourcesResponse); i { case 0: return &v.state case 1: @@ -11078,7 +11281,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[65].Exporter = func(v any, i int) any { - switch v := v.(*GetExploreRequest); i { + switch v := v.(*GetResourceRequest); i { case 0: return &v.state case 1: @@ -11090,7 +11293,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[66].Exporter = func(v any, i int) any { - switch v := v.(*GetExploreResponse); i { + switch v := v.(*GetResourceResponse); i { case 0: return &v.state case 1: @@ -11102,7 +11305,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[67].Exporter = func(v any, i int) any { - switch v := v.(*GetModelPartitionsRequest); i { + switch v := v.(*GetExploreRequest); i { case 0: return &v.state case 1: @@ -11114,7 +11317,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[68].Exporter = func(v any, i int) any { - switch v := v.(*GetModelPartitionsResponse); i { + switch v := v.(*GetExploreResponse); i { case 0: return &v.state case 1: @@ -11126,7 +11329,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[69].Exporter = func(v any, i int) any { - switch v := v.(*CreateTriggerRequest); i { + switch v := v.(*GetModelPartitionsRequest); i { case 0: return &v.state case 1: @@ -11138,7 +11341,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[70].Exporter = func(v any, i int) any { - switch v := v.(*CreateTriggerResponse); i { + switch v := v.(*GetModelPartitionsResponse); i { case 0: return &v.state case 1: @@ -11150,7 +11353,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[71].Exporter = func(v any, i int) any { - switch v := v.(*ConnectorDriver); i { + switch v := v.(*CreateTriggerRequest); i { case 0: return &v.state case 1: @@ -11162,7 +11365,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[72].Exporter = func(v any, i int) any { - switch v := v.(*AnalyzedConnector); i { + switch v := v.(*CreateTriggerResponse); i { case 0: return &v.state case 1: @@ -11174,7 +11377,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[73].Exporter = func(v any, i int) any { - switch v := v.(*ListConnectorDriversRequest); i { + switch v := v.(*ConnectorDriver); i { case 0: return &v.state case 1: @@ -11186,7 +11389,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[74].Exporter = func(v any, i int) any { - switch v := v.(*ListConnectorDriversResponse); i { + switch v := v.(*AnalyzedConnector); i { case 0: return &v.state case 1: @@ -11198,7 +11401,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[75].Exporter = func(v any, i int) any { - switch v := v.(*AnalyzeConnectorsRequest); i { + switch v := v.(*ListConnectorDriversRequest); i { case 0: return &v.state case 1: @@ -11210,7 +11413,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[76].Exporter = func(v any, i int) any { - switch v := v.(*AnalyzeConnectorsResponse); i { + switch v := v.(*ListConnectorDriversResponse); i { case 0: return &v.state case 1: @@ -11222,7 +11425,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[77].Exporter = func(v any, i int) any { - switch v := v.(*ListNotifierConnectorsRequest); i { + switch v := v.(*AnalyzeConnectorsRequest); i { case 0: return &v.state case 1: @@ -11234,7 +11437,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[78].Exporter = func(v any, i int) any { - switch v := v.(*ListNotifierConnectorsResponse); i { + switch v := v.(*AnalyzeConnectorsResponse); i { case 0: return &v.state case 1: @@ -11246,7 +11449,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[79].Exporter = func(v any, i int) any { - switch v := v.(*Conversation); i { + switch v := v.(*ListNotifierConnectorsRequest); i { case 0: return &v.state case 1: @@ -11258,7 +11461,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[80].Exporter = func(v any, i int) any { - switch v := v.(*Message); i { + switch v := v.(*ListNotifierConnectorsResponse); i { case 0: return &v.state case 1: @@ -11270,7 +11473,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[81].Exporter = func(v any, i int) any { - switch v := v.(*AnalystAgentContext); i { + switch v := v.(*Conversation); i { case 0: return &v.state case 1: @@ -11282,7 +11485,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[82].Exporter = func(v any, i int) any { - switch v := v.(*DeveloperAgentContext); i { + switch v := v.(*Message); i { case 0: return &v.state case 1: @@ -11294,7 +11497,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[83].Exporter = func(v any, i int) any { - switch v := v.(*FeedbackAgentContext); i { + switch v := v.(*AnalystAgentContext); i { case 0: return &v.state case 1: @@ -11306,7 +11509,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[84].Exporter = func(v any, i int) any { - switch v := v.(*ListConversationsRequest); i { + switch v := v.(*DeveloperAgentContext); i { case 0: return &v.state case 1: @@ -11318,7 +11521,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[85].Exporter = func(v any, i int) any { - switch v := v.(*ListConversationsResponse); i { + switch v := v.(*FeedbackAgentContext); i { case 0: return &v.state case 1: @@ -11330,7 +11533,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[86].Exporter = func(v any, i int) any { - switch v := v.(*GetConversationRequest); i { + switch v := v.(*ListConversationsRequest); i { case 0: return &v.state case 1: @@ -11342,7 +11545,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[87].Exporter = func(v any, i int) any { - switch v := v.(*GetConversationResponse); i { + switch v := v.(*ListConversationsResponse); i { case 0: return &v.state case 1: @@ -11354,7 +11557,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[88].Exporter = func(v any, i int) any { - switch v := v.(*ShareConversationRequest); i { + switch v := v.(*GetConversationRequest); i { case 0: return &v.state case 1: @@ -11366,7 +11569,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[89].Exporter = func(v any, i int) any { - switch v := v.(*ShareConversationResponse); i { + switch v := v.(*GetConversationResponse); i { case 0: return &v.state case 1: @@ -11378,7 +11581,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[90].Exporter = func(v any, i int) any { - switch v := v.(*ForkConversationRequest); i { + switch v := v.(*ShareConversationRequest); i { case 0: return &v.state case 1: @@ -11390,7 +11593,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[91].Exporter = func(v any, i int) any { - switch v := v.(*ForkConversationResponse); i { + switch v := v.(*ShareConversationResponse); i { case 0: return &v.state case 1: @@ -11402,7 +11605,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[92].Exporter = func(v any, i int) any { - switch v := v.(*ListToolsRequest); i { + switch v := v.(*ForkConversationRequest); i { case 0: return &v.state case 1: @@ -11414,7 +11617,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[93].Exporter = func(v any, i int) any { - switch v := v.(*ListToolsResponse); i { + switch v := v.(*ForkConversationResponse); i { case 0: return &v.state case 1: @@ -11426,7 +11629,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[94].Exporter = func(v any, i int) any { - switch v := v.(*CompleteRequest); i { + switch v := v.(*ListToolsRequest); i { case 0: return &v.state case 1: @@ -11438,7 +11641,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[95].Exporter = func(v any, i int) any { - switch v := v.(*CompleteResponse); i { + switch v := v.(*ListToolsResponse); i { case 0: return &v.state case 1: @@ -11450,7 +11653,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[96].Exporter = func(v any, i int) any { - switch v := v.(*CompleteStreamingRequest); i { + switch v := v.(*CompleteRequest); i { case 0: return &v.state case 1: @@ -11462,7 +11665,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[97].Exporter = func(v any, i int) any { - switch v := v.(*CompleteStreamingResponse); i { + switch v := v.(*CompleteResponse); i { case 0: return &v.state case 1: @@ -11474,7 +11677,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[98].Exporter = func(v any, i int) any { - switch v := v.(*IssueDevJWTRequest); i { + switch v := v.(*CompleteStreamingRequest); i { case 0: return &v.state case 1: @@ -11486,7 +11689,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[99].Exporter = func(v any, i int) any { - switch v := v.(*IssueDevJWTResponse); i { + switch v := v.(*CompleteStreamingResponse); i { case 0: return &v.state case 1: @@ -11498,7 +11701,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[100].Exporter = func(v any, i int) any { - switch v := v.(*AnalyzeVariablesRequest); i { + switch v := v.(*IssueDevJWTRequest); i { case 0: return &v.state case 1: @@ -11510,7 +11713,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[101].Exporter = func(v any, i int) any { - switch v := v.(*AnalyzeVariablesResponse); i { + switch v := v.(*IssueDevJWTResponse); i { case 0: return &v.state case 1: @@ -11522,7 +11725,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[102].Exporter = func(v any, i int) any { - switch v := v.(*AnalyzedVariable); i { + switch v := v.(*AnalyzeVariablesRequest); i { case 0: return &v.state case 1: @@ -11534,7 +11737,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[103].Exporter = func(v any, i int) any { - switch v := v.(*ListGitCommitsRequest); i { + switch v := v.(*AnalyzeVariablesResponse); i { case 0: return &v.state case 1: @@ -11546,7 +11749,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[104].Exporter = func(v any, i int) any { - switch v := v.(*ListGitCommitsResponse); i { + switch v := v.(*AnalyzedVariable); i { case 0: return &v.state case 1: @@ -11558,7 +11761,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[105].Exporter = func(v any, i int) any { - switch v := v.(*GitCommit); i { + switch v := v.(*ListGitCommitsRequest); i { case 0: return &v.state case 1: @@ -11570,7 +11773,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[106].Exporter = func(v any, i int) any { - switch v := v.(*GitStatusRequest); i { + switch v := v.(*ListGitCommitsResponse); i { case 0: return &v.state case 1: @@ -11582,7 +11785,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[107].Exporter = func(v any, i int) any { - switch v := v.(*GitStatusResponse); i { + switch v := v.(*GitCommit); i { case 0: return &v.state case 1: @@ -11594,7 +11797,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[108].Exporter = func(v any, i int) any { - switch v := v.(*ListGitBranchesRequest); i { + switch v := v.(*GitStatusRequest); i { case 0: return &v.state case 1: @@ -11606,7 +11809,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[109].Exporter = func(v any, i int) any { - switch v := v.(*ListGitBranchesResponse); i { + switch v := v.(*GitStatusResponse); i { case 0: return &v.state case 1: @@ -11618,7 +11821,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[110].Exporter = func(v any, i int) any { - switch v := v.(*GitBranch); i { + switch v := v.(*ListGitBranchesRequest); i { case 0: return &v.state case 1: @@ -11630,7 +11833,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[111].Exporter = func(v any, i int) any { - switch v := v.(*GitCommitRequest); i { + switch v := v.(*ListGitBranchesResponse); i { case 0: return &v.state case 1: @@ -11642,7 +11845,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[112].Exporter = func(v any, i int) any { - switch v := v.(*GitCommitResponse); i { + switch v := v.(*GitBranch); i { case 0: return &v.state case 1: @@ -11654,7 +11857,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[113].Exporter = func(v any, i int) any { - switch v := v.(*RestoreGitCommitRequest); i { + switch v := v.(*GitCommitRequest); i { case 0: return &v.state case 1: @@ -11666,7 +11869,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[114].Exporter = func(v any, i int) any { - switch v := v.(*RestoreGitCommitResponse); i { + switch v := v.(*GitCommitResponse); i { case 0: return &v.state case 1: @@ -11678,7 +11881,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[115].Exporter = func(v any, i int) any { - switch v := v.(*GitMergeToBranchRequest); i { + switch v := v.(*RestoreGitCommitRequest); i { case 0: return &v.state case 1: @@ -11690,7 +11893,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[116].Exporter = func(v any, i int) any { - switch v := v.(*GitMergeToBranchResponse); i { + switch v := v.(*RestoreGitCommitResponse); i { case 0: return &v.state case 1: @@ -11702,7 +11905,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[117].Exporter = func(v any, i int) any { - switch v := v.(*GitSwitchBranchRequest); i { + switch v := v.(*GitMergeToBranchRequest); i { case 0: return &v.state case 1: @@ -11714,7 +11917,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[118].Exporter = func(v any, i int) any { - switch v := v.(*GitSwitchBranchResponse); i { + switch v := v.(*GitMergeToBranchResponse); i { case 0: return &v.state case 1: @@ -11726,7 +11929,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[119].Exporter = func(v any, i int) any { - switch v := v.(*GitPullRequest); i { + switch v := v.(*GitSwitchBranchRequest); i { case 0: return &v.state case 1: @@ -11738,7 +11941,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[120].Exporter = func(v any, i int) any { - switch v := v.(*GitPullResponse); i { + switch v := v.(*GitSwitchBranchResponse); i { case 0: return &v.state case 1: @@ -11750,7 +11953,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[121].Exporter = func(v any, i int) any { - switch v := v.(*GitPushRequest); i { + switch v := v.(*GitPullRequest); i { case 0: return &v.state case 1: @@ -11762,6 +11965,30 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[122].Exporter = func(v any, i int) any { + switch v := v.(*GitPullResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rill_runtime_v1_api_proto_msgTypes[123].Exporter = func(v any, i int) any { + switch v := v.(*GitPushRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rill_runtime_v1_api_proto_msgTypes[124].Exporter = func(v any, i int) any { switch v := v.(*GitPushResponse); i { case 0: return &v.state @@ -11773,7 +12000,7 @@ func file_rill_runtime_v1_api_proto_init() { return nil } } - file_rill_runtime_v1_api_proto_msgTypes[131].Exporter = func(v any, i int) any { + file_rill_runtime_v1_api_proto_msgTypes[134].Exporter = func(v any, i int) any { switch v := v.(*ConnectorDriver_Property); i { case 0: return &v.state @@ -11793,7 +12020,7 @@ func file_rill_runtime_v1_api_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_rill_runtime_v1_api_proto_rawDesc, NumEnums: 4, - NumMessages: 134, + NumMessages: 137, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gen/rill/runtime/v1/api.pb.gw.go b/proto/gen/rill/runtime/v1/api.pb.gw.go index e270bdeaddf..aa1b607955c 100644 --- a/proto/gen/rill/runtime/v1/api.pb.gw.go +++ b/proto/gen/rill/runtime/v1/api.pb.gw.go @@ -1244,6 +1244,66 @@ func local_request_RuntimeService_GenerateRenderer_0(ctx context.Context, marsha } +func request_RuntimeService_GenerateTemplate_0(ctx context.Context, marshaler runtime.Marshaler, client RuntimeServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GenerateTemplateRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["instance_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "instance_id") + } + + protoReq.InstanceId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "instance_id", err) + } + + msg, err := client.GenerateTemplate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RuntimeService_GenerateTemplate_0(ctx context.Context, marshaler runtime.Marshaler, server RuntimeServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GenerateTemplateRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["instance_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "instance_id") + } + + protoReq.InstanceId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "instance_id", err) + } + + msg, err := server.GenerateTemplate(ctx, &protoReq) + return msg, metadata, err + +} + func request_RuntimeService_QueryResolver_0(ctx context.Context, marshaler runtime.Marshaler, client RuntimeServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryResolverRequest var metadata runtime.ServerMetadata @@ -3594,6 +3654,31 @@ func RegisterRuntimeServiceHandlerServer(ctx context.Context, mux *runtime.Serve }) + mux.Handle("POST", pattern_RuntimeService_GenerateTemplate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/rill.runtime.v1.RuntimeService/GenerateTemplate", runtime.WithHTTPPathPattern("/v1/instances/{instance_id}/generate/template")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RuntimeService_GenerateTemplate_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_RuntimeService_GenerateTemplate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_RuntimeService_QueryResolver_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -4837,6 +4922,28 @@ func RegisterRuntimeServiceHandlerClient(ctx context.Context, mux *runtime.Serve }) + mux.Handle("POST", pattern_RuntimeService_GenerateTemplate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/rill.runtime.v1.RuntimeService/GenerateTemplate", runtime.WithHTTPPathPattern("/v1/instances/{instance_id}/generate/template")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RuntimeService_GenerateTemplate_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_RuntimeService_GenerateTemplate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_RuntimeService_QueryResolver_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -5547,6 +5654,8 @@ var ( pattern_RuntimeService_GenerateRenderer_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 2, 4}, []string{"v1", "instances", "instance_id", "generate", "renderer"}, "")) + pattern_RuntimeService_GenerateTemplate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 2, 4}, []string{"v1", "instances", "instance_id", "generate", "template"}, "")) + pattern_RuntimeService_QueryResolver_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 2, 4}, []string{"v1", "instances", "instance_id", "query", "resolver"}, "")) pattern_RuntimeService_GetLogs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"v1", "instances", "instance_id", "logs"}, "")) @@ -5655,6 +5764,8 @@ var ( forward_RuntimeService_GenerateRenderer_0 = runtime.ForwardResponseMessage + forward_RuntimeService_GenerateTemplate_0 = runtime.ForwardResponseMessage + forward_RuntimeService_QueryResolver_0 = runtime.ForwardResponseMessage forward_RuntimeService_GetLogs_0 = runtime.ForwardResponseMessage diff --git a/proto/gen/rill/runtime/v1/api.pb.validate.go b/proto/gen/rill/runtime/v1/api.pb.validate.go index 86197f0eed8..675999a8149 100644 --- a/proto/gen/rill/runtime/v1/api.pb.validate.go +++ b/proto/gen/rill/runtime/v1/api.pb.validate.go @@ -6386,6 +6386,291 @@ var _ interface { ErrorName() string } = GenerateRendererResponseValidationError{} +// Validate checks the field values on GenerateTemplateRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GenerateTemplateRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GenerateTemplateRequest with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GenerateTemplateRequestMultiError, or nil if none found. +func (m *GenerateTemplateRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *GenerateTemplateRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if !_GenerateTemplateRequest_InstanceId_Pattern.MatchString(m.GetInstanceId()) { + err := GenerateTemplateRequestValidationError{ + field: "InstanceId", + reason: "value does not match regex pattern \"^[_\\\\-a-zA-Z0-9]+$\"", + } + if !all { + return err + } + errors = append(errors, err) + } + + if _, ok := _GenerateTemplateRequest_ResourceType_InLookup[m.GetResourceType()]; !ok { + err := GenerateTemplateRequestValidationError{ + field: "ResourceType", + reason: "value must be in list [connector model]", + } + if !all { + return err + } + errors = append(errors, err) + } + + if !_GenerateTemplateRequest_Driver_Pattern.MatchString(m.GetDriver()) { + err := GenerateTemplateRequestValidationError{ + field: "Driver", + reason: "value does not match regex pattern \"^[a-z][a-z0-9_]*$\"", + } + if !all { + return err + } + errors = append(errors, err) + } + + if all { + switch v := interface{}(m.GetProperties()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GenerateTemplateRequestValidationError{ + field: "Properties", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GenerateTemplateRequestValidationError{ + field: "Properties", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetProperties()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GenerateTemplateRequestValidationError{ + field: "Properties", + reason: "embedded message failed validation", + cause: err, + } + } + } + + // no validation rules for ConnectorName + + if len(errors) > 0 { + return GenerateTemplateRequestMultiError(errors) + } + + return nil +} + +// GenerateTemplateRequestMultiError is an error wrapping multiple validation +// errors returned by GenerateTemplateRequest.ValidateAll() if the designated +// constraints aren't met. +type GenerateTemplateRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GenerateTemplateRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GenerateTemplateRequestMultiError) AllErrors() []error { return m } + +// GenerateTemplateRequestValidationError is the validation error returned by +// GenerateTemplateRequest.Validate if the designated constraints aren't met. +type GenerateTemplateRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GenerateTemplateRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GenerateTemplateRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GenerateTemplateRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GenerateTemplateRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GenerateTemplateRequestValidationError) ErrorName() string { + return "GenerateTemplateRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e GenerateTemplateRequestValidationError) 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 %sGenerateTemplateRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GenerateTemplateRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GenerateTemplateRequestValidationError{} + +var _GenerateTemplateRequest_InstanceId_Pattern = regexp.MustCompile("^[_\\-a-zA-Z0-9]+$") + +var _GenerateTemplateRequest_ResourceType_InLookup = map[string]struct{}{ + "connector": {}, + "model": {}, +} + +var _GenerateTemplateRequest_Driver_Pattern = regexp.MustCompile("^[a-z][a-z0-9_]*$") + +// Validate checks the field values on GenerateTemplateResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GenerateTemplateResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GenerateTemplateResponse with the +// rules defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GenerateTemplateResponseMultiError, or nil if none found. +func (m *GenerateTemplateResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *GenerateTemplateResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Blob + + // no validation rules for EnvVars + + // no validation rules for ResourceType + + // no validation rules for Driver + + if len(errors) > 0 { + return GenerateTemplateResponseMultiError(errors) + } + + return nil +} + +// GenerateTemplateResponseMultiError is an error wrapping multiple validation +// errors returned by GenerateTemplateResponse.ValidateAll() if the designated +// constraints aren't met. +type GenerateTemplateResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GenerateTemplateResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GenerateTemplateResponseMultiError) AllErrors() []error { return m } + +// GenerateTemplateResponseValidationError is the validation error returned by +// GenerateTemplateResponse.Validate if the designated constraints aren't met. +type GenerateTemplateResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GenerateTemplateResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GenerateTemplateResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GenerateTemplateResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GenerateTemplateResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GenerateTemplateResponseValidationError) ErrorName() string { + return "GenerateTemplateResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e GenerateTemplateResponseValidationError) 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 %sGenerateTemplateResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GenerateTemplateResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GenerateTemplateResponseValidationError{} + // Validate checks the field values on QueryResolverRequest with the rules // defined in the proto definition for this message. If any rules are // violated, the first error encountered is returned, or nil if there are no violations. diff --git a/proto/gen/rill/runtime/v1/api_grpc.pb.go b/proto/gen/rill/runtime/v1/api_grpc.pb.go index d02b82b3dc2..ea3fda78d06 100644 --- a/proto/gen/rill/runtime/v1/api_grpc.pb.go +++ b/proto/gen/rill/runtime/v1/api_grpc.pb.go @@ -42,6 +42,7 @@ const ( RuntimeService_GenerateCanvasFile_FullMethodName = "/rill.runtime.v1.RuntimeService/GenerateCanvasFile" RuntimeService_GenerateResolver_FullMethodName = "/rill.runtime.v1.RuntimeService/GenerateResolver" RuntimeService_GenerateRenderer_FullMethodName = "/rill.runtime.v1.RuntimeService/GenerateRenderer" + RuntimeService_GenerateTemplate_FullMethodName = "/rill.runtime.v1.RuntimeService/GenerateTemplate" RuntimeService_QueryResolver_FullMethodName = "/rill.runtime.v1.RuntimeService/QueryResolver" RuntimeService_GetLogs_FullMethodName = "/rill.runtime.v1.RuntimeService/GetLogs" RuntimeService_WatchLogs_FullMethodName = "/rill.runtime.v1.RuntimeService/WatchLogs" @@ -129,6 +130,8 @@ type RuntimeServiceClient interface { GenerateResolver(ctx context.Context, in *GenerateResolverRequest, opts ...grpc.CallOption) (*GenerateResolverResponse, error) // GenerateRenderer generates a component renderer and renderer properties from a resolver and resolver properties GenerateRenderer(ctx context.Context, in *GenerateRendererRequest, opts ...grpc.CallOption) (*GenerateRendererResponse, error) + // GenerateTemplate generates a connector or model YAML file from structured form data + GenerateTemplate(ctx context.Context, in *GenerateTemplateRequest, opts ...grpc.CallOption) (*GenerateTemplateResponse, error) // QueryResolver queries a resolver with the given properties and arguments QueryResolver(ctx context.Context, in *QueryResolverRequest, opts ...grpc.CallOption) (*QueryResolverResponse, error) // GetLogs returns recent logs from a controller @@ -446,6 +449,16 @@ func (c *runtimeServiceClient) GenerateRenderer(ctx context.Context, in *Generat return out, nil } +func (c *runtimeServiceClient) GenerateTemplate(ctx context.Context, in *GenerateTemplateRequest, opts ...grpc.CallOption) (*GenerateTemplateResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GenerateTemplateResponse) + err := c.cc.Invoke(ctx, RuntimeService_GenerateTemplate_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *runtimeServiceClient) QueryResolver(ctx context.Context, in *QueryResolverRequest, opts ...grpc.CallOption) (*QueryResolverResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(QueryResolverResponse) @@ -828,6 +841,8 @@ type RuntimeServiceServer interface { GenerateResolver(context.Context, *GenerateResolverRequest) (*GenerateResolverResponse, error) // GenerateRenderer generates a component renderer and renderer properties from a resolver and resolver properties GenerateRenderer(context.Context, *GenerateRendererRequest) (*GenerateRendererResponse, error) + // GenerateTemplate generates a connector or model YAML file from structured form data + GenerateTemplate(context.Context, *GenerateTemplateRequest) (*GenerateTemplateResponse, error) // QueryResolver queries a resolver with the given properties and arguments QueryResolver(context.Context, *QueryResolverRequest) (*QueryResolverResponse, error) // GetLogs returns recent logs from a controller @@ -975,6 +990,9 @@ func (UnimplementedRuntimeServiceServer) GenerateResolver(context.Context, *Gene func (UnimplementedRuntimeServiceServer) GenerateRenderer(context.Context, *GenerateRendererRequest) (*GenerateRendererResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GenerateRenderer not implemented") } +func (UnimplementedRuntimeServiceServer) GenerateTemplate(context.Context, *GenerateTemplateRequest) (*GenerateTemplateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GenerateTemplate not implemented") +} func (UnimplementedRuntimeServiceServer) QueryResolver(context.Context, *QueryResolverRequest) (*QueryResolverResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryResolver not implemented") } @@ -1493,6 +1511,24 @@ func _RuntimeService_GenerateRenderer_Handler(srv interface{}, ctx context.Conte return interceptor(ctx, in, info, handler) } +func _RuntimeService_GenerateTemplate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GenerateTemplateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RuntimeServiceServer).GenerateTemplate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: RuntimeService_GenerateTemplate_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RuntimeServiceServer).GenerateTemplate(ctx, req.(*GenerateTemplateRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _RuntimeService_QueryResolver_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryResolverRequest) if err := dec(in); err != nil { @@ -2107,6 +2143,10 @@ var RuntimeService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GenerateRenderer", Handler: _RuntimeService_GenerateRenderer_Handler, }, + { + MethodName: "GenerateTemplate", + Handler: _RuntimeService_GenerateTemplate_Handler, + }, { MethodName: "QueryResolver", Handler: _RuntimeService_QueryResolver_Handler, diff --git a/proto/gen/rill/runtime/v1/runtime.swagger.yaml b/proto/gen/rill/runtime/v1/runtime.swagger.yaml index 206c86f03de..f03f3ea0dd0 100644 --- a/proto/gen/rill/runtime/v1/runtime.swagger.yaml +++ b/proto/gen/rill/runtime/v1/runtime.swagger.yaml @@ -1197,6 +1197,40 @@ paths: description: table and connector should not be provided if metrics_view is provided. tags: - RuntimeService + /v1/instances/{instanceId}/generate/template: + post: + summary: GenerateTemplate generates a connector or model YAML file from structured form data + operationId: RuntimeService_GenerateTemplate + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/v1GenerateTemplateResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpcStatus' + parameters: + - name: instanceId + in: path + required: true + type: string + - name: body + in: body + required: true + schema: + type: object + properties: + resourceType: + type: string + driver: + type: string + properties: + type: object + connectorName: + type: string + tags: + - RuntimeService /v1/instances/{instanceId}/git/branches: get: operationId: RuntimeService_ListGitBranches @@ -5325,6 +5359,21 @@ definitions: type: string resolverProperties: type: object + v1GenerateTemplateResponse: + type: object + properties: + blob: + type: string + envVars: + type: object + additionalProperties: + type: string + resourceType: + type: string + title: Actual resource type used; may differ from request when driver is rewritten + driver: + type: string + title: Actual driver used; may differ from request when rewritten to duckdb v1GetConversationResponse: type: object properties: diff --git a/proto/rill/runtime/v1/api.proto b/proto/rill/runtime/v1/api.proto index e76e368dbda..7bb2e88c758 100644 --- a/proto/rill/runtime/v1/api.proto +++ b/proto/rill/runtime/v1/api.proto @@ -173,6 +173,14 @@ service RuntimeService { }; } + // GenerateTemplate generates a connector or model YAML file from structured form data + rpc GenerateTemplate(GenerateTemplateRequest) returns (GenerateTemplateResponse) { + option (google.api.http) = { + post: "/v1/instances/{instance_id}/generate/template", + body: "*" + }; + } + // QueryResolver queries a resolver with the given properties and arguments rpc QueryResolver(QueryResolverRequest) returns (QueryResolverResponse) { option (google.api.http) = { @@ -758,6 +766,23 @@ message GenerateRendererResponse { google.protobuf.Struct renderer_properties = 2; } +message GenerateTemplateRequest { + string instance_id = 1 [(validate.rules).string = {pattern: "^[_\\-a-zA-Z0-9]+$"}]; + string resource_type = 2 [(validate.rules).string = {in: ["connector", "model"]}]; + string driver = 3 [(validate.rules).string = {pattern: "^[a-z][a-z0-9_]*$"}]; + google.protobuf.Struct properties = 4; + string connector_name = 5; +} + +message GenerateTemplateResponse { + string blob = 1; + map env_vars = 2; + // Actual resource type used; may differ from request when driver is rewritten + string resource_type = 3; + // Actual driver used; may differ from request when rewritten to duckdb + string driver = 4; +} + message QueryResolverRequest { string instance_id = 1; string resolver = 2; diff --git a/runtime/drivers/athena/athena.go b/runtime/drivers/athena/athena.go index 5dcf6f850b1..a089ad2474b 100644 --- a/runtime/drivers/athena/athena.go +++ b/runtime/drivers/athena/athena.go @@ -42,6 +42,7 @@ var spec = drivers.Spec{ Placeholder: "your_access_key_id", Required: true, Secret: true, + EnvVarName: "AWS_ACCESS_KEY_ID", }, { Key: "aws_secret_access_key", @@ -51,6 +52,7 @@ var spec = drivers.Spec{ Placeholder: "your_secret_access_key", Required: true, Secret: true, + EnvVarName: "AWS_SECRET_ACCESS_KEY", }, { Key: "output_location", diff --git a/runtime/drivers/azure/azure.go b/runtime/drivers/azure/azure.go index cb44d219271..dad7a04e0f9 100644 --- a/runtime/drivers/azure/azure.go +++ b/runtime/drivers/azure/azure.go @@ -29,14 +29,16 @@ var spec = drivers.Spec{ Secret: true, }, { - Key: "azure_storage_key", - Type: drivers.StringPropertyType, - Secret: true, + Key: "azure_storage_key", + Type: drivers.StringPropertyType, + Secret: true, + EnvVarName: "AZURE_STORAGE_KEY", }, { - Key: "azure_storage_sas_token", - Type: drivers.StringPropertyType, - Secret: true, + Key: "azure_storage_sas_token", + Type: drivers.StringPropertyType, + Secret: true, + EnvVarName: "AZURE_STORAGE_SAS_TOKEN", }, { Key: "azure_storage_connection_string", @@ -45,6 +47,7 @@ var spec = drivers.Spec{ Description: "Azure connection string for storage account", Placeholder: "Paste your Azure connection string here", Secret: true, + EnvVarName: "AZURE_STORAGE_CONNECTION_STRING", }, }, SourceProperties: []*drivers.PropertySpec{ diff --git a/runtime/drivers/bigquery/bigquery.go b/runtime/drivers/bigquery/bigquery.go index 8b5487ecef7..f483dd4a18d 100644 --- a/runtime/drivers/bigquery/bigquery.go +++ b/runtime/drivers/bigquery/bigquery.go @@ -43,6 +43,7 @@ var spec = drivers.Spec{ Description: "GCP credentials as JSON string", Placeholder: "Paste your GCP service account JSON here", Secret: true, + EnvVarName: "GOOGLE_APPLICATION_CREDENTIALS", Required: true, }, }, diff --git a/runtime/drivers/clickhouse/clickhouse.go b/runtime/drivers/clickhouse/clickhouse.go index 63c92034d7d..e0af958ccb4 100644 --- a/runtime/drivers/clickhouse/clickhouse.go +++ b/runtime/drivers/clickhouse/clickhouse.go @@ -67,6 +67,7 @@ var spec = drivers.Spec{ DisplayName: "Connection string", Placeholder: "clickhouse://localhost:9000?username=default&password=password", Secret: true, + EnvVarName: "CLICKHOUSE_DSN", NoPrompt: true, }, { @@ -106,6 +107,7 @@ var spec = drivers.Spec{ Description: "Password to connect to the ClickHouse server", Placeholder: "Database password", Secret: true, + EnvVarName: "CLICKHOUSE_PASSWORD", Hint: "Password to your database", }, { diff --git a/runtime/drivers/connectors.go b/runtime/drivers/connectors.go index 72cad88651a..9de7edb97a1 100644 --- a/runtime/drivers/connectors.go +++ b/runtime/drivers/connectors.go @@ -46,8 +46,9 @@ type PropertySpec struct { Hint string Default string Placeholder string - Secret bool - NoPrompt bool + Secret bool + EnvVarName string + NoPrompt bool } // PropertyType is an enum of types supported for connector properties. diff --git a/runtime/drivers/druid/druid.go b/runtime/drivers/druid/druid.go index e829f31cfac..414d1c65b69 100644 --- a/runtime/drivers/druid/druid.go +++ b/runtime/drivers/druid/druid.go @@ -42,6 +42,7 @@ var spec = drivers.Spec{ DisplayName: "Connection string", Placeholder: "https://example.com/druid/v2/sql/avatica-protobuf?authentication=BASIC&avaticaUser=username&avaticaPassword=password", Secret: true, + EnvVarName: "DRUID_DSN", NoPrompt: true, }, { @@ -76,6 +77,7 @@ var spec = drivers.Spec{ Description: "Password to connect to the Druid server", Placeholder: "password", Secret: true, + EnvVarName: "DRUID_PASSWORD", }, { Key: "ssl", diff --git a/runtime/drivers/duckdb/duckdb.go b/runtime/drivers/duckdb/duckdb.go index e0b20da013d..2f14af6dce8 100644 --- a/runtime/drivers/duckdb/duckdb.go +++ b/runtime/drivers/duckdb/duckdb.go @@ -105,6 +105,7 @@ var motherduckSpec = drivers.Spec{ Key: "token", Type: drivers.StringPropertyType, Secret: true, + EnvVarName: "MOTHERDUCK_TOKEN", Required: true, DisplayName: "Token", Description: "MotherDuck token", diff --git a/runtime/drivers/gcs/gcs.go b/runtime/drivers/gcs/gcs.go index 8c60d261a29..4fe6fbac6ca 100644 --- a/runtime/drivers/gcs/gcs.go +++ b/runtime/drivers/gcs/gcs.go @@ -37,6 +37,7 @@ var spec = drivers.Spec{ Description: "GCP credentials as JSON string", Placeholder: "Paste your GCP service account JSON here", Secret: true, + EnvVarName: "GOOGLE_APPLICATION_CREDENTIALS", }, { Key: "key_id", @@ -45,6 +46,7 @@ var spec = drivers.Spec{ Description: "HMAC access key ID for S3-compatible authentication", Hint: "Optional S3-compatible Key ID when used in compatibility mode", Secret: true, + EnvVarName: "GCP_ACCESS_KEY_ID", }, { Key: "secret", @@ -53,6 +55,7 @@ var spec = drivers.Spec{ Description: "HMAC secret access key for S3-compatible authentication", Hint: "Optional S3-compatible Secret when used in compatibility mode", Secret: true, + EnvVarName: "GCP_SECRET_ACCESS_KEY", }, }, SourceProperties: []*drivers.PropertySpec{ diff --git a/runtime/drivers/mysql/mysql.go b/runtime/drivers/mysql/mysql.go index f1d6ac43cc7..e4290b357ee 100644 --- a/runtime/drivers/mysql/mysql.go +++ b/runtime/drivers/mysql/mysql.go @@ -38,6 +38,7 @@ var spec = drivers.Spec{ Placeholder: "mysql://user:password@host:3306/my-db", Hint: "Can be configured here or by setting the 'connector.mysql.dsn' environment variable (using '.env' or '--env')", Secret: true, + EnvVarName: "MYSQL_DSN", }, { Key: "user", @@ -54,6 +55,7 @@ var spec = drivers.Spec{ Placeholder: "your_password", Hint: "MySQL password for authentication", Secret: true, + EnvVarName: "MYSQL_PASSWORD", }, { Key: "host", diff --git a/runtime/drivers/pinot/pinot.go b/runtime/drivers/pinot/pinot.go index 5e45ed723c3..91c5fe7743c 100644 --- a/runtime/drivers/pinot/pinot.go +++ b/runtime/drivers/pinot/pinot.go @@ -36,6 +36,7 @@ var spec = drivers.Spec{ DisplayName: "Connection string", Placeholder: "http(s)://username:password@localhost:8000?controller=localhost:9000", Secret: true, + EnvVarName: "PINOT_DSN", NoPrompt: true, }, { @@ -86,6 +87,7 @@ var spec = drivers.Spec{ Description: "Password to connect to the Pinot server", Placeholder: "password", Secret: true, + EnvVarName: "PINOT_PASSWORD", }, { Key: "ssl", diff --git a/runtime/drivers/postgres/postgres.go b/runtime/drivers/postgres/postgres.go index 806c9ed66a6..a6df86ea9a7 100644 --- a/runtime/drivers/postgres/postgres.go +++ b/runtime/drivers/postgres/postgres.go @@ -37,6 +37,7 @@ var spec = drivers.Spec{ Placeholder: "postgresql://postgres:postgres@localhost:5432/postgres", Hint: "Can be configured here or by setting the 'connector.postgres.dsn' environment variable (using '.env' or '--env').", Secret: true, + EnvVarName: "POSTGRES_DSN", }, { Key: "host", @@ -69,6 +70,7 @@ var spec = drivers.Spec{ Placeholder: "your_password", Hint: "Postgres password for authentication", Secret: true, + EnvVarName: "POSTGRES_PASSWORD", }, { Key: "dbname", diff --git a/runtime/drivers/redshift/redshift.go b/runtime/drivers/redshift/redshift.go index cb04f1acc80..dbd16eca914 100644 --- a/runtime/drivers/redshift/redshift.go +++ b/runtime/drivers/redshift/redshift.go @@ -39,6 +39,7 @@ var spec = drivers.Spec{ Placeholder: "your_access_key_id", Required: true, Secret: true, + EnvVarName: "AWS_ACCESS_KEY_ID", }, { Key: "aws_secret_access_key", @@ -48,6 +49,7 @@ var spec = drivers.Spec{ Placeholder: "your_secret_access_key", Required: true, Secret: true, + EnvVarName: "AWS_SECRET_ACCESS_KEY", }, { Key: "workgroup", diff --git a/runtime/drivers/s3/s3.go b/runtime/drivers/s3/s3.go index a7e6427129f..e9f2d750325 100644 --- a/runtime/drivers/s3/s3.go +++ b/runtime/drivers/s3/s3.go @@ -32,6 +32,7 @@ var spec = drivers.Spec{ Description: "AWS access key ID for explicit credentials", Placeholder: "Enter your AWS access key ID", Secret: true, + EnvVarName: "AWS_ACCESS_KEY_ID", Required: true, }, { @@ -41,6 +42,7 @@ var spec = drivers.Spec{ Description: "AWS secret access key for explicit credentials", Placeholder: "Enter your AWS secret access key", Secret: true, + EnvVarName: "AWS_SECRET_ACCESS_KEY", Required: true, }, { @@ -65,6 +67,7 @@ var spec = drivers.Spec{ Key: "aws_role_arn", Type: drivers.StringPropertyType, Secret: true, + EnvVarName: "AWS_ROLE_ARN", Description: "AWS Role ARN to assume", }, { diff --git a/runtime/drivers/salesforce/salesforce.go b/runtime/drivers/salesforce/salesforce.go index f99a704dd39..90bd4897cb6 100644 --- a/runtime/drivers/salesforce/salesforce.go +++ b/runtime/drivers/salesforce/salesforce.go @@ -35,14 +35,16 @@ var spec = drivers.Spec{ Secret: false, }, { - Key: "password", - Type: drivers.StringPropertyType, - Secret: true, + Key: "password", + Type: drivers.StringPropertyType, + Secret: true, + EnvVarName: "SALESFORCE_PASSWORD", }, { - Key: "key", - Type: drivers.StringPropertyType, - Secret: true, + Key: "key", + Type: drivers.StringPropertyType, + Secret: true, + EnvVarName: "SALESFORCE_KEY", }, { Key: "endpoint", @@ -99,6 +101,7 @@ var spec = drivers.Spec{ Hint: "Your Salesforce password, optionally followed by a security token if required.", Placeholder: "your_password", Secret: true, + EnvVarName: "SALESFORCE_PASSWORD", }, { Key: "key", @@ -108,6 +111,7 @@ var spec = drivers.Spec{ Hint: "Paste your JWT private key for token-based authentication. Used with Connected App and Client ID.", Placeholder: "your_jwt_key", Secret: true, + EnvVarName: "SALESFORCE_KEY", }, { Key: "endpoint", diff --git a/runtime/drivers/snowflake/snowflake.go b/runtime/drivers/snowflake/snowflake.go index a185e44c12f..1ad8a581906 100644 --- a/runtime/drivers/snowflake/snowflake.go +++ b/runtime/drivers/snowflake/snowflake.go @@ -44,6 +44,7 @@ var spec = drivers.Spec{ Placeholder: "@//?warehouse=&role=&authenticator=SNOWFLAKE_JWT&privateKey=", Hint: "Can be configured here or by setting the 'connector.snowflake.dsn' environment variable (using '.env' or '--env').", Secret: true, + EnvVarName: "SNOWFLAKE_DSN", }, { Key: "account", @@ -69,6 +70,7 @@ var spec = drivers.Spec{ Placeholder: "your_password", Hint: "Your Snowflake database password. This will be stored securely and used to authenticate your connection.", Secret: true, + EnvVarName: "SNOWFLAKE_PASSWORD", }, { Key: "database", diff --git a/runtime/server/generate_template.go b/runtime/server/generate_template.go new file mode 100644 index 00000000000..db3d61099a8 --- /dev/null +++ b/runtime/server/generate_template.go @@ -0,0 +1,445 @@ +package server + +import ( + "bufio" + "bytes" + "context" + "fmt" + "path/filepath" + "strings" + + runtimev1 "github.com/rilldata/rill/proto/gen/rill/runtime/v1" + "github.com/rilldata/rill/runtime" + "github.com/rilldata/rill/runtime/drivers" + "github.com/rilldata/rill/runtime/pkg/observability" + "github.com/rilldata/rill/runtime/server/auth" + "go.opentelemetry.io/otel/attribute" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "gopkg.in/yaml.v3" +) + +// GenerateTemplate generates a connector or model YAML file from structured form data. +func (s *Server) GenerateTemplate(ctx context.Context, req *runtimev1.GenerateTemplateRequest) (*runtimev1.GenerateTemplateResponse, error) { + observability.AddRequestAttributes(ctx, + attribute.String("args.instance_id", req.InstanceId), + attribute.String("args.resource_type", req.ResourceType), + attribute.String("args.driver", req.Driver), + attribute.String("args.connector_name", req.ConnectorName), + ) + s.addInstanceRequestAttributes(ctx, req.InstanceId) + + if !auth.GetClaims(ctx, req.InstanceId).Can(runtime.EditRepo) { + return nil, ErrForbidden + } + + // Validate resource type + if req.ResourceType != "connector" && req.ResourceType != "model" { + return nil, status.Errorf(codes.InvalidArgument, "resource_type must be \"connector\" or \"model\"") + } + + // Validate driver exists + drv, ok := drivers.Connectors[req.Driver] + if !ok { + return nil, status.Errorf(codes.InvalidArgument, "unknown driver %q", req.Driver) + } + spec := drv.Spec() + + // Convert properties + var props map[string]any + if req.Properties != nil { + props = req.Properties.AsMap() + } else { + props = make(map[string]any) + } + + // Validate properties against the original driver spec (before any rewrite) + if err := validateProperties(spec, req.ResourceType, props); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "%s", err) + } + + // DuckDB rewrite for object store, file store, and sqlite drivers + actualDriver := req.Driver + actualResourceType := req.ResourceType + if req.ResourceType == "model" { + actualDriver, props = maybeRewriteToDuckDB(spec, req.Driver, props, req.ConnectorName) + } + + // Read existing .env for env var conflict resolution + existingEnv := make(map[string]bool) + repo, release, err := s.runtime.Repo(ctx, req.InstanceId) + if err == nil { + existingEnv = readEnvKeys(ctx, repo) + release() + } + + // Render YAML + extract secrets + var blob string + envVars := make(map[string]string) + switch actualResourceType { + case "connector": + blob = renderConnectorYAML(spec, actualDriver, props, existingEnv, envVars) + case "model": + if actualDriver == req.Driver { + // Non-rewritten model (warehouse driver) + blob = renderModelYAML(spec, actualDriver, props, req.ConnectorName, existingEnv, envVars) + } else { + // Rewritten to DuckDB + blob = renderDuckDBModelYAML(props, req.ConnectorName) + } + } + + return &runtimev1.GenerateTemplateResponse{ + Blob: blob, + EnvVars: envVars, + ResourceType: actualResourceType, + Driver: actualDriver, + }, nil +} + +// validateProperties rejects unknown property keys. +func validateProperties(spec drivers.Spec, resourceType string, properties map[string]any) error { + allowed := make(map[string]bool) + var props []*drivers.PropertySpec + if resourceType == "connector" { + props = spec.ConfigProperties + } else { + props = spec.SourceProperties + // Universal model properties: sql and name are always allowed for models, + // even if the driver's SourceProperties doesn't list them explicitly. + allowed["sql"] = true + allowed["name"] = true + } + for _, p := range props { + allowed[p.Key] = true + } + for key := range properties { + if !allowed[key] { + return fmt.Errorf("unknown property %q for driver", key) + } + } + return nil +} + +// maybeRewriteToDuckDB transforms object store, file store, and sqlite drivers into DuckDB models. +func maybeRewriteToDuckDB(spec drivers.Spec, driverName string, props map[string]any, connectorName string) (string, map[string]any) { + if !spec.ImplementsObjectStore && !spec.ImplementsFileStore && driverName != "sqlite" { + return driverName, props + } + + rewritten := make(map[string]any, len(props)) + for k, v := range props { + rewritten[k] = v + } + + switch { + case spec.ImplementsObjectStore: // s3, gcs, azure + if connectorName != "" { + rewritten["create_secrets_from_connectors"] = connectorName + } + rewritten["sql"] = buildDuckDBQuery(strVal(props["path"]), false) + delete(rewritten, "path") + delete(rewritten, "name") + + case driverName == "https": + if connectorName != "" { + rewritten["create_secrets_from_connectors"] = connectorName + } + rewritten["sql"] = buildDuckDBQuery(strVal(props["path"]), true) + delete(rewritten, "path") + delete(rewritten, "name") + + case spec.ImplementsFileStore: // local_file + rewritten["sql"] = buildDuckDBQuery(strVal(props["path"]), false) + delete(rewritten, "path") + delete(rewritten, "name") + delete(rewritten, "format") + + case driverName == "sqlite": + rewritten["sql"] = fmt.Sprintf("SELECT * FROM sqlite_scan('%s', '%s');", strVal(props["db"]), strVal(props["table"])) + delete(rewritten, "db") + delete(rewritten, "table") + delete(rewritten, "name") + } + + return "duckdb", rewritten +} + +// buildDuckDBQuery maps a file path + extension to a DuckDB read function. +func buildDuckDBQuery(path string, defaultToJSON bool) string { + ext := strings.ToLower(filepath.Ext(path)) + // Handle compound extensions like .v1.parquet.gz by checking if ext is contained + fullLower := strings.ToLower(path) + switch { + case containsExt(fullLower, ext, ".csv", ".tsv", ".txt"): + return fmt.Sprintf("select * from read_csv('%s', auto_detect=true, ignore_errors=1, header=true)", path) + case containsExt(fullLower, ext, ".parquet"): + return fmt.Sprintf("select * from read_parquet('%s')", path) + case containsExt(fullLower, ext, ".json", ".ndjson"): + return fmt.Sprintf("select * from read_json('%s', auto_detect=true, format='auto')", path) + default: + if defaultToJSON { + return fmt.Sprintf("select * from read_json('%s', auto_detect=true, format='auto')", path) + } + return fmt.Sprintf("select * from '%s'", path) + } +} + +// containsExt checks if the file extension or full path contains any of the target extensions. +// This handles compound extensions like .v1.parquet.gz. +func containsExt(fullLower, ext string, targets ...string) bool { + for _, t := range targets { + if ext == t { + return true + } + // Check for compound extensions + if strings.Contains(fullLower, t) { + return true + } + } + return false +} + +// renderConnectorYAML builds a connector YAML file using yaml.Node for precise formatting. +func renderConnectorYAML(spec drivers.Spec, driverName string, props map[string]any, existingEnv map[string]bool, envVars map[string]string) string { + doc := &yaml.Node{Kind: yaml.DocumentNode} + mapping := &yaml.Node{Kind: yaml.MappingNode} + mapping.HeadComment = fmt.Sprintf("Connector YAML\nReference documentation: %s", spec.DocsURL) + + addScalarPair(mapping, "type", "connector") + addScalarPair(mapping, "driver", driverName) + + for _, propSpec := range spec.ConfigProperties { + val, ok := props[propSpec.Key] + if !ok || isEmpty(val) { + continue + } + // Skip managed: false for ClickHouse (it's the default) + if propSpec.Key == "managed" && !toBool(val) { + continue + } + if propSpec.Secret { + envName := resolveEnvVarName(driverName, propSpec, existingEnv) + existingEnv[envName] = true + envVars[envName] = fmt.Sprintf("%v", val) + addQuotedPair(mapping, propSpec.Key, fmt.Sprintf("{{ .env.%s }}", envName)) + } else { + addTypedPair(mapping, propSpec, val) + } + } + + doc.Content = append(doc.Content, mapping) + return encodeYAML(doc) +} + +// renderModelYAML builds a model YAML file for warehouse drivers (non-rewritten). +func renderModelYAML(spec drivers.Spec, driverName string, props map[string]any, connectorName string, existingEnv map[string]bool, envVars map[string]string) string { + doc := &yaml.Node{Kind: yaml.DocumentNode} + mapping := &yaml.Node{Kind: yaml.MappingNode} + mapping.HeadComment = fmt.Sprintf("Model YAML\nReference documentation: %s", spec.DocsURL) + + addScalarPair(mapping, "type", "model") + if connectorName != "" { + addQuotedPair(mapping, "connector", connectorName) + } + + // Non-DuckDB warehouse models need materialize: true + if driverName != "duckdb" && driverName != "motherduck" { + addScalarPair(mapping, "materialize", "true") + } + + // Add source properties from the driver spec + sqlHandled := false + for _, propSpec := range spec.SourceProperties { + val, ok := props[propSpec.Key] + if !ok || isEmpty(val) { + continue + } + if propSpec.Key == "name" { + continue // name is used for the file path, not in YAML + } + if propSpec.Key == "sql" { + addSQLBlock(mapping, fmt.Sprintf("%v", val)) + sqlHandled = true + continue + } + if propSpec.Secret { + envName := resolveEnvVarName(driverName, propSpec, existingEnv) + existingEnv[envName] = true + envVars[envName] = fmt.Sprintf("%v", val) + addQuotedPair(mapping, propSpec.Key, fmt.Sprintf("{{ .env.%s }}", envName)) + } else { + addTypedPair(mapping, propSpec, val) + } + } + + // Handle sql as a universal model property (warehouse drivers don't list it in SourceProperties) + if !sqlHandled { + if sql, ok := props["sql"]; ok && !isEmpty(sql) { + addSQLBlock(mapping, fmt.Sprintf("%v", sql)) + } + } + + // Dev section with limit (except Redshift) + if driverName != "redshift" { + addDevSection(mapping) + } + + doc.Content = append(doc.Content, mapping) + return encodeYAML(doc) +} + +// renderDuckDBModelYAML builds a DuckDB model YAML file for rewritten object/file store drivers. +func renderDuckDBModelYAML(props map[string]any, connectorName string) string { + doc := &yaml.Node{Kind: yaml.DocumentNode} + mapping := &yaml.Node{Kind: yaml.MappingNode} + mapping.HeadComment = "Model YAML\nReference documentation: https://docs.rilldata.com/developers/build/connectors/olap/duckdb" + + addScalarPair(mapping, "type", "model") + addQuotedPair(mapping, "connector", "duckdb") + + // Add create_secrets_from_connectors if present + if secretsConn, ok := props["create_secrets_from_connectors"]; ok && !isEmpty(secretsConn) { + addQuotedPair(mapping, "create_secrets_from_connectors", fmt.Sprintf("%v", secretsConn)) + } + + // Add SQL block + if sql, ok := props["sql"]; ok && !isEmpty(sql) { + addSQLBlock(mapping, fmt.Sprintf("%v", sql)) + } + + doc.Content = append(doc.Content, mapping) + return encodeYAML(doc) +} + +// resolveEnvVarName determines the env var name for a secret property, resolving conflicts. +func resolveEnvVarName(driverName string, propSpec *drivers.PropertySpec, existingEnv map[string]bool) string { + var base string + if propSpec.EnvVarName != "" { + base = propSpec.EnvVarName + } else { + // Fallback: DRIVER_KEY format (SCREAMING_SNAKE_CASE) + base = strings.ToUpper(driverName) + "_" + strings.ToUpper(propSpec.Key) + } + + // Check for conflicts + candidate := base + for i := 1; existingEnv[candidate]; i++ { + candidate = fmt.Sprintf("%s_%d", base, i) + } + return candidate +} + +// readEnvKeys parses an .env file into a set of key names. +func readEnvKeys(ctx context.Context, repo drivers.RepoStore) map[string]bool { + keys := make(map[string]bool) + content, err := repo.Get(ctx, ".env") + if err != nil { + return keys + } + scanner := bufio.NewScanner(strings.NewReader(content)) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if line == "" || strings.HasPrefix(line, "#") { + continue + } + if idx := strings.IndexByte(line, '='); idx > 0 { + keys[line[:idx]] = true + } + } + return keys +} + +// addScalarPair adds a key-value pair with plain scalar style. +func addScalarPair(m *yaml.Node, key, value string) { + m.Content = append(m.Content, + &yaml.Node{Kind: yaml.ScalarNode, Value: key}, + &yaml.Node{Kind: yaml.ScalarNode, Value: value}, + ) +} + +// addQuotedPair adds a key-value pair with double-quoted value style. +func addQuotedPair(m *yaml.Node, key, value string) { + m.Content = append(m.Content, + &yaml.Node{Kind: yaml.ScalarNode, Value: key}, + &yaml.Node{Kind: yaml.ScalarNode, Value: value, Style: yaml.DoubleQuotedStyle}, + ) +} + +// addTypedPair adds a key-value pair with appropriate formatting based on property type. +func addTypedPair(m *yaml.Node, propSpec *drivers.PropertySpec, val any) { + strVal := fmt.Sprintf("%v", val) + switch propSpec.Type { + case drivers.NumberPropertyType, drivers.BooleanPropertyType: + addScalarPair(m, propSpec.Key, strVal) + default: + addQuotedPair(m, propSpec.Key, strVal) + } +} + +// addSQLBlock adds a SQL key with literal block style (|). +func addSQLBlock(m *yaml.Node, sql string) { + m.Content = append(m.Content, + &yaml.Node{Kind: yaml.ScalarNode, Value: "sql"}, + &yaml.Node{Kind: yaml.ScalarNode, Value: sql, Style: yaml.LiteralStyle}, + ) +} + +// addDevSection adds a dev section with a SQL limit clause. +func addDevSection(m *yaml.Node) { + devMapping := &yaml.Node{Kind: yaml.MappingNode} + addSQLBlock(devMapping, "select * from {{ ref \"self\" }} limit 10000") + m.Content = append(m.Content, + &yaml.Node{Kind: yaml.ScalarNode, Value: "dev"}, + devMapping, + ) +} + +// encodeYAML renders a yaml.Node tree to a string. +func encodeYAML(doc *yaml.Node) string { + buf := new(bytes.Buffer) + enc := yaml.NewEncoder(buf) + enc.SetIndent(2) + if err := enc.Encode(doc); err != nil { + return "" + } + if err := enc.Close(); err != nil { + return "" + } + return buf.String() +} + +// isEmpty checks if a value is empty (nil, empty string, or false for booleans). +func isEmpty(v any) bool { + if v == nil { + return true + } + switch val := v.(type) { + case string: + return val == "" + case bool: + return false // bools are never "empty"; handled explicitly where needed + default: + return fmt.Sprintf("%v", v) == "" + } +} + +// toBool converts a value to bool. +func toBool(v any) bool { + switch val := v.(type) { + case bool: + return val + case string: + return val == "true" + default: + return false + } +} + +// strVal extracts a string value from an interface. +func strVal(v any) string { + if v == nil { + return "" + } + return fmt.Sprintf("%v", v) +} diff --git a/runtime/server/generate_template_test.go b/runtime/server/generate_template_test.go new file mode 100644 index 00000000000..0e1067bbb99 --- /dev/null +++ b/runtime/server/generate_template_test.go @@ -0,0 +1,884 @@ +package server_test + +import ( + "fmt" + "sort" + "testing" + + runtimev1 "github.com/rilldata/rill/proto/gen/rill/runtime/v1" + "github.com/rilldata/rill/runtime/drivers" + "github.com/rilldata/rill/runtime/pkg/activity" + "github.com/rilldata/rill/runtime/pkg/ratelimit" + "github.com/rilldata/rill/runtime/server" + "github.com/rilldata/rill/runtime/testruntime" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/types/known/structpb" + + // Register all connector drivers + _ "github.com/rilldata/rill/runtime/drivers/athena" + _ "github.com/rilldata/rill/runtime/drivers/azure" + _ "github.com/rilldata/rill/runtime/drivers/bigquery" + _ "github.com/rilldata/rill/runtime/drivers/clickhouse" + _ "github.com/rilldata/rill/runtime/drivers/druid" + _ "github.com/rilldata/rill/runtime/drivers/duckdb" + _ "github.com/rilldata/rill/runtime/drivers/file" + _ "github.com/rilldata/rill/runtime/drivers/gcs" + _ "github.com/rilldata/rill/runtime/drivers/https" + _ "github.com/rilldata/rill/runtime/drivers/mysql" + _ "github.com/rilldata/rill/runtime/drivers/pinot" + _ "github.com/rilldata/rill/runtime/drivers/postgres" + _ "github.com/rilldata/rill/runtime/drivers/redshift" + _ "github.com/rilldata/rill/runtime/drivers/s3" + _ "github.com/rilldata/rill/runtime/drivers/salesforce" + _ "github.com/rilldata/rill/runtime/drivers/snowflake" + _ "github.com/rilldata/rill/runtime/drivers/sqlite" + _ "github.com/rilldata/rill/runtime/drivers/starrocks" +) + +// TestPropertySpecSecretFlags asserts that PropertySpec.Secret flags match expected values. +func TestPropertySpecSecretFlags(t *testing.T) { + expected := map[string][]string{ + "s3": {"aws_access_key_id", "aws_secret_access_key", "aws_role_arn", "aws_role_session_name", "aws_external_id"}, + "gcs": {"google_application_credentials", "key_id", "secret"}, + "azure": {"azure_storage_account", "azure_storage_key", "azure_storage_sas_token", "azure_storage_connection_string"}, + "clickhouse": {"dsn", "password"}, + "postgres": {"dsn", "password"}, + "bigquery": {"google_application_credentials"}, + "snowflake": {"dsn", "password"}, + "redshift": {"aws_access_key_id", "aws_secret_access_key"}, + "motherduck": {"token"}, + "athena": {"aws_access_key_id", "aws_secret_access_key"}, + "mysql": {"dsn", "password"}, + "druid": {"dsn", "password"}, + "pinot": {"dsn", "password"}, + "starrocks": {"dsn", "password"}, + "salesforce": {"password", "key"}, + } + + for driverName, drv := range drivers.Connectors { + expectedKeys, ok := expected[driverName] + if !ok { + continue + } + spec := drv.Spec() + actualSecrets := secretKeys(spec.ConfigProperties) + sort.Strings(expectedKeys) + sort.Strings(actualSecrets) + require.Equal(t, expectedKeys, actualSecrets, "driver %s: secret keys mismatch", driverName) + } +} + +func secretKeys(props []*drivers.PropertySpec) []string { + var keys []string + for _, p := range props { + if p.Secret { + keys = append(keys, p.Key) + } + } + return keys +} + +// TestGenerateTemplate tests the GenerateTemplate RPC handler end-to-end. +func TestGenerateTemplate(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": ``, + }, + }) + + ctx := testCtx() + srv, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + tt := []struct { + name string + req *runtimev1.GenerateTemplateRequest + wantContains []string + wantExcludes []string + wantEnvKeys []string + wantDriver string + wantResType string + wantErr codes.Code + }{ + { + name: "clickhouse connector with parameters", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: mustStruct(map[string]any{"host": "ch.example.com", "port": float64(9000), "password": "secret123"}), + }, + wantContains: []string{ + "type: connector", + "driver: clickhouse", + `host: "ch.example.com"`, + "port: 9000", + `{{ .env.CLICKHOUSE_PASSWORD }}`, + "# Connector YAML", + }, + wantExcludes: []string{"secret123"}, + wantEnvKeys: []string{"CLICKHOUSE_PASSWORD"}, + wantDriver: "clickhouse", + wantResType: "connector", + }, + { + name: "clickhouse connector with dsn", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: mustStruct(map[string]any{"dsn": "clickhouse://user:pass@host:9000/db"}), + }, + wantContains: []string{`{{ .env.CLICKHOUSE_DSN }}`}, + wantExcludes: []string{"clickhouse://user:pass"}, + wantEnvKeys: []string{"CLICKHOUSE_DSN"}, + wantDriver: "clickhouse", + wantResType: "connector", + }, + { + name: "s3 connector", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "s3", + Properties: mustStruct(map[string]any{"aws_access_key_id": "AKIATEST", "aws_secret_access_key": "secretkey"}), + }, + wantContains: []string{ + "driver: s3", + `{{ .env.AWS_ACCESS_KEY_ID }}`, + `{{ .env.AWS_SECRET_ACCESS_KEY }}`, + }, + wantExcludes: []string{"AKIATEST", "secretkey"}, + wantEnvKeys: []string{"AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"}, + wantDriver: "s3", + wantResType: "connector", + }, + { + name: "bigquery connector", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "bigquery", + Properties: mustStruct(map[string]any{"project_id": "my-project", "google_application_credentials": `{"type":"service_account"}`}), + }, + wantContains: []string{ + "driver: bigquery", + `project_id: "my-project"`, + `{{ .env.GOOGLE_APPLICATION_CREDENTIALS }}`, + }, + wantExcludes: []string{"service_account"}, + wantEnvKeys: []string{"GOOGLE_APPLICATION_CREDENTIALS"}, + wantDriver: "bigquery", + wantResType: "connector", + }, + { + name: "postgres connector with params", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "postgres", + Properties: mustStruct(map[string]any{"host": "db.example.com", "port": "5432", "password": "my_pg_secret"}), + }, + wantContains: []string{ + "driver: postgres", + `host: "db.example.com"`, + `{{ .env.POSTGRES_PASSWORD }}`, + }, + wantExcludes: []string{"my_pg_secret"}, + wantDriver: "postgres", + wantResType: "connector", + }, + { + name: "empty values filtered", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: mustStruct(map[string]any{"host": "ch.example.com", "port": "", "database": ""}), + }, + wantContains: []string{"host:"}, + wantExcludes: []string{"port:", "database:"}, + wantDriver: "clickhouse", + wantResType: "connector", + }, + { + name: "clickhouse managed false excluded", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: mustStruct(map[string]any{"host": "ch.example.com", "managed": false}), + }, + wantContains: []string{"host:"}, + wantExcludes: []string{"managed"}, + wantDriver: "clickhouse", + wantResType: "connector", + }, + { + name: "s3 model rewritten to duckdb parquet", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "model", + Driver: "s3", + Properties: mustStruct(map[string]any{"path": "s3://bucket/data.parquet", "name": "my_source"}), + ConnectorName: "my_s3", + }, + wantContains: []string{ + "type: model", + `connector: "duckdb"`, + "read_parquet", + `create_secrets_from_connectors: "my_s3"`, + }, + wantDriver: "duckdb", + wantResType: "model", + }, + { + name: "s3 model rewritten to duckdb csv", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "model", + Driver: "s3", + Properties: mustStruct(map[string]any{"path": "s3://bucket/data.csv", "name": "test"}), + }, + wantContains: []string{ + "read_csv", + "auto_detect=true", + "ignore_errors=1", + "header=true", + }, + wantDriver: "duckdb", + wantResType: "model", + }, + { + name: "gcs model rewritten with json", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "model", + Driver: "gcs", + Properties: mustStruct(map[string]any{"path": "gs://bucket/data.json", "name": "test"}), + }, + wantContains: []string{ + "read_json", + "auto_detect=true", + "format='auto'", + }, + wantDriver: "duckdb", + wantResType: "model", + }, + { + name: "https model defaults to json", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "model", + Driver: "https", + Properties: mustStruct(map[string]any{"path": "https://api.example.com/data", "name": "test"}), + ConnectorName: "my_http", + }, + wantContains: []string{ + "read_json", + `create_secrets_from_connectors: "my_http"`, + }, + wantDriver: "duckdb", + wantResType: "model", + }, + { + name: "local_file csv model", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "model", + Driver: "local_file", + Properties: mustStruct(map[string]any{"path": "/data/file.csv", "name": "test"}), + }, + wantContains: []string{ + "read_csv", + }, + wantExcludes: []string{"create_secrets_from_connectors"}, + wantDriver: "duckdb", + wantResType: "model", + }, + { + name: "sqlite model rewritten", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "model", + Driver: "sqlite", + Properties: mustStruct(map[string]any{"db": "/data/app.db", "table": "users", "name": "test"}), + }, + wantContains: []string{ + "type: model", + "sqlite_scan('/data/app.db', 'users')", + }, + wantDriver: "duckdb", + wantResType: "model", + }, + { + name: "clickhouse not rewritten for model", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "model", + Driver: "clickhouse", + Properties: mustStruct(map[string]any{"sql": "SELECT * FROM events"}), + ConnectorName: "ch_prod", + }, + wantContains: []string{ + "type: model", + "materialize: true", + `connector: "ch_prod"`, + "SELECT * FROM events", + "dev:", + "limit 10000", + }, + wantDriver: "clickhouse", + wantResType: "model", + }, + { + name: "redshift model without dev section", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "model", + Driver: "redshift", + Properties: mustStruct(map[string]any{"sql": "SELECT * FROM events"}), + ConnectorName: "rs_prod", + }, + wantContains: []string{"type: model", `connector: "rs_prod"`, "materialize: true"}, + wantExcludes: []string{"dev:"}, + wantDriver: "redshift", + wantResType: "model", + }, + { + name: "unknown driver rejected", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "nonexistent", + Properties: mustStruct(map[string]any{}), + }, + wantErr: codes.InvalidArgument, + }, + { + name: "unknown property rejected", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: mustStruct(map[string]any{"bogus_key": "value"}), + }, + wantErr: codes.InvalidArgument, + }, + { + name: "invalid resource type rejected", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "dashboard", + Driver: "clickhouse", + Properties: mustStruct(map[string]any{}), + }, + wantErr: codes.InvalidArgument, + }, + { + name: "secret values never in error messages", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: mustStruct(map[string]any{"bogus_key": "super_secret_value"}), + }, + wantErr: codes.InvalidArgument, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + resp, err := srv.GenerateTemplate(ctx, tc.req) + if tc.wantErr != 0 { + require.Error(t, err) + s, ok := status.FromError(err) + require.True(t, ok) + require.Equal(t, tc.wantErr, s.Code()) + // Ensure secret values never appear in error messages + require.NotContains(t, err.Error(), "super_secret_value") + return + } + require.NoError(t, err) + + for _, c := range tc.wantContains { + require.Contains(t, resp.Blob, c, "blob should contain %q", c) + } + for _, e := range tc.wantExcludes { + require.NotContains(t, resp.Blob, e, "blob should not contain %q", e) + } + if tc.wantDriver != "" { + require.Equal(t, tc.wantDriver, resp.Driver) + } + if tc.wantResType != "" { + require.Equal(t, tc.wantResType, resp.ResourceType) + } + for _, envKey := range tc.wantEnvKeys { + require.Contains(t, resp.EnvVars, envKey, "env_vars should contain key %q", envKey) + } + }) + } +} + +// TestGenerateTemplateEnvConflict tests env var conflict resolution with existing .env files. +func TestGenerateTemplateEnvConflict(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": ``, + ".env": "CLICKHOUSE_PASSWORD=old_value\n", + }, + }) + + ctx := testCtx() + srv, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + resp, err := srv.GenerateTemplate(ctx, &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: mustStruct(map[string]any{"host": "ch.example.com", "password": "new_secret"}), + }) + require.NoError(t, err) + + // Should use CLICKHOUSE_PASSWORD_1 since CLICKHOUSE_PASSWORD already exists + require.Contains(t, resp.EnvVars, "CLICKHOUSE_PASSWORD_1") + require.Contains(t, resp.Blob, "{{ .env.CLICKHOUSE_PASSWORD_1 }}") + require.NotContains(t, resp.Blob, "new_secret") +} + +// TestGenerateTemplateEnvConflictDouble tests double-conflict resolution. +func TestGenerateTemplateEnvConflictDouble(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": ``, + ".env": "CLICKHOUSE_PASSWORD=old\nCLICKHOUSE_PASSWORD_1=also_old\n", + }, + }) + + ctx := testCtx() + srv, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + resp, err := srv.GenerateTemplate(ctx, &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: mustStruct(map[string]any{"host": "ch.example.com", "password": "new_secret"}), + }) + require.NoError(t, err) + + require.Contains(t, resp.EnvVars, "CLICKHOUSE_PASSWORD_2") + require.Contains(t, resp.Blob, "{{ .env.CLICKHOUSE_PASSWORD_2 }}") +} + +// TestGenerateTemplateMotherduckConnector tests MotherDuck connector generation. +func TestGenerateTemplateMotherduckConnector(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": ``, + }, + }) + + ctx := testCtx() + srv, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + resp, err := srv.GenerateTemplate(ctx, &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "motherduck", + Properties: mustStruct(map[string]any{"path": "md:my_db", "token": "my_token_123"}), + }) + require.NoError(t, err) + + require.Contains(t, resp.Blob, "driver: motherduck") + require.Contains(t, resp.Blob, `{{ .env.MOTHERDUCK_TOKEN }}`) + require.NotContains(t, resp.Blob, "my_token_123") + require.Contains(t, resp.EnvVars, "MOTHERDUCK_TOKEN") + require.Equal(t, "my_token_123", resp.EnvVars["MOTHERDUCK_TOKEN"]) +} + +// TestGenerateTemplateSnowflakeConnector tests Snowflake connector generation. +func TestGenerateTemplateSnowflakeConnector(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": ``, + }, + }) + + ctx := testCtx() + srv, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + resp, err := srv.GenerateTemplate(ctx, &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "snowflake", + Properties: mustStruct(map[string]any{"account": "my_account", "user": "admin", "password": "pw123", "database": "analytics"}), + }) + require.NoError(t, err) + + require.Contains(t, resp.Blob, "driver: snowflake") + require.Contains(t, resp.Blob, `account: "my_account"`) + require.Contains(t, resp.Blob, `{{ .env.SNOWFLAKE_PASSWORD }}`) + require.NotContains(t, resp.Blob, "pw123") +} + +// TestGenerateTemplateAllConnectorDrivers ensures every registered connector can generate a connector YAML. +func TestGenerateTemplateAllConnectorDrivers(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": ``, + }, + }) + + ctx := testCtx() + srv, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + // Drivers that have ConfigProperties (connector-type drivers) + driversWithConfig := []struct { + name string + props map[string]any + }{ + {"s3", map[string]any{"aws_access_key_id": "test", "aws_secret_access_key": "test"}}, + {"gcs", map[string]any{"google_application_credentials": "{}"}}, + {"azure", map[string]any{"azure_storage_connection_string": "test"}}, + {"clickhouse", map[string]any{"host": "localhost"}}, + {"postgres", map[string]any{"host": "localhost"}}, + {"bigquery", map[string]any{"google_application_credentials": "{}"}}, + {"snowflake", map[string]any{"account": "test", "user": "test", "password": "test"}}, + {"redshift", map[string]any{"aws_access_key_id": "test", "aws_secret_access_key": "test"}}, + {"motherduck", map[string]any{"path": "md:test", "token": "test"}}, + {"athena", map[string]any{"aws_access_key_id": "test", "aws_secret_access_key": "test"}}, + {"mysql", map[string]any{"host": "localhost"}}, + {"druid", map[string]any{"host": "localhost"}}, + {"pinot", map[string]any{"broker_host": "localhost"}}, + {"starrocks", map[string]any{"host": "localhost"}}, + {"salesforce", map[string]any{"username": "test"}}, + } + + for _, d := range driversWithConfig { + t.Run(d.name, func(t *testing.T) { + resp, err := srv.GenerateTemplate(ctx, &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: d.name, + Properties: mustStruct(d.props), + }) + require.NoError(t, err) + require.Contains(t, resp.Blob, "type: connector") + require.Contains(t, resp.Blob, "driver: "+d.name) + }) + } +} + +// TestGenerateTemplateDuckDBRewrite tests all DuckDB rewrite cases. +func TestGenerateTemplateDuckDBRewrite(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": ``, + }, + }) + + ctx := testCtx() + srv, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + tt := []struct { + name string + driver string + props map[string]any + connName string + wantDriver string + wantContains []string + wantExcludes []string + }{ + { + name: "s3 parquet", + driver: "s3", + props: map[string]any{"path": "s3://bucket/data.parquet", "name": "test"}, + wantDriver: "duckdb", + wantContains: []string{ + "read_parquet('s3://bucket/data.parquet')", + }, + }, + { + name: "s3 csv", + driver: "s3", + props: map[string]any{"path": "s3://bucket/data.csv", "name": "test"}, + wantDriver: "duckdb", + wantContains: []string{ + "read_csv('s3://bucket/data.csv', auto_detect=true, ignore_errors=1, header=true)", + }, + }, + { + name: "s3 compressed parquet", + driver: "s3", + props: map[string]any{"path": "s3://bucket/data.v1.parquet.gz", "name": "test"}, + wantDriver: "duckdb", + wantContains: []string{ + "read_parquet('s3://bucket/data.v1.parquet.gz')", + }, + }, + { + name: "gcs ndjson", + driver: "gcs", + props: map[string]any{"path": "gs://bucket/data.ndjson", "name": "test"}, + wantDriver: "duckdb", + wantContains: []string{ + "read_json('gs://bucket/data.ndjson', auto_detect=true, format='auto')", + }, + }, + { + name: "azure tsv", + driver: "azure", + props: map[string]any{"path": "azure://container/data.tsv", "name": "test"}, + wantDriver: "duckdb", + wantContains: []string{ + "read_csv('azure://container/data.tsv', auto_detect=true, ignore_errors=1, header=true)", + }, + }, + { + name: "s3 unknown extension", + driver: "s3", + props: map[string]any{"path": "s3://bucket/data.avro", "name": "test"}, + wantDriver: "duckdb", + wantContains: []string{ + "select * from 's3://bucket/data.avro'", + }, + }, + { + name: "s3 with connector name sets secrets", + driver: "s3", + props: map[string]any{"path": "s3://bucket/data.parquet", "name": "test"}, + connName: "my_s3", + wantDriver: "duckdb", + wantContains: []string{`create_secrets_from_connectors: "my_s3"`}, + }, + { + name: "https defaults to json", + driver: "https", + props: map[string]any{"path": "https://api.example.com/data", "name": "test"}, + wantDriver: "duckdb", + wantContains: []string{ + "read_json('https://api.example.com/data', auto_detect=true, format='auto')", + }, + }, + { + name: "https with csv extension", + driver: "https", + props: map[string]any{"path": "https://example.com/data.csv", "name": "test"}, + wantDriver: "duckdb", + wantContains: []string{ + "read_csv('https://example.com/data.csv', auto_detect=true, ignore_errors=1, header=true)", + }, + }, + { + name: "https with connector name", + driver: "https", + props: map[string]any{"path": "https://api.example.com/data", "name": "test"}, + connName: "my_http", + wantDriver: "duckdb", + wantContains: []string{`create_secrets_from_connectors: "my_http"`}, + }, + { + name: "local_file csv", + driver: "local_file", + props: map[string]any{"path": "/data/file.csv", "name": "test"}, + wantDriver: "duckdb", + wantContains: []string{"read_csv('/data/file.csv'"}, + wantExcludes: []string{"create_secrets_from_connectors"}, + }, + { + name: "sqlite", + driver: "sqlite", + props: map[string]any{"db": "/data/app.db", "table": "users", "name": "test"}, + wantDriver: "duckdb", + wantContains: []string{ + "sqlite_scan('/data/app.db', 'users')", + }, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + resp, err := srv.GenerateTemplate(ctx, &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "model", + Driver: tc.driver, + Properties: mustStruct(tc.props), + ConnectorName: tc.connName, + }) + require.NoError(t, err) + require.Equal(t, tc.wantDriver, resp.Driver) + require.Equal(t, "model", resp.ResourceType) + for _, c := range tc.wantContains { + require.Contains(t, resp.Blob, c, "blob should contain %q", c) + } + for _, e := range tc.wantExcludes { + require.NotContains(t, resp.Blob, e, "blob should not contain %q", e) + } + }) + } +} + +// TestGenerateTemplateEnvVarNaming tests env var name resolution. +func TestGenerateTemplateEnvVarNaming(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": ``, + }, + }) + + ctx := testCtx() + srv, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + tt := []struct { + name string + driver string + props map[string]any + wantEnvKey string + }{ + { + name: "s3 access key uses EnvVarName", + driver: "s3", + props: map[string]any{"aws_access_key_id": "test"}, + wantEnvKey: "AWS_ACCESS_KEY_ID", + }, + { + name: "bigquery creds uses EnvVarName", + driver: "bigquery", + props: map[string]any{"google_application_credentials": "{}"}, + wantEnvKey: "GOOGLE_APPLICATION_CREDENTIALS", + }, + { + name: "motherduck token uses EnvVarName", + driver: "motherduck", + props: map[string]any{"token": "test", "path": "md:test"}, + wantEnvKey: "MOTHERDUCK_TOKEN", + }, + { + name: "clickhouse password uses EnvVarName", + driver: "clickhouse", + props: map[string]any{"password": "test"}, + wantEnvKey: "CLICKHOUSE_PASSWORD", + }, + { + name: "starrocks dsn uses fallback format", + driver: "starrocks", + props: map[string]any{"dsn": "test"}, + wantEnvKey: "STARROCKS_DSN", + }, + { + name: "starrocks password uses fallback format", + driver: "starrocks", + props: map[string]any{"password": "test"}, + wantEnvKey: "STARROCKS_PASSWORD", + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + resp, err := srv.GenerateTemplate(ctx, &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: tc.driver, + Properties: mustStruct(tc.props), + }) + require.NoError(t, err) + require.Contains(t, resp.EnvVars, tc.wantEnvKey, "env_vars should contain %q", tc.wantEnvKey) + require.Contains(t, resp.Blob, fmt.Sprintf("{{ .env.%s }}", tc.wantEnvKey)) + }) + } +} + +// TestGenerateTemplateValidateProperties tests property validation. +func TestGenerateTemplateValidateProperties(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": ``, + }, + }) + + ctx := testCtx() + srv, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + tt := []struct { + name string + driver string + resourceType string + props map[string]any + wantErr bool + }{ + { + name: "valid connector props", + driver: "clickhouse", + resourceType: "connector", + props: map[string]any{"host": "localhost"}, + wantErr: false, + }, + { + name: "unknown prop rejected", + driver: "clickhouse", + resourceType: "connector", + props: map[string]any{"bogus": "value"}, + wantErr: true, + }, + { + name: "source prop on connector rejected", + driver: "duckdb", + resourceType: "connector", + props: map[string]any{"sql": "SELECT 1"}, + wantErr: true, + }, + { + name: "source prop on model accepted", + driver: "duckdb", + resourceType: "model", + props: map[string]any{"sql": "SELECT 1"}, + wantErr: false, + }, + { + name: "empty properties valid", + driver: "clickhouse", + resourceType: "connector", + props: map[string]any{}, + wantErr: false, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + _, err := srv.GenerateTemplate(ctx, &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: tc.resourceType, + Driver: tc.driver, + Properties: mustStruct(tc.props), + }) + if tc.wantErr { + require.Error(t, err) + s, ok := status.FromError(err) + require.True(t, ok) + require.Equal(t, codes.InvalidArgument, s.Code()) + } else { + require.NoError(t, err) + } + }) + } +} + +func mustStruct(m map[string]any) *structpb.Struct { + s, err := structpb.NewStruct(m) + if err != nil { + panic(err) + } + return s +} + diff --git a/web-common/src/proto/gen/rill/runtime/v1/api_pb.ts b/web-common/src/proto/gen/rill/runtime/v1/api_pb.ts index 1dd34f5642d..35713621255 100644 --- a/web-common/src/proto/gen/rill/runtime/v1/api_pb.ts +++ b/web-common/src/proto/gen/rill/runtime/v1/api_pb.ts @@ -2638,6 +2638,126 @@ export class GenerateRendererResponse extends Message$1 { + /** + * @generated from field: string instance_id = 1; + */ + instanceId = ""; + + /** + * @generated from field: string resource_type = 2; + */ + resourceType = ""; + + /** + * @generated from field: string driver = 3; + */ + driver = ""; + + /** + * @generated from field: google.protobuf.Struct properties = 4; + */ + properties?: Struct; + + /** + * @generated from field: string connector_name = 5; + */ + connectorName = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "rill.runtime.v1.GenerateTemplateRequest"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "instance_id", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "resource_type", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 3, name: "driver", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 4, name: "properties", kind: "message", T: Struct }, + { no: 5, name: "connector_name", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GenerateTemplateRequest { + return new GenerateTemplateRequest().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GenerateTemplateRequest { + return new GenerateTemplateRequest().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GenerateTemplateRequest { + return new GenerateTemplateRequest().fromJsonString(jsonString, options); + } + + static equals(a: GenerateTemplateRequest | PlainMessage | undefined, b: GenerateTemplateRequest | PlainMessage | undefined): boolean { + return proto3.util.equals(GenerateTemplateRequest, a, b); + } +} + +/** + * @generated from message rill.runtime.v1.GenerateTemplateResponse + */ +export class GenerateTemplateResponse extends Message$1 { + /** + * @generated from field: string blob = 1; + */ + blob = ""; + + /** + * @generated from field: map env_vars = 2; + */ + envVars: { [key: string]: string } = {}; + + /** + * Actual resource type used; may differ from request when driver is rewritten + * + * @generated from field: string resource_type = 3; + */ + resourceType = ""; + + /** + * Actual driver used; may differ from request when rewritten to duckdb + * + * @generated from field: string driver = 4; + */ + driver = ""; + + constructor(data?: PartialMessage) { + super(); + proto3.util.initPartial(data, this); + } + + static readonly runtime: typeof proto3 = proto3; + static readonly typeName = "rill.runtime.v1.GenerateTemplateResponse"; + static readonly fields: FieldList = proto3.util.newFieldList(() => [ + { no: 1, name: "blob", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 2, name: "env_vars", kind: "map", K: 9 /* ScalarType.STRING */, V: {kind: "scalar", T: 9 /* ScalarType.STRING */} }, + { no: 3, name: "resource_type", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + { no: 4, name: "driver", kind: "scalar", T: 9 /* ScalarType.STRING */ }, + ]); + + static fromBinary(bytes: Uint8Array, options?: Partial): GenerateTemplateResponse { + return new GenerateTemplateResponse().fromBinary(bytes, options); + } + + static fromJson(jsonValue: JsonValue, options?: Partial): GenerateTemplateResponse { + return new GenerateTemplateResponse().fromJson(jsonValue, options); + } + + static fromJsonString(jsonString: string, options?: Partial): GenerateTemplateResponse { + return new GenerateTemplateResponse().fromJsonString(jsonString, options); + } + + static equals(a: GenerateTemplateResponse | PlainMessage | undefined, b: GenerateTemplateResponse | PlainMessage | undefined): boolean { + return proto3.util.equals(GenerateTemplateResponse, a, b); + } +} + /** * @generated from message rill.runtime.v1.QueryResolverRequest */ diff --git a/web-common/src/runtime-client/gen/index.schemas.ts b/web-common/src/runtime-client/gen/index.schemas.ts index e1e874d68de..f557f1ff1c9 100644 --- a/web-common/src/runtime-client/gen/index.schemas.ts +++ b/web-common/src/runtime-client/gen/index.schemas.ts @@ -1088,6 +1088,15 @@ export interface V1GenerateResolverResponse { resolverProperties?: V1GenerateResolverResponseResolverProperties; } +export type V1GenerateTemplateResponseEnvVars = { [key: string]: string }; + +export interface V1GenerateTemplateResponse { + blob?: string; + envVars?: V1GenerateTemplateResponseEnvVars; + resourceType?: string; + driver?: string; +} + export interface V1GetConversationResponse { conversation?: V1Conversation; messages?: V1Message[]; @@ -2838,6 +2847,17 @@ export type RuntimeServiceGenerateResolverBody = { metricsView?: string; }; +export type RuntimeServiceGenerateTemplateBodyProperties = { + [key: string]: unknown; +}; + +export type RuntimeServiceGenerateTemplateBody = { + resourceType?: string; + driver?: string; + properties?: RuntimeServiceGenerateTemplateBodyProperties; + connectorName?: string; +}; + export type RuntimeServiceGitSwitchBranchBody = { branch?: string; create?: boolean; diff --git a/web-common/src/runtime-client/gen/runtime-service/runtime-service.ts b/web-common/src/runtime-client/gen/runtime-service/runtime-service.ts index 336d637bec0..9b8b6619831 100644 --- a/web-common/src/runtime-client/gen/runtime-service/runtime-service.ts +++ b/web-common/src/runtime-client/gen/runtime-service/runtime-service.ts @@ -39,6 +39,7 @@ import type { RuntimeServiceGenerateMetricsViewFileBody, RuntimeServiceGenerateRendererBody, RuntimeServiceGenerateResolverBody, + RuntimeServiceGenerateTemplateBody, RuntimeServiceGetExploreParams, RuntimeServiceGetFileParams, RuntimeServiceGetInstanceParams, @@ -84,6 +85,7 @@ import type { V1GenerateMetricsViewFileResponse, V1GenerateRendererResponse, V1GenerateResolverResponse, + V1GenerateTemplateResponse, V1GetConversationResponse, V1GetExploreResponse, V1GetFileResponse, @@ -3132,6 +3134,94 @@ export const createRuntimeServiceGenerateResolver = < return createMutation(mutationOptions, queryClient); }; +/** + * @summary GenerateTemplate generates a connector or model YAML file from structured form data + */ +export const runtimeServiceGenerateTemplate = ( + instanceId: string, + runtimeServiceGenerateTemplateBody: RuntimeServiceGenerateTemplateBody, + signal?: AbortSignal, +) => { + return httpClient({ + url: `/v1/instances/${instanceId}/generate/template`, + method: "POST", + headers: { "Content-Type": "application/json" }, + data: runtimeServiceGenerateTemplateBody, + signal, + }); +}; + +export const getRuntimeServiceGenerateTemplateMutationOptions = < + TError = ErrorType, + TContext = unknown, +>(options?: { + mutation?: CreateMutationOptions< + Awaited>, + TError, + { instanceId: string; data: RuntimeServiceGenerateTemplateBody }, + TContext + >; +}): CreateMutationOptions< + Awaited>, + TError, + { instanceId: string; data: RuntimeServiceGenerateTemplateBody }, + TContext +> => { + const mutationKey = ["runtimeServiceGenerateTemplate"]; + const { mutation: mutationOptions } = options + ? options.mutation && + "mutationKey" in options.mutation && + options.mutation.mutationKey + ? options + : { ...options, mutation: { ...options.mutation, mutationKey } } + : { mutation: { mutationKey } }; + + const mutationFn: MutationFunction< + Awaited>, + { instanceId: string; data: RuntimeServiceGenerateTemplateBody } + > = (props) => { + const { instanceId, data } = props ?? {}; + + return runtimeServiceGenerateTemplate(instanceId, data); + }; + + return { mutationFn, ...mutationOptions }; +}; + +export type RuntimeServiceGenerateTemplateMutationResult = NonNullable< + Awaited> +>; +export type RuntimeServiceGenerateTemplateMutationBody = + RuntimeServiceGenerateTemplateBody; +export type RuntimeServiceGenerateTemplateMutationError = ErrorType; + +/** + * @summary GenerateTemplate generates a connector or model YAML file from structured form data + */ +export const createRuntimeServiceGenerateTemplate = < + TError = ErrorType, + TContext = unknown, +>( + options?: { + mutation?: CreateMutationOptions< + Awaited>, + TError, + { instanceId: string; data: RuntimeServiceGenerateTemplateBody }, + TContext + >; + }, + queryClient?: QueryClient, +): CreateMutationResult< + Awaited>, + TError, + { instanceId: string; data: RuntimeServiceGenerateTemplateBody }, + TContext +> => { + const mutationOptions = + getRuntimeServiceGenerateTemplateMutationOptions(options); + + return createMutation(mutationOptions, queryClient); +}; export const runtimeServiceListGitBranches = ( instanceId: string, signal?: AbortSignal, From 8252f8e6538f443aac93080d4afac9b8fbf3e19e Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Fri, 20 Feb 2026 14:24:10 -0800 Subject: [PATCH 02/62] feat(web): migrate frontend to GenerateTemplate RPC for YAML generation Replace client-side YAML builders with backend RPC for single source of truth. - New helper: `generateTemplate()` + `mergeEnvVars()` in generate-template.ts - Updated submission paths: submitAddConnectorForm, submitAddSourceForm, saveConnectorAnyway - Updated preview: computeYamlPreview now calls RPC (async, 150ms debounced) - HTTPS connector path preserved (backend doesn't support headers array yet) - Removed dead code: compileSourceYAML, prepareSourceFormData, maybeRewriteToDuckDb - Backend now handles DuckDB rewrite and env var naming (conflict resolution) - Tests: added mergeEnvVars (9 tests) and normalizeConnectorError (11 tests) - Net: 234 lines removed (~27% reduction in submission/preview code) Co-Authored-By: Claude Opus 4.6 --- .../features/sources/modal/AddDataForm.svelte | 48 +- .../sources/modal/AddDataFormManager.ts | 182 ++++---- .../sources/modal/generate-template.spec.ts | 181 ++++++++ .../sources/modal/generate-template.ts | 76 ++++ .../sources/modal/submitAddDataForm.ts | 245 +++++----- .../src/features/sources/modal/utils.spec.ts | 127 ++++++ .../src/features/sources/sourceUtils.spec.ts | 423 ------------------ .../src/features/sources/sourceUtils.ts | 226 ---------- 8 files changed, 637 insertions(+), 871 deletions(-) create mode 100644 web-common/src/features/sources/modal/generate-template.spec.ts create mode 100644 web-common/src/features/sources/modal/generate-template.ts create mode 100644 web-common/src/features/sources/modal/utils.spec.ts diff --git a/web-common/src/features/sources/modal/AddDataForm.svelte b/web-common/src/features/sources/modal/AddDataForm.svelte index 729768b0c16..15258af7810 100644 --- a/web-common/src/features/sources/modal/AddDataForm.svelte +++ b/web-common/src/features/sources/modal/AddDataForm.svelte @@ -4,7 +4,6 @@ import SubmissionError from "@rilldata/web-common/components/forms/SubmissionError.svelte"; import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient"; import { type V1ConnectorDriver } from "@rilldata/web-common/runtime-client"; - import { runtime } from "@rilldata/web-common/runtime-client/runtime-store"; import type { ActionResult } from "@sveltejs/kit"; import type { SuperValidated } from "sveltekit-superforms"; @@ -19,14 +18,13 @@ import { createConnectorForm } from "./FormValidation"; import AddDataFormSection from "./AddDataFormSection.svelte"; import { get } from "svelte/store"; - import { onMount } from "svelte"; + import { onDestroy } from "svelte"; import { getConnectorSchema } from "./connector-schemas"; import { getRequiredFieldsForValues, getSchemaButtonLabels, isVisibleForValues, } from "../../templates/schema-utils"; - import { runtimeServiceGetFile } from "@rilldata/web-common/runtime-client"; import { ICONS } from "./icons"; export let connector: V1ConnectorDriver; @@ -102,22 +100,6 @@ const connectorSchema = getConnectorSchema(schemaName); - // Capture .env blob ONCE on mount for consistent conflict detection in YAML preview. - // This prevents the preview from updating when Test and Connect writes to .env. - // Use null to indicate "not yet loaded" vs "" for "loaded but empty" - let existingEnvBlob: string | null = null; - onMount(async () => { - try { - const envFile = await runtimeServiceGetFile($runtime.instanceId, { - path: ".env", - }); - existingEnvBlob = envFile.blob ?? ""; - } catch { - // .env doesn't exist yet - existingEnvBlob = ""; - } - }); - // Clear errors when connection type changes $: { const currentDeploymentType = $form.deployment_type as string | undefined; @@ -237,14 +219,26 @@ saveAnyway = false; } - // Re-compute preview when existingEnvBlob is loaded (changes from null to string) - $: yamlPreview = formManager.computeYamlPreview({ - stepState, - isMultiStepConnector: isStepFlowConnector, - isConnectorForm, - formValues: $form, - existingEnvBlob: existingEnvBlob ?? "", - }); + // Debounced async YAML preview via the GenerateTemplate RPC + let yamlPreview = ""; + let previewTimer: ReturnType; + $: { + const ctx = { + stepState, + isMultiStepConnector: isStepFlowConnector, + isConnectorForm, + formValues: $form, + }; + clearTimeout(previewTimer); + previewTimer = setTimeout(async () => { + try { + yamlPreview = await formManager.computeYamlPreview(ctx); + } catch { + // Keep last valid preview on error (e.g., incomplete form data) + } + }, 150); + } + onDestroy(() => clearTimeout(previewTimer)); $: shouldShowSaveAnywayButton = isConnectorForm && showSaveAnyway; $: saveAnywayLoading = submitting && saveAnyway; diff --git a/web-common/src/features/sources/modal/AddDataFormManager.ts b/web-common/src/features/sources/modal/AddDataFormManager.ts index 8fe36d87ec4..875a653d138 100644 --- a/web-common/src/features/sources/modal/AddDataFormManager.ts +++ b/web-common/src/features/sources/modal/AddDataFormManager.ts @@ -24,7 +24,6 @@ import { } from "./connectorStepStore"; import { get } from "svelte/store"; import { compileConnectorYAML } from "../../connectors/code-utils"; -import { compileSourceYAML, prepareSourceFormData } from "../sourceUtils"; import type { ActionResult } from "@sveltejs/kit"; import type { QueryClient } from "@tanstack/query-core"; import { @@ -36,6 +35,8 @@ import { } from "../../templates/schema-utils"; import type { ButtonLabels } from "../../templates/schemas/types"; import { processFileContent } from "../../templates/file-encoding"; +import { generateTemplate } from "./generate-template"; +import { runtime } from "../../../runtime-client/runtime-store"; type FormData = Record; // Use unknown to be compatible with superforms' complex ValidationErrors type @@ -498,38 +499,37 @@ export class AddDataFormManager { /** * Compute YAML preview for the current form state. - * Schema conditionals handle connector-specific requirements. + * HTTPS connector step uses synchronous client-side YAML generation; + * all other paths call the GenerateTemplate RPC. */ - computeYamlPreview(ctx: { + async computeYamlPreview(ctx: { stepState: ConnectorStepState | undefined; isMultiStepConnector: boolean; isConnectorForm: boolean; formValues: Record; - existingEnvBlob?: string; - }): string { + }): Promise { const connector = this.connector; - const { - stepState, - isMultiStepConnector, - isConnectorForm, - formValues, - existingEnvBlob, - } = ctx; + const { stepState, isMultiStepConnector, isConnectorForm, formValues } = + ctx; const schema = getConnectorSchema(this.schemaName); - const schemaConnectorFields = schema - ? getSchemaFieldMetaList(schema, { step: "connector" }) - : null; - const schemaConnectorSecretKeys = schema - ? getSchemaSecretKeys(schema, { step: "connector" }) - : undefined; - const schemaConnectorStringKeys = schema - ? getSchemaStringKeys(schema, { step: "connector" }) - : undefined; - - const connectorPropertiesForPreview = schemaConnectorFields ?? []; - - const getConnectorYamlPreview = (values: Record) => { + const instanceId = get(runtime).instanceId; + + // HTTPS connector step: use synchronous client-side YAML generation + // (backend doesn't support headers array yet) + const getHttpsConnectorYamlPreview = ( + values: Record, + ): string => { + const schemaConnectorFields = schema + ? getSchemaFieldMetaList(schema, { step: "connector" }) + : []; + const schemaConnectorSecretKeys = schema + ? getSchemaSecretKeys(schema, { step: "connector" }) + : undefined; + const schemaConnectorStringKeys = schema + ? getSchemaStringKeys(schema, { step: "connector" }) + : undefined; + const filteredValues = schema ? filterSchemaValuesForSubmit(schema, values, { step: "connector" }) : values; @@ -538,77 +538,99 @@ export class AddDataFormManager { if ("internal" in property && property.internal) return false; return !("noPrompt" in property && property.noPrompt); }, - orderedProperties: connectorPropertiesForPreview, + orderedProperties: schemaConnectorFields, secretKeys: schemaConnectorSecretKeys, stringKeys: schemaConnectorStringKeys, schema: schema ?? undefined, - existingEnvBlob, }); }; - const getSourceYamlPreview = (values: Record) => { - // For multi-step connectors in step 2, filter out connector properties - let filteredValues = values; - if ( - (isMultiStepConnector && stepState?.step === "source") || - stepState?.step === "explorer" - ) { + // For HTTPS connector step, use client-side preview + if (connector.name === "https" && isConnectorForm) { + return getHttpsConnectorYamlPreview(formValues); + } + if ( + connector.name === "https" && + isMultiStepConnector && + stepState?.step === "connector" + ) { + return getHttpsConnectorYamlPreview(formValues); + } + + // All other paths: use the GenerateTemplate RPC + const isOnConnectorStep = !stepState || stepState.step === "connector"; + const isOnSourceOrExplorerStep = + stepState?.step === "source" || stepState?.step === "explorer"; + + if (isMultiStepConnector && isOnConnectorStep) { + // Step 1 of multi-step: preview the connector YAML + const filteredValues = schema + ? filterSchemaValuesForSubmit(schema, formValues, { + step: "connector", + }) + : formValues; + const response = await generateTemplate(instanceId, { + resourceType: "connector", + driver: connector.name as string, + properties: filteredValues, + }); + return response.blob ?? ""; + } + + if (isMultiStepConnector && isOnSourceOrExplorerStep) { + // Step 2 of multi-step: preview the model/source YAML + const combinedValues = { + ...(stepState?.connectorConfig || {}), + ...formValues, + } as Record; + + // Filter out connector-step properties + let sourceValues = combinedValues; + if (schema) { const connectorPropertyKeys = new Set( - schema - ? getSchemaFieldMetaList(schema, { step: "connector" }).map( - (field) => field.key, - ) - : [], + getSchemaFieldMetaList(schema, { step: "connector" }).map( + (field) => field.key, + ), ); - filteredValues = Object.fromEntries( - Object.entries(values).filter( + sourceValues = Object.fromEntries( + Object.entries(combinedValues).filter( ([key]) => !connectorPropertyKeys.has(key), ), ); } - const [rewrittenConnector, rewrittenFormValues] = prepareSourceFormData( - connector, - filteredValues, - { - connectorInstanceName: stepState?.connectorInstanceName || undefined, - }, - ); - const isExplorerStep = stepState?.step === "explorer"; - const isRewrittenToDuckDb = rewrittenConnector.name === "duckdb"; - const rewrittenSchema = getConnectorSchema(rewrittenConnector.name ?? ""); - const sourceStep = isExplorerStep ? "explorer" : "source"; - const rewrittenSecretKeys = rewrittenSchema - ? getSchemaSecretKeys(rewrittenSchema, { step: sourceStep }) - : undefined; - const rewrittenStringKeys = rewrittenSchema - ? getSchemaStringKeys(rewrittenSchema, { step: sourceStep }) - : undefined; - if (isRewrittenToDuckDb || isExplorerStep) { - return compileSourceYAML(rewrittenConnector, rewrittenFormValues, { - secretKeys: rewrittenSecretKeys, - stringKeys: rewrittenStringKeys, - originalDriverName: connector.name || undefined, - }); - } - return getConnectorYamlPreview(rewrittenFormValues); - }; + const response = await generateTemplate(instanceId, { + resourceType: "model", + driver: connector.name as string, + properties: sourceValues, + connectorName: + stepState?.connectorInstanceName || (connector.name as string), + }); + return response.blob ?? ""; + } - // Multi-step connectors (S3, GCS, Azure) - if (isMultiStepConnector) { - if (stepState?.step === "connector") { - return getConnectorYamlPreview(formValues); - } else { - const combinedValues = { - ...(stepState?.connectorConfig || {}), - ...formValues, - } as Record; - return getSourceYamlPreview(combinedValues); - } + if (isConnectorForm) { + // Single-step connector + const filteredValues = schema + ? filterSchemaValuesForSubmit(schema, formValues, { + step: "connector", + }) + : formValues; + const response = await generateTemplate(instanceId, { + resourceType: "connector", + driver: connector.name as string, + properties: filteredValues, + }); + return response.blob ?? ""; } - if (isConnectorForm) return getConnectorYamlPreview(formValues); - return getSourceYamlPreview(formValues); + // Single-step source form + const response = await generateTemplate(instanceId, { + resourceType: "model", + driver: connector.name as string, + properties: formValues, + }); + return response.blob ?? ""; } /** diff --git a/web-common/src/features/sources/modal/generate-template.spec.ts b/web-common/src/features/sources/modal/generate-template.spec.ts new file mode 100644 index 00000000000..e422932c67f --- /dev/null +++ b/web-common/src/features/sources/modal/generate-template.spec.ts @@ -0,0 +1,181 @@ +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { mergeEnvVars } from "./generate-template"; + +// Mock the runtime store +vi.mock("../../../runtime-client/runtime-store", () => ({ + runtime: { + subscribe: vi.fn((cb) => { + cb({ instanceId: "test-instance" }); + return () => {}; + }), + }, +})); + +// Mock the runtime client +const mockGetFile = vi.fn(); +vi.mock("../../../runtime-client", () => ({ + getRuntimeServiceGetFileQueryKey: vi.fn( + (instanceId: string, params: { path: string }) => [ + "runtimeServiceGetFile", + instanceId, + params, + ], + ), + runtimeServiceGetFile: (...args: unknown[]) => mockGetFile(...args), +})); + +// Mock replaceOrAddEnvVariable (use actual implementation) +vi.mock("../../connectors/code-utils", async () => { + return { + replaceOrAddEnvVariable: ( + existingEnvBlob: string, + key: string, + newValue: string, + ): string => { + const lines = existingEnvBlob.split("\n"); + let keyFound = false; + + const updatedLines = lines.map((line) => { + if (line.startsWith(`${key}=`)) { + keyFound = true; + return `${key}=${newValue}`; + } + return line; + }); + + if (!keyFound) { + updatedLines.push(`${key}=${newValue}`); + } + + const newBlob = updatedLines + .filter((line, index) => !(line === "" && index === 0)) + .join("\n") + .trim(); + + return newBlob; + }, + }; +}); + +describe("mergeEnvVars", () => { + let queryClient: any; + + beforeEach(() => { + vi.clearAllMocks(); + queryClient = { + invalidateQueries: vi.fn().mockResolvedValue(undefined), + fetchQuery: vi.fn(), + }; + }); + + it("should merge env vars into existing .env content", async () => { + queryClient.fetchQuery.mockResolvedValue({ + blob: "EXISTING_VAR=existing_value", + }); + + const result = await mergeEnvVars(queryClient, { + CLICKHOUSE_PASSWORD: "secret123", + CLICKHOUSE_HOST: "ch.example.com", + }); + + expect(result.originalBlob).toBe("EXISTING_VAR=existing_value"); + expect(result.newBlob).toContain("EXISTING_VAR=existing_value"); + expect(result.newBlob).toContain("CLICKHOUSE_PASSWORD=secret123"); + expect(result.newBlob).toContain("CLICKHOUSE_HOST=ch.example.com"); + }); + + it("should handle empty .env file", async () => { + queryClient.fetchQuery.mockResolvedValue({ blob: "" }); + + const result = await mergeEnvVars(queryClient, { + S3_ACCESS_KEY: "AKID123", + }); + + expect(result.originalBlob).toBe(""); + expect(result.newBlob).toContain("S3_ACCESS_KEY=AKID123"); + }); + + it("should handle .env file not found", async () => { + queryClient.fetchQuery.mockRejectedValue({ + response: { data: { message: "no such file" } }, + }); + + const result = await mergeEnvVars(queryClient, { + NEW_VAR: "new_value", + }); + + expect(result.originalBlob).toBe(""); + expect(result.newBlob).toContain("NEW_VAR=new_value"); + }); + + it("should update existing env var values", async () => { + queryClient.fetchQuery.mockResolvedValue({ + blob: "CLICKHOUSE_PASSWORD=old_secret", + }); + + const result = await mergeEnvVars(queryClient, { + CLICKHOUSE_PASSWORD: "new_secret", + }); + + expect(result.newBlob).toContain("CLICKHOUSE_PASSWORD=new_secret"); + expect(result.newBlob).not.toContain("old_secret"); + }); + + it("should handle empty envVars map", async () => { + queryClient.fetchQuery.mockResolvedValue({ + blob: "EXISTING=value", + }); + + const result = await mergeEnvVars(queryClient, {}); + + expect(result.originalBlob).toBe("EXISTING=value"); + expect(result.newBlob).toBe("EXISTING=value"); + }); + + it("should skip entries with empty keys or values", async () => { + queryClient.fetchQuery.mockResolvedValue({ blob: "" }); + + const result = await mergeEnvVars(queryClient, { + "": "no_key", + VALID_KEY: "", + REAL_KEY: "real_value", + }); + + expect(result.newBlob).toContain("REAL_KEY=real_value"); + expect(result.newBlob).not.toContain("no_key"); + expect(result.newBlob).not.toContain("VALID_KEY"); + }); + + it("should invalidate query cache before fetching", async () => { + queryClient.fetchQuery.mockResolvedValue({ blob: "" }); + + await mergeEnvVars(queryClient, { KEY: "value" }); + + expect(queryClient.invalidateQueries).toHaveBeenCalledBefore( + queryClient.fetchQuery, + ); + }); + + it("should re-throw non-file-not-found errors", async () => { + const error = new Error("network error"); + queryClient.fetchQuery.mockRejectedValue(error); + + await expect(mergeEnvVars(queryClient, { KEY: "value" })).rejects.toThrow( + "network error", + ); + }); + + it("should handle suffixed env var names from backend", async () => { + queryClient.fetchQuery.mockResolvedValue({ + blob: "CLICKHOUSE_PASSWORD=first_secret", + }); + + // Backend already resolved the conflict and returned _1 suffix + const result = await mergeEnvVars(queryClient, { + CLICKHOUSE_PASSWORD_1: "second_secret", + }); + + expect(result.newBlob).toContain("CLICKHOUSE_PASSWORD=first_secret"); + expect(result.newBlob).toContain("CLICKHOUSE_PASSWORD_1=second_secret"); + }); +}); diff --git a/web-common/src/features/sources/modal/generate-template.ts b/web-common/src/features/sources/modal/generate-template.ts new file mode 100644 index 00000000000..202738a20e5 --- /dev/null +++ b/web-common/src/features/sources/modal/generate-template.ts @@ -0,0 +1,76 @@ +import type { QueryClient } from "@tanstack/query-core"; +import { get } from "svelte/store"; +import { + type V1GenerateTemplateResponse, + getRuntimeServiceGetFileQueryKey, + runtimeServiceGenerateTemplate, + runtimeServiceGetFile, +} from "../../../runtime-client"; +import { runtime } from "../../../runtime-client/runtime-store"; +import { replaceOrAddEnvVariable } from "../../connectors/code-utils"; + +/** + * Call the GenerateTemplate RPC to produce YAML + env var names from + * structured form data. The backend handles DuckDB rewrites, env var + * naming/conflict resolution, and YAML formatting. + */ +export async function generateTemplate( + instanceId: string, + opts: { + resourceType: string; + driver: string; + properties: Record; + connectorName?: string; + }, +): Promise { + return runtimeServiceGenerateTemplate(instanceId, { + resourceType: opts.resourceType, + driver: opts.driver, + properties: opts.properties, + connectorName: opts.connectorName, + }); +} + +/** + * Merge env vars returned by the GenerateTemplate RPC into the existing + * `.env` file. The backend already resolved names and conflict suffixes, + * so this is a straight key=value merge. + * + * Returns the updated blob and the original blob (for rollback). + */ +export async function mergeEnvVars( + queryClient: QueryClient, + envVars: Record, +): Promise<{ newBlob: string; originalBlob: string }> { + const instanceId = get(runtime).instanceId; + + // Invalidate cache to get fresh .env content + await queryClient.invalidateQueries({ + queryKey: getRuntimeServiceGetFileQueryKey(instanceId, { path: ".env" }), + }); + + let blob: string; + let originalBlob: string; + try { + const file = await queryClient.fetchQuery({ + queryKey: getRuntimeServiceGetFileQueryKey(instanceId, { path: ".env" }), + queryFn: () => runtimeServiceGetFile(instanceId, { path: ".env" }), + }); + blob = file.blob || ""; + originalBlob = blob; + } catch (error) { + if ((error as any)?.response?.data?.message?.includes("no such file")) { + blob = ""; + originalBlob = ""; + } else { + throw error; + } + } + + for (const [key, value] of Object.entries(envVars)) { + if (!key || !value) continue; + blob = replaceOrAddEnvVariable(blob, key, value); + } + + return { newBlob: blob, originalBlob }; +} diff --git a/web-common/src/features/sources/modal/submitAddDataForm.ts b/web-common/src/features/sources/modal/submitAddDataForm.ts index f1585be5547..d18e5fa27f2 100644 --- a/web-common/src/features/sources/modal/submitAddDataForm.ts +++ b/web-common/src/features/sources/modal/submitAddDataForm.ts @@ -31,7 +31,6 @@ import { ResourceKind } from "../../entity-management/resource-selectors"; import { EntityType } from "../../entity-management/types"; import { EMPTY_PROJECT_TITLE } from "../../welcome/constants"; import { isProjectInitialized } from "../../welcome/is-project-initialized"; -import { compileSourceYAML, prepareSourceFormData } from "../sourceUtils"; import { sourceIngestionTracker } from "../sources-store"; import { OLAP_ENGINES } from "./constants"; import { getConnectorSchema } from "./connector-schemas"; @@ -40,6 +39,7 @@ import { getSchemaSecretKeys, getSchemaStringKeys, } from "../../templates/schema-utils"; +import { generateTemplate, mergeEnvVars } from "./generate-template"; interface AddDataFormValues { // name: string; // Commenting out until we add user-provided names for Connectors @@ -141,16 +141,6 @@ async function saveConnectorAnyway( instanceId?: string, ): Promise { const resolvedInstanceId = instanceId ?? get(runtime).instanceId; - const schema = getConnectorSchema(connector.name ?? ""); - const schemaFields = schema - ? getSchemaFieldMetaList(schema, { step: "connector" }) - : []; - const schemaSecretKeys = schema - ? getSchemaSecretKeys(schema, { step: "connector" }) - : []; - const schemaStringKeys = schema - ? getSchemaStringKeys(schema, { step: "connector" }) - : []; // Create connector file const newConnectorFilePath = getFileAPIPathFromNameAndType( @@ -161,37 +151,74 @@ async function saveConnectorAnyway( // Mark to avoid rollback by concurrent submissions savedAnywayPaths.add(newConnectorFilePath); - // Update .env file with secrets (keep ordering consistent with Test and Connect) - const { newBlob: newEnvBlob, originalBlob: envBlobForYaml } = - await updateDotEnvWithSecrets(queryClient, connector, formValues, { - secretKeys: schemaSecretKeys, - schema: schema ?? undefined, + if (connector.name === "https") { + // HTTPS: keep client-side path (backend doesn't support headers array yet) + const schema = getConnectorSchema(connector.name ?? ""); + const schemaFields = schema + ? getSchemaFieldMetaList(schema, { step: "connector" }) + : []; + const schemaSecretKeys = schema + ? getSchemaSecretKeys(schema, { step: "connector" }) + : []; + const schemaStringKeys = schema + ? getSchemaStringKeys(schema, { step: "connector" }) + : []; + + const { newBlob: newEnvBlob, originalBlob: envBlobForYaml } = + await updateDotEnvWithSecrets(queryClient, connector, formValues, { + secretKeys: schemaSecretKeys, + schema: schema ?? undefined, + }); + + await runtimeServicePutFile(resolvedInstanceId, { + path: ".env", + blob: newEnvBlob, + create: true, + createOnly: false, }); - await runtimeServicePutFile(resolvedInstanceId, { - path: ".env", - blob: newEnvBlob, - create: true, - createOnly: false, - }); + await runtimeServicePutFile(resolvedInstanceId, { + path: newConnectorFilePath, + blob: compileConnectorYAML(connector, formValues, { + connectorInstanceName: newConnectorName, + orderedProperties: schemaFields, + secretKeys: schemaSecretKeys, + stringKeys: schemaStringKeys, + schema: schema ?? undefined, + existingEnvBlob: envBlobForYaml, + fieldFilter: schemaFields + ? (property) => !("internal" in property && property.internal) + : undefined, + }), + create: true, + createOnly: false, + }); + } else { + // All other connectors: use the GenerateTemplate RPC + const templateResponse = await generateTemplate(resolvedInstanceId, { + resourceType: "connector", + driver: connector.name as string, + properties: formValues, + }); + const { newBlob: newEnvBlob } = await mergeEnvVars( + queryClient, + templateResponse.envVars ?? {}, + ); - // Always create/overwrite to ensure the connector file is created immediately - await runtimeServicePutFile(resolvedInstanceId, { - path: newConnectorFilePath, - blob: compileConnectorYAML(connector, formValues, { - connectorInstanceName: newConnectorName, - orderedProperties: schemaFields, - secretKeys: schemaSecretKeys, - stringKeys: schemaStringKeys, - schema: schema ?? undefined, - existingEnvBlob: envBlobForYaml, - fieldFilter: schemaFields - ? (property) => !("internal" in property && property.internal) - : undefined, - }), - create: true, - createOnly: false, - }); + await runtimeServicePutFile(resolvedInstanceId, { + path: ".env", + blob: newEnvBlob, + create: true, + createOnly: false, + }); + + await runtimeServicePutFile(resolvedInstanceId, { + path: newConnectorFilePath, + blob: templateResponse.blob ?? "", + create: true, + createOnly: false, + }); + } if (OLAP_ENGINES.includes(connector.name as string)) { await setOlapConnectorInRillYAML( @@ -213,16 +240,6 @@ export async function submitAddConnectorForm( ): Promise { const instanceId = get(runtime).instanceId; await beforeSubmitForm(instanceId, connector); - const schema = getConnectorSchema(connector.name ?? ""); - const schemaFields = schema - ? getSchemaFieldMetaList(schema, { step: "connector" }) - : []; - const schemaSecretKeys = schema - ? getSchemaSecretKeys(schema, { step: "connector" }) - : []; - const schemaStringKeys = schema - ? getSchemaStringKeys(schema, { step: "connector" }) - : []; // Create a unique key for this connector submission const uniqueConnectorSubmissionKey = `${instanceId}:${connector.name}`; @@ -246,9 +263,6 @@ export async function submitAddConnectorForm( // Use the same connector name from the ongoing operation const newConnectorName = existingSubmission.connectorName; - // Proceed immediately with Save Anyway logic - // Use the pre-computed env blobs from the concurrent Test and Connect operation - // to ensure consistent variable naming (e.g., GOOGLE_APPLICATION_CREDENTIALS not _2) await saveConnectorAnyway( queryClient, connector, @@ -285,19 +299,60 @@ export async function submitAddConnectorForm( throw new Error("Operation cancelled"); } - // Capture original .env and compute updated contents up front - // Use originalBlob from updateDotEnvWithSecrets for consistent conflict detection - const envResult = await updateDotEnvWithSecrets( - queryClient, - connector, - formValues, - { + let newEnvBlob: string; + let connectorYamlBlob: string; + + if (connector.name === "https") { + // HTTPS: keep client-side path (backend doesn't support headers array yet) + const schema = getConnectorSchema(connector.name ?? ""); + const schemaFields = schema + ? getSchemaFieldMetaList(schema, { step: "connector" }) + : []; + const schemaSecretKeys = schema + ? getSchemaSecretKeys(schema, { step: "connector" }) + : []; + const schemaStringKeys = schema + ? getSchemaStringKeys(schema, { step: "connector" }) + : []; + + const envResult = await updateDotEnvWithSecrets( + queryClient, + connector, + formValues, + { + secretKeys: schemaSecretKeys, + schema: schema ?? undefined, + }, + ); + newEnvBlob = envResult.newBlob; + originalEnvBlob = envResult.originalBlob; + + connectorYamlBlob = compileConnectorYAML(connector, formValues, { + connectorInstanceName: newConnectorName, + orderedProperties: schemaFields, secretKeys: schemaSecretKeys, + stringKeys: schemaStringKeys, schema: schema ?? undefined, - }, - ); - const newEnvBlob = envResult.newBlob; - originalEnvBlob = envResult.originalBlob; + existingEnvBlob: originalEnvBlob, + fieldFilter: schemaFields + ? (property) => !("internal" in property && property.internal) + : undefined, + }); + } else { + // All other connectors: use the GenerateTemplate RPC + const templateResponse = await generateTemplate(instanceId, { + resourceType: "connector", + driver: connector.name as string, + properties: formValues, + }); + const envResult = await mergeEnvVars( + queryClient, + templateResponse.envVars ?? {}, + ); + newEnvBlob = envResult.newBlob; + originalEnvBlob = envResult.originalBlob; + connectorYamlBlob = templateResponse.blob ?? ""; + } if (saveAnyway) { // Save Anyway: bypass reconciliation entirely via centralized helper @@ -329,17 +384,7 @@ export async function submitAddConnectorForm( instanceId, { path: newConnectorFilePath, - blob: compileConnectorYAML(connector, formValues, { - connectorInstanceName: newConnectorName, - orderedProperties: schemaFields, - secretKeys: schemaSecretKeys, - stringKeys: schemaStringKeys, - schema: schema ?? undefined, - existingEnvBlob: originalEnvBlob, - fieldFilter: schemaFields - ? (property) => !("internal" in property && property.internal) - : undefined, - }), + blob: connectorYamlBlob, create: true, createOnly: false, }, @@ -406,8 +451,6 @@ export async function submitAddConnectorForm( throw error; } finally { - // Mark the submission as completed but keep the connector name around - // so a subsequent "Save Anyway" can still reuse the same connector file connectorSubmissions.delete(uniqueConnectorSubmissionKey); } })(); @@ -433,27 +476,15 @@ export async function submitAddSourceForm( await beforeSubmitForm(instanceId, connector); const newSourceName = formValues.name as string; - const [rewrittenConnector, rewrittenFormValues] = prepareSourceFormData( - connector, - formValues, - { connectorInstanceName }, - ); - const schema = getConnectorSchema(rewrittenConnector.name ?? ""); - const schemaSecretKeys = schema - ? getSchemaSecretKeys(schema, { step: "source" }) - : []; - const schemaStringKeys = schema - ? getSchemaStringKeys(schema, { step: "source" }) - : []; - - // When connector is rewritten to DuckDB (e.g., S3 -> DuckDB), don't use - // the original connectorInstanceName in YAML. The original connector is - // referenced via create_secrets_from_connectors for credential access. - const isRewrittenToDuckDb = - rewrittenConnector.name === "duckdb" && connector.name !== "duckdb"; - const yamlConnectorInstanceName = isRewrittenToDuckDb - ? undefined - : connectorInstanceName; + // Use the GenerateTemplate RPC; backend handles DuckDB rewrite and env var naming + const templateResponse = await generateTemplate(instanceId, { + resourceType: "model", + driver: connector.name as string, + properties: formValues, + connectorName: connectorInstanceName || (connector.name as string), + }); + const { newBlob: newEnvBlob, originalBlob: originalEnvBlob } = + await mergeEnvVars(queryClient, templateResponse.envVars ?? {}); // Create model YAML file const newSourceFilePath = getFileAPIPathFromNameAndType( @@ -463,28 +494,12 @@ export async function submitAddSourceForm( sourceIngestionTracker.trackPending(`/${newSourceFilePath}`); await runtimeServicePutFile(instanceId, { path: newSourceFilePath, - blob: compileSourceYAML(rewrittenConnector, rewrittenFormValues, { - secretKeys: schemaSecretKeys, - stringKeys: schemaStringKeys, - connectorInstanceName: yamlConnectorInstanceName, - originalDriverName: connector.name || undefined, - }), + blob: templateResponse.blob ?? "", create: true, createOnly: false, }); - // Create or update the `.env` file - const { newBlob: newEnvBlob, originalBlob: originalEnvBlob } = - await updateDotEnvWithSecrets( - queryClient, - rewrittenConnector, - rewrittenFormValues, - { - secretKeys: schemaSecretKeys, - }, - ); - - // Make sure the file has reconciled before testing the connection + // Make sure the .env file has reconciled before testing the connection await runtimeServicePutFileAndWaitForReconciliation(instanceId, { path: ".env", blob: newEnvBlob, diff --git a/web-common/src/features/sources/modal/utils.spec.ts b/web-common/src/features/sources/modal/utils.spec.ts new file mode 100644 index 00000000000..55b17b9d918 --- /dev/null +++ b/web-common/src/features/sources/modal/utils.spec.ts @@ -0,0 +1,127 @@ +import { describe, it, expect } from "vitest"; +import { normalizeConnectorError } from "./utils"; + +describe("normalizeConnectorError", () => { + it("should handle standard Error instance", () => { + const error = new Error("connection refused"); + const result = normalizeConnectorError("postgres", error); + expect(result.message).toBe("connection refused"); + expect(result.details).toBeUndefined(); + }); + + it("should handle Error with details (from waitForResourceReconciliation)", () => { + const error = new Error("Resource configuration failed to reconcile"); + (error as any).details = + 'failed to connect to "host=localhost user=postgres database=postgres": connection refused'; + + // submitAddConnectorForm re-throws as a plain object with { message, details } + const rethrown = { + message: error.message, + details: (error as any).details, + }; + const result = normalizeConnectorError("postgres", rethrown); + + expect(result.message).toBe("Resource configuration failed to reconcile"); + expect(result.details).toBe( + 'failed to connect to "host=localhost user=postgres database=postgres": connection refused', + ); + }); + + it("should handle error with HTTP response data", () => { + const error = { + response: { + data: { + message: 'unknown property "bad_prop" for driver', + code: 3, // InvalidArgument + }, + }, + }; + const result = normalizeConnectorError("postgres", error); + + // Postgres is not in connectorErrorMap, so it gets the generic template + expect(result.message).toContain("postgres"); + expect(result.details).toBe('unknown property "bad_prop" for driver'); + }); + + it("should handle plain object with message only", () => { + const error = { message: "Unable to establish a connection" }; + const result = normalizeConnectorError("postgres", error); + expect(result.message).toBe("Unable to establish a connection"); + expect(result.details).toBeUndefined(); + }); + + it("should handle plain object with same message and details", () => { + const error = { + message: "connection refused", + details: "connection refused", + }; + const result = normalizeConnectorError("postgres", error); + expect(result.message).toBe("connection refused"); + // details should be undefined when same as message + expect(result.details).toBeUndefined(); + }); + + it("should handle unknown error types", () => { + const result = normalizeConnectorError("postgres", 42); + expect(result.message).toBe("Unknown error"); + expect(result.details).toBeUndefined(); + }); + + it("should handle null error", () => { + const result = normalizeConnectorError("postgres", null); + expect(result.message).toBe("Unknown error"); + }); + + it("should handle string error", () => { + // Strings don't match any of the type guards (not Error, not object with response, not object with message) + const result = normalizeConnectorError("postgres", "some error"); + expect(result.message).toBe("Unknown error"); + }); + + it("should use humanReadableErrorMessage for ClickHouse connection errors", () => { + const error = { + response: { + data: { + message: "connection refused to host:9000", + code: 2, // Unknown gRPC code + }, + }, + }; + const result = normalizeConnectorError("clickhouse", error); + + // ClickHouse has custom error mapping for "connection refused" + expect(result.message).toContain("Could not connect to ClickHouse"); + // Details should have the original message since humanReadable differs + expect(result.details).toBe("connection refused to host:9000"); + }); + + it("should handle GenerateTemplate RPC validation error", () => { + const error = { + response: { + data: { + message: 'unknown property "connection_mode" for driver', + code: 3, // InvalidArgument + }, + }, + }; + const result = normalizeConnectorError("postgres", error); + + expect(result.message).toBeTruthy(); + // The details should include the original error + expect(result.details).toBe( + 'unknown property "connection_mode" for driver', + ); + }); + + it("should handle reconciliation error that was auto-deleted", () => { + const error = new Error( + "Resource configuration failed to reconcile and was automatically deleted. This usually indicates a connection or configuration error.", + ); + const result = normalizeConnectorError("postgres", error); + + expect(result.message).toBe( + "Resource configuration failed to reconcile and was automatically deleted. This usually indicates a connection or configuration error.", + ); + expect(result.details).toBeUndefined(); + }); +}); diff --git a/web-common/src/features/sources/sourceUtils.spec.ts b/web-common/src/features/sources/sourceUtils.spec.ts index 1ba27e3afa5..f703218e685 100644 --- a/web-common/src/features/sources/sourceUtils.spec.ts +++ b/web-common/src/features/sources/sourceUtils.spec.ts @@ -1,12 +1,8 @@ import { describe, it, expect } from "vitest"; -import type { V1ConnectorDriver } from "@rilldata/web-common/runtime-client"; import { getFileTypeFromPath, inferSourceName, buildDuckDbQuery, - maybeRewriteToDuckDb, - compileSourceYAML, - prepareSourceFormData, } from "./sourceUtils"; const gcsTests = [ @@ -185,422 +181,3 @@ describe("buildDuckDbQuery", () => { }); } }); - -describe("maybeRewriteToDuckDb", () => { - it("should rewrite s3 with connector name", () => { - const connector: V1ConnectorDriver = { name: "s3" }; - const formValues: Record = { - path: "s3://bucket/data.parquet", - }; - const [result, values] = maybeRewriteToDuckDb(connector, formValues, { - connectorInstanceName: "my_s3", - }); - expect(result.name).toBe("duckdb"); - expect(values.sql).toBe( - "select * from read_parquet('s3://bucket/data.parquet')", - ); - expect(values.path).toBeUndefined(); - expect(values.create_secrets_from_connectors).toBe("my_s3"); - }); - - it("should rewrite s3 without connector name — uses driver name for secrets", () => { - const connector: V1ConnectorDriver = { name: "s3" }; - const formValues: Record = { - path: "s3://bucket/data.csv", - }; - const [result, values] = maybeRewriteToDuckDb(connector, formValues); - expect(result.name).toBe("duckdb"); - expect(values.sql).toContain("read_csv"); - expect(values.create_secrets_from_connectors).toBe("s3"); - }); - - it("should rewrite gcs", () => { - const connector: V1ConnectorDriver = { name: "gcs" }; - const formValues: Record = { - path: "gs://bucket/data.json", - }; - const [result, values] = maybeRewriteToDuckDb(connector, formValues, { - connectorInstanceName: "my_gcs", - }); - expect(result.name).toBe("duckdb"); - expect(values.sql).toContain("read_json"); - expect(values.create_secrets_from_connectors).toBe("my_gcs"); - }); - - it("should rewrite azure", () => { - const connector: V1ConnectorDriver = { name: "azure" }; - const formValues: Record = { - path: "azure://container/data.parquet", - }; - const [result, values] = maybeRewriteToDuckDb(connector, formValues, { - connectorInstanceName: "my_azure", - }); - expect(result.name).toBe("duckdb"); - expect(values.sql).toContain("read_parquet"); - expect(values.create_secrets_from_connectors).toBe("my_azure"); - }); - - it("should rewrite https with connector name", () => { - const connector: V1ConnectorDriver = { name: "https" }; - const formValues: Record = { - path: "https://api.example.com/data", - }; - const [result, values] = maybeRewriteToDuckDb(connector, formValues, { - connectorInstanceName: "my_http", - }); - expect(result.name).toBe("duckdb"); - // https defaults to read_json - expect(values.sql).toContain("read_json"); - expect(values.create_secrets_from_connectors).toBe("my_http"); - }); - - it("should rewrite https without connector name — no create_secrets", () => { - const connector: V1ConnectorDriver = { name: "https" }; - const formValues: Record = { - path: "https://example.com/data.csv", - }; - const [result, values] = maybeRewriteToDuckDb(connector, formValues); - expect(result.name).toBe("duckdb"); - expect(values.sql).toContain("read_csv"); - expect(values.create_secrets_from_connectors).toBeUndefined(); - }); - - it("should rewrite local_file", () => { - const connector: V1ConnectorDriver = { name: "local_file" }; - const formValues: Record = { path: "/data/file.parquet" }; - const [result, values] = maybeRewriteToDuckDb(connector, formValues); - expect(result.name).toBe("duckdb"); - expect(values.sql).toContain("read_parquet"); - expect(values.path).toBeUndefined(); - }); - - it("should rewrite sqlite with sqlite_scan", () => { - const connector: V1ConnectorDriver = { name: "sqlite" }; - const formValues: Record = { - db: "/data/app.db", - table: "users", - }; - const [result, values] = maybeRewriteToDuckDb(connector, formValues); - expect(result.name).toBe("duckdb"); - expect(values.sql).toBe( - "SELECT * FROM sqlite_scan('/data/app.db', 'users');", - ); - expect(values.db).toBeUndefined(); - expect(values.table).toBeUndefined(); - }); - - it("should not rewrite clickhouse", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const formValues: Record = { sql: "SELECT 1" }; - const [result, values] = maybeRewriteToDuckDb(connector, formValues); - expect(result.name).toBe("clickhouse"); - expect(values.sql).toBe("SELECT 1"); - }); - - it("should not rewrite postgres", () => { - const connector: V1ConnectorDriver = { name: "postgres" }; - const formValues: Record = { sql: "SELECT 1" }; - const [result, values] = maybeRewriteToDuckDb(connector, formValues); - expect(result.name).toBe("postgres"); - expect(values.sql).toBe("SELECT 1"); - }); - - it("should not mutate the original connector object", () => { - const connector: V1ConnectorDriver = { name: "s3" }; - const formValues: Record = { - path: "s3://bucket/data.csv", - }; - maybeRewriteToDuckDb(connector, formValues); - expect(connector.name).toBe("s3"); - }); - - it("should preserve existing create_secrets_from_connectors for s3", () => { - const connector: V1ConnectorDriver = { name: "s3" }; - const formValues: Record = { - path: "s3://bucket/data.csv", - create_secrets_from_connectors: "existing_connector", - }; - const [, values] = maybeRewriteToDuckDb(connector, formValues, { - connectorInstanceName: "new_s3", - }); - // Should preserve existing value, not overwrite - expect(values.create_secrets_from_connectors).toBe("existing_connector"); - }); -}); - -describe("compileSourceYAML", () => { - it("should produce basic model YAML with SQL", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileSourceYAML(connector, { - sql: "SELECT * FROM events", - }); - expect(result).toContain("# Model YAML"); - expect(result).toContain("type: model"); - expect(result).toContain("materialize: true"); - expect(result).toContain("connector: clickhouse"); - expect(result).toContain("sql: |"); - expect(result).toContain(" SELECT * FROM events"); - }); - - it("should replace secret properties with env var placeholders", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileSourceYAML( - connector, - { password: "super_secret", sql: "SELECT 1" }, - { secretKeys: ["password"] }, - ); - expect(result).toContain("{{ .env.CLICKHOUSE_PASSWORD }}"); - expect(result).not.toContain("super_secret"); - }); - - it("should quote string properties", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileSourceYAML( - connector, - { host: "ch.example.com", sql: "SELECT 1" }, - { stringKeys: ["host"] }, - ); - expect(result).toContain('host: "ch.example.com"'); - }); - - it("should not quote non-string properties", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileSourceYAML(connector, { - port: 9000, - sql: "SELECT 1", - }); - expect(result).toContain("port: 9000"); - expect(result).not.toContain('port: "9000"'); - }); - - it("should filter out empty string values", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileSourceYAML(connector, { - database: "", - sql: "SELECT 1", - }); - expect(result).not.toContain("database:"); - }); - - it("should filter out undefined values", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileSourceYAML(connector, { - database: undefined, - sql: "SELECT 1", - }); - expect(result).not.toContain("database:"); - }); - - it("should always exclude the name field", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileSourceYAML(connector, { - name: "my_source", - sql: "SELECT 1", - }); - expect(result).not.toContain("name: my_source"); - }); - - it("should include dev section for warehouse connectors", () => { - const connector: V1ConnectorDriver = { - name: "clickhouse", - implementsWarehouse: true, - }; - const result = compileSourceYAML(connector, { - sql: "SELECT * FROM events;", - }); - expect(result).toContain("dev:"); - expect(result).toContain("limit 10000"); - // Dev SQL should strip trailing semicolons - expect(result).toContain("SELECT * FROM events limit 10000"); - }); - - it("should skip dev section for redshift", () => { - const connector: V1ConnectorDriver = { - name: "redshift", - implementsWarehouse: true, - }; - const result = compileSourceYAML(connector, { - sql: "SELECT * FROM events", - }); - expect(result).not.toContain("dev:"); - }); - - it("should skip dev section for non-warehouse connectors", () => { - const connector: V1ConnectorDriver = { - name: "duckdb", - implementsWarehouse: false, - }; - const result = compileSourceYAML(connector, { - sql: "SELECT * FROM events", - }); - expect(result).not.toContain("dev:"); - }); - - it("should skip dev section when no SQL", () => { - const connector: V1ConnectorDriver = { - name: "clickhouse", - implementsWarehouse: true, - }; - const result = compileSourceYAML(connector, { host: "ch.example.com" }); - expect(result).not.toContain("dev:"); - }); - - it("should use connectorInstanceName as connector value", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileSourceYAML( - connector, - { sql: "SELECT 1" }, - { connectorInstanceName: "clickhouse_prod" }, - ); - expect(result).toContain("connector: clickhouse_prod"); - }); - - it("should use originalDriverName in header comment", () => { - const connector: V1ConnectorDriver = { name: "duckdb" }; - const result = compileSourceYAML( - connector, - { sql: "SELECT 1" }, - { originalDriverName: "s3" }, - ); - expect(result).toContain( - "https://docs.rilldata.com/developers/build/connectors/data-source/s3", - ); - }); - - it("should handle env var conflict resolution with existingEnvBlob", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileSourceYAML( - connector, - { password: "secret", sql: "SELECT 1" }, - { - secretKeys: ["password"], - existingEnvBlob: "CLICKHOUSE_PASSWORD=old_value", - }, - ); - expect(result).toContain("CLICKHOUSE_PASSWORD_1"); - }); -}); - -describe("prepareSourceFormData", () => { - it("should strip auth_method from form values", () => { - const connector: V1ConnectorDriver = { name: "s3" }; - const formValues: Record = { - auth_method: "access_keys", - path: "s3://bucket/data.parquet", - }; - const [, values] = prepareSourceFormData(connector, formValues); - expect(values.auth_method).toBeUndefined(); - }); - - it("should strip connector-step fields for s3", () => { - const connector: V1ConnectorDriver = { name: "s3" }; - const formValues: Record = { - aws_access_key_id: "AKID", - aws_secret_access_key: "secret", - region: "us-east-1", - endpoint: "https://s3.example.com", - path: "s3://bucket/data.csv", - }; - const [, values] = prepareSourceFormData(connector, formValues); - // Connector-level fields should be removed - expect(values.aws_access_key_id).toBeUndefined(); - expect(values.aws_secret_access_key).toBeUndefined(); - expect(values.region).toBeUndefined(); - expect(values.endpoint).toBeUndefined(); - }); - - it("should apply DuckDB rewrite for s3", () => { - const connector: V1ConnectorDriver = { name: "s3" }; - const formValues: Record = { - path: "s3://bucket/data.parquet", - }; - const [result, values] = prepareSourceFormData(connector, formValues, { - connectorInstanceName: "my_s3", - }); - expect(result.name).toBe("duckdb"); - expect(values.sql).toContain("read_parquet"); - expect(values.path).toBeUndefined(); - }); - - it("should not mutate original formValues", () => { - const connector: V1ConnectorDriver = { name: "s3" }; - const formValues: Record = { - auth_method: "access_keys", - aws_access_key_id: "AKID", - path: "s3://bucket/data.csv", - }; - prepareSourceFormData(connector, formValues); - // Original should be preserved - expect(formValues.auth_method).toBe("access_keys"); - expect(formValues.aws_access_key_id).toBe("AKID"); - expect(formValues.path).toBe("s3://bucket/data.csv"); - }); - - it("should not mutate original connector", () => { - const connector: V1ConnectorDriver = { name: "s3" }; - prepareSourceFormData(connector, { path: "s3://bucket/data.csv" }); - expect(connector.name).toBe("s3"); - }); - - it("should pass through non-rewritten connectors", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const formValues: Record = { - sql: "SELECT * FROM events", - }; - const [result, values] = prepareSourceFormData(connector, formValues); - expect(result.name).toBe("clickhouse"); - expect(values.sql).toBe("SELECT * FROM events"); - }); - - it("should strip connector-step fields for clickhouse", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const formValues: Record = { - host: "ch.example.com", - port: 8443, - username: "default", - password: "secret", - sql: "SELECT * FROM events", - }; - const [, values] = prepareSourceFormData(connector, formValues); - // All connector-step fields removed - expect(values.host).toBeUndefined(); - expect(values.port).toBeUndefined(); - expect(values.username).toBeUndefined(); - expect(values.password).toBeUndefined(); - // Source-step fields preserved - expect(values.sql).toBe("SELECT * FROM events"); - }); - - it("should handle https with DuckDB rewrite and defaultToJson", () => { - const connector: V1ConnectorDriver = { name: "https" }; - const formValues: Record = { - path: "https://api.example.com/data", - }; - const [result, values] = prepareSourceFormData(connector, formValues); - expect(result.name).toBe("duckdb"); - expect(values.sql).toContain("read_json"); - }); - - it("should handle connector with no schema gracefully", () => { - const connector: V1ConnectorDriver = { name: "unknown_connector" }; - const formValues: Record = { - sql: "SELECT 1", - some_field: "value", - }; - const [result, values] = prepareSourceFormData(connector, formValues); - // No schema, so no stripping/placeholder logic applies - expect(result.name).toBe("unknown_connector"); - expect(values.sql).toBe("SELECT 1"); - expect(values.some_field).toBe("value"); - }); - - it("should strip auth_method even when no schema exists", () => { - const connector: V1ConnectorDriver = { name: "unknown_connector" }; - const formValues: Record = { - auth_method: "oauth", - sql: "SELECT 1", - }; - const [, values] = prepareSourceFormData(connector, formValues); - expect(values.auth_method).toBeUndefined(); - }); -}); diff --git a/web-common/src/features/sources/sourceUtils.ts b/web-common/src/features/sources/sourceUtils.ts index 5332ab67a08..5ba94323a41 100644 --- a/web-common/src/features/sources/sourceUtils.ts +++ b/web-common/src/features/sources/sourceUtils.ts @@ -3,14 +3,7 @@ import type { V1ConnectorDriver, V1Source, } from "@rilldata/web-common/runtime-client"; -import { makeEnvVarKey } from "../connectors/code-utils"; import { sanitizeEntityName } from "../entity-management/name-utils"; -import { getConnectorSchema } from "./modal/connector-schemas"; -import { - getSchemaFieldMetaList, - getSchemaSecretKeys, - getSchemaStringKeys, -} from "../templates/schema-utils"; // Helper text that we put at the top of every Model YAML file function sourceModelFileTop(driverName: string) { @@ -21,97 +14,6 @@ type: model materialize: true`; } -export function compileSourceYAML( - connector: V1ConnectorDriver, - formValues: Record, - opts?: { - secretKeys?: string[]; - stringKeys?: string[]; - connectorInstanceName?: string; - originalDriverName?: string; - existingEnvBlob?: string; - }, -) { - const schema = getConnectorSchema(connector.name ?? ""); - - // Get the secret property keys - const secretPropertyKeys = - opts?.secretKeys ?? - (schema ? getSchemaSecretKeys(schema, { step: "source" }) : []); - - // Get the string property keys - const stringPropertyKeys = - opts?.stringKeys ?? - (schema ? getSchemaStringKeys(schema, { step: "source" }) : []); - - const formatSqlBlock = (sql: string, indent: string) => - `sql: |\n${sql - .split("\n") - .map((line) => `${indent}${line}`) - .join("\n")}`; - const trimSqlForDev = (sql: string) => sql.trim().replace(/;+\s*$/, ""); - - // Compile key value pairs - const compiledKeyValues = Object.keys(formValues) - .filter((key) => { - // For source files, exclude user-provided name since we use connector type - if (key === "name") return false; - const value = formValues[key]; - if (value === undefined) return false; - // Filter out empty strings for optional fields - if (typeof value === "string" && value.trim() === "") return false; - return true; - }) - .map((key) => { - const value = formValues[key] as string; - - const isSecretProperty = secretPropertyKeys.includes(key); - if (isSecretProperty) { - // For source files, we include secret properties - return `${key}: "{{ .env.${makeEnvVarKey( - connector.name as string, - key, - opts?.existingEnvBlob, - schema ?? undefined, - )} }}"`; // uses standard Go template syntax - } - - if (key === "sql") { - // For SQL, we want to use a multi-line string - return formatSqlBlock(value, " "); - } - - const isStringProperty = stringPropertyKeys.includes(key); - if (isStringProperty) { - return `${key}: "${value}"`; - } - - return `${key}: ${value}`; - }) - .join("\n"); - - const devSection = - connector.implementsWarehouse && - connector.name !== "redshift" && - typeof formValues.sql === "string" && - formValues.sql.trim() - ? `\n\ndev:\n ${formatSqlBlock( - `${trimSqlForDev(formValues.sql)} limit 10000`, - " ", - )}` - : ""; - - // Use connector instance name if provided, otherwise fall back to driver name - const connectorName = opts?.connectorInstanceName || connector.name; - - const driverName = opts?.originalDriverName || connector.name || "duckdb"; - return ( - `${sourceModelFileTop(driverName)}\n\nconnector: ${connectorName}\n\n` + - compiledKeyValues + - devSection - ); -} - export function compileLocalFileSourceYAML(path: string) { return `${sourceModelFileTop("local_file")}\n\nconnector: duckdb\nsql: "${buildDuckDbQuery(path)}"`; } @@ -202,134 +104,6 @@ export function getFileTypeFromPath(fileName) { return fileType; } -/** - * Convert applicable connectors to DuckDB. We do this to leverage DuckDB's native, - * well-documented file reading capabilities. - */ -export function maybeRewriteToDuckDb( - connector: V1ConnectorDriver, - formValues: Record, - options?: { connectorInstanceName?: string }, -): [V1ConnectorDriver, Record] { - // Create a copy of the connector, so that we don't overwrite the original - const connectorCopy = { ...connector }; - const connectorInstanceName = - options?.connectorInstanceName?.trim() || undefined; - const secretConnectorName = connectorInstanceName || connector.name || ""; - - switch (connector.name) { - case "s3": - case "gcs": - case "azure": - // Ensure DuckDB creates a temporary secret for the original connector. - if (secretConnectorName) { - if (connectorInstanceName) { - if (!formValues.create_secrets_from_connectors) { - formValues.create_secrets_from_connectors = secretConnectorName; - } - } else { - // When skipping connector creation, force the default driver name. - formValues.create_secrets_from_connectors = secretConnectorName; - } - } - // falls through to rewrite as DuckDB - case "local_file": - connectorCopy.name = "duckdb"; - - formValues.sql = buildDuckDbQuery(formValues.path as string); - delete formValues.path; - - break; - case "https": { - // HTTP sources are typically public; avoid surfacing secret wiring unless - // the user is explicitly targeting a configured connector instance. - if (connectorInstanceName && secretConnectorName) { - if (!formValues.create_secrets_from_connectors) { - formValues.create_secrets_from_connectors = secretConnectorName; - } - } - - connectorCopy.name = "duckdb"; - // Default to read_json for HTTPS URLs without a recognized file extension, - // since most HTTP endpoints return JSON responses. - formValues.sql = buildDuckDbQuery(formValues.path as string, { - defaultToJson: true, - }); - delete formValues.path; - - break; - } - case "sqlite": - connectorCopy.name = "duckdb"; - - formValues.sql = `SELECT * FROM sqlite_scan('${formValues.db as string}', '${ - formValues.table as string - }');`; - delete formValues.db; - delete formValues.table; - - break; - } - - return [connectorCopy, formValues]; -} - -/** - * Process form data for sources, including DuckDB rewrite logic and placeholder handling. - * This serves as a single source of truth for both preview and submission. - */ -export function prepareSourceFormData( - connector: V1ConnectorDriver, - formValues: Record, - options?: { connectorInstanceName?: string }, -): [V1ConnectorDriver, Record] { - // Create a copy of form values to avoid mutating the original - const processedValues = { ...formValues }; - - // Never carry connector auth selection into the source/model layer. - delete processedValues.auth_method; - - // Strip connector configuration keys from the source form values to prevent - // leaking connector-level fields (e.g., credentials) into the model file. - const schema = getConnectorSchema(connector.name ?? ""); - const connectorPropertyKeys = new Set(); - if (schema) { - const connectorFields = getSchemaFieldMetaList(schema, { - step: "connector", - }) - .filter((field) => !field.internal) - .map((field) => field.key); - for (const key of connectorFields) { - connectorPropertyKeys.add(key); - delete processedValues[key]; - } - } - - // Handle placeholder values for required source properties - // Skip connector fields - they're handled by the connector, not the model - if (schema) { - const sourceFields = getSchemaFieldMetaList(schema, { step: "source" }); - for (const field of sourceFields) { - // Don't fill placeholders for connector fields (even if they match source step) - if (connectorPropertyKeys.has(field.key)) continue; - if (field.required && !(field.key in processedValues)) { - if (field.placeholder) { - processedValues[field.key] = field.placeholder; - } - } - } - } - - // Apply DuckDB rewrite logic - const [rewrittenConnector, rewrittenFormValues] = maybeRewriteToDuckDb( - connector, - processedValues, - options, - ); - - return [rewrittenConnector, rewrittenFormValues]; -} - export function getFileExtension(source: V1Source): string { const path = String(source?.spec?.properties?.path).toLowerCase(); if (path?.includes(".csv")) return "CSV"; From 7b57e055d602cfceb5da6eb48ed8270238dd29a4 Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Fri, 20 Feb 2026 16:06:50 -0800 Subject: [PATCH 03/62] feat(runtime): complete GenerateTemplate RPC migration for HTTPS connector headers Add HTTPS headers support to the backend GenerateTemplate RPC, enabling removal of all client-side YAML generation code. The HTTPS connector now uses the same RPC path as all other connectors. Backend changes: - Add `headers` property to HTTPS driver ConfigProperties - Implement header rendering with sensitive value extraction to .env - Support Authorization header scheme prefixes (Bearer, Basic, Token, Bot) - Use `connector.{driver}.{key}` naming convention for header env vars - Add 4 comprehensive test cases for header handling Frontend changes: - Convert key-value UI arrays to maps before RPC submission - Remove HTTPS-specific YAML preview and submission code - All connectors now use GenerateTemplate RPC exclusively - Remove 13 dead functions (compileConnectorYAML, updateDotEnvWithSecrets, etc) - Consolidate env var naming to backend-only responsibility Schema cleanup: - Remove 30 dead `x-env-var-name` annotations (frontend no longer reads them) - Single source of truth for env var names: backend PropertySpec.EnvVarName Results: - -1,317 lines of dead code removed - +221 lines of backend implementation - 2,055 frontend tests pass, 62 backend tests pass (4 new HTTPS tests) --- ...-02-16-generate-template-api-brainstorm.md | 260 +++++ ...6-02-16-feat-generate-template-rpc-plan.md | 915 +++++++++++++++++ runtime/drivers/https/https.go | 8 + runtime/server/generate_template.go | 86 ++ runtime/server/generate_template_test.go | 135 +++ .../features/connectors/code-utils.spec.ts | 968 +----------------- .../src/features/connectors/code-utils.ts | 434 +------- .../sources/modal/AddDataFormManager.ts | 49 +- .../sources/modal/submitAddDataForm.ts | 162 +-- .../src/features/templates/schema-utils.ts | 30 +- .../src/features/templates/schemas/athena.ts | 2 - .../src/features/templates/schemas/azure.ts | 3 - .../features/templates/schemas/bigquery.ts | 1 - .../features/templates/schemas/clickhouse.ts | 2 - .../src/features/templates/schemas/druid.ts | 2 - .../src/features/templates/schemas/gcs.ts | 3 - .../features/templates/schemas/motherduck.ts | 1 - .../src/features/templates/schemas/mysql.ts | 2 - .../src/features/templates/schemas/pinot.ts | 2 - .../features/templates/schemas/postgres.ts | 2 - .../features/templates/schemas/redshift.ts | 2 - .../src/features/templates/schemas/s3.ts | 3 - .../features/templates/schemas/salesforce.ts | 2 - .../features/templates/schemas/snowflake.ts | 3 - .../src/features/templates/schemas/types.ts | 5 - 25 files changed, 1470 insertions(+), 1612 deletions(-) create mode 100644 docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md create mode 100644 docs/plans/2026-02-16-feat-generate-template-rpc-plan.md diff --git a/docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md b/docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md new file mode 100644 index 00000000000..f88010bf869 --- /dev/null +++ b/docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md @@ -0,0 +1,260 @@ +# Tech Design: YAML Generation — Imperative Functions vs. GenerateTemplate API + +**Date:** 2026-02-16 +**Status:** Brainstorm +**Author:** Cyrus Goh + +--- + +## Problem Statement + +The frontend has two imperative YAML builder functions — `compileSourceYAML()` and `compileConnectorYAML()` — that share overlapping logic but diverge in subtle ways. This creates: + +1. **Duplication:** Both functions handle secret extraction (`{{ .env.* }}` placeholders), string quoting, empty-value filtering, and property ordering — but with separate, slightly different implementations. +2. **Maintenance burden:** Adding a new connector or field type requires touching complex conditional logic with many special cases (ClickHouse `managed: false` exclusion, DuckDB SQL rewriting, HTTP header formatting, etc.). +3. **Frontend owns YAML format:** The frontend knows too much about what valid YAML looks like for each resource type. This knowledge should live closer to the backend, which actually parses and validates these files. + +### Current Architecture + +``` +Form Data → compileSourceYAML() / compileConnectorYAML() → YAML string → PutFile RPC → Backend + (imperative string builder) +``` + +**Key files:** +- `web-common/src/features/sources/sourceUtils.ts` — `compileSourceYAML()` (~90 lines) +- `web-common/src/features/connectors/code-utils.ts` — `compileConnectorYAML()` (~100 lines) +- `web-common/src/features/sources/modal/submitAddDataForm.ts` — primary caller +- `web-common/src/features/sources/modal/AddDataFormManager.ts` — YAML preview caller + +### Shared Logic (duplicated between the two functions) + +| Concern | compileSourceYAML | compileConnectorYAML | +|---------|-------------------|----------------------| +| YAML header with doc link | Yes | Yes | +| Secret → `{{ .env.VAR }}` | Yes | Yes | +| String property quoting | Yes | Yes | +| Empty value filtering | Yes | Yes | +| Env var name generation | Via `makeEnvVarKey()` | Via `makeEnvVarKey()` | +| SQL multi-line formatting | Yes | No | +| Headers map formatting | No | Yes | +| Property ordering | Implicit (object key order) | Explicit (orderedProperties) | +| Field filtering | Implicit (step-based) | Explicit (fieldFilter function) | +| Dev section | Yes (with Redshift exception) | No | + +--- + +## Approach A: Consolidate Imperative Functions (Frontend-Only Refactor) + +Merge `compileConnectorYAML` and `compileSourceYAML` into a unified `compileResourceYAML()` function that handles all resource types through configuration. + +### Design + +```typescript +interface ResourceYAMLOptions { + resourceType: "connector" | "source" | "model"; + driver: string; + formValues: Record; + orderedProperties?: ConnectorDriverProperty[]; + fieldFilter?: (property: ConnectorDriverProperty) => boolean; + secretKeys?: string[]; + stringKeys?: string[]; + connectorInstanceName?: string; + schema?: { properties?: Record }; + existingEnvBlob?: string; + includeDevSection?: boolean; + originalDriverName?: string; +} + +function compileResourceYAML(opts: ResourceYAMLOptions): string { + // Unified logic: + // 1. Generate header (type + driver + doc link) + // 2. Filter properties (by step, field filter, empty values) + // 3. Order properties (explicit or implicit) + // 4. Format each property: + // - Secrets → {{ .env.VAR }} + // - Strings → quoted + // - SQL → multi-line + // - Headers → YAML map + // - Default → raw value + // 5. Optional dev section + // 6. Return assembled YAML +} +``` + +### Migration Path + +1. Create `compileResourceYAML()` with all shared logic +2. Re-implement `compileSourceYAML()` and `compileConnectorYAML()` as thin wrappers +3. Gradually migrate callers to the unified function +4. Remove wrappers once all callers are migrated + +### Pros + +- No backend changes required +- Incremental, low-risk refactor +- Eliminates duplication between the two functions +- Can be done in a single PR + +### Cons + +- Frontend still owns YAML format knowledge — can drift from backend expectations +- Special cases keep accumulating as connectors are added +- Doesn't extend to other resource types (explores, dashboards, etc.) without growing the function +- YAML string building is inherently fragile (indentation, quoting, escaping) + +### Effort Estimate + +Small — 1-2 days of frontend work. + +--- + +## Approach B: Backend `GenerateTemplate` RPC (Recommended) + +New backend endpoint that accepts structured data and returns rendered YAML. The frontend becomes a thin form layer. + +### Design + +#### New RPC + +```protobuf +// GenerateTemplate renders a YAML file from structured input. +// Supports all resource types: connector, source, model, explore, dashboard, etc. +rpc GenerateTemplate(GenerateTemplateRequest) returns (GenerateTemplateResponse) { + option (google.api.http) = { + post: "/v1/instances/{instance_id}/generate/template", + body: "*" + }; +} + +message GenerateTemplateRequest { + string instance_id = 1; + // Resource type: "connector", "source", "model", "explore", "metrics_view", etc. + string resource_type = 2; + // Driver name (for connectors/sources): "clickhouse", "s3", "duckdb", etc. + string driver = 3; + // Structured key-value properties from the form + google.protobuf.Struct properties = 4; + // Optional: connector instance name (for sources that reference a connector) + string connector_name = 5; + // Optional: fields that should be treated as secrets (extracted to .env) + repeated string secret_keys = 6; +} + +message GenerateTemplateResponse { + // Rendered YAML blob, ready to write via PutFile + string blob = 1; + // Environment variables to write to .env (key → value) + map env_vars = 2; +} +``` + +#### New Architecture + +``` +Form Data → GenerateTemplate RPC → { blob, env_vars } → PutFile RPC (blob) + update .env (env_vars) + (backend) +``` + +#### Backend Implementation + +The backend would: +1. Look up a Go template for the given `resource_type` + `driver` combination +2. Apply structured properties to the template +3. Handle secret extraction: replace secret values with `{{ .env.VAR }}` and return the real values in `env_vars` +4. Return the rendered YAML blob + +Templates could be Go `text/template` files or a simple struct-to-YAML mapper using the `gopkg.in/yaml.v3` library. + +#### Frontend Changes + +```typescript +// Before (imperative) +const blob = compileConnectorYAML(connector, formValues, { ...options }); +await runtimeServicePutFile(instanceId, { path, blob, create: true }); +await updateDotEnvWithSecrets(instanceId, connector, formValues, options); + +// After (declarative) +const { blob, envVars } = await runtimeServiceGenerateTemplate(instanceId, { + resourceType: "connector", + driver: connector.name, + properties: formValues, + secretKeys: schemaSecretKeys, +}); +await runtimeServicePutFile(instanceId, { path, blob, create: true }); +await writeDotEnv(instanceId, envVars); +``` + +### Migration Path + +1. **Phase 1:** Implement `GenerateTemplate` RPC for connectors +2. **Phase 2:** Migrate `compileConnectorYAML()` callers to use the RPC +3. **Phase 3:** Add source/model support, migrate `compileSourceYAML()` callers +4. **Phase 4:** Extend to other resource types (explores, dashboards, etc.) +5. **Phase 5:** Remove frontend compile functions + +Each phase can be a separate PR. Old and new paths can coexist during migration. + +### Pros + +- Backend owns the canonical YAML format — single source of truth +- Frontend complexity drops dramatically — no YAML string building, quoting, or escaping +- Generalizes to all resource types (connectors, sources, models, explores, dashboards, APIs, canvases, themes, reports, alerts) +- Aligns with existing backend generation patterns (`GenerateMetricsViewFile`, `GenerateCanvas`, `GenerateResolver`) +- Secret handling can be co-located with template logic +- Backend can validate property completeness before rendering + +### Cons + +- Requires backend work (new RPC, template registry, tests) +- Larger scope — multi-phase migration across frontend and backend +- YAML preview in the form is lost (acceptable per discussion — not critical) +- Network round-trip for template rendering (acceptable — only on submit) +- Need to decide where templates live (Go code, embedded files, or database) + +### Effort Estimate + +Medium — 1-2 weeks across backend + frontend. + +--- + +## Open Questions + +1. **Secret handling ownership:** Should the backend fully own env var naming and `.env` file writes? Or should it just return `env_vars` and let the frontend write them? + - Option A: Backend returns `env_vars` map, frontend writes to `.env` (simpler, frontend already has this code) + - Option B: Backend writes `.env` directly as part of `GenerateTemplate` (cleaner, but couples template rendering with file I/O) + +2. **Template storage:** Where do the YAML templates live? + - Go struct-to-YAML mapping (type-safe, no template files) + - Embedded Go `text/template` files (flexible, easy to edit) + - Hardcoded strings in Go (simple, like current frontend approach but server-side) + +3. **DuckDB rewriting:** Currently `maybeRewriteToDuckDb()` transforms S3/GCS/HTTPS sources into DuckDB SQL. Should this logic move to the backend too, or stay as a frontend preprocessing step? + +4. **Connector property metadata:** The frontend schemas define `x-secret`, `x-string`, `x-env-var-name` extensions. Should the backend be the source of truth for these, or should the frontend continue to pass `secretKeys`/`stringKeys` in the request? + +5. **Backward compatibility:** Do we need to support both old (imperative) and new (RPC) paths simultaneously during migration? Or can we cut over all at once? + +--- + +## Recommendation + +**Approach B (Backend `GenerateTemplate` RPC)** is recommended because: + +- It addresses the root cause: the frontend shouldn't own YAML format knowledge +- It's a natural extension of existing backend patterns (`GenerateMetricsViewFile`, etc.) +- It generalizes to all resource types, not just connectors/sources +- The migration can be incremental (phase by phase) +- Loss of YAML preview is acceptable + +Approach A is a valid stopgap if backend bandwidth is limited, but it doesn't solve the fundamental problem of frontend-owned YAML format. + +--- + +## Key Decisions Made + +- **Motivation:** Duplication and maintenance burden in `compileSourceYAML`/`compileConnectorYAML` +- **Direction:** Backend RPC over frontend-only refactor +- **Scope:** All resource types (design wide), implement connectors/sources first +- **YAML Preview:** Can be dropped — not critical for users +- **Secret handling:** Open question to resolve during planning diff --git a/docs/plans/2026-02-16-feat-generate-template-rpc-plan.md b/docs/plans/2026-02-16-feat-generate-template-rpc-plan.md new file mode 100644 index 00000000000..723e0e47e37 --- /dev/null +++ b/docs/plans/2026-02-16-feat-generate-template-rpc-plan.md @@ -0,0 +1,915 @@ +--- +title: "feat: Backend GenerateTemplate RPC for declarative YAML generation" +type: feat +date: 2026-02-16 +--- + +# Backend GenerateTemplate RPC for Declarative YAML Generation + +## Overview + +Replace the frontend's imperative `compileSourceYAML()` and `compileConnectorYAML()` string-building functions with a backend `GenerateTemplate` RPC endpoint. The backend becomes the single source of truth for YAML file format, using driver `PropertySpec` metadata to render YAML from structured form data. This includes absorbing the `maybeRewriteToDuckDb()` logic — the backend uses `Spec.ImplementsObjectStore` / `ImplementsFileStore` to detect when a driver should be rewritten to a DuckDB model, builds the appropriate SQL query, and returns the rewritten resource type. Scoped to connectors and sources/models — skeleton resource YAML (explores, dashboards, etc.) remains as frontend constants. + +## Problem Statement + +The frontend has two imperative YAML builder functions that share overlapping logic but diverge in subtle ways: + +| Shared Concern | `compileSourceYAML` | `compileConnectorYAML` | +|---|---|---| +| YAML header + doc link | Yes | Yes | +| Secret -> `{{ .env.VAR }}` | Yes | Yes | +| String quoting | Yes | Yes | +| Empty value filtering | Yes | Yes | +| SQL multi-line formatting | Yes | No | +| Headers map formatting | No | Yes | +| Property ordering | Implicit | Explicit (`orderedProperties`) | +| Dev section | Yes (except Redshift) | No | + +**Pain points:** +1. **Duplication** — both functions reimplement secret handling, quoting, and value filtering +2. **Maintenance burden** — adding a new connector requires touching complex conditional logic with special cases (ClickHouse `managed: false`, DuckDB SQL rewriting, HTTP auth scheme splitting) +3. **Frontend owns format** — the frontend knows too much about what valid YAML looks like; this knowledge should live server-side +4. **Frontend owns driver rewriting** — `maybeRewriteToDuckDb()` makes resource-type decisions (connector → model) and driver decisions (s3 → duckdb) that belong server-side. The backend already has the signals it needs (`Spec.ImplementsObjectStore`, `Spec.ImplementsFileStore`) + +## Proposed Solution + +**Before:** +``` +Form Data -> compileSourceYAML() / compileConnectorYAML() -> YAML string -> PutFile RPC -> Backend + (imperative string builder) +``` + +**After:** +``` +Form Data -> GenerateTemplate RPC -> { blob, env_vars } -> PutFile RPC (blob) + merge .env (env_vars) + (backend) +``` + +## Technical Approach + +### Proto Definition + +```protobuf +rpc GenerateTemplate(GenerateTemplateRequest) returns (GenerateTemplateResponse) { + option (google.api.http) = { + post: "/v1/instances/{instance_id}/generate/template", + body: "*" + }; +} + +message GenerateTemplateRequest { + string instance_id = 1 [(validate.rules).string = {pattern: "^[_\\-a-zA-Z0-9]+$"}]; + string resource_type = 2 [(validate.rules).string = {in: ["connector", "model"]}]; + string driver = 3 [(validate.rules).string = {pattern: "^[a-z][a-z0-9_]*$"}]; + google.protobuf.Struct properties = 4; + string connector_name = 5; +} + +message GenerateTemplateResponse { + string blob = 1; + map env_vars = 2; + // Actual resource type used — may differ from request when driver is rewritten + // (e.g., s3 model request → duckdb model with SQL wrapping the s3 path) + string resource_type = 3; + // Actual driver used — may differ from request when rewritten to duckdb + string driver = 4; +} +``` + +`google.protobuf.Struct` matches existing codebase patterns (used in 11 places across `api.proto`). `resource_type` scoped to `"connector"` and `"model"` only. The response echoes the actual `resource_type` and `driver` used after any rewrites, so the frontend knows the correct file path and directory. + +### Backend Handler + +New file: `runtime/server/generate_template.go` + +```go +func (s *Server) GenerateTemplate(ctx context.Context, req *runtimev1.GenerateTemplateRequest) (*runtimev1.GenerateTemplateResponse, error) { + // 1. Permission check + if !auth.GetClaims(ctx, req.InstanceId).Can(runtime.EditRepo) { + return nil, ErrForbidden + } + + // 2. Validate driver exists + driver, ok := drivers.Connectors[req.Driver] + if !ok { + return nil, status.Errorf(codes.InvalidArgument, "unknown driver: %s", req.Driver) + } + spec := driver.Spec() + + // 3. Validate properties against original driver spec (reject unknown keys) + props := req.Properties.AsMap() + if err := validateProperties(spec, req.ResourceType, props); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "%s", err) + } + + // 4. DuckDB rewrite for object store / file store / sqlite drivers + // Rewrite happens AFTER validation against the original driver spec, + // since the request properties match the original driver (e.g., s3's "path"). + actualDriver, actualResourceType := req.Driver, req.ResourceType + if req.ResourceType == "model" { + actualDriver, props = maybeRewriteToDuckDB(spec, req.Driver, props, req.ConnectorName) + } + + // 5. Read existing .env for env var conflict resolution + repo, release, err := s.runtime.Repo(ctx, req.InstanceId) + if err != nil { + return nil, err + } + defer release() + existingEnv := readEnvKeys(repo, ctx) + + // 6. Render YAML + extract secrets (using rewritten driver/props) + blob, envVars := renderYAML(spec, actualDriver, actualResourceType, props, existingEnv) + + return &runtimev1.GenerateTemplateResponse{ + Blob: blob, + EnvVars: envVars, + ResourceType: actualResourceType, + Driver: actualDriver, + }, nil +} +``` + +The handler reads `.env` via `repo.Get()` rather than accepting it as a request field. This eliminates sending ALL project secrets over the wire and removes the TOCTOU race between frontend read and backend use. + +### YAML Rendering Engine + +The backend renders YAML using the driver's `PropertySpec` metadata: + +1. **Property ordering**: Use `ConfigProperties` / `SourceProperties` order from the driver `Spec` +2. **Secret detection**: Use `PropertySpec.Secret` (backend is source of truth) +3. **Env var naming**: Use new `PropertySpec.EnvVarName` field (falls back to `DRIVER_KEY` format) +4. **String quoting**: Use `PropertySpec.Type == StringPropertyType` +5. **Value filtering**: Skip empty/nil values, skip properties not in request +6. **Property validation**: Reject unknown property keys not in driver's `PropertySpec` +7. **Header comment**: Generate `# Connector YAML\n# Reference documentation: ` +8. **Dev section**: Auto-generate for warehouse drivers (except Redshift) with `limit 10000` + +Build the `yaml.Node` tree directly rather than the marshal-unmarshal-encode triple-pass used in `generate_metrics_view.go:549-582`: + +```go +func buildConnectorYAML(spec drivers.Spec, driverName string, props map[string]any, envVarMap map[string]string) *yaml.Node { + doc := &yaml.Node{Kind: yaml.DocumentNode} + mapping := &yaml.Node{Kind: yaml.MappingNode} + mapping.HeadComment = fmt.Sprintf("Connector YAML\nReference documentation: %s", spec.DocsURL) + + addScalarPair(mapping, "type", "connector") + addScalarPair(mapping, "driver", driverName) + + for _, propSpec := range spec.ConfigProperties { + val, ok := props[propSpec.Key] + if !ok || isEmpty(val) { + continue + } + if propSpec.Secret { + addScalarPair(mapping, propSpec.Key, fmt.Sprintf("{{ .env.%s }}", envVarMap[propSpec.Key])) + } else if propSpec.Type == drivers.StringPropertyType { + addQuotedPair(mapping, propSpec.Key, fmt.Sprintf("%v", val)) + } else { + addScalarPair(mapping, propSpec.Key, fmt.Sprintf("%v", val)) + } + } + + doc.Content = append(doc.Content, mapping) + return doc +} + +func addScalarPair(m *yaml.Node, key, value string) { + m.Content = append(m.Content, + &yaml.Node{Kind: yaml.ScalarNode, Value: key}, + &yaml.Node{Kind: yaml.ScalarNode, Value: value}, + ) +} + +func addQuotedPair(m *yaml.Node, key, value string) { + m.Content = append(m.Content, + &yaml.Node{Kind: yaml.ScalarNode, Value: key}, + &yaml.Node{Kind: yaml.ScalarNode, Value: value, Style: yaml.DoubleQuotedStyle}, + ) +} + +func validateProperties(spec drivers.Spec, resourceType string, properties map[string]any) error { + allowed := make(map[string]bool) + props := spec.ConfigProperties + if resourceType == "model" { + props = spec.SourceProperties + } + for _, p := range props { + allowed[p.Key] = true + } + for key := range properties { + if !allowed[key] { + return fmt.Errorf("unknown property %q for driver", key) + } + } + return nil +} +``` + +### Key Design Decisions + +#### 1. DuckDB Rewrite Moves to Backend + +`maybeRewriteToDuckDb()` transforms S3/GCS/Azure/HTTPS/SQLite/local_file into DuckDB model files. This logic moves to the backend because: + +- The backend already has the signals: `Spec.ImplementsObjectStore` (s3, gcs, azure), `Spec.ImplementsFileStore` (https, local_file), and driver name (`sqlite`) +- The rewrite is a resource-type decision that the backend should own +- The `buildDuckDbQuery()` file-extension → read function mapping is ~20 lines of Go +- The `create_secrets_from_connectors` wiring is ~5 lines + +The frontend sends the **original** driver and properties (e.g., `driver: "s3"`, `properties: {path: "s3://bucket/file.parquet"}`). The backend detects the rewrite case, builds the DuckDB SQL, and returns the actual driver/resource_type used in the response so the frontend knows the correct file path. + +```go +func maybeRewriteToDuckDB(spec drivers.Spec, driverName string, props map[string]any, connectorName string) (string, map[string]any) { + if !spec.ImplementsObjectStore && !spec.ImplementsFileStore && driverName != "sqlite" { + return driverName, props + } + + rewritten := make(map[string]any, len(props)) + for k, v := range props { + rewritten[k] = v + } + + switch { + case spec.ImplementsObjectStore: // s3, gcs, azure + if connectorName != "" { + rewritten["create_secrets_from_connectors"] = connectorName + } + rewritten["sql"] = buildDuckDBQuery(strVal(props["path"]), false) + delete(rewritten, "path") + + case spec.ImplementsFileStore && driverName == "https": + if connectorName != "" { + rewritten["create_secrets_from_connectors"] = connectorName + } + rewritten["sql"] = buildDuckDBQuery(strVal(props["path"]), true) + delete(rewritten, "path") + + case spec.ImplementsFileStore: // local_file + rewritten["sql"] = buildDuckDBQuery(strVal(props["path"]), false) + delete(rewritten, "path") + + case driverName == "sqlite": + rewritten["sql"] = fmt.Sprintf("SELECT * FROM sqlite_scan('%s', '%s');", + strVal(props["db"]), strVal(props["table"])) + delete(rewritten, "db") + delete(rewritten, "table") + } + + return "duckdb", rewritten +} + +func buildDuckDBQuery(path string, defaultToJSON bool) string { + ext := strings.ToLower(filepath.Ext(path)) + switch { + case containsExt(ext, ".csv", ".tsv", ".txt"): + return fmt.Sprintf("select * from read_csv('%s', auto_detect=true, ignore_errors=1, header=true)", path) + case containsExt(ext, ".parquet"): + return fmt.Sprintf("select * from read_parquet('%s')", path) + case containsExt(ext, ".json", ".ndjson"): + return fmt.Sprintf("select * from read_json('%s', auto_detect=true, format='auto')", path) + default: + if defaultToJSON { + return fmt.Sprintf("select * from read_json('%s', auto_detect=true, format='auto')", path) + } + return fmt.Sprintf("select * from '%s'", path) + } +} +``` + +Note: `containsExt` checks if the full extension (e.g., `.v1.parquet.gz`) contains the target part, matching the current frontend behavior of `extensionContainsParts()`. + +#### 2. Backend Is Source of Truth for Secrets + +Backend uses `PropertySpec.Secret` to identify secrets. No `secret_keys` in the request. Automated Go test asserts Secret flags match expected values for all drivers before shipping. + +#### 3. Env Var Naming Uses New `EnvVarName` Field + +Add `EnvVarName string` to `PropertySpec`. When set, use it (e.g., S3's `aws_access_key_id` -> `AWS_ACCESS_KEY_ID`). When empty, fall back to `DRIVER_KEY` format. Must match current frontend naming exactly or existing `.env` files break on upgrade. + +#### 4. Backend Reads `.env` Directly + +Backend reads `.env` via `repo.Get()` and parses key names into a `map[string]bool` for O(1) conflict detection. Response `env_vars` is a delta. Frontend merges with existing `.env` using `replaceOrAddEnvVariable()`. + +#### 5. Frontend Strips x-ui-only Fields + +Fields like `deployment_type`, `connection_mode`, `auth_method` are stripped before calling `GenerateTemplate`. Backend validates and rejects unknown keys. Postgres DSN-vs-parameters tabs are handled by `filterSchemaValuesForSubmit()`. + +#### 6. `GenerateTemplate` Does Not Write Files + +Returns blob + env_vars. Frontend calls `PutFile` separately. This enables rollback (restore original `.env` on reconciliation failure) and the "Save Anyway" bypass flow. + +#### 7. No Backward Compatibility Fallback + +Runtime deploys before UI. No catch-UNIMPLEMENTED fallback needed. Old frontend compile functions are removed immediately after migration. + +### Implementation + +**Scope:** All connectors (including HTTPS), all sources/models, and cleanup — shipped as one unit. + +**Backend tasks:** +- [ ] Add `EnvVarName string` field to `PropertySpec` in `runtime/drivers/connectors.go` +- [ ] Add `EnvVarName` values to drivers with custom env var names (S3, GCS, BigQuery, etc.) +- [ ] Write automated Go test asserting `PropertySpec.Secret` matches expected values for all drivers; fix discrepancies +- [ ] Define `GenerateTemplateRequest`/`GenerateTemplateResponse` in `proto/rill/runtime/v1/api.proto` with validation annotations +- [ ] Run `buf generate` to regenerate Go and TypeScript proto bindings +- [ ] Implement `GenerateTemplate` handler in `runtime/server/generate_template.go` + - Permission check (`EditRepo`) + - Driver validation (must exist in `drivers.Connectors`) + - Property validation (reject unknown keys) + - `.env` read via `repo.Get()` for conflict resolution + - YAML rendering via `yaml.Node` direct construction + - Secret -> `{{ .env.VAR }}` replacement using `PropertySpec.Secret` + - Env var naming from `PropertySpec.EnvVarName` with conflict suffix + - Header comment with driver `DocsURL` + - Value filtering (empty/nil) + - String quoting for `StringPropertyType` + - ClickHouse: exclude `managed: false` when default + - Redshift: skip dev section + - Model type: `type: model`, `materialize: true`, `connector:`, `sql:`, dev section + - HTTPS headers: `formatHeadersAsYamlMap()` equivalent with auth-scheme splitting + - DuckDB rewrite: detect `ImplementsObjectStore`/`ImplementsFileStore`/sqlite, build SQL from path + file extension, set `create_secrets_from_connectors` + - Return actual `resource_type` and `driver` in response (may differ from request after rewrite) +- [ ] Write Go unit tests (see Testing Strategy below) +- [ ] Never include property values or env var values in error messages + +**Frontend tasks:** +- [ ] Update `submitAddDataForm.ts` to call `GenerateTemplate` for all connectors +- [ ] Update `submitAddDataForm.ts` to call `GenerateTemplate` for source/model creation (send original driver + properties, no preprocessing) +- [ ] Use response `resource_type` and `driver` to determine file path (replaces frontend rewrite logic for path calculation) +- [ ] Strip `x-ui-only` fields from form values before sending (using `filterSchemaValuesForSubmit()`) +- [ ] Update `.env` merge logic to use `env_vars` response delta +- [ ] Remove `compileConnectorYAML()` and `compileSourceYAML()` (dead code) +- [ ] Remove `maybeRewriteToDuckDb()`, `buildDuckDbQuery()`, `extensionContainsParts()`, `prepareSourceFormData()` (dead code) +- [ ] Remove `updateDotEnvWithSecrets()`, `makeEnvVarKey()`, `findAvailableEnvVarName()`, `getGenericEnvVarName()` (dead code) + +**Success criteria:** +- [ ] Creating any connector via the form produces identical YAML as before +- [ ] Creating any source/model via the form produces identical YAML as before +- [ ] S3/GCS/Azure/HTTPS/local_file/SQLite sources are correctly rewritten to DuckDB models with proper SQL +- [ ] `create_secrets_from_connectors` is set correctly for object store and HTTPS sources +- [ ] `.env` file is correctly updated with secrets +- [ ] All auth method variants work (S3 access_keys vs public, ClickHouse parameters vs DSN, etc.) +- [ ] HTTPS headers with sensitive auth tokens correctly extracted to `.env` +- [ ] Zero frontend YAML string building or driver rewriting remains + +### Testing Strategy + +New file: `runtime/server/generate_template_test.go` + +Tests follow the codebase's existing pattern: table-driven tests using `testruntime.NewInstanceWithOptions()` and `server.NewServer()`, with `require.Contains()` / `require.Equal()` assertions on YAML output. + +Note: The frontend functions being replaced (`compileSourceYAML`, `compileConnectorYAML`, `maybeRewriteToDuckDb`, `buildDuckDbQuery`) have **zero direct unit tests**. Only env var helpers are tested. The backend tests here are net-new coverage — there is no existing frontend test output to port. + +#### Test 1: PropertySpec.Secret Flag Assertion + +Automated test that asserts `PropertySpec.Secret` matches expected values for every registered driver. Catches drift between backend metadata and frontend `x-secret` annotations. + +```go +func TestPropertySpecSecretFlags(t *testing.T) { + // Expected secret keys per driver, derived from frontend x-secret annotations + expected := map[string][]string{ + "s3": {"aws_access_key_id", "aws_secret_access_key", "aws_role_arn", "aws_role_session_name", "aws_external_id"}, + "gcs": {"google_application_credentials", "key_id", "secret"}, + "azure": {"azure_storage_account", "azure_storage_key", "azure_storage_sas_token", "azure_storage_connection_string"}, + "clickhouse": {"dsn", "password", "write_dsn"}, + "postgres": {"dsn", "password"}, + "bigquery": {"google_application_credentials"}, + "snowflake": {"dsn", "password", "privateKey"}, + "redshift": {"aws_access_key_id", "aws_secret_access_key"}, + "motherduck": {"token"}, + "athena": {"aws_access_key_id", "aws_secret_access_key"}, + "mysql": {"dsn", "password"}, + "druid": {"dsn", "password"}, + "pinot": {"dsn", "password"}, + "starrocks": {"dsn", "password"}, + "salesforce": {"password", "key"}, + } + + for driverName, driver := range drivers.Connectors { + spec := driver.Spec() + expectedKeys, ok := expected[driverName] + if !ok { + continue // AI/notifier drivers not relevant to GenerateTemplate + } + actualSecrets := secretKeys(spec.ConfigProperties) + require.ElementsMatch(t, expectedKeys, actualSecrets, "driver %s", driverName) + } +} +``` + +#### Test 2: Connector YAML Rendering (Table-Driven) + +One test case per driver, covering the most common form submission for each. Validates the full YAML blob output. + +```go +func TestBuildConnectorYAML(t *testing.T) { + tt := []struct { + name string + driver string + props map[string]any + contains []string // key substrings that must appear in output + excludes []string // substrings that must NOT appear + }{ + { + name: "clickhouse with parameters", + driver: "clickhouse", + props: map[string]any{"host": "ch.example.com", "port": "9000", "password": "secret123"}, + contains: []string{ + "type: connector", + "driver: clickhouse", + `host: "ch.example.com"`, + "port: 9000", + `password: "{{ .env.CLICKHOUSE_PASSWORD }}"`, + "# Connector YAML", + "Reference documentation: https://docs.rilldata.com", + }, + excludes: []string{"secret123"}, // actual secret value must never appear + }, + { + name: "clickhouse with dsn", + driver: "clickhouse", + props: map[string]any{"dsn": "clickhouse://user:pass@host:9000/db"}, + contains: []string{ + `dsn: "{{ .env.CLICKHOUSE_DSN }}"`, + }, + excludes: []string{"clickhouse://user:pass"}, + }, + { + name: "s3 connector", + driver: "s3", + props: map[string]any{"aws_access_key_id": "AKIA...", "aws_secret_access_key": "secret"}, + contains: []string{ + "driver: s3", + `aws_access_key_id: "{{ .env.AWS_ACCESS_KEY_ID }}"`, + `aws_secret_access_key: "{{ .env.AWS_SECRET_ACCESS_KEY }}"`, + }, + excludes: []string{"AKIA", "secret"}, + }, + { + name: "bigquery connector", + driver: "bigquery", + props: map[string]any{"project_id": "my-project", "google_application_credentials": `{"type":"service_account"}`}, + contains: []string{ + "driver: bigquery", + `project_id: "my-project"`, + `google_application_credentials: "{{ .env.GOOGLE_APPLICATION_CREDENTIALS }}"`, + }, + }, + { + name: "postgres with individual params", + driver: "postgres", + props: map[string]any{"host": "db.example.com", "port": "5432", "password": "pass"}, + contains: []string{ + "driver: postgres", + `host: "db.example.com"`, + `password: "{{ .env.POSTGRES_PASSWORD }}"`, + }, + }, + { + name: "empty values filtered", + driver: "clickhouse", + props: map[string]any{"host": "ch.example.com", "port": "", "database": ""}, + contains: []string{"host:"}, + excludes: []string{"port:", "database:"}, + }, + { + name: "clickhouse managed false excluded when default", + driver: "clickhouse", + props: map[string]any{"host": "ch.example.com", "managed": false}, + excludes: []string{"managed"}, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + // ... render and assert + }) + } +} +``` + +**Drivers to cover:** clickhouse (params + DSN), postgres (params + DSN), s3, gcs, azure, bigquery, snowflake, redshift, athena, motherduck, duckdb, druid, pinot, starrocks, mysql, salesforce. That's 16 drivers × 1-2 variants each. + +#### Test 3: Model YAML Rendering (Table-Driven) + +Validates model output including `type: model`, `materialize: true`, `connector:`, SQL formatting, and dev section. + +```go +func TestBuildModelYAML(t *testing.T) { + tt := []struct { + name string + driver string + props map[string]any + connName string + contains []string + excludes []string + }{ + { + name: "clickhouse model with dev section", + driver: "clickhouse", + props: map[string]any{"sql": "SELECT * FROM events"}, + connName: "clickhouse_prod", + contains: []string{ + "type: model", + "materialize: true", + "connector: clickhouse_prod", + "sql: |", + " SELECT * FROM events", + "dev:", + "limit 10000", + "# Model YAML", + }, + }, + { + name: "redshift model without dev section", + driver: "redshift", + props: map[string]any{"sql": "SELECT * FROM events"}, + connName: "redshift_prod", + contains: []string{"type: model", "connector: redshift_prod"}, + excludes: []string{"dev:"}, + }, + { + name: "bigquery model with dev section", + driver: "bigquery", + props: map[string]any{"sql": "SELECT * FROM `project.dataset.table`"}, + connName: "bq_prod", + contains: []string{"dev:", "limit 10000"}, + }, + } + // ... +} +``` + +#### Test 4: DuckDB Rewrite (Table-Driven) + +Tests `maybeRewriteToDuckDB` and `buildDuckDBQuery` — the logic moving from frontend. + +```go +func TestMaybeRewriteToDuckDB(t *testing.T) { + tt := []struct { + name string + driver string + props map[string]any + connectorName string + wantDriver string + wantSQL string + wantSecrets string // expected create_secrets_from_connectors value + wantDeleted []string // keys that should be removed from props + }{ + // Object store drivers + { + name: "s3 csv", + driver: "s3", + props: map[string]any{"path": "s3://bucket/data.csv"}, + connectorName: "my_s3", + wantDriver: "duckdb", + wantSQL: "select * from read_csv('s3://bucket/data.csv', auto_detect=true, ignore_errors=1, header=true)", + wantSecrets: "my_s3", + wantDeleted: []string{"path"}, + }, + { + name: "s3 parquet", + driver: "s3", + props: map[string]any{"path": "s3://bucket/data.parquet"}, + wantDriver: "duckdb", + wantSQL: "select * from read_parquet('s3://bucket/data.parquet')", + }, + { + name: "s3 compressed parquet", + driver: "s3", + props: map[string]any{"path": "s3://bucket/data.v1.parquet.gz"}, + wantDriver: "duckdb", + wantSQL: "select * from read_parquet('s3://bucket/data.v1.parquet.gz')", + }, + { + name: "gcs json", + driver: "gcs", + props: map[string]any{"path": "gs://bucket/data.json"}, + wantDriver: "duckdb", + wantSQL: "select * from read_json('gs://bucket/data.json', auto_detect=true, format='auto')", + }, + { + name: "gcs ndjson", + driver: "gcs", + props: map[string]any{"path": "gs://bucket/data.ndjson"}, + wantDriver: "duckdb", + wantSQL: "select * from read_json('gs://bucket/data.ndjson', auto_detect=true, format='auto')", + }, + { + name: "azure tsv", + driver: "azure", + props: map[string]any{"path": "azure://container/data.tsv"}, + wantDriver: "duckdb", + wantSQL: "select * from read_csv('azure://container/data.tsv', auto_detect=true, ignore_errors=1, header=true)", + }, + { + name: "s3 unknown extension falls through", + driver: "s3", + props: map[string]any{"path": "s3://bucket/data.avro"}, + wantDriver: "duckdb", + wantSQL: "select * from 's3://bucket/data.avro'", + }, + + // File store drivers + { + name: "https defaults to json", + driver: "https", + props: map[string]any{"path": "https://api.example.com/data"}, + wantDriver: "duckdb", + wantSQL: "select * from read_json('https://api.example.com/data', auto_detect=true, format='auto')", + }, + { + name: "https with csv extension", + driver: "https", + props: map[string]any{"path": "https://example.com/data.csv"}, + wantDriver: "duckdb", + wantSQL: "select * from read_csv('https://example.com/data.csv', auto_detect=true, ignore_errors=1, header=true)", + }, + { + name: "https with connector name sets secrets", + driver: "https", + props: map[string]any{"path": "https://api.example.com/data"}, + connectorName: "my_http", + wantSecrets: "my_http", + }, + { + name: "local_file csv", + driver: "local_file", + props: map[string]any{"path": "/data/file.csv"}, + wantDriver: "duckdb", + wantSQL: "select * from read_csv('/data/file.csv', auto_detect=true, ignore_errors=1, header=true)", + wantSecrets: "", // no create_secrets_from_connectors for local_file + }, + + // SQLite + { + name: "sqlite", + driver: "sqlite", + props: map[string]any{"db": "/data/app.db", "table": "users"}, + wantDriver: "duckdb", + wantSQL: "SELECT * FROM sqlite_scan('/data/app.db', 'users');", + wantDeleted: []string{"db", "table"}, + }, + + // Non-rewritable drivers pass through + { + name: "clickhouse not rewritten", + driver: "clickhouse", + props: map[string]any{"sql": "SELECT 1"}, + wantDriver: "clickhouse", + }, + { + name: "postgres not rewritten", + driver: "postgres", + props: map[string]any{"sql": "SELECT 1"}, + wantDriver: "postgres", + }, + } + // ... +} +``` + +#### Test 5: Env Var Naming and Conflict Resolution + +Tests the `EnvVarName` field and `_1`, `_2` suffix logic. Mirrors the 48 frontend test cases in `code-utils.spec.ts`. + +```go +func TestEnvVarNaming(t *testing.T) { + tt := []struct { + name string + driver string + propKey string + envVarName string // PropertySpec.EnvVarName override + existingEnv map[string]bool + want string + }{ + // Schema-driven names (EnvVarName set) + {name: "s3 access key", driver: "s3", propKey: "aws_access_key_id", envVarName: "AWS_ACCESS_KEY_ID", want: "AWS_ACCESS_KEY_ID"}, + {name: "bigquery creds", driver: "bigquery", propKey: "google_application_credentials", envVarName: "GOOGLE_APPLICATION_CREDENTIALS", want: "GOOGLE_APPLICATION_CREDENTIALS"}, + {name: "motherduck token", driver: "motherduck", propKey: "token", envVarName: "MOTHERDUCK_TOKEN", want: "MOTHERDUCK_TOKEN"}, + {name: "clickhouse password", driver: "clickhouse", propKey: "password", envVarName: "CLICKHOUSE_PASSWORD", want: "CLICKHOUSE_PASSWORD"}, + + // Fallback naming (EnvVarName empty) → DRIVER_KEY format + {name: "fallback format", driver: "custom", propKey: "api_token", want: "CUSTOM_API_TOKEN"}, + + // Conflict resolution + {name: "first conflict", driver: "bigquery", propKey: "google_application_credentials", envVarName: "GOOGLE_APPLICATION_CREDENTIALS", + existingEnv: map[string]bool{"GOOGLE_APPLICATION_CREDENTIALS": true}, + want: "GOOGLE_APPLICATION_CREDENTIALS_1"}, + {name: "second conflict", driver: "bigquery", propKey: "google_application_credentials", envVarName: "GOOGLE_APPLICATION_CREDENTIALS", + existingEnv: map[string]bool{"GOOGLE_APPLICATION_CREDENTIALS": true, "GOOGLE_APPLICATION_CREDENTIALS_1": true}, + want: "GOOGLE_APPLICATION_CREDENTIALS_2"}, + {name: "multi-key conflict (s3)", driver: "s3", propKey: "aws_access_key_id", envVarName: "AWS_ACCESS_KEY_ID", + existingEnv: map[string]bool{"AWS_ACCESS_KEY_ID": true}, + want: "AWS_ACCESS_KEY_ID_1"}, + } + // ... +} +``` + +#### Test 6: Property Validation + +```go +func TestValidateProperties(t *testing.T) { + tt := []struct { + name string + driver string + resourceType string + props map[string]any + wantErr string + }{ + {name: "valid connector props", driver: "clickhouse", resourceType: "connector", props: map[string]any{"host": "x"}, wantErr: ""}, + {name: "unknown prop rejected", driver: "clickhouse", resourceType: "connector", props: map[string]any{"bogus": "x"}, wantErr: `unknown property "bogus"`}, + {name: "source prop on connector rejected", driver: "duckdb", resourceType: "connector", props: map[string]any{"sql": "SELECT 1"}, wantErr: `unknown property "sql"`}, + {name: "source prop on model accepted", driver: "duckdb", resourceType: "model", props: map[string]any{"sql": "SELECT 1"}, wantErr: ""}, + } + // ... +} +``` + +#### Test 7: Handler Integration Test + +End-to-end test through the RPC handler, using the same test infrastructure as `generate_metrics_view_test.go`. + +```go +func TestGenerateTemplate(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{"rill.yaml": ""}, + }) + server, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + tt := []struct { + name string + req *runtimev1.GenerateTemplateRequest + wantContains []string + wantEnvVars map[string]string + wantDriver string // response driver (after rewrite) + wantResType string // response resource_type + wantErr codes.Code + }{ + { + name: "clickhouse connector", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: structpb("host", "ch.example.com", "password", "secret123"), + }, + wantContains: []string{"type: connector", "driver: clickhouse", `{{ .env.CLICKHOUSE_PASSWORD }}`}, + wantEnvVars: map[string]string{"CLICKHOUSE_PASSWORD": "secret123"}, + wantDriver: "clickhouse", + wantResType: "connector", + }, + { + name: "s3 model rewritten to duckdb", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "model", + Driver: "s3", + Properties: structpb("path", "s3://bucket/data.parquet"), + ConnectorName: "my_s3", + }, + wantContains: []string{"type: model", "connector: duckdb", "read_parquet", "create_secrets_from_connectors: my_s3"}, + wantDriver: "duckdb", + wantResType: "model", + }, + { + name: "unknown driver rejected", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "nonexistent", + Properties: structpb(), + }, + wantErr: codes.InvalidArgument, + }, + { + name: "unknown property rejected", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: structpb("bogus_key", "value"), + }, + wantErr: codes.InvalidArgument, + }, + { + name: "secret values never in error messages", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: structpb("bogus_key", "super_secret_value"), + }, + wantErr: codes.InvalidArgument, + // Additionally assert: !strings.Contains(err.Error(), "super_secret_value") + }, + } + // ... +} +``` + +#### Test 8: Env Var Conflict With Existing `.env` + +Tests that the handler reads existing `.env` via `repo.Get()` and resolves conflicts correctly. + +```go +func TestGenerateTemplateEnvConflict(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": "", + ".env": "CLICKHOUSE_PASSWORD=old_value\n", + }, + }) + // ... call GenerateTemplate with clickhouse password + // Assert env_vars returns CLICKHOUSE_PASSWORD_1 (not CLICKHOUSE_PASSWORD) +} +``` + +#### Test Matrix Summary + +| Test | What it validates | Cases | +|---|---|---| +| PropertySpec.Secret flags | Backend secret metadata matches frontend | 15 drivers | +| Connector YAML rendering | Full connector YAML output per driver | ~20 cases (16 drivers × 1-2 variants) | +| Model YAML rendering | Model output with dev section, SQL formatting | ~8 cases (warehouse drivers + DuckDB) | +| DuckDB rewrite | Driver/property transformation for object/file stores | ~15 cases (6 drivers × extension variants) | +| Env var naming | EnvVarName field, fallback format, conflict suffixes | ~10 cases | +| Property validation | Reject unknown keys, accept valid keys | ~5 cases | +| Handler integration | End-to-end RPC with test runtime | ~8 cases | +| Env conflict resolution | `.env` read + suffix logic | ~3 cases | + +**Total: ~85 test cases** in `runtime/server/generate_template_test.go`. + +## Alternative Approach Considered + +### Consolidate Frontend Functions Only + +Merge `compileConnectorYAML` and `compileSourceYAML` into a unified `compileResourceYAML()` on the frontend. + +**Why rejected:** Doesn't solve the root problem (frontend owns YAML format knowledge), special cases keep accumulating, YAML string building is inherently fragile. + +**When to reconsider:** If backend bandwidth is severely limited and we need a quick win. + +## Acceptance Criteria + +### Functional Requirements + +- [ ] `GenerateTemplate` RPC produces valid YAML for all connectors and sources/models +- [ ] Output matches current frontend output for all connectors (verified by golden file tests) +- [ ] Object store drivers (s3, gcs, azure), file store drivers (https, local_file), and sqlite are rewritten to DuckDB models with correct SQL +- [ ] File extension → DuckDB read function mapping matches current frontend behavior (csv/tsv/txt → `read_csv`, parquet → `read_parquet`, json/ndjson → `read_json`, HTTPS default → `read_json`) +- [ ] Response `resource_type` and `driver` reflect actual values after rewrite +- [ ] Secret values replaced with `{{ .env.VAR }}` placeholders +- [ ] Env var names match current naming (including `EnvVarName` overrides) +- [ ] Env var conflicts resolved with `_1`, `_2`, etc. suffixes +- [ ] Unknown property keys rejected with `InvalidArgument` + +### Quality Gates + +- [ ] ~85 Go unit tests across 8 test categories (see Testing Strategy) +- [ ] `TestPropertySpecSecretFlags` passes for all 15 drivers +- [ ] `TestBuildConnectorYAML` covers all 16 form-relevant drivers +- [ ] `TestMaybeRewriteToDuckDB` covers all 6 rewritable drivers × file extension variants +- [ ] `TestGenerateTemplate` integration tests pass through full RPC handler +- [ ] Proto definitions pass `buf lint` +- [ ] No regression in existing connector creation flows +- [ ] Error messages never contain property values or secret data + +## Dependencies & Prerequisites + +- **Backend PropertySpec updates** — `EnvVarName` field and automated Secret flag test must be done before handler implementation +- **Proto generation pipeline** — `buf generate` must produce updated TypeScript bindings before frontend migration +- **Version rollout** — runtime deploys before UI; no backward-compatibility fallback needed + +## Risk Analysis & Mitigation + +| Risk | Severity | Mitigation | +|---|---|---| +| YAML output differs subtly from frontend | High | Golden file tests for every driver | +| Backend `PropertySpec.Secret` doesn't match frontend `x-secret` | High | Automated Go test asserting Secret flags | +| Env var naming changes break existing `.env` files | High | `EnvVarName` field matches exact current naming; test against real `.env` files | +| Dual-metadata divergence (PropertySpec vs frontend JSON Schemas) | Medium | Pre-ship audit; long-term: generate frontend schemas from PropertySpec | +| DuckDB rewrite SQL differs from frontend | High | Golden file tests for every rewritable driver (s3, gcs, azure, https, local_file, sqlite) with each file extension | +| TOCTOU race in `.env` (concurrent connector creations) | Medium | Backend reads `.env` directly; future: atomic read-modify-write | + +## Technical Debt + +1. **Dual-metadata problem:** `PropertySpec` (Go) and frontend JSON Schemas (TypeScript) describe overlapping property metadata. Generate frontend schemas from `PropertySpec` to eliminate this divergence. +2. **File path generation stays in frontend:** `getName()` and `getFileAPIPathFromNameAndType()` remain frontend-owned. Could eventually use response `driver` to infer path server-side. +3. **`rill.yaml` OLAP connector update stays in frontend:** Orchestration, not template rendering. + +## References + +- Brainstorm: `docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md` +- Frontend YAML builders: `web-common/src/features/sources/sourceUtils.ts:24-113`, `web-common/src/features/connectors/code-utils.ts:158-256` +- Submission flow: `web-common/src/features/sources/modal/submitAddDataForm.ts` +- Existing Generate* RPCs: `runtime/server/generate_metrics_view.go`, `runtime/server/generate_resolver.go`, `runtime/server/generate_chart.go`, `runtime/server/generate_canvas_dashboard.go` +- Driver PropertySpec: `runtime/drivers/connectors.go:19-64` +- ClickHouse driver spec: `runtime/drivers/clickhouse/clickhouse.go:43+` +- Frontend schemas: `web-common/src/features/templates/schemas/*.ts` +- DuckDB rewrite (moving to backend): `web-common/src/features/sources/sourceUtils.ts:209-275` +- Backend driver specs with ObjectStore/FileStore flags: `runtime/drivers/s3/s3.go`, `runtime/drivers/gcs/gcs.go`, `runtime/drivers/azure/azure.go`, `runtime/drivers/https/https.go`, `runtime/drivers/file/file.go` +- Env var naming: `web-common/src/features/connectors/code-utils.ts:403-495` diff --git a/runtime/drivers/https/https.go b/runtime/drivers/https/https.go index 4d4893ffe8e..84640876cf1 100644 --- a/runtime/drivers/https/https.go +++ b/runtime/drivers/https/https.go @@ -25,6 +25,14 @@ var spec = drivers.Spec{ Description: "Connect to a remote file.", DocsURL: "https://docs.rilldata.com/developers/build/connect/#adding-a-remote-source", // Important: Any edits to the below properties must be accompanied by changes to the client-side form validation schemas. + ConfigProperties: []*drivers.PropertySpec{ + { + Key: "headers", + Type: drivers.StringPropertyType, + DisplayName: "Headers", + Description: "HTTP headers to include in requests.", + }, + }, SourceProperties: []*drivers.PropertySpec{ { Key: "path", diff --git a/runtime/server/generate_template.go b/runtime/server/generate_template.go index db3d61099a8..b6e572fd082 100644 --- a/runtime/server/generate_template.go +++ b/runtime/server/generate_template.go @@ -6,6 +6,8 @@ import ( "context" "fmt" "path/filepath" + "regexp" + "sort" "strings" runtimev1 "github.com/rilldata/rill/proto/gen/rill/runtime/v1" @@ -214,6 +216,11 @@ func renderConnectorYAML(spec drivers.Spec, driverName string, props map[string] if !ok || isEmpty(val) { continue } + // Handle map-typed properties (e.g. headers) + if mapVal, isMap := val.(map[string]any); isMap { + renderHeadersMap(mapping, mapVal, driverName, existingEnv, envVars) + continue + } // Skip managed: false for ClickHouse (it's the default) if propSpec.Key == "managed" && !toBool(val) { continue @@ -395,6 +402,85 @@ func addDevSection(m *yaml.Node) { ) } +// sensitiveHeaderPattern matches header keys that carry secret values. +var sensitiveHeaderPattern = regexp.MustCompile( + `(?i)^(authorization|x-api-key|api-key|token|x-token|x-auth|x-secret|proxy-authorization)$`, +) + +// isSensitiveHeaderKey returns true when a header key likely carries a secret value. +func isSensitiveHeaderKey(key string) bool { + return sensitiveHeaderPattern.MatchString(strings.TrimSpace(key)) +} + +// authSchemePrefixes are common HTTP authentication scheme prefixes. +// When a sensitive header value starts with one of these (case-insensitive), +// only the token portion is stored in .env. +var authSchemePrefixes = []string{"Bearer ", "Basic ", "Token ", "Bot "} + +// splitAuthSchemePrefix splits a value into scheme prefix and secret if it starts +// with a known auth scheme. Returns ("", "", false) when no prefix matches. +func splitAuthSchemePrefix(value string) (scheme, secret string, ok bool) { + for _, prefix := range authSchemePrefixes { + if len(value) > len(prefix) && strings.EqualFold(value[:len(prefix)], prefix) { + return value[:len(prefix)], value[len(prefix):], true + } + } + return "", "", false +} + +// headerKeyToEnvSegment sanitizes a header key into a valid .env variable segment. +func headerKeyToEnvSegment(key string) string { + return regexp.MustCompile(`[^a-z0-9]+`).ReplaceAllString(strings.ToLower(key), "_") +} + +// resolveHeaderEnvVarName determines the env var name for a header, resolving conflicts. +func resolveHeaderEnvVarName(connectorName, segment string, existingEnv map[string]bool) string { + base := fmt.Sprintf("connector.%s.%s", connectorName, segment) + candidate := base + for i := 1; existingEnv[candidate]; i++ { + candidate = fmt.Sprintf("%s_%d", base, i) + } + return candidate +} + +// renderHeadersMap builds a YAML headers mapping, extracting sensitive values to envVars. +func renderHeadersMap(m *yaml.Node, headers map[string]any, connectorName string, existingEnv map[string]bool, envVars map[string]string) { + if len(headers) == 0 { + return + } + + // Sort keys for deterministic output + keys := make([]string, 0, len(headers)) + for k := range headers { + keys = append(keys, k) + } + sort.Strings(keys) + + headerMapping := &yaml.Node{Kind: yaml.MappingNode} + for _, key := range keys { + strVal := fmt.Sprintf("%v", headers[key]) + if isSensitiveHeaderKey(key) { + envSegment := headerKeyToEnvSegment(key) + envName := resolveHeaderEnvVarName(connectorName, envSegment, existingEnv) + existingEnv[envName] = true + if scheme, secret, ok := splitAuthSchemePrefix(strVal); ok { + envVars[envName] = secret + addQuotedPair(headerMapping, key, fmt.Sprintf("%s{{ .env.%s }}", scheme, envName)) + } else { + envVars[envName] = strVal + addQuotedPair(headerMapping, key, fmt.Sprintf("{{ .env.%s }}", envName)) + } + } else { + addQuotedPair(headerMapping, key, strVal) + } + } + + m.Content = append(m.Content, + &yaml.Node{Kind: yaml.ScalarNode, Value: "headers"}, + headerMapping, + ) +} + // encodeYAML renders a yaml.Node tree to a string. func encodeYAML(doc *yaml.Node) string { buf := new(bytes.Buffer) diff --git a/runtime/server/generate_template_test.go b/runtime/server/generate_template_test.go index 0e1067bbb99..a8d672fa562 100644 --- a/runtime/server/generate_template_test.go +++ b/runtime/server/generate_template_test.go @@ -560,6 +560,7 @@ func TestGenerateTemplateAllConnectorDrivers(t *testing.T) { {"pinot", map[string]any{"broker_host": "localhost"}}, {"starrocks", map[string]any{"host": "localhost"}}, {"salesforce", map[string]any{"username": "test"}}, + {"https", map[string]any{}}, } for _, d := range driversWithConfig { @@ -874,6 +875,140 @@ func TestGenerateTemplateValidateProperties(t *testing.T) { } } +// TestGenerateTemplateHTTPSConnectorWithHeaders tests HTTPS connector with non-sensitive headers. +func TestGenerateTemplateHTTPSConnectorWithHeaders(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": ``, + }, + }) + + ctx := testCtx() + srv, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + resp, err := srv.GenerateTemplate(ctx, &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "https", + Properties: mustStruct(map[string]any{ + "headers": map[string]any{ + "Content-Type": "application/json", + "Accept": "text/html", + }, + }), + }) + require.NoError(t, err) + + require.Contains(t, resp.Blob, "type: connector") + require.Contains(t, resp.Blob, "driver: https") + require.Contains(t, resp.Blob, "headers:") + require.Contains(t, resp.Blob, `"application/json"`) + require.Contains(t, resp.Blob, `"text/html"`) + require.Empty(t, resp.EnvVars) +} + +// TestGenerateTemplateHTTPSConnectorWithSensitiveHeaders tests Authorization header extraction. +func TestGenerateTemplateHTTPSConnectorWithSensitiveHeaders(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": ``, + }, + }) + + ctx := testCtx() + srv, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + resp, err := srv.GenerateTemplate(ctx, &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "https", + Properties: mustStruct(map[string]any{ + "headers": map[string]any{ + "Authorization": "my_secret_token", + }, + }), + }) + require.NoError(t, err) + + require.Contains(t, resp.Blob, "{{ .env.connector.https.authorization }}") + require.NotContains(t, resp.Blob, "my_secret_token") + require.Contains(t, resp.EnvVars, "connector.https.authorization") + require.Equal(t, "my_secret_token", resp.EnvVars["connector.https.authorization"]) +} + +// TestGenerateTemplateHTTPSConnectorBearerPrefix tests Bearer scheme preservation. +func TestGenerateTemplateHTTPSConnectorBearerPrefix(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": ``, + }, + }) + + ctx := testCtx() + srv, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + resp, err := srv.GenerateTemplate(ctx, &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "https", + Properties: mustStruct(map[string]any{ + "headers": map[string]any{ + "Authorization": "Bearer my_token_123", + }, + }), + }) + require.NoError(t, err) + + // Bearer prefix preserved in YAML, only token in envVars + require.Contains(t, resp.Blob, "Bearer {{ .env.connector.https.authorization }}") + require.NotContains(t, resp.Blob, "my_token_123") + require.Contains(t, resp.EnvVars, "connector.https.authorization") + require.Equal(t, "my_token_123", resp.EnvVars["connector.https.authorization"]) +} + +// TestGenerateTemplateHTTPSConnectorMixedHeaders tests a mix of sensitive and non-sensitive headers. +func TestGenerateTemplateHTTPSConnectorMixedHeaders(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": ``, + }, + }) + + ctx := testCtx() + srv, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + resp, err := srv.GenerateTemplate(ctx, &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "https", + Properties: mustStruct(map[string]any{ + "headers": map[string]any{ + "Content-Type": "application/json", + "Authorization": "Basic dXNlcjpwYXNz", + "X-API-Key": "secret_key_value", + }, + }), + }) + require.NoError(t, err) + + // Non-sensitive header as plain text + require.Contains(t, resp.Blob, `"application/json"`) + + // Authorization with Basic prefix preserved + require.Contains(t, resp.Blob, "Basic {{ .env.connector.https.authorization }}") + require.NotContains(t, resp.Blob, "dXNlcjpwYXNz") + require.Equal(t, "dXNlcjpwYXNz", resp.EnvVars["connector.https.authorization"]) + + // X-API-Key is sensitive, no prefix + require.Contains(t, resp.Blob, "{{ .env.connector.https.x_api_key }}") + require.NotContains(t, resp.Blob, "secret_key_value") + require.Equal(t, "secret_key_value", resp.EnvVars["connector.https.x_api_key"]) +} + func mustStruct(m map[string]any) *structpb.Struct { s, err := structpb.NewStruct(m) if err != nil { diff --git a/web-common/src/features/connectors/code-utils.spec.ts b/web-common/src/features/connectors/code-utils.spec.ts index 0f9f840b39f..21b5ff5c171 100644 --- a/web-common/src/features/connectors/code-utils.spec.ts +++ b/web-common/src/features/connectors/code-utils.spec.ts @@ -1,30 +1,9 @@ -import { describe, expect, it, vi, beforeEach } from "vitest"; -import type { V1ConnectorDriver } from "@rilldata/web-common/runtime-client"; +import { describe, expect, it } from "vitest"; import { replaceOlapConnectorInYAML, replaceOrAddEnvVariable, - getGenericEnvVarName, - envVarExists, - findAvailableEnvVarName, - makeEnvVarKey, - compileConnectorYAML, - formatHeadersAsYamlMap, - updateDotEnvWithSecrets, } from "./code-utils"; -// Mock runtime store and API -vi.mock("../../runtime-client/runtime-store", () => ({ - runtime: { subscribe: vi.fn() }, -})); - -vi.mock("svelte/store", async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - get: () => ({ instanceId: "test-instance" }), - }; -}); - // Import the template for testing const YAML_MODEL_TEMPLATE = `type: model materialize: true\n @@ -134,948 +113,3 @@ describe("replaceOlapConnectorInYAML", () => { ); }); }); - -describe("getGenericEnvVarName", () => { - describe("Schema-driven x-env-var-name (production behavior)", () => { - it("should use x-env-var-name from schema when provided", () => { - const schema = { - properties: { - key_id: { "x-env-var-name": "GCS_ACCESS_KEY_ID" }, - }, - }; - const result = getGenericEnvVarName("gcs", "key_id", schema); - expect(result).toBe("GCS_ACCESS_KEY_ID"); - }); - - it("should use x-env-var-name for AWS credentials", () => { - const schema = { - properties: { - aws_access_key_id: { "x-env-var-name": "AWS_ACCESS_KEY_ID" }, - aws_secret_access_key: { "x-env-var-name": "AWS_SECRET_ACCESS_KEY" }, - }, - }; - expect(getGenericEnvVarName("s3", "aws_access_key_id", schema)).toBe( - "AWS_ACCESS_KEY_ID", - ); - expect(getGenericEnvVarName("s3", "aws_secret_access_key", schema)).toBe( - "AWS_SECRET_ACCESS_KEY", - ); - }); - - it("should use x-env-var-name for Google credentials", () => { - const schema = { - properties: { - google_application_credentials: { - "x-env-var-name": "GOOGLE_APPLICATION_CREDENTIALS", - }, - }, - }; - expect( - getGenericEnvVarName( - "bigquery", - "google_application_credentials", - schema, - ), - ).toBe("GOOGLE_APPLICATION_CREDENTIALS"); - }); - - it("should use x-env-var-name for driver-specific secrets", () => { - const motherduckSchema = { - properties: { - token: { "x-env-var-name": "MOTHERDUCK_TOKEN" }, - }, - }; - expect( - getGenericEnvVarName("motherduck", "token", motherduckSchema), - ).toBe("MOTHERDUCK_TOKEN"); - - const clickhouseSchema = { - properties: { - dsn: { "x-env-var-name": "CLICKHOUSE_DSN" }, - password: { "x-env-var-name": "CLICKHOUSE_PASSWORD" }, - }, - }; - expect(getGenericEnvVarName("clickhouse", "dsn", clickhouseSchema)).toBe( - "CLICKHOUSE_DSN", - ); - expect( - getGenericEnvVarName("clickhouse", "password", clickhouseSchema), - ).toBe("CLICKHOUSE_PASSWORD"); - }); - }); - - describe("Fallback behavior (DRIVERNAME_PROPERTYKEY format)", () => { - it("should use DRIVERNAME_PROPERTYKEY when schema has no x-env-var-name", () => { - const schema = { - properties: { - other_field: { "x-env-var-name": "OTHER_VAR" }, - }, - }; - const result = getGenericEnvVarName("gcs", "key_id", schema); - expect(result).toBe("GCS_KEY_ID"); - }); - - it("should use DRIVERNAME_PROPERTYKEY when schema is undefined", () => { - const result = getGenericEnvVarName("motherduck", "token", undefined); - expect(result).toBe("MOTHERDUCK_TOKEN"); - }); - - it("should use DRIVERNAME_PROPERTYKEY when schema has no properties", () => { - const schema = { properties: {} }; - const result = getGenericEnvVarName("motherduck", "token", schema); - expect(result).toBe("MOTHERDUCK_TOKEN"); - }); - - it("should convert camelCase to SCREAMING_SNAKE_CASE", () => { - const result = getGenericEnvVarName("bigquery", "projectId"); - expect(result).toBe("BIGQUERY_PROJECT_ID"); - }); - - it("should handle dots and hyphens by converting to underscores", () => { - const result = getGenericEnvVarName( - "custom", - "property.with-mixed.separators", - ); - expect(result).toBe("CUSTOM_PROPERTY_WITH_MIXED_SEPARATORS"); - }); - }); -}); - -describe("envVarExists", () => { - it("should return true when variable exists", () => { - const envBlob = `KEY1=VALUE1\nKEY2=VALUE2\nKEY3=VALUE3`; - expect(envVarExists(envBlob, "KEY2")).toBe(true); - }); - - it("should return false when variable does not exist", () => { - const envBlob = `KEY1=VALUE1\nKEY2=VALUE2`; - expect(envVarExists(envBlob, "KEY3")).toBe(false); - }); - - it("should return true for variable at start of file", () => { - const envBlob = `FIRST_KEY=VALUE\nKEY2=VALUE2`; - expect(envVarExists(envBlob, "FIRST_KEY")).toBe(true); - }); - - it("should return true for variable at end of file", () => { - const envBlob = `KEY1=VALUE1\nLAST_KEY=VALUE`; - expect(envVarExists(envBlob, "LAST_KEY")).toBe(true); - }); - - it("should not match partial variable names", () => { - const envBlob = `MY_VARIABLE_1=VALUE\nMY_VARIABLE_2=VALUE2`; - expect(envVarExists(envBlob, "MY_VARIABLE")).toBe(false); - }); - - it("should return false for empty blob", () => { - expect(envVarExists("", "KEY1")).toBe(false); - }); - - it("should handle variables with complex values", () => { - const envBlob = `JSON_VAR={"key":"value","nested":{"data":"here"}}\nSIMPLE=value`; - expect(envVarExists(envBlob, "JSON_VAR")).toBe(true); - }); - - it("should handle multiline values (only checks line start)", () => { - const envBlob = `KEY1=line1\nline2\nKEY2=VALUE2`; - expect(envVarExists(envBlob, "KEY1")).toBe(true); - }); -}); - -describe("findAvailableEnvVarName", () => { - it("should return base name when no conflicts", () => { - const envBlob = `OTHER_VAR=value`; - const result = findAvailableEnvVarName(envBlob, "MY_VAR"); - expect(result).toBe("MY_VAR"); - }); - - it("should append _1 when base name exists", () => { - const envBlob = `MY_VAR=value`; - const result = findAvailableEnvVarName(envBlob, "MY_VAR"); - expect(result).toBe("MY_VAR_1"); - }); - - it("should append _2 when _1 exists", () => { - const envBlob = `MY_VAR=value\nMY_VAR_1=value`; - const result = findAvailableEnvVarName(envBlob, "MY_VAR"); - expect(result).toBe("MY_VAR_2"); - }); - - it("should skip gaps and find next available number", () => { - const envBlob = `MY_VAR=value\nMY_VAR_1=value\nMY_VAR_2=value\nMY_VAR_3=value`; - const result = findAvailableEnvVarName(envBlob, "MY_VAR"); - expect(result).toBe("MY_VAR_4"); - }); - - it("should handle empty blob", () => { - const result = findAvailableEnvVarName("", "NEW_VAR"); - expect(result).toBe("NEW_VAR"); - }); - - it("should handle base name with underscores", () => { - const envBlob = `GOOGLE_APPLICATION_CREDENTIALS=value\nGOOGLE_APPLICATION_CREDENTIALS_1=value`; - const result = findAvailableEnvVarName( - envBlob, - "GOOGLE_APPLICATION_CREDENTIALS", - ); - expect(result).toBe("GOOGLE_APPLICATION_CREDENTIALS_2"); - }); - - it("should be case sensitive", () => { - const envBlob = `my_var=value`; - const result = findAvailableEnvVarName(envBlob, "MY_VAR"); - expect(result).toBe("MY_VAR"); - }); -}); - -describe("makeEnvVarKey", () => { - // Mock schemas matching production x-env-var-name definitions - const bigquerySchema = { - properties: { - google_application_credentials: { - "x-env-var-name": "GOOGLE_APPLICATION_CREDENTIALS", - }, - }, - }; - - const s3Schema = { - properties: { - aws_access_key_id: { "x-env-var-name": "AWS_ACCESS_KEY_ID" }, - aws_secret_access_key: { "x-env-var-name": "AWS_SECRET_ACCESS_KEY" }, - }, - }; - - const motherduckSchema = { - properties: { - token: { "x-env-var-name": "MOTHERDUCK_TOKEN" }, - }, - }; - - const postgresSchema = { - properties: { - password: { "x-env-var-name": "POSTGRES_PASSWORD" }, - }, - }; - - describe("Without existing env blob - returns schema-defined name", () => { - it("should return GOOGLE_APPLICATION_CREDENTIALS for bigquery", () => { - const result = makeEnvVarKey( - "bigquery", - "google_application_credentials", - undefined, - bigquerySchema, - ); - expect(result).toBe("GOOGLE_APPLICATION_CREDENTIALS"); - }); - - it("should return MOTHERDUCK_TOKEN for motherduck", () => { - const result = makeEnvVarKey( - "motherduck", - "token", - undefined, - motherduckSchema, - ); - expect(result).toBe("MOTHERDUCK_TOKEN"); - }); - - it("should return POSTGRES_PASSWORD for postgres", () => { - const result = makeEnvVarKey("postgres", "password", "", postgresSchema); - expect(result).toBe("POSTGRES_PASSWORD"); - }); - }); - - describe("With existing env blob - handles conflicts with _# suffix", () => { - it("should append _1 when variable already exists", () => { - const envBlob = `GOOGLE_APPLICATION_CREDENTIALS=existing_value`; - const result = makeEnvVarKey( - "bigquery", - "google_application_credentials", - envBlob, - bigquerySchema, - ); - expect(result).toBe("GOOGLE_APPLICATION_CREDENTIALS_1"); - }); - - it("should return base name when no conflict exists", () => { - const envBlob = `OTHER_VAR=value`; - const result = makeEnvVarKey( - "bigquery", - "google_application_credentials", - envBlob, - bigquerySchema, - ); - expect(result).toBe("GOOGLE_APPLICATION_CREDENTIALS"); - }); - - it("should find next available number for multiple connectors of same type", () => { - const envBlob = `GOOGLE_APPLICATION_CREDENTIALS=first_creds\nGOOGLE_APPLICATION_CREDENTIALS_1=second_creds\nGOOGLE_APPLICATION_CREDENTIALS_2=third_creds`; - const result = makeEnvVarKey( - "bigquery", - "google_application_credentials", - envBlob, - bigquerySchema, - ); - expect(result).toBe("GOOGLE_APPLICATION_CREDENTIALS_3"); - }); - - it("should handle multiple different properties", () => { - const envBlob = `AWS_ACCESS_KEY_ID=key1\nAWS_SECRET_ACCESS_KEY=secret1`; - const result = makeEnvVarKey( - "s3", - "aws_access_key_id", - envBlob, - s3Schema, - ); - expect(result).toBe("AWS_ACCESS_KEY_ID_1"); - }); - - it("should handle driver-specific properties with conflicts", () => { - const envBlob = `MOTHERDUCK_TOKEN=token1\nMOTHERDUCK_TOKEN_1=token2`; - const result = makeEnvVarKey( - "motherduck", - "token", - envBlob, - motherduckSchema, - ); - expect(result).toBe("MOTHERDUCK_TOKEN_2"); - }); - - it("should handle complex env blobs with comments and multiple variables", () => { - const envBlob = `# This is a comment -SOME_OTHER_VAR=value -MOTHERDUCK_TOKEN=token1 -MOTHERDUCK_TOKEN_1=token2 -# Another comment -DATABASE_URL=something`; - const result = makeEnvVarKey( - "motherduck", - "token", - envBlob, - motherduckSchema, - ); - expect(result).toBe("MOTHERDUCK_TOKEN_2"); - }); - }); - - describe("Integration - full workflows with schemas", () => { - it("should support adding first BigQuery connector", () => { - const emptyEnv = ""; - const result = makeEnvVarKey( - "bigquery", - "google_application_credentials", - emptyEnv, - bigquerySchema, - ); - expect(result).toBe("GOOGLE_APPLICATION_CREDENTIALS"); - }); - - it("should support adding second BigQuery connector", () => { - const envAfterFirst = `GOOGLE_APPLICATION_CREDENTIALS=first_creds`; - const result = makeEnvVarKey( - "bigquery", - "google_application_credentials", - envAfterFirst, - bigquerySchema, - ); - expect(result).toBe("GOOGLE_APPLICATION_CREDENTIALS_1"); - }); - - it("should support adding AWS credentials to existing non-AWS variables", () => { - const envBlob = `MOTHERDUCK_TOKEN=token1\nGOOGLE_APPLICATION_CREDENTIALS=creds1`; - const result = makeEnvVarKey( - "s3", - "aws_access_key_id", - envBlob, - s3Schema, - ); - expect(result).toBe("AWS_ACCESS_KEY_ID"); - }); - - it("should support adding multiple AWS connectors", () => { - const envBlob = `AWS_ACCESS_KEY_ID=key1\nAWS_SECRET_ACCESS_KEY=secret1`; - const result1 = makeEnvVarKey( - "s3", - "aws_access_key_id", - envBlob, - s3Schema, - ); - expect(result1).toBe("AWS_ACCESS_KEY_ID_1"); - - const updatedEnv = `${envBlob}\nAWS_ACCESS_KEY_ID_1=key2`; - const result2 = makeEnvVarKey( - "s3", - "aws_secret_access_key", - updatedEnv, - s3Schema, - ); - expect(result2).toBe("AWS_SECRET_ACCESS_KEY_1"); - }); - }); -}); - -describe("formatHeadersAsYamlMap", () => { - describe("array input", () => { - it("should format non-sensitive headers as plain text", () => { - const result = formatHeadersAsYamlMap([ - { key: "Content-Type", value: "application/json" }, - { key: "Accept", value: "text/html" }, - ]); - expect(result).toBe( - `headers:\n "Content-Type": "application/json"\n "Accept": "text/html"`, - ); - }); - - it("should replace sensitive header with env ref when driverName provided", () => { - const result = formatHeadersAsYamlMap( - [{ key: "Authorization", value: "my_secret_token" }], - "https", - ); - expect(result).toContain( - '"Authorization": "{{ .env.connector.https.authorization }}"', - ); - }); - - it("should preserve Bearer scheme prefix", () => { - const result = formatHeadersAsYamlMap( - [{ key: "Authorization", value: "Bearer my_token" }], - "https", - ); - expect(result).toContain( - '"Authorization": "Bearer {{ .env.connector.https.authorization }}"', - ); - }); - - it("should preserve Basic scheme prefix", () => { - const result = formatHeadersAsYamlMap( - [{ key: "Authorization", value: "Basic dXNlcjpwYXNz" }], - "https", - ); - expect(result).toContain( - '"Authorization": "Basic {{ .env.connector.https.authorization }}"', - ); - }); - - it("should handle mixed sensitive and non-sensitive headers", () => { - const result = formatHeadersAsYamlMap( - [ - { key: "Content-Type", value: "application/json" }, - { key: "Authorization", value: "Bearer token123" }, - ], - "https", - ); - expect(result).toContain('"Content-Type": "application/json"'); - expect(result).toContain( - '"Authorization": "Bearer {{ .env.connector.https.authorization }}"', - ); - }); - - it("should filter entries with empty keys", () => { - const result = formatHeadersAsYamlMap([ - { key: "", value: "ignored" }, - { key: "Accept", value: "text/html" }, - ]); - expect(result).toBe(`headers:\n "Accept": "text/html"`); - }); - - it("should return empty string for empty array", () => { - expect(formatHeadersAsYamlMap([])).toBe(""); - }); - - it("should use connectorInstanceName for env refs when provided", () => { - const result = formatHeadersAsYamlMap( - [{ key: "X-API-Key", value: "secret" }], - "https", - "my_api", - ); - expect(result).toContain("{{ .env.connector.my_api.x_api_key }}"); - }); - - it("should not create env refs when no driverName", () => { - const result = formatHeadersAsYamlMap([ - { key: "Authorization", value: "Bearer token" }, - ]); - expect(result).toContain('"Authorization": "Bearer token"'); - expect(result).not.toContain(".env."); - }); - }); - - describe("string input (legacy)", () => { - it("should parse Key: Value lines", () => { - const result = formatHeadersAsYamlMap( - "Content-Type: application/json\nAccept: text/html", - ); - expect(result).toBe( - `headers:\n "Content-Type": "application/json"\n "Accept": "text/html"`, - ); - }); - - it("should replace sensitive headers with env refs", () => { - const result = formatHeadersAsYamlMap( - "Authorization: Bearer my_token", - "https", - ); - expect(result).toContain( - "Bearer {{ .env.connector.https.authorization }}", - ); - }); - - it("should return empty string for empty input", () => { - expect(formatHeadersAsYamlMap("")).toBe(""); - }); - }); -}); - -describe("compileConnectorYAML", () => { - it("should produce basic connector YAML", () => { - const connector: V1ConnectorDriver = { - name: "clickhouse", - docsUrl: - "https://docs.rilldata.com/developers/build/connectors/data-source/clickhouse", - }; - const result = compileConnectorYAML( - connector, - { host: "ch.example.com" }, - { - orderedProperties: [{ key: "host" }], - }, - ); - expect(result).toContain("# Connector YAML"); - expect(result).toContain("type: connector"); - expect(result).toContain("driver: clickhouse"); - expect(result).toContain("host: ch.example.com"); - }); - - it("should preserve property ordering from orderedProperties", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileConnectorYAML( - connector, - { host: "ch.example.com", port: 9000, database: "default" }, - { - orderedProperties: [ - { key: "database" }, - { key: "host" }, - { key: "port" }, - ], - }, - ); - const dbIdx = result.indexOf("database:"); - const hostIdx = result.indexOf("host:"); - const portIdx = result.indexOf("port:"); - expect(dbIdx).toBeLessThan(hostIdx); - expect(hostIdx).toBeLessThan(portIdx); - }); - - it("should replace secret properties with env var placeholders", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const schema = { - properties: { - password: { "x-env-var-name": "CLICKHOUSE_PASSWORD" }, - }, - }; - const result = compileConnectorYAML( - connector, - { password: "super_secret" }, - { - orderedProperties: [{ key: "password", secret: true }], - secretKeys: ["password"], - schema, - }, - ); - expect(result).toContain("{{ .env.CLICKHOUSE_PASSWORD }}"); - expect(result).not.toContain("super_secret"); - }); - - it("should quote string properties", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileConnectorYAML( - connector, - { host: "ch.example.com" }, - { - orderedProperties: [{ key: "host" }], - stringKeys: ["host"], - }, - ); - expect(result).toContain('host: "ch.example.com"'); - }); - - it("should not quote non-string properties", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileConnectorYAML( - connector, - { port: 9000 }, - { orderedProperties: [{ key: "port" }] }, - ); - expect(result).toContain("port: 9000"); - expect(result).not.toContain('"9000"'); - }); - - it("should filter out empty string values", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileConnectorYAML( - connector, - { host: "ch.example.com", database: "" }, - { orderedProperties: [{ key: "host" }, { key: "database" }] }, - ); - expect(result).toContain("host:"); - expect(result).not.toContain("database:"); - }); - - it("should filter out undefined values", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileConnectorYAML( - connector, - { host: "ch.example.com", database: undefined }, - { orderedProperties: [{ key: "host" }, { key: "database" }] }, - ); - expect(result).not.toContain("database:"); - }); - - it("should filter out empty arrays", () => { - const connector: V1ConnectorDriver = { name: "https" }; - const result = compileConnectorYAML( - connector, - { url: "https://example.com", headers: [] }, - { orderedProperties: [{ key: "url" }, { key: "headers" }] }, - ); - expect(result).not.toContain("headers:"); - }); - - it("should exclude clickhouse managed: false", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileConnectorYAML( - connector, - { host: "ch.example.com", managed: false }, - { orderedProperties: [{ key: "host" }, { key: "managed" }] }, - ); - expect(result).not.toContain("managed"); - }); - - it("should include clickhouse managed: true", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileConnectorYAML( - connector, - { host: "ch.example.com", managed: true }, - { orderedProperties: [{ key: "host" }, { key: "managed" }] }, - ); - expect(result).toContain("managed: true"); - }); - - it("should output driver as duckdb for motherduck", () => { - const connector: V1ConnectorDriver = { name: "motherduck" }; - const result = compileConnectorYAML( - connector, - { path: "md:my_db" }, - { orderedProperties: [{ key: "path" }] }, - ); - expect(result).toContain("driver: duckdb"); - expect(result).not.toContain("driver: motherduck"); - }); - - it("should apply fieldFilter to exclude internal properties", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileConnectorYAML( - connector, - { host: "ch.example.com", managed: true }, - { - orderedProperties: [ - { key: "host" }, - { key: "managed", internal: true }, - ], - fieldFilter: (p) => !("internal" in p && p.internal), - }, - ); - expect(result).toContain("host:"); - expect(result).not.toContain("managed:"); - }); - - it("should handle env var conflict resolution with existingEnvBlob", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const schema = { - properties: { - password: { "x-env-var-name": "CLICKHOUSE_PASSWORD" }, - }, - }; - const result = compileConnectorYAML( - connector, - { password: "secret" }, - { - orderedProperties: [{ key: "password", secret: true }], - secretKeys: ["password"], - schema, - existingEnvBlob: "CLICKHOUSE_PASSWORD=old_value", - }, - ); - expect(result).toContain("CLICKHOUSE_PASSWORD_1"); - }); - - it("should produce no property lines when orderedProperties is empty", () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const result = compileConnectorYAML(connector, { host: "ch.example.com" }); - expect(result).toContain("type: connector"); - expect(result).toContain("driver: clickhouse"); - expect(result).not.toContain("host:"); - }); -}); - -describe("updateDotEnvWithSecrets", () => { - // Track fetchQuery calls so tests can inspect them - let mockEnvBlob = ""; - const mockQueryClient = { - invalidateQueries: vi.fn().mockResolvedValue(undefined), - fetchQuery: vi - .fn() - .mockImplementation(() => Promise.resolve({ blob: mockEnvBlob })), - }; - - beforeEach(() => { - vi.clearAllMocks(); - mockEnvBlob = ""; - mockQueryClient.fetchQuery.mockImplementation(() => - Promise.resolve({ blob: mockEnvBlob }), - ); - }); - - it("should add secret keys to empty .env", async () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const formValues: Record = { - password: "my_secret", - sql: "SELECT 1", - }; - const { newBlob } = await updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - formValues, - { secretKeys: ["password"] }, - ); - expect(newBlob).toContain("CLICKHOUSE_PASSWORD=my_secret"); - }); - - it("should add multiple secret keys", async () => { - const connector: V1ConnectorDriver = { name: "s3" }; - const formValues: Record = { - aws_access_key_id: "AKID123", - aws_secret_access_key: "SECRET456", - }; - const schema = { - properties: { - aws_access_key_id: { "x-env-var-name": "AWS_ACCESS_KEY_ID" }, - aws_secret_access_key: { - "x-env-var-name": "AWS_SECRET_ACCESS_KEY", - }, - }, - }; - const { newBlob } = await updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - formValues, - { secretKeys: ["aws_access_key_id", "aws_secret_access_key"], schema }, - ); - expect(newBlob).toContain("AWS_ACCESS_KEY_ID=AKID123"); - expect(newBlob).toContain("AWS_SECRET_ACCESS_KEY=SECRET456"); - }); - - it("should append to existing .env without overwriting", async () => { - mockEnvBlob = "EXISTING_VAR=existing_value"; - mockQueryClient.fetchQuery.mockResolvedValue({ blob: mockEnvBlob }); - - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const formValues: Record = { password: "new_pw" }; - const { newBlob, originalBlob } = await updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - formValues, - { secretKeys: ["password"] }, - ); - expect(originalBlob).toBe("EXISTING_VAR=existing_value"); - expect(newBlob).toContain("EXISTING_VAR=existing_value"); - expect(newBlob).toContain("CLICKHOUSE_PASSWORD=new_pw"); - }); - - it("should handle env var conflicts with _1 suffix", async () => { - mockEnvBlob = "CLICKHOUSE_PASSWORD=old_value"; - mockQueryClient.fetchQuery.mockResolvedValue({ blob: mockEnvBlob }); - - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const formValues: Record = { password: "new_value" }; - const { newBlob } = await updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - formValues, - { secretKeys: ["password"] }, - ); - // Should use _1 suffix since base name already exists - expect(newBlob).toContain("CLICKHOUSE_PASSWORD=old_value"); - expect(newBlob).toContain("CLICKHOUSE_PASSWORD_1=new_value"); - }); - - it("should skip empty or missing secret values", async () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const formValues: Record = { - password: "", - dsn: undefined, - }; - const { newBlob } = await updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - formValues, - { secretKeys: ["password", "dsn"] }, - ); - expect(newBlob).toBe(""); - }); - - it("should persist sensitive header values as env entries", async () => { - const connector: V1ConnectorDriver = { name: "https" }; - const formValues: Record = { - headers: [ - { key: "Authorization", value: "Bearer my_token" }, - { key: "Content-Type", value: "application/json" }, - ], - }; - const { newBlob } = await updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - formValues, - { secretKeys: [] }, - ); - // Authorization is sensitive — secret part stored (without Bearer prefix) - expect(newBlob).toContain("my_token"); - // Content-Type is not sensitive — should NOT be in .env - expect(newBlob).not.toContain("application/json"); - }); - - it("should extract secret from Bearer scheme for sensitive headers", async () => { - const connector: V1ConnectorDriver = { name: "https" }; - const formValues: Record = { - headers: [{ key: "Authorization", value: "Bearer abc123" }], - }; - const { newBlob } = await updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - formValues, - { secretKeys: [] }, - ); - // Only the secret portion (after "Bearer ") is stored - expect(newBlob).toContain("=abc123"); - expect(newBlob).not.toContain("Bearer"); - }); - - it("should store full value when no auth scheme prefix", async () => { - const connector: V1ConnectorDriver = { name: "https" }; - const formValues: Record = { - headers: [{ key: "X-API-Key", value: "raw_api_key_value" }], - }; - const { newBlob } = await updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - formValues, - { secretKeys: [] }, - ); - expect(newBlob).toContain("=raw_api_key_value"); - }); - - it("should handle both secrets and sensitive headers together", async () => { - const connector: V1ConnectorDriver = { name: "https" }; - const formValues: Record = { - password: "http_pass", - headers: [{ key: "Authorization", value: "Token secret_tok" }], - }; - const { newBlob } = await updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - formValues, - { secretKeys: ["password"] }, - ); - expect(newBlob).toContain("HTTPS_PASSWORD=http_pass"); - expect(newBlob).toContain("secret_tok"); - }); - - it("should skip headers with empty keys or values", async () => { - const connector: V1ConnectorDriver = { name: "https" }; - const formValues: Record = { - headers: [ - { key: "", value: "some_value" }, - { key: "Authorization", value: "" }, - { key: " ", value: "Bearer token" }, - ], - }; - const { newBlob } = await updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - formValues, - { secretKeys: [] }, - ); - expect(newBlob).toBe(""); - }); - - it("should invalidate cache before reading .env", async () => { - const connector: V1ConnectorDriver = { name: "clickhouse" }; - await updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - { password: "pw" }, - { secretKeys: ["password"] }, - ); - expect(mockQueryClient.invalidateQueries).toHaveBeenCalledTimes(1); - // invalidateQueries should be called before fetchQuery - const invalidateOrder = - mockQueryClient.invalidateQueries.mock.invocationCallOrder[0]; - const fetchOrder = mockQueryClient.fetchQuery.mock.invocationCallOrder[0]; - expect(invalidateOrder).toBeLessThan(fetchOrder); - }); - - it("should handle missing .env file gracefully", async () => { - mockQueryClient.fetchQuery.mockRejectedValue({ - response: { data: { message: "no such file" } }, - }); - - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const { newBlob, originalBlob } = await updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - { password: "pw" }, - { secretKeys: ["password"] }, - ); - expect(originalBlob).toBe(""); - expect(newBlob).toContain("CLICKHOUSE_PASSWORD=pw"); - }); - - it("should rethrow non-file-not-found errors", async () => { - mockQueryClient.fetchQuery.mockRejectedValue({ - response: { data: { message: "permission denied" } }, - }); - - const connector: V1ConnectorDriver = { name: "clickhouse" }; - await expect( - updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - { password: "pw" }, - { secretKeys: ["password"] }, - ), - ).rejects.toEqual({ - response: { data: { message: "permission denied" } }, - }); - }); - - it("should use originalBlob for conflict detection across all secrets", async () => { - // When adding multiple secrets, conflict detection should use the original blob, - // not the progressively updated one - mockEnvBlob = ""; - mockQueryClient.fetchQuery.mockResolvedValue({ blob: mockEnvBlob }); - - const connector: V1ConnectorDriver = { name: "clickhouse" }; - const formValues: Record = { - password: "pw1", - dsn: "clickhouse://...", - }; - const { newBlob } = await updateDotEnvWithSecrets( - mockQueryClient as any, - connector, - formValues, - { secretKeys: ["password", "dsn"] }, - ); - // Both should use base name since originalBlob is empty - expect(newBlob).toContain("CLICKHOUSE_PASSWORD=pw1"); - expect(newBlob).toContain("CLICKHOUSE_DSN=clickhouse://..."); - }); -}); diff --git a/web-common/src/features/connectors/code-utils.ts b/web-common/src/features/connectors/code-utils.ts index 8a90f10aa27..93549a5078a 100644 --- a/web-common/src/features/connectors/code-utils.ts +++ b/web-common/src/features/connectors/code-utils.ts @@ -1,8 +1,6 @@ import { QueryClient } from "@tanstack/svelte-query"; import { get } from "svelte/store"; import { - type V1ConnectorDriver, - type ConnectorDriverProperty, getRuntimeServiceGetFileQueryKey, runtimeServiceGetFile, } from "../../runtime-client"; @@ -21,10 +19,7 @@ import { runtimeServiceGetInstance, runtimeServicePutFile, } from "../../runtime-client"; -import { - getDriverNameForConnector, - makeSufficientlyQualifiedTableName, -} from "./connectors-utils"; +import { makeSufficientlyQualifiedTableName } from "./connectors-utils"; function yamlModelTemplate(driverName: string) { return `# Model YAML @@ -39,311 +34,6 @@ sql: {{ sql }}{{ dev_section }} `; } -const SENSITIVE_HEADER_PATTERN = - /^(authorization|x-api-key|api-key|token|x-token|x-auth|x-secret|proxy-authorization)$/i; - -/** - * Returns true when a header key likely carries a secret value (e.g. tokens, - * API keys). Only these headers are stored in `.env`; the rest stay as plain - * text in the connector YAML. - */ -function isSensitiveHeaderKey(headerKey: string): boolean { - return SENSITIVE_HEADER_PATTERN.test(headerKey.trim()); -} - -/** - * Sanitize a header key into a valid .env variable segment. - * Lowercases, replaces non-alphanumeric characters with underscores, and - * collapses consecutive underscores. - */ -function headerKeyToEnvSegment(headerKey: string): string { - return headerKey - .toLowerCase() - .replace(/[^a-z0-9]+/g, "_") - .replace(/^_|_$/g, ""); -} - -/** - * Common HTTP authentication scheme prefixes. - * When a sensitive header value starts with one of these (case-insensitive), - * only the token portion after the prefix is stored in `.env`, while the - * scheme keyword is kept as plain text in the connector YAML. - */ -const AUTH_SCHEME_PREFIXES = ["Bearer ", "Basic ", "Token ", "Bot "]; - -/** - * If `value` begins with a recognised auth scheme prefix (e.g. "Bearer "), - * returns `{ scheme, secret }` where `scheme` includes the trailing space. - * Returns `null` when no known prefix is detected. - */ -function splitAuthSchemePrefix( - value: string, -): { scheme: string; secret: string } | null { - for (const prefix of AUTH_SCHEME_PREFIXES) { - if ( - value.length > prefix.length && - value.slice(0, prefix.length).toLowerCase() === prefix.toLowerCase() - ) { - return { - scheme: value.slice(0, prefix.length), - secret: value.slice(prefix.length), - }; - } - } - return null; -} - -/** - * Convert header entries into a YAML map block. - * Accepts an array of {key, value} objects (new key-value input) or a legacy - * multi-line "Header-Name: value" string. Returns empty string when there are - * no valid entries. - * - * When `driverName` is provided, header values are replaced with - * `{{ .env.connector.. }}` references so that secrets are - * stored in `.env` rather than in the connector YAML file. - */ -export function formatHeadersAsYamlMap( - value: Array<{ key: string; value: string }> | string, - driverName?: string, - connectorInstanceName?: string, -): string { - const nameForEnv = connectorInstanceName || driverName; - - if (typeof value === "string") { - // Legacy textarea format: parse "Key: Value" lines - const lines = value - .split("\n") - .map((line) => line.trim()) - .filter((line) => line.includes(":")); - if (lines.length === 0) return ""; - const entries = lines.map((line) => { - const idx = line.indexOf(":"); - const k = line.substring(0, idx).trim().replace(/^"|"$/g, ""); - const raw = line - .substring(idx + 1) - .trim() - .replace(/^"|"$/g, ""); - let v: string; - if (nameForEnv && isSensitiveHeaderKey(k)) { - const envRef = `{{ .env.connector.${nameForEnv}.${headerKeyToEnvSegment(k)} }}`; - const split = splitAuthSchemePrefix(raw); - v = split ? `${split.scheme}${envRef}` : envRef; - } else { - v = raw; - } - return ` "${k}": "${v}"`; - }); - return `headers:\n${entries.join("\n")}`; - } - - // Array of {key, value} objects from key-value input - const valid = value.filter((e) => e.key.trim() !== ""); - if (valid.length === 0) return ""; - const entries = valid.map((e) => { - const k = e.key.trim(); - let v: string; - if (nameForEnv && isSensitiveHeaderKey(k)) { - const envRef = `{{ .env.connector.${nameForEnv}.${headerKeyToEnvSegment(k)} }}`; - const split = splitAuthSchemePrefix(e.value.trim()); - v = split ? `${split.scheme}${envRef}` : envRef; - } else { - v = e.value.trim(); - } - return ` "${k}": "${v}"`; - }); - return `headers:\n${entries.join("\n")}`; -} - -export function compileConnectorYAML( - connector: V1ConnectorDriver, - formValues: Record, - options?: { - fieldFilter?: ( - property: - | ConnectorDriverProperty - | { key?: string; type?: string; secret?: boolean; internal?: boolean }, - ) => boolean; - orderedProperties?: Array< - | ConnectorDriverProperty - | { key?: string; type?: string; secret?: boolean; internal?: boolean } - >; - connectorInstanceName?: string; - secretKeys?: string[]; - stringKeys?: string[]; - schema?: { properties?: Record }; - existingEnvBlob?: string; - }, -) { - // Add instructions to the top of the file - const driverName = getDriverNameForConnector(connector.name as string); - const topOfFile = `# Connector YAML -# Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/${driverName} - -type: connector - -driver: ${driverName}`; - - // Use the provided orderedProperties if available. - let properties = options?.orderedProperties ?? []; - - // Optionally filter properties - if (options?.fieldFilter) { - properties = properties.filter(options.fieldFilter); - } - - // Get the secret property keys - const secretPropertyKeys = options?.secretKeys ?? []; - - // Get the string property keys - const stringPropertyKeys = options?.stringKeys ?? []; - - // Compile key value pairs in the order of properties - const compiledKeyValues = properties - .filter((property) => { - if (!property.key) return false; - const value = formValues[property.key]; - if (value === undefined) return false; - // Filter out empty strings for optional fields - if (typeof value === "string" && value.trim() === "") return false; - // Filter out empty arrays (e.g. key-value inputs with no entries) - if (Array.isArray(value) && value.length === 0) return false; - // For ClickHouse, exclude managed: false as it's the default behavior - // When managed=false, it's the default self-managed mode and doesn't need to be explicit - if ( - connector.name === "clickhouse" && - property.key === "managed" && - value === false - ) - return false; - return true; - }) - .map((property) => { - const key = property.key as string; - const value = formValues[key] as string; - - if (key === "headers") { - return formatHeadersAsYamlMap( - value as Array<{ key: string; value: string }> | string, - driverName, - options?.connectorInstanceName, - ); - } - - const isSecretProperty = secretPropertyKeys.includes(key); - if (isSecretProperty) { - const envVarName = makeEnvVarKey( - connector.name as string, - key, - options?.existingEnvBlob, - options?.schema, - ); - return `${key}: "{{ .env.${envVarName} }}"`; // uses standard Go template syntax - } - - const isStringProperty = stringPropertyKeys.includes(key); - if (isStringProperty) { - return `${key}: "${value}"`; - } - - return `${key}: ${value}`; - }) - .filter((line) => line !== "") - .join("\n"); - - // Return the compiled YAML - return `${topOfFile}\n` + compiledKeyValues; -} - -export async function updateDotEnvWithSecrets( - queryClient: QueryClient, - connector: V1ConnectorDriver, - formValues: Record, - opts?: { - secretKeys?: string[]; - schema?: { properties?: Record }; - }, -): Promise<{ newBlob: string; originalBlob: string }> { - const instanceId = get(runtime).instanceId; - - // Invalidate the cache to ensure we get fresh .env content - // This prevents overwriting credentials added by a previous step - await queryClient.invalidateQueries({ - queryKey: getRuntimeServiceGetFileQueryKey(instanceId, { path: ".env" }), - }); - - // Get the existing .env file with fresh data - let blob: string; - let originalBlob: string; - try { - const file = await queryClient.fetchQuery({ - queryKey: getRuntimeServiceGetFileQueryKey(instanceId, { path: ".env" }), - queryFn: () => runtimeServiceGetFile(instanceId, { path: ".env" }), - }); - blob = file.blob || ""; - originalBlob = blob; // Keep original for conflict detection - } catch (error) { - // Handle the case where the .env file does not exist - if (error?.response?.data?.message?.includes("no such file")) { - blob = ""; - originalBlob = ""; - } else { - throw error; - } - } - - // Get the secret keys - const secretKeys = opts?.secretKeys ?? []; - - // In reality, all connectors have secret keys, but this is a safeguard - if (!secretKeys) { - return { newBlob: blob, originalBlob }; - } - - // Update the blob with the new secrets - // Use originalBlob for conflict detection so all secrets use consistent naming - secretKeys.forEach((key) => { - if (!key || !formValues[key]) { - return; - } - - const connectorSecretKey = makeEnvVarKey( - connector.name as string, - key, - originalBlob, - opts?.schema, - ); - - blob = replaceOrAddEnvVariable( - blob, - connectorSecretKey, - formValues[key] as string, - ); - }); - - // Persist sensitive header values (e.g. Authorization, API keys) as - // individual .env entries so tokens are not stored as raw text in YAML. - const headers = formValues.headers; - if (Array.isArray(headers)) { - for (const entry of headers as Array<{ key: string; value: string }>) { - if (!entry.key?.trim() || !entry.value?.trim()) continue; - if (!isSensitiveHeaderKey(entry.key)) continue; - const envSegment = headerKeyToEnvSegment(entry.key); - const envKey = makeEnvVarKey( - connector.name as string, - envSegment, - originalBlob, - opts?.schema, - ); - const raw = entry.value.trim(); - const split = splitAuthSchemePrefix(raw); - blob = replaceOrAddEnvVariable(blob, envKey, split ? split.secret : raw); - } - } - - return { newBlob: blob, originalBlob }; -} - export function replaceOrAddEnvVariable( existingEnvBlob: string, key: string, @@ -372,128 +62,6 @@ export function replaceOrAddEnvVariable( return newBlob; } -export function deleteEnvVariable( - existingEnvBlob: string, - key: string, -): string { - const lines = existingEnvBlob.split("\n"); - const updatedLines = lines.filter((line) => !line.startsWith(`${key}=`)); - const newBlob = updatedLines - .filter((line, index) => !(line === "" && index === 0)) - .join("\n") - .trim(); - - return newBlob; -} - -/** - * Get a generic ALL_CAPS environment variable name for a connector property. - * If schema provides x-env-var-name, use it directly. - * Otherwise uses DRIVER_NAME_PROPERTY_KEY format. - * - * @param driverName - The connector driver name (e.g., "clickhouse", "s3") - * @param propertyKey - The property key (e.g., "password", "aws_access_key_id") - * @param schema - Optional schema with x-env-var-name annotations - * @returns The environment variable name in SCREAMING_SNAKE_CASE - * - * @example - * getGenericEnvVarName("clickhouse", "password") // "CLICKHOUSE_PASSWORD" - * getGenericEnvVarName("s3", "aws_access_key_id", s3Schema) // "AWS_ACCESS_KEY_ID" (from x-env-var-name) - */ -export function getGenericEnvVarName( - driverName: string, - propertyKey: string, - schema?: { properties?: Record }, -): string { - // If schema provides explicit env var name, use it - const field = schema?.properties?.[propertyKey]; - if (field?.["x-env-var-name"]) { - return field["x-env-var-name"]; - } - - // Convert property key to SCREAMING_SNAKE_CASE - const propertyKeyUpper = propertyKey - .replace(/([a-z])([A-Z])/g, "$1_$2") - .replace(/[._-]+/g, "_") - .toUpperCase(); - - // Otherwise, use DriverName_PropertyKey format - const driverNameUpper = driverName - .replace(/([a-z])([A-Z])/g, "$1_$2") - .replace(/[._-]+/g, "_") - .toUpperCase(); - - return `${driverNameUpper}_${propertyKeyUpper}`; -} - -/** - * Check if an environment variable exists in the env blob. - * - * @param envBlob - The contents of the .env file as a string - * @param varName - The environment variable name to check for - * @returns true if the variable exists, false otherwise - */ -export function envVarExists(envBlob: string, varName: string): boolean { - const lines = envBlob.split("\n"); - return lines.some((line) => line.startsWith(`${varName}=`)); -} - -/** - * Find the next available environment variable name by appending _1, _2, etc. - * Used to avoid conflicts when creating multiple connectors of the same type. - * - * @param envBlob - The contents of the .env file as a string - * @param baseName - The base environment variable name to check - * @returns The first available name (baseName, baseName_1, baseName_2, etc.) - * - * @example - * // If .env contains "AWS_ACCESS_KEY_ID=xxx" - * findAvailableEnvVarName(envBlob, "AWS_ACCESS_KEY_ID") // "AWS_ACCESS_KEY_ID_1" - */ -export function findAvailableEnvVarName( - envBlob: string, - baseName: string, -): string { - let varName = baseName; - let counter = 1; - - while (envVarExists(envBlob, varName)) { - varName = `${baseName}_${counter}`; - counter++; - } - - return varName; -} - -/** - * Generate an environment variable key for a property. - * Uses schema-defined x-env-var-name when available, otherwise generates - * DRIVER_NAME_PROPERTY_KEY format. Handles conflicts by appending _1, _2, etc. - * - * @param driverName - The connector driver name (e.g., "clickhouse", "s3") - * @param key - The property key (e.g., "password", "dsn") - * @param existingEnvBlob - Optional existing .env content for conflict detection - * @param schema - Optional schema with x-env-var-name annotations - * @returns The environment variable name, with suffix if needed to avoid conflicts - */ -export function makeEnvVarKey( - driverName: string, - key: string, - existingEnvBlob?: string, - schema?: { properties?: Record }, -): string { - // Generate generic ALL_CAPS environment variable name - const baseGenericName = getGenericEnvVarName(driverName, key, schema); - - // If no existing env blob is provided, just return the base generic name - if (!existingEnvBlob) { - return baseGenericName; - } - - // Check for conflicts and append _# if necessary - return findAvailableEnvVarName(existingEnvBlob, baseGenericName); -} - export async function updateRillYAMLWithOlapConnector( queryClient: QueryClient, newConnector: string, diff --git a/web-common/src/features/sources/modal/AddDataFormManager.ts b/web-common/src/features/sources/modal/AddDataFormManager.ts index 875a653d138..4d99c0ee2f7 100644 --- a/web-common/src/features/sources/modal/AddDataFormManager.ts +++ b/web-common/src/features/sources/modal/AddDataFormManager.ts @@ -23,15 +23,12 @@ import { type ConnectorStepState, } from "./connectorStepStore"; import { get } from "svelte/store"; -import { compileConnectorYAML } from "../../connectors/code-utils"; import type { ActionResult } from "@sveltejs/kit"; import type { QueryClient } from "@tanstack/query-core"; import { filterSchemaValuesForSubmit, findRadioEnumKey, getSchemaFieldMetaList, - getSchemaSecretKeys, - getSchemaStringKeys, } from "../../templates/schema-utils"; import type { ButtonLabels } from "../../templates/schemas/types"; import { processFileContent } from "../../templates/file-encoding"; @@ -499,8 +496,7 @@ export class AddDataFormManager { /** * Compute YAML preview for the current form state. - * HTTPS connector step uses synchronous client-side YAML generation; - * all other paths call the GenerateTemplate RPC. + * All connectors use the GenerateTemplate RPC. */ async computeYamlPreview(ctx: { stepState: ConnectorStepState | undefined; @@ -515,49 +511,6 @@ export class AddDataFormManager { const schema = getConnectorSchema(this.schemaName); const instanceId = get(runtime).instanceId; - // HTTPS connector step: use synchronous client-side YAML generation - // (backend doesn't support headers array yet) - const getHttpsConnectorYamlPreview = ( - values: Record, - ): string => { - const schemaConnectorFields = schema - ? getSchemaFieldMetaList(schema, { step: "connector" }) - : []; - const schemaConnectorSecretKeys = schema - ? getSchemaSecretKeys(schema, { step: "connector" }) - : undefined; - const schemaConnectorStringKeys = schema - ? getSchemaStringKeys(schema, { step: "connector" }) - : undefined; - - const filteredValues = schema - ? filterSchemaValuesForSubmit(schema, values, { step: "connector" }) - : values; - return compileConnectorYAML(connector, filteredValues, { - fieldFilter: (property) => { - if ("internal" in property && property.internal) return false; - return !("noPrompt" in property && property.noPrompt); - }, - orderedProperties: schemaConnectorFields, - secretKeys: schemaConnectorSecretKeys, - stringKeys: schemaConnectorStringKeys, - schema: schema ?? undefined, - }); - }; - - // For HTTPS connector step, use client-side preview - if (connector.name === "https" && isConnectorForm) { - return getHttpsConnectorYamlPreview(formValues); - } - if ( - connector.name === "https" && - isMultiStepConnector && - stepState?.step === "connector" - ) { - return getHttpsConnectorYamlPreview(formValues); - } - - // All other paths: use the GenerateTemplate RPC const isOnConnectorStep = !stepState || stepState.step === "connector"; const isOnSourceOrExplorerStep = stepState?.step === "source" || stepState?.step === "explorer"; diff --git a/web-common/src/features/sources/modal/submitAddDataForm.ts b/web-common/src/features/sources/modal/submitAddDataForm.ts index d18e5fa27f2..11eac7cb11c 100644 --- a/web-common/src/features/sources/modal/submitAddDataForm.ts +++ b/web-common/src/features/sources/modal/submitAddDataForm.ts @@ -15,11 +15,7 @@ import { runtimeServiceUnpackEmpty, } from "../../../runtime-client"; import { runtime } from "../../../runtime-client/runtime-store"; -import { - compileConnectorYAML, - updateDotEnvWithSecrets, - updateRillYAMLWithOlapConnector, -} from "../../connectors/code-utils"; +import { updateRillYAMLWithOlapConnector } from "../../connectors/code-utils"; import { runtimeServicePutFileAndWaitForReconciliation, waitForResourceReconciliation, @@ -33,12 +29,6 @@ import { EMPTY_PROJECT_TITLE } from "../../welcome/constants"; import { isProjectInitialized } from "../../welcome/is-project-initialized"; import { sourceIngestionTracker } from "../sources-store"; import { OLAP_ENGINES } from "./constants"; -import { getConnectorSchema } from "./connector-schemas"; -import { - getSchemaFieldMetaList, - getSchemaSecretKeys, - getSchemaStringKeys, -} from "../../templates/schema-utils"; import { generateTemplate, mergeEnvVars } from "./generate-template"; interface AddDataFormValues { @@ -151,74 +141,29 @@ async function saveConnectorAnyway( // Mark to avoid rollback by concurrent submissions savedAnywayPaths.add(newConnectorFilePath); - if (connector.name === "https") { - // HTTPS: keep client-side path (backend doesn't support headers array yet) - const schema = getConnectorSchema(connector.name ?? ""); - const schemaFields = schema - ? getSchemaFieldMetaList(schema, { step: "connector" }) - : []; - const schemaSecretKeys = schema - ? getSchemaSecretKeys(schema, { step: "connector" }) - : []; - const schemaStringKeys = schema - ? getSchemaStringKeys(schema, { step: "connector" }) - : []; - - const { newBlob: newEnvBlob, originalBlob: envBlobForYaml } = - await updateDotEnvWithSecrets(queryClient, connector, formValues, { - secretKeys: schemaSecretKeys, - schema: schema ?? undefined, - }); - - await runtimeServicePutFile(resolvedInstanceId, { - path: ".env", - blob: newEnvBlob, - create: true, - createOnly: false, - }); - - await runtimeServicePutFile(resolvedInstanceId, { - path: newConnectorFilePath, - blob: compileConnectorYAML(connector, formValues, { - connectorInstanceName: newConnectorName, - orderedProperties: schemaFields, - secretKeys: schemaSecretKeys, - stringKeys: schemaStringKeys, - schema: schema ?? undefined, - existingEnvBlob: envBlobForYaml, - fieldFilter: schemaFields - ? (property) => !("internal" in property && property.internal) - : undefined, - }), - create: true, - createOnly: false, - }); - } else { - // All other connectors: use the GenerateTemplate RPC - const templateResponse = await generateTemplate(resolvedInstanceId, { - resourceType: "connector", - driver: connector.name as string, - properties: formValues, - }); - const { newBlob: newEnvBlob } = await mergeEnvVars( - queryClient, - templateResponse.envVars ?? {}, - ); + const templateResponse = await generateTemplate(resolvedInstanceId, { + resourceType: "connector", + driver: connector.name as string, + properties: formValues, + }); + const { newBlob: newEnvBlob } = await mergeEnvVars( + queryClient, + templateResponse.envVars ?? {}, + ); - await runtimeServicePutFile(resolvedInstanceId, { - path: ".env", - blob: newEnvBlob, - create: true, - createOnly: false, - }); + await runtimeServicePutFile(resolvedInstanceId, { + path: ".env", + blob: newEnvBlob, + create: true, + createOnly: false, + }); - await runtimeServicePutFile(resolvedInstanceId, { - path: newConnectorFilePath, - blob: templateResponse.blob ?? "", - create: true, - createOnly: false, - }); - } + await runtimeServicePutFile(resolvedInstanceId, { + path: newConnectorFilePath, + blob: templateResponse.blob ?? "", + create: true, + createOnly: false, + }); if (OLAP_ENGINES.includes(connector.name as string)) { await setOlapConnectorInRillYAML( @@ -302,57 +247,18 @@ export async function submitAddConnectorForm( let newEnvBlob: string; let connectorYamlBlob: string; - if (connector.name === "https") { - // HTTPS: keep client-side path (backend doesn't support headers array yet) - const schema = getConnectorSchema(connector.name ?? ""); - const schemaFields = schema - ? getSchemaFieldMetaList(schema, { step: "connector" }) - : []; - const schemaSecretKeys = schema - ? getSchemaSecretKeys(schema, { step: "connector" }) - : []; - const schemaStringKeys = schema - ? getSchemaStringKeys(schema, { step: "connector" }) - : []; - - const envResult = await updateDotEnvWithSecrets( - queryClient, - connector, - formValues, - { - secretKeys: schemaSecretKeys, - schema: schema ?? undefined, - }, - ); - newEnvBlob = envResult.newBlob; - originalEnvBlob = envResult.originalBlob; - - connectorYamlBlob = compileConnectorYAML(connector, formValues, { - connectorInstanceName: newConnectorName, - orderedProperties: schemaFields, - secretKeys: schemaSecretKeys, - stringKeys: schemaStringKeys, - schema: schema ?? undefined, - existingEnvBlob: originalEnvBlob, - fieldFilter: schemaFields - ? (property) => !("internal" in property && property.internal) - : undefined, - }); - } else { - // All other connectors: use the GenerateTemplate RPC - const templateResponse = await generateTemplate(instanceId, { - resourceType: "connector", - driver: connector.name as string, - properties: formValues, - }); - const envResult = await mergeEnvVars( - queryClient, - templateResponse.envVars ?? {}, - ); - newEnvBlob = envResult.newBlob; - originalEnvBlob = envResult.originalBlob; - connectorYamlBlob = templateResponse.blob ?? ""; - } + const templateResponse = await generateTemplate(instanceId, { + resourceType: "connector", + driver: connector.name as string, + properties: formValues, + }); + const envResult = await mergeEnvVars( + queryClient, + templateResponse.envVars ?? {}, + ); + newEnvBlob = envResult.newBlob; + originalEnvBlob = envResult.originalBlob; + connectorYamlBlob = templateResponse.blob ?? ""; if (saveAnyway) { // Save Anyway: bypass reconciliation entirely via centralized helper diff --git a/web-common/src/features/templates/schema-utils.ts b/web-common/src/features/templates/schema-utils.ts index 583e1dd81a6..18a4b94a88f 100644 --- a/web-common/src/features/templates/schema-utils.ts +++ b/web-common/src/features/templates/schema-utils.ts @@ -340,7 +340,35 @@ export function filterSchemaValuesForSubmit( opts?: { step?: "connector" | "source" | string }, ): Record { const tabFiltered = filterValuesByTabGroups(schema, values, opts); - return filterSchemaInternalValues(schema, tabFiltered, opts); + const internalFiltered = filterSchemaInternalValues( + schema, + tabFiltered, + opts, + ); + return convertKeyValueFieldsToMap(schema, internalFiltered); +} + +/** + * Convert key-value display fields from array format [{key, value}] to a plain + * map {key: value}. The backend RPC expects map-typed properties, but the + * key-value UI produces arrays. + */ +function convertKeyValueFieldsToMap( + schema: MultiStepFormSchema, + values: Record, +): Record { + const result = { ...values }; + for (const [key, prop] of Object.entries(schema.properties ?? {})) { + if (prop["x-display"] !== "key-value") continue; + const val = result[key]; + if (!Array.isArray(val)) continue; + result[key] = Object.fromEntries( + (val as Array<{ key: string; value: string }>) + .filter((e) => e.key?.trim()) + .map((e) => [e.key.trim(), e.value ?? ""]), + ); + } + return result; } export function findRadioEnumKey(schema: MultiStepFormSchema): string | null { diff --git a/web-common/src/features/templates/schemas/athena.ts b/web-common/src/features/templates/schemas/athena.ts index 20e8dd7becc..b8765fcd578 100644 --- a/web-common/src/features/templates/schemas/athena.ts +++ b/web-common/src/features/templates/schemas/athena.ts @@ -12,7 +12,6 @@ export const athenaSchema: MultiStepFormSchema = { description: "AWS access key ID used to authenticate to Athena", "x-placeholder": "your_access_key_id", "x-secret": true, - "x-env-var-name": "AWS_ACCESS_KEY_ID", "x-step": "connector", }, aws_secret_access_key: { @@ -21,7 +20,6 @@ export const athenaSchema: MultiStepFormSchema = { description: "AWS secret access key paired with the access key ID", "x-placeholder": "your_secret_access_key", "x-secret": true, - "x-env-var-name": "AWS_SECRET_ACCESS_KEY", "x-step": "connector", }, output_location: { diff --git a/web-common/src/features/templates/schemas/azure.ts b/web-common/src/features/templates/schemas/azure.ts index 99d6357f414..7eac49b916a 100644 --- a/web-common/src/features/templates/schemas/azure.ts +++ b/web-common/src/features/templates/schemas/azure.ts @@ -40,7 +40,6 @@ export const azureSchema: MultiStepFormSchema = { description: "Paste an Azure Storage connection string", "x-placeholder": "Enter Azure storage connection string", "x-secret": true, - "x-env-var-name": "AZURE_STORAGE_CONNECTION_STRING", "x-step": "connector", "x-visible-if": { auth_method: "connection_string" }, }, @@ -58,7 +57,6 @@ export const azureSchema: MultiStepFormSchema = { description: "Primary or secondary access key for the storage account", "x-placeholder": "Enter Azure storage access key", "x-secret": true, - "x-env-var-name": "AZURE_STORAGE_KEY", "x-step": "connector", "x-visible-if": { auth_method: "account_key" }, }, @@ -69,7 +67,6 @@ export const azureSchema: MultiStepFormSchema = { "Shared Access Signature token for the storage account (starting with ?sv=)", "x-placeholder": "Enter Azure SAS token", "x-secret": true, - "x-env-var-name": "AZURE_STORAGE_SAS_TOKEN", "x-step": "connector", "x-visible-if": { auth_method: "sas_token" }, }, diff --git a/web-common/src/features/templates/schemas/bigquery.ts b/web-common/src/features/templates/schemas/bigquery.ts index 7c15d00cd8a..ccc047ce1ab 100644 --- a/web-common/src/features/templates/schemas/bigquery.ts +++ b/web-common/src/features/templates/schemas/bigquery.ts @@ -16,7 +16,6 @@ export const bigquerySchema: MultiStepFormSchema = { "x-file-encoding": "json", "x-file-extract": { project_id: "project_id" }, "x-secret": true, - "x-env-var-name": "GOOGLE_APPLICATION_CREDENTIALS", "x-step": "connector", }, project_id: { diff --git a/web-common/src/features/templates/schemas/clickhouse.ts b/web-common/src/features/templates/schemas/clickhouse.ts index 400120bbe93..46dbd67b06a 100644 --- a/web-common/src/features/templates/schemas/clickhouse.ts +++ b/web-common/src/features/templates/schemas/clickhouse.ts @@ -72,7 +72,6 @@ export const clickhouseSchema: MultiStepFormSchema = { "x-placeholder": "clickhouse://localhost:9000?username=default&password=password", "x-secret": true, - "x-env-var-name": "CLICKHOUSE_DSN", "x-visible-if": { deployment_type: ["cloud", "self-managed"], }, @@ -145,7 +144,6 @@ export const clickhouseSchema: MultiStepFormSchema = { description: "Password to connect to the ClickHouse server", "x-placeholder": "Database password", "x-secret": true, - "x-env-var-name": "CLICKHOUSE_PASSWORD", "x-visible-if": { deployment_type: ["cloud", "self-managed"], }, diff --git a/web-common/src/features/templates/schemas/druid.ts b/web-common/src/features/templates/schemas/druid.ts index ac647fd0b8e..f3ac15ed0cf 100644 --- a/web-common/src/features/templates/schemas/druid.ts +++ b/web-common/src/features/templates/schemas/druid.ts @@ -27,7 +27,6 @@ export const druidSchema: MultiStepFormSchema = { "x-placeholder": "https://example.com/druid/v2/sql/avatica-protobuf?authentication=BASIC&avaticaUser=user&avaticaPassword=pass", "x-secret": true, - "x-env-var-name": "DRUID_DSN", }, host: { type: "string", @@ -55,7 +54,6 @@ export const druidSchema: MultiStepFormSchema = { description: "Druid password", "x-placeholder": "password", "x-secret": true, - "x-env-var-name": "DRUID_PASSWORD", }, ssl: { type: "boolean", diff --git a/web-common/src/features/templates/schemas/gcs.ts b/web-common/src/features/templates/schemas/gcs.ts index 6024b9305d6..29f569cc901 100644 --- a/web-common/src/features/templates/schemas/gcs.ts +++ b/web-common/src/features/templates/schemas/gcs.ts @@ -37,7 +37,6 @@ export const gcsSchema: MultiStepFormSchema = { "x-file-accept": ".json", "x-file-encoding": "json", "x-secret": true, - "x-env-var-name": "GOOGLE_APPLICATION_CREDENTIALS", "x-step": "connector", "x-visible-if": { auth_method: "credentials" }, }, @@ -47,7 +46,6 @@ export const gcsSchema: MultiStepFormSchema = { description: "HMAC access key ID for S3-compatible authentication", "x-placeholder": "Enter your HMAC access key ID", "x-secret": true, - "x-env-var-name": "GCP_ACCESS_KEY_ID", "x-step": "connector", "x-visible-if": { auth_method: "hmac" }, }, @@ -57,7 +55,6 @@ export const gcsSchema: MultiStepFormSchema = { description: "HMAC secret access key for S3-compatible authentication", "x-placeholder": "Enter your HMAC secret access key", "x-secret": true, - "x-env-var-name": "GCP_SECRET_ACCESS_KEY", "x-step": "connector", "x-visible-if": { auth_method: "hmac" }, }, diff --git a/web-common/src/features/templates/schemas/motherduck.ts b/web-common/src/features/templates/schemas/motherduck.ts index 38581c3f2c9..dfb082b0645 100644 --- a/web-common/src/features/templates/schemas/motherduck.ts +++ b/web-common/src/features/templates/schemas/motherduck.ts @@ -18,7 +18,6 @@ export const motherduckSchema: MultiStepFormSchema = { description: "MotherDuck token", "x-placeholder": "your_motherduck_token", "x-secret": true, - "x-env-var-name": "MOTHERDUCK_TOKEN", }, schema_name: { type: "string", diff --git a/web-common/src/features/templates/schemas/mysql.ts b/web-common/src/features/templates/schemas/mysql.ts index 272aecb047c..c8585f97ba2 100644 --- a/web-common/src/features/templates/schemas/mysql.ts +++ b/web-common/src/features/templates/schemas/mysql.ts @@ -33,7 +33,6 @@ export const mysqlSchema: MultiStepFormSchema = { "Full DSN, e.g. mysql://user:password@host:3306/database?ssl-mode=REQUIRED", "x-placeholder": "mysql://user:password@host:3306/database", "x-secret": true, - "x-env-var-name": "MYSQL_DSN", "x-hint": "Use DSN or fill host/user/password/database below (not both at once).", }, @@ -70,7 +69,6 @@ export const mysqlSchema: MultiStepFormSchema = { description: "MySQL password", "x-placeholder": "your_password", "x-secret": true, - "x-env-var-name": "MYSQL_PASSWORD", }, "ssl-mode": { type: "string", diff --git a/web-common/src/features/templates/schemas/pinot.ts b/web-common/src/features/templates/schemas/pinot.ts index c937319088a..d9b5706f291 100644 --- a/web-common/src/features/templates/schemas/pinot.ts +++ b/web-common/src/features/templates/schemas/pinot.ts @@ -35,7 +35,6 @@ export const pinotSchema: MultiStepFormSchema = { "x-placeholder": "https://username:password@localhost:8000?controller=localhost:9000", "x-secret": true, - "x-env-var-name": "PINOT_DSN", }, broker_host: { type: "string", @@ -77,7 +76,6 @@ export const pinotSchema: MultiStepFormSchema = { description: "Pinot password", "x-placeholder": "password", "x-secret": true, - "x-env-var-name": "PINOT_PASSWORD", }, ssl: { type: "boolean", diff --git a/web-common/src/features/templates/schemas/postgres.ts b/web-common/src/features/templates/schemas/postgres.ts index 7c97f1c14ad..bc4efd04163 100644 --- a/web-common/src/features/templates/schemas/postgres.ts +++ b/web-common/src/features/templates/schemas/postgres.ts @@ -26,7 +26,6 @@ export const postgresSchema: MultiStepFormSchema = { "e.g. postgresql://user:password@host:5432/dbname?sslmode=require", "x-placeholder": "postgresql://postgres:postgres@localhost:5432/postgres", "x-secret": true, - "x-env-var-name": "POSTGRES_DSN", "x-hint": "Use a DSN or provide host/user/password/dbname below (but not both).", }, @@ -57,7 +56,6 @@ export const postgresSchema: MultiStepFormSchema = { description: "Postgres password", "x-placeholder": "your_password", "x-secret": true, - "x-env-var-name": "POSTGRES_PASSWORD", }, dbname: { type: "string", diff --git a/web-common/src/features/templates/schemas/redshift.ts b/web-common/src/features/templates/schemas/redshift.ts index 7b0351cf3a6..63a00057737 100644 --- a/web-common/src/features/templates/schemas/redshift.ts +++ b/web-common/src/features/templates/schemas/redshift.ts @@ -12,7 +12,6 @@ export const redshiftSchema: MultiStepFormSchema = { description: "AWS access key ID", "x-placeholder": "your_access_key_id", "x-secret": true, - "x-env-var-name": "AWS_ACCESS_KEY_ID", }, aws_secret_access_key: { type: "string", @@ -20,7 +19,6 @@ export const redshiftSchema: MultiStepFormSchema = { description: "AWS secret access key", "x-placeholder": "your_secret_access_key", "x-secret": true, - "x-env-var-name": "AWS_SECRET_ACCESS_KEY", }, region: { type: "string", diff --git a/web-common/src/features/templates/schemas/s3.ts b/web-common/src/features/templates/schemas/s3.ts index 5d1657ff809..d285b165896 100644 --- a/web-common/src/features/templates/schemas/s3.ts +++ b/web-common/src/features/templates/schemas/s3.ts @@ -37,7 +37,6 @@ export const s3Schema: MultiStepFormSchema = { description: "AWS access key ID for the bucket", "x-placeholder": "Enter AWS access key ID", "x-secret": true, - "x-env-var-name": "AWS_ACCESS_KEY_ID", "x-step": "connector", "x-visible-if": { auth_method: "access_keys" }, }, @@ -47,7 +46,6 @@ export const s3Schema: MultiStepFormSchema = { description: "AWS secret access key for the bucket", "x-placeholder": "Enter AWS secret access key", "x-secret": true, - "x-env-var-name": "AWS_SECRET_ACCESS_KEY", "x-step": "connector", "x-visible-if": { auth_method: "access_keys" }, }, @@ -75,7 +73,6 @@ export const s3Schema: MultiStepFormSchema = { description: "AWS Role ARN to assume", "x-placeholder": "arn:aws:iam::123456789012:role/MyRole", "x-secret": true, - "x-env-var-name": "AWS_ROLE_ARN", "x-step": "connector", "x-visible-if": { auth_method: "access_keys" }, }, diff --git a/web-common/src/features/templates/schemas/salesforce.ts b/web-common/src/features/templates/schemas/salesforce.ts index a37ba739239..83f87afef09 100644 --- a/web-common/src/features/templates/schemas/salesforce.ts +++ b/web-common/src/features/templates/schemas/salesforce.ts @@ -40,7 +40,6 @@ export const salesforceSchema: MultiStepFormSchema = { "Salesforce password, optionally followed by security token if required", "x-placeholder": "your_password_or_password+token", "x-secret": true, - "x-env-var-name": "SALESFORCE_PASSWORD", }, key: { type: "string", @@ -49,7 +48,6 @@ export const salesforceSchema: MultiStepFormSchema = { "x-display": "textarea", "x-placeholder": "your_private_key", "x-secret": true, - "x-env-var-name": "SALESFORCE_KEY", }, client_id: { type: "string", diff --git a/web-common/src/features/templates/schemas/snowflake.ts b/web-common/src/features/templates/schemas/snowflake.ts index 950084f4d5f..4449d65b4d5 100644 --- a/web-common/src/features/templates/schemas/snowflake.ts +++ b/web-common/src/features/templates/schemas/snowflake.ts @@ -56,7 +56,6 @@ export const snowflakeSchema: MultiStepFormSchema = { description: "Snowflake password", "x-placeholder": "your_password", "x-secret": true, - "x-env-var-name": "SNOWFLAKE_PASSWORD", "x-visible-if": { auth_method: "password" }, }, privateKey: { @@ -68,7 +67,6 @@ export const snowflakeSchema: MultiStepFormSchema = { "x-file-accept": ".pem,.p8", "x-file-encoding": "base64", "x-secret": true, - "x-env-var-name": "SNOWFLAKE_PRIVATE_KEY", "x-visible-if": { auth_method: "private_key" }, }, warehouse: { @@ -103,7 +101,6 @@ export const snowflakeSchema: MultiStepFormSchema = { "x-placeholder": "@//?warehouse=&role=", "x-secret": true, - "x-env-var-name": "SNOWFLAKE_DSN", "x-hint": "Include authenticator and privateKey query params for JWT if needed.", "x-visible-if": { auth_method: "dsn" }, diff --git a/web-common/src/features/templates/schemas/types.ts b/web-common/src/features/templates/schemas/types.ts index e4f71ac89b8..04625529282 100644 --- a/web-common/src/features/templates/schemas/types.ts +++ b/web-common/src/features/templates/schemas/types.ts @@ -66,11 +66,6 @@ export type JSONSchemaField = { * Group fields under tab options for enum-driven tab layouts. */ "x-tab-group"?: Record; - /** - * Explicit environment variable name for secret fields. - * When set, this name is used instead of computing it from driver + property key. - */ - "x-env-var-name"?: string; // Allow custom keywords such as errorMessage or future x-extensions. [key: string]: unknown; }; From 106af5f192cdd393d8eba9230965f9badfe9b5e5 Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Fri, 20 Feb 2026 16:11:18 -0800 Subject: [PATCH 04/62] chore: untrack personal docs and add to .gitignore --- .gitignore | 5 + ...-02-16-generate-template-api-brainstorm.md | 260 ----- ...6-02-16-feat-generate-template-rpc-plan.md | 915 ------------------ 3 files changed, 5 insertions(+), 1175 deletions(-) delete mode 100644 docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md delete mode 100644 docs/plans/2026-02-16-feat-generate-template-rpc-plan.md diff --git a/.gitignore b/.gitignore index dca5a1cc6b8..ca3cbc01861 100644 --- a/.gitignore +++ b/.gitignore @@ -98,6 +98,11 @@ latest.txt .claude/plans/ .claude/worktrees/ +# Personal docs and config (do not commit) +docs/brainstorms/ +docs/plans/ +.mcp.json + # Vite temp files vite.config.ts.timestamp-* diff --git a/docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md b/docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md deleted file mode 100644 index f88010bf869..00000000000 --- a/docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md +++ /dev/null @@ -1,260 +0,0 @@ -# Tech Design: YAML Generation — Imperative Functions vs. GenerateTemplate API - -**Date:** 2026-02-16 -**Status:** Brainstorm -**Author:** Cyrus Goh - ---- - -## Problem Statement - -The frontend has two imperative YAML builder functions — `compileSourceYAML()` and `compileConnectorYAML()` — that share overlapping logic but diverge in subtle ways. This creates: - -1. **Duplication:** Both functions handle secret extraction (`{{ .env.* }}` placeholders), string quoting, empty-value filtering, and property ordering — but with separate, slightly different implementations. -2. **Maintenance burden:** Adding a new connector or field type requires touching complex conditional logic with many special cases (ClickHouse `managed: false` exclusion, DuckDB SQL rewriting, HTTP header formatting, etc.). -3. **Frontend owns YAML format:** The frontend knows too much about what valid YAML looks like for each resource type. This knowledge should live closer to the backend, which actually parses and validates these files. - -### Current Architecture - -``` -Form Data → compileSourceYAML() / compileConnectorYAML() → YAML string → PutFile RPC → Backend - (imperative string builder) -``` - -**Key files:** -- `web-common/src/features/sources/sourceUtils.ts` — `compileSourceYAML()` (~90 lines) -- `web-common/src/features/connectors/code-utils.ts` — `compileConnectorYAML()` (~100 lines) -- `web-common/src/features/sources/modal/submitAddDataForm.ts` — primary caller -- `web-common/src/features/sources/modal/AddDataFormManager.ts` — YAML preview caller - -### Shared Logic (duplicated between the two functions) - -| Concern | compileSourceYAML | compileConnectorYAML | -|---------|-------------------|----------------------| -| YAML header with doc link | Yes | Yes | -| Secret → `{{ .env.VAR }}` | Yes | Yes | -| String property quoting | Yes | Yes | -| Empty value filtering | Yes | Yes | -| Env var name generation | Via `makeEnvVarKey()` | Via `makeEnvVarKey()` | -| SQL multi-line formatting | Yes | No | -| Headers map formatting | No | Yes | -| Property ordering | Implicit (object key order) | Explicit (orderedProperties) | -| Field filtering | Implicit (step-based) | Explicit (fieldFilter function) | -| Dev section | Yes (with Redshift exception) | No | - ---- - -## Approach A: Consolidate Imperative Functions (Frontend-Only Refactor) - -Merge `compileConnectorYAML` and `compileSourceYAML` into a unified `compileResourceYAML()` function that handles all resource types through configuration. - -### Design - -```typescript -interface ResourceYAMLOptions { - resourceType: "connector" | "source" | "model"; - driver: string; - formValues: Record; - orderedProperties?: ConnectorDriverProperty[]; - fieldFilter?: (property: ConnectorDriverProperty) => boolean; - secretKeys?: string[]; - stringKeys?: string[]; - connectorInstanceName?: string; - schema?: { properties?: Record }; - existingEnvBlob?: string; - includeDevSection?: boolean; - originalDriverName?: string; -} - -function compileResourceYAML(opts: ResourceYAMLOptions): string { - // Unified logic: - // 1. Generate header (type + driver + doc link) - // 2. Filter properties (by step, field filter, empty values) - // 3. Order properties (explicit or implicit) - // 4. Format each property: - // - Secrets → {{ .env.VAR }} - // - Strings → quoted - // - SQL → multi-line - // - Headers → YAML map - // - Default → raw value - // 5. Optional dev section - // 6. Return assembled YAML -} -``` - -### Migration Path - -1. Create `compileResourceYAML()` with all shared logic -2. Re-implement `compileSourceYAML()` and `compileConnectorYAML()` as thin wrappers -3. Gradually migrate callers to the unified function -4. Remove wrappers once all callers are migrated - -### Pros - -- No backend changes required -- Incremental, low-risk refactor -- Eliminates duplication between the two functions -- Can be done in a single PR - -### Cons - -- Frontend still owns YAML format knowledge — can drift from backend expectations -- Special cases keep accumulating as connectors are added -- Doesn't extend to other resource types (explores, dashboards, etc.) without growing the function -- YAML string building is inherently fragile (indentation, quoting, escaping) - -### Effort Estimate - -Small — 1-2 days of frontend work. - ---- - -## Approach B: Backend `GenerateTemplate` RPC (Recommended) - -New backend endpoint that accepts structured data and returns rendered YAML. The frontend becomes a thin form layer. - -### Design - -#### New RPC - -```protobuf -// GenerateTemplate renders a YAML file from structured input. -// Supports all resource types: connector, source, model, explore, dashboard, etc. -rpc GenerateTemplate(GenerateTemplateRequest) returns (GenerateTemplateResponse) { - option (google.api.http) = { - post: "/v1/instances/{instance_id}/generate/template", - body: "*" - }; -} - -message GenerateTemplateRequest { - string instance_id = 1; - // Resource type: "connector", "source", "model", "explore", "metrics_view", etc. - string resource_type = 2; - // Driver name (for connectors/sources): "clickhouse", "s3", "duckdb", etc. - string driver = 3; - // Structured key-value properties from the form - google.protobuf.Struct properties = 4; - // Optional: connector instance name (for sources that reference a connector) - string connector_name = 5; - // Optional: fields that should be treated as secrets (extracted to .env) - repeated string secret_keys = 6; -} - -message GenerateTemplateResponse { - // Rendered YAML blob, ready to write via PutFile - string blob = 1; - // Environment variables to write to .env (key → value) - map env_vars = 2; -} -``` - -#### New Architecture - -``` -Form Data → GenerateTemplate RPC → { blob, env_vars } → PutFile RPC (blob) + update .env (env_vars) - (backend) -``` - -#### Backend Implementation - -The backend would: -1. Look up a Go template for the given `resource_type` + `driver` combination -2. Apply structured properties to the template -3. Handle secret extraction: replace secret values with `{{ .env.VAR }}` and return the real values in `env_vars` -4. Return the rendered YAML blob - -Templates could be Go `text/template` files or a simple struct-to-YAML mapper using the `gopkg.in/yaml.v3` library. - -#### Frontend Changes - -```typescript -// Before (imperative) -const blob = compileConnectorYAML(connector, formValues, { ...options }); -await runtimeServicePutFile(instanceId, { path, blob, create: true }); -await updateDotEnvWithSecrets(instanceId, connector, formValues, options); - -// After (declarative) -const { blob, envVars } = await runtimeServiceGenerateTemplate(instanceId, { - resourceType: "connector", - driver: connector.name, - properties: formValues, - secretKeys: schemaSecretKeys, -}); -await runtimeServicePutFile(instanceId, { path, blob, create: true }); -await writeDotEnv(instanceId, envVars); -``` - -### Migration Path - -1. **Phase 1:** Implement `GenerateTemplate` RPC for connectors -2. **Phase 2:** Migrate `compileConnectorYAML()` callers to use the RPC -3. **Phase 3:** Add source/model support, migrate `compileSourceYAML()` callers -4. **Phase 4:** Extend to other resource types (explores, dashboards, etc.) -5. **Phase 5:** Remove frontend compile functions - -Each phase can be a separate PR. Old and new paths can coexist during migration. - -### Pros - -- Backend owns the canonical YAML format — single source of truth -- Frontend complexity drops dramatically — no YAML string building, quoting, or escaping -- Generalizes to all resource types (connectors, sources, models, explores, dashboards, APIs, canvases, themes, reports, alerts) -- Aligns with existing backend generation patterns (`GenerateMetricsViewFile`, `GenerateCanvas`, `GenerateResolver`) -- Secret handling can be co-located with template logic -- Backend can validate property completeness before rendering - -### Cons - -- Requires backend work (new RPC, template registry, tests) -- Larger scope — multi-phase migration across frontend and backend -- YAML preview in the form is lost (acceptable per discussion — not critical) -- Network round-trip for template rendering (acceptable — only on submit) -- Need to decide where templates live (Go code, embedded files, or database) - -### Effort Estimate - -Medium — 1-2 weeks across backend + frontend. - ---- - -## Open Questions - -1. **Secret handling ownership:** Should the backend fully own env var naming and `.env` file writes? Or should it just return `env_vars` and let the frontend write them? - - Option A: Backend returns `env_vars` map, frontend writes to `.env` (simpler, frontend already has this code) - - Option B: Backend writes `.env` directly as part of `GenerateTemplate` (cleaner, but couples template rendering with file I/O) - -2. **Template storage:** Where do the YAML templates live? - - Go struct-to-YAML mapping (type-safe, no template files) - - Embedded Go `text/template` files (flexible, easy to edit) - - Hardcoded strings in Go (simple, like current frontend approach but server-side) - -3. **DuckDB rewriting:** Currently `maybeRewriteToDuckDb()` transforms S3/GCS/HTTPS sources into DuckDB SQL. Should this logic move to the backend too, or stay as a frontend preprocessing step? - -4. **Connector property metadata:** The frontend schemas define `x-secret`, `x-string`, `x-env-var-name` extensions. Should the backend be the source of truth for these, or should the frontend continue to pass `secretKeys`/`stringKeys` in the request? - -5. **Backward compatibility:** Do we need to support both old (imperative) and new (RPC) paths simultaneously during migration? Or can we cut over all at once? - ---- - -## Recommendation - -**Approach B (Backend `GenerateTemplate` RPC)** is recommended because: - -- It addresses the root cause: the frontend shouldn't own YAML format knowledge -- It's a natural extension of existing backend patterns (`GenerateMetricsViewFile`, etc.) -- It generalizes to all resource types, not just connectors/sources -- The migration can be incremental (phase by phase) -- Loss of YAML preview is acceptable - -Approach A is a valid stopgap if backend bandwidth is limited, but it doesn't solve the fundamental problem of frontend-owned YAML format. - ---- - -## Key Decisions Made - -- **Motivation:** Duplication and maintenance burden in `compileSourceYAML`/`compileConnectorYAML` -- **Direction:** Backend RPC over frontend-only refactor -- **Scope:** All resource types (design wide), implement connectors/sources first -- **YAML Preview:** Can be dropped — not critical for users -- **Secret handling:** Open question to resolve during planning diff --git a/docs/plans/2026-02-16-feat-generate-template-rpc-plan.md b/docs/plans/2026-02-16-feat-generate-template-rpc-plan.md deleted file mode 100644 index 723e0e47e37..00000000000 --- a/docs/plans/2026-02-16-feat-generate-template-rpc-plan.md +++ /dev/null @@ -1,915 +0,0 @@ ---- -title: "feat: Backend GenerateTemplate RPC for declarative YAML generation" -type: feat -date: 2026-02-16 ---- - -# Backend GenerateTemplate RPC for Declarative YAML Generation - -## Overview - -Replace the frontend's imperative `compileSourceYAML()` and `compileConnectorYAML()` string-building functions with a backend `GenerateTemplate` RPC endpoint. The backend becomes the single source of truth for YAML file format, using driver `PropertySpec` metadata to render YAML from structured form data. This includes absorbing the `maybeRewriteToDuckDb()` logic — the backend uses `Spec.ImplementsObjectStore` / `ImplementsFileStore` to detect when a driver should be rewritten to a DuckDB model, builds the appropriate SQL query, and returns the rewritten resource type. Scoped to connectors and sources/models — skeleton resource YAML (explores, dashboards, etc.) remains as frontend constants. - -## Problem Statement - -The frontend has two imperative YAML builder functions that share overlapping logic but diverge in subtle ways: - -| Shared Concern | `compileSourceYAML` | `compileConnectorYAML` | -|---|---|---| -| YAML header + doc link | Yes | Yes | -| Secret -> `{{ .env.VAR }}` | Yes | Yes | -| String quoting | Yes | Yes | -| Empty value filtering | Yes | Yes | -| SQL multi-line formatting | Yes | No | -| Headers map formatting | No | Yes | -| Property ordering | Implicit | Explicit (`orderedProperties`) | -| Dev section | Yes (except Redshift) | No | - -**Pain points:** -1. **Duplication** — both functions reimplement secret handling, quoting, and value filtering -2. **Maintenance burden** — adding a new connector requires touching complex conditional logic with special cases (ClickHouse `managed: false`, DuckDB SQL rewriting, HTTP auth scheme splitting) -3. **Frontend owns format** — the frontend knows too much about what valid YAML looks like; this knowledge should live server-side -4. **Frontend owns driver rewriting** — `maybeRewriteToDuckDb()` makes resource-type decisions (connector → model) and driver decisions (s3 → duckdb) that belong server-side. The backend already has the signals it needs (`Spec.ImplementsObjectStore`, `Spec.ImplementsFileStore`) - -## Proposed Solution - -**Before:** -``` -Form Data -> compileSourceYAML() / compileConnectorYAML() -> YAML string -> PutFile RPC -> Backend - (imperative string builder) -``` - -**After:** -``` -Form Data -> GenerateTemplate RPC -> { blob, env_vars } -> PutFile RPC (blob) + merge .env (env_vars) - (backend) -``` - -## Technical Approach - -### Proto Definition - -```protobuf -rpc GenerateTemplate(GenerateTemplateRequest) returns (GenerateTemplateResponse) { - option (google.api.http) = { - post: "/v1/instances/{instance_id}/generate/template", - body: "*" - }; -} - -message GenerateTemplateRequest { - string instance_id = 1 [(validate.rules).string = {pattern: "^[_\\-a-zA-Z0-9]+$"}]; - string resource_type = 2 [(validate.rules).string = {in: ["connector", "model"]}]; - string driver = 3 [(validate.rules).string = {pattern: "^[a-z][a-z0-9_]*$"}]; - google.protobuf.Struct properties = 4; - string connector_name = 5; -} - -message GenerateTemplateResponse { - string blob = 1; - map env_vars = 2; - // Actual resource type used — may differ from request when driver is rewritten - // (e.g., s3 model request → duckdb model with SQL wrapping the s3 path) - string resource_type = 3; - // Actual driver used — may differ from request when rewritten to duckdb - string driver = 4; -} -``` - -`google.protobuf.Struct` matches existing codebase patterns (used in 11 places across `api.proto`). `resource_type` scoped to `"connector"` and `"model"` only. The response echoes the actual `resource_type` and `driver` used after any rewrites, so the frontend knows the correct file path and directory. - -### Backend Handler - -New file: `runtime/server/generate_template.go` - -```go -func (s *Server) GenerateTemplate(ctx context.Context, req *runtimev1.GenerateTemplateRequest) (*runtimev1.GenerateTemplateResponse, error) { - // 1. Permission check - if !auth.GetClaims(ctx, req.InstanceId).Can(runtime.EditRepo) { - return nil, ErrForbidden - } - - // 2. Validate driver exists - driver, ok := drivers.Connectors[req.Driver] - if !ok { - return nil, status.Errorf(codes.InvalidArgument, "unknown driver: %s", req.Driver) - } - spec := driver.Spec() - - // 3. Validate properties against original driver spec (reject unknown keys) - props := req.Properties.AsMap() - if err := validateProperties(spec, req.ResourceType, props); err != nil { - return nil, status.Errorf(codes.InvalidArgument, "%s", err) - } - - // 4. DuckDB rewrite for object store / file store / sqlite drivers - // Rewrite happens AFTER validation against the original driver spec, - // since the request properties match the original driver (e.g., s3's "path"). - actualDriver, actualResourceType := req.Driver, req.ResourceType - if req.ResourceType == "model" { - actualDriver, props = maybeRewriteToDuckDB(spec, req.Driver, props, req.ConnectorName) - } - - // 5. Read existing .env for env var conflict resolution - repo, release, err := s.runtime.Repo(ctx, req.InstanceId) - if err != nil { - return nil, err - } - defer release() - existingEnv := readEnvKeys(repo, ctx) - - // 6. Render YAML + extract secrets (using rewritten driver/props) - blob, envVars := renderYAML(spec, actualDriver, actualResourceType, props, existingEnv) - - return &runtimev1.GenerateTemplateResponse{ - Blob: blob, - EnvVars: envVars, - ResourceType: actualResourceType, - Driver: actualDriver, - }, nil -} -``` - -The handler reads `.env` via `repo.Get()` rather than accepting it as a request field. This eliminates sending ALL project secrets over the wire and removes the TOCTOU race between frontend read and backend use. - -### YAML Rendering Engine - -The backend renders YAML using the driver's `PropertySpec` metadata: - -1. **Property ordering**: Use `ConfigProperties` / `SourceProperties` order from the driver `Spec` -2. **Secret detection**: Use `PropertySpec.Secret` (backend is source of truth) -3. **Env var naming**: Use new `PropertySpec.EnvVarName` field (falls back to `DRIVER_KEY` format) -4. **String quoting**: Use `PropertySpec.Type == StringPropertyType` -5. **Value filtering**: Skip empty/nil values, skip properties not in request -6. **Property validation**: Reject unknown property keys not in driver's `PropertySpec` -7. **Header comment**: Generate `# Connector YAML\n# Reference documentation: ` -8. **Dev section**: Auto-generate for warehouse drivers (except Redshift) with `limit 10000` - -Build the `yaml.Node` tree directly rather than the marshal-unmarshal-encode triple-pass used in `generate_metrics_view.go:549-582`: - -```go -func buildConnectorYAML(spec drivers.Spec, driverName string, props map[string]any, envVarMap map[string]string) *yaml.Node { - doc := &yaml.Node{Kind: yaml.DocumentNode} - mapping := &yaml.Node{Kind: yaml.MappingNode} - mapping.HeadComment = fmt.Sprintf("Connector YAML\nReference documentation: %s", spec.DocsURL) - - addScalarPair(mapping, "type", "connector") - addScalarPair(mapping, "driver", driverName) - - for _, propSpec := range spec.ConfigProperties { - val, ok := props[propSpec.Key] - if !ok || isEmpty(val) { - continue - } - if propSpec.Secret { - addScalarPair(mapping, propSpec.Key, fmt.Sprintf("{{ .env.%s }}", envVarMap[propSpec.Key])) - } else if propSpec.Type == drivers.StringPropertyType { - addQuotedPair(mapping, propSpec.Key, fmt.Sprintf("%v", val)) - } else { - addScalarPair(mapping, propSpec.Key, fmt.Sprintf("%v", val)) - } - } - - doc.Content = append(doc.Content, mapping) - return doc -} - -func addScalarPair(m *yaml.Node, key, value string) { - m.Content = append(m.Content, - &yaml.Node{Kind: yaml.ScalarNode, Value: key}, - &yaml.Node{Kind: yaml.ScalarNode, Value: value}, - ) -} - -func addQuotedPair(m *yaml.Node, key, value string) { - m.Content = append(m.Content, - &yaml.Node{Kind: yaml.ScalarNode, Value: key}, - &yaml.Node{Kind: yaml.ScalarNode, Value: value, Style: yaml.DoubleQuotedStyle}, - ) -} - -func validateProperties(spec drivers.Spec, resourceType string, properties map[string]any) error { - allowed := make(map[string]bool) - props := spec.ConfigProperties - if resourceType == "model" { - props = spec.SourceProperties - } - for _, p := range props { - allowed[p.Key] = true - } - for key := range properties { - if !allowed[key] { - return fmt.Errorf("unknown property %q for driver", key) - } - } - return nil -} -``` - -### Key Design Decisions - -#### 1. DuckDB Rewrite Moves to Backend - -`maybeRewriteToDuckDb()` transforms S3/GCS/Azure/HTTPS/SQLite/local_file into DuckDB model files. This logic moves to the backend because: - -- The backend already has the signals: `Spec.ImplementsObjectStore` (s3, gcs, azure), `Spec.ImplementsFileStore` (https, local_file), and driver name (`sqlite`) -- The rewrite is a resource-type decision that the backend should own -- The `buildDuckDbQuery()` file-extension → read function mapping is ~20 lines of Go -- The `create_secrets_from_connectors` wiring is ~5 lines - -The frontend sends the **original** driver and properties (e.g., `driver: "s3"`, `properties: {path: "s3://bucket/file.parquet"}`). The backend detects the rewrite case, builds the DuckDB SQL, and returns the actual driver/resource_type used in the response so the frontend knows the correct file path. - -```go -func maybeRewriteToDuckDB(spec drivers.Spec, driverName string, props map[string]any, connectorName string) (string, map[string]any) { - if !spec.ImplementsObjectStore && !spec.ImplementsFileStore && driverName != "sqlite" { - return driverName, props - } - - rewritten := make(map[string]any, len(props)) - for k, v := range props { - rewritten[k] = v - } - - switch { - case spec.ImplementsObjectStore: // s3, gcs, azure - if connectorName != "" { - rewritten["create_secrets_from_connectors"] = connectorName - } - rewritten["sql"] = buildDuckDBQuery(strVal(props["path"]), false) - delete(rewritten, "path") - - case spec.ImplementsFileStore && driverName == "https": - if connectorName != "" { - rewritten["create_secrets_from_connectors"] = connectorName - } - rewritten["sql"] = buildDuckDBQuery(strVal(props["path"]), true) - delete(rewritten, "path") - - case spec.ImplementsFileStore: // local_file - rewritten["sql"] = buildDuckDBQuery(strVal(props["path"]), false) - delete(rewritten, "path") - - case driverName == "sqlite": - rewritten["sql"] = fmt.Sprintf("SELECT * FROM sqlite_scan('%s', '%s');", - strVal(props["db"]), strVal(props["table"])) - delete(rewritten, "db") - delete(rewritten, "table") - } - - return "duckdb", rewritten -} - -func buildDuckDBQuery(path string, defaultToJSON bool) string { - ext := strings.ToLower(filepath.Ext(path)) - switch { - case containsExt(ext, ".csv", ".tsv", ".txt"): - return fmt.Sprintf("select * from read_csv('%s', auto_detect=true, ignore_errors=1, header=true)", path) - case containsExt(ext, ".parquet"): - return fmt.Sprintf("select * from read_parquet('%s')", path) - case containsExt(ext, ".json", ".ndjson"): - return fmt.Sprintf("select * from read_json('%s', auto_detect=true, format='auto')", path) - default: - if defaultToJSON { - return fmt.Sprintf("select * from read_json('%s', auto_detect=true, format='auto')", path) - } - return fmt.Sprintf("select * from '%s'", path) - } -} -``` - -Note: `containsExt` checks if the full extension (e.g., `.v1.parquet.gz`) contains the target part, matching the current frontend behavior of `extensionContainsParts()`. - -#### 2. Backend Is Source of Truth for Secrets - -Backend uses `PropertySpec.Secret` to identify secrets. No `secret_keys` in the request. Automated Go test asserts Secret flags match expected values for all drivers before shipping. - -#### 3. Env Var Naming Uses New `EnvVarName` Field - -Add `EnvVarName string` to `PropertySpec`. When set, use it (e.g., S3's `aws_access_key_id` -> `AWS_ACCESS_KEY_ID`). When empty, fall back to `DRIVER_KEY` format. Must match current frontend naming exactly or existing `.env` files break on upgrade. - -#### 4. Backend Reads `.env` Directly - -Backend reads `.env` via `repo.Get()` and parses key names into a `map[string]bool` for O(1) conflict detection. Response `env_vars` is a delta. Frontend merges with existing `.env` using `replaceOrAddEnvVariable()`. - -#### 5. Frontend Strips x-ui-only Fields - -Fields like `deployment_type`, `connection_mode`, `auth_method` are stripped before calling `GenerateTemplate`. Backend validates and rejects unknown keys. Postgres DSN-vs-parameters tabs are handled by `filterSchemaValuesForSubmit()`. - -#### 6. `GenerateTemplate` Does Not Write Files - -Returns blob + env_vars. Frontend calls `PutFile` separately. This enables rollback (restore original `.env` on reconciliation failure) and the "Save Anyway" bypass flow. - -#### 7. No Backward Compatibility Fallback - -Runtime deploys before UI. No catch-UNIMPLEMENTED fallback needed. Old frontend compile functions are removed immediately after migration. - -### Implementation - -**Scope:** All connectors (including HTTPS), all sources/models, and cleanup — shipped as one unit. - -**Backend tasks:** -- [ ] Add `EnvVarName string` field to `PropertySpec` in `runtime/drivers/connectors.go` -- [ ] Add `EnvVarName` values to drivers with custom env var names (S3, GCS, BigQuery, etc.) -- [ ] Write automated Go test asserting `PropertySpec.Secret` matches expected values for all drivers; fix discrepancies -- [ ] Define `GenerateTemplateRequest`/`GenerateTemplateResponse` in `proto/rill/runtime/v1/api.proto` with validation annotations -- [ ] Run `buf generate` to regenerate Go and TypeScript proto bindings -- [ ] Implement `GenerateTemplate` handler in `runtime/server/generate_template.go` - - Permission check (`EditRepo`) - - Driver validation (must exist in `drivers.Connectors`) - - Property validation (reject unknown keys) - - `.env` read via `repo.Get()` for conflict resolution - - YAML rendering via `yaml.Node` direct construction - - Secret -> `{{ .env.VAR }}` replacement using `PropertySpec.Secret` - - Env var naming from `PropertySpec.EnvVarName` with conflict suffix - - Header comment with driver `DocsURL` - - Value filtering (empty/nil) - - String quoting for `StringPropertyType` - - ClickHouse: exclude `managed: false` when default - - Redshift: skip dev section - - Model type: `type: model`, `materialize: true`, `connector:`, `sql:`, dev section - - HTTPS headers: `formatHeadersAsYamlMap()` equivalent with auth-scheme splitting - - DuckDB rewrite: detect `ImplementsObjectStore`/`ImplementsFileStore`/sqlite, build SQL from path + file extension, set `create_secrets_from_connectors` - - Return actual `resource_type` and `driver` in response (may differ from request after rewrite) -- [ ] Write Go unit tests (see Testing Strategy below) -- [ ] Never include property values or env var values in error messages - -**Frontend tasks:** -- [ ] Update `submitAddDataForm.ts` to call `GenerateTemplate` for all connectors -- [ ] Update `submitAddDataForm.ts` to call `GenerateTemplate` for source/model creation (send original driver + properties, no preprocessing) -- [ ] Use response `resource_type` and `driver` to determine file path (replaces frontend rewrite logic for path calculation) -- [ ] Strip `x-ui-only` fields from form values before sending (using `filterSchemaValuesForSubmit()`) -- [ ] Update `.env` merge logic to use `env_vars` response delta -- [ ] Remove `compileConnectorYAML()` and `compileSourceYAML()` (dead code) -- [ ] Remove `maybeRewriteToDuckDb()`, `buildDuckDbQuery()`, `extensionContainsParts()`, `prepareSourceFormData()` (dead code) -- [ ] Remove `updateDotEnvWithSecrets()`, `makeEnvVarKey()`, `findAvailableEnvVarName()`, `getGenericEnvVarName()` (dead code) - -**Success criteria:** -- [ ] Creating any connector via the form produces identical YAML as before -- [ ] Creating any source/model via the form produces identical YAML as before -- [ ] S3/GCS/Azure/HTTPS/local_file/SQLite sources are correctly rewritten to DuckDB models with proper SQL -- [ ] `create_secrets_from_connectors` is set correctly for object store and HTTPS sources -- [ ] `.env` file is correctly updated with secrets -- [ ] All auth method variants work (S3 access_keys vs public, ClickHouse parameters vs DSN, etc.) -- [ ] HTTPS headers with sensitive auth tokens correctly extracted to `.env` -- [ ] Zero frontend YAML string building or driver rewriting remains - -### Testing Strategy - -New file: `runtime/server/generate_template_test.go` - -Tests follow the codebase's existing pattern: table-driven tests using `testruntime.NewInstanceWithOptions()` and `server.NewServer()`, with `require.Contains()` / `require.Equal()` assertions on YAML output. - -Note: The frontend functions being replaced (`compileSourceYAML`, `compileConnectorYAML`, `maybeRewriteToDuckDb`, `buildDuckDbQuery`) have **zero direct unit tests**. Only env var helpers are tested. The backend tests here are net-new coverage — there is no existing frontend test output to port. - -#### Test 1: PropertySpec.Secret Flag Assertion - -Automated test that asserts `PropertySpec.Secret` matches expected values for every registered driver. Catches drift between backend metadata and frontend `x-secret` annotations. - -```go -func TestPropertySpecSecretFlags(t *testing.T) { - // Expected secret keys per driver, derived from frontend x-secret annotations - expected := map[string][]string{ - "s3": {"aws_access_key_id", "aws_secret_access_key", "aws_role_arn", "aws_role_session_name", "aws_external_id"}, - "gcs": {"google_application_credentials", "key_id", "secret"}, - "azure": {"azure_storage_account", "azure_storage_key", "azure_storage_sas_token", "azure_storage_connection_string"}, - "clickhouse": {"dsn", "password", "write_dsn"}, - "postgres": {"dsn", "password"}, - "bigquery": {"google_application_credentials"}, - "snowflake": {"dsn", "password", "privateKey"}, - "redshift": {"aws_access_key_id", "aws_secret_access_key"}, - "motherduck": {"token"}, - "athena": {"aws_access_key_id", "aws_secret_access_key"}, - "mysql": {"dsn", "password"}, - "druid": {"dsn", "password"}, - "pinot": {"dsn", "password"}, - "starrocks": {"dsn", "password"}, - "salesforce": {"password", "key"}, - } - - for driverName, driver := range drivers.Connectors { - spec := driver.Spec() - expectedKeys, ok := expected[driverName] - if !ok { - continue // AI/notifier drivers not relevant to GenerateTemplate - } - actualSecrets := secretKeys(spec.ConfigProperties) - require.ElementsMatch(t, expectedKeys, actualSecrets, "driver %s", driverName) - } -} -``` - -#### Test 2: Connector YAML Rendering (Table-Driven) - -One test case per driver, covering the most common form submission for each. Validates the full YAML blob output. - -```go -func TestBuildConnectorYAML(t *testing.T) { - tt := []struct { - name string - driver string - props map[string]any - contains []string // key substrings that must appear in output - excludes []string // substrings that must NOT appear - }{ - { - name: "clickhouse with parameters", - driver: "clickhouse", - props: map[string]any{"host": "ch.example.com", "port": "9000", "password": "secret123"}, - contains: []string{ - "type: connector", - "driver: clickhouse", - `host: "ch.example.com"`, - "port: 9000", - `password: "{{ .env.CLICKHOUSE_PASSWORD }}"`, - "# Connector YAML", - "Reference documentation: https://docs.rilldata.com", - }, - excludes: []string{"secret123"}, // actual secret value must never appear - }, - { - name: "clickhouse with dsn", - driver: "clickhouse", - props: map[string]any{"dsn": "clickhouse://user:pass@host:9000/db"}, - contains: []string{ - `dsn: "{{ .env.CLICKHOUSE_DSN }}"`, - }, - excludes: []string{"clickhouse://user:pass"}, - }, - { - name: "s3 connector", - driver: "s3", - props: map[string]any{"aws_access_key_id": "AKIA...", "aws_secret_access_key": "secret"}, - contains: []string{ - "driver: s3", - `aws_access_key_id: "{{ .env.AWS_ACCESS_KEY_ID }}"`, - `aws_secret_access_key: "{{ .env.AWS_SECRET_ACCESS_KEY }}"`, - }, - excludes: []string{"AKIA", "secret"}, - }, - { - name: "bigquery connector", - driver: "bigquery", - props: map[string]any{"project_id": "my-project", "google_application_credentials": `{"type":"service_account"}`}, - contains: []string{ - "driver: bigquery", - `project_id: "my-project"`, - `google_application_credentials: "{{ .env.GOOGLE_APPLICATION_CREDENTIALS }}"`, - }, - }, - { - name: "postgres with individual params", - driver: "postgres", - props: map[string]any{"host": "db.example.com", "port": "5432", "password": "pass"}, - contains: []string{ - "driver: postgres", - `host: "db.example.com"`, - `password: "{{ .env.POSTGRES_PASSWORD }}"`, - }, - }, - { - name: "empty values filtered", - driver: "clickhouse", - props: map[string]any{"host": "ch.example.com", "port": "", "database": ""}, - contains: []string{"host:"}, - excludes: []string{"port:", "database:"}, - }, - { - name: "clickhouse managed false excluded when default", - driver: "clickhouse", - props: map[string]any{"host": "ch.example.com", "managed": false}, - excludes: []string{"managed"}, - }, - } - - for _, tc := range tt { - t.Run(tc.name, func(t *testing.T) { - // ... render and assert - }) - } -} -``` - -**Drivers to cover:** clickhouse (params + DSN), postgres (params + DSN), s3, gcs, azure, bigquery, snowflake, redshift, athena, motherduck, duckdb, druid, pinot, starrocks, mysql, salesforce. That's 16 drivers × 1-2 variants each. - -#### Test 3: Model YAML Rendering (Table-Driven) - -Validates model output including `type: model`, `materialize: true`, `connector:`, SQL formatting, and dev section. - -```go -func TestBuildModelYAML(t *testing.T) { - tt := []struct { - name string - driver string - props map[string]any - connName string - contains []string - excludes []string - }{ - { - name: "clickhouse model with dev section", - driver: "clickhouse", - props: map[string]any{"sql": "SELECT * FROM events"}, - connName: "clickhouse_prod", - contains: []string{ - "type: model", - "materialize: true", - "connector: clickhouse_prod", - "sql: |", - " SELECT * FROM events", - "dev:", - "limit 10000", - "# Model YAML", - }, - }, - { - name: "redshift model without dev section", - driver: "redshift", - props: map[string]any{"sql": "SELECT * FROM events"}, - connName: "redshift_prod", - contains: []string{"type: model", "connector: redshift_prod"}, - excludes: []string{"dev:"}, - }, - { - name: "bigquery model with dev section", - driver: "bigquery", - props: map[string]any{"sql": "SELECT * FROM `project.dataset.table`"}, - connName: "bq_prod", - contains: []string{"dev:", "limit 10000"}, - }, - } - // ... -} -``` - -#### Test 4: DuckDB Rewrite (Table-Driven) - -Tests `maybeRewriteToDuckDB` and `buildDuckDBQuery` — the logic moving from frontend. - -```go -func TestMaybeRewriteToDuckDB(t *testing.T) { - tt := []struct { - name string - driver string - props map[string]any - connectorName string - wantDriver string - wantSQL string - wantSecrets string // expected create_secrets_from_connectors value - wantDeleted []string // keys that should be removed from props - }{ - // Object store drivers - { - name: "s3 csv", - driver: "s3", - props: map[string]any{"path": "s3://bucket/data.csv"}, - connectorName: "my_s3", - wantDriver: "duckdb", - wantSQL: "select * from read_csv('s3://bucket/data.csv', auto_detect=true, ignore_errors=1, header=true)", - wantSecrets: "my_s3", - wantDeleted: []string{"path"}, - }, - { - name: "s3 parquet", - driver: "s3", - props: map[string]any{"path": "s3://bucket/data.parquet"}, - wantDriver: "duckdb", - wantSQL: "select * from read_parquet('s3://bucket/data.parquet')", - }, - { - name: "s3 compressed parquet", - driver: "s3", - props: map[string]any{"path": "s3://bucket/data.v1.parquet.gz"}, - wantDriver: "duckdb", - wantSQL: "select * from read_parquet('s3://bucket/data.v1.parquet.gz')", - }, - { - name: "gcs json", - driver: "gcs", - props: map[string]any{"path": "gs://bucket/data.json"}, - wantDriver: "duckdb", - wantSQL: "select * from read_json('gs://bucket/data.json', auto_detect=true, format='auto')", - }, - { - name: "gcs ndjson", - driver: "gcs", - props: map[string]any{"path": "gs://bucket/data.ndjson"}, - wantDriver: "duckdb", - wantSQL: "select * from read_json('gs://bucket/data.ndjson', auto_detect=true, format='auto')", - }, - { - name: "azure tsv", - driver: "azure", - props: map[string]any{"path": "azure://container/data.tsv"}, - wantDriver: "duckdb", - wantSQL: "select * from read_csv('azure://container/data.tsv', auto_detect=true, ignore_errors=1, header=true)", - }, - { - name: "s3 unknown extension falls through", - driver: "s3", - props: map[string]any{"path": "s3://bucket/data.avro"}, - wantDriver: "duckdb", - wantSQL: "select * from 's3://bucket/data.avro'", - }, - - // File store drivers - { - name: "https defaults to json", - driver: "https", - props: map[string]any{"path": "https://api.example.com/data"}, - wantDriver: "duckdb", - wantSQL: "select * from read_json('https://api.example.com/data', auto_detect=true, format='auto')", - }, - { - name: "https with csv extension", - driver: "https", - props: map[string]any{"path": "https://example.com/data.csv"}, - wantDriver: "duckdb", - wantSQL: "select * from read_csv('https://example.com/data.csv', auto_detect=true, ignore_errors=1, header=true)", - }, - { - name: "https with connector name sets secrets", - driver: "https", - props: map[string]any{"path": "https://api.example.com/data"}, - connectorName: "my_http", - wantSecrets: "my_http", - }, - { - name: "local_file csv", - driver: "local_file", - props: map[string]any{"path": "/data/file.csv"}, - wantDriver: "duckdb", - wantSQL: "select * from read_csv('/data/file.csv', auto_detect=true, ignore_errors=1, header=true)", - wantSecrets: "", // no create_secrets_from_connectors for local_file - }, - - // SQLite - { - name: "sqlite", - driver: "sqlite", - props: map[string]any{"db": "/data/app.db", "table": "users"}, - wantDriver: "duckdb", - wantSQL: "SELECT * FROM sqlite_scan('/data/app.db', 'users');", - wantDeleted: []string{"db", "table"}, - }, - - // Non-rewritable drivers pass through - { - name: "clickhouse not rewritten", - driver: "clickhouse", - props: map[string]any{"sql": "SELECT 1"}, - wantDriver: "clickhouse", - }, - { - name: "postgres not rewritten", - driver: "postgres", - props: map[string]any{"sql": "SELECT 1"}, - wantDriver: "postgres", - }, - } - // ... -} -``` - -#### Test 5: Env Var Naming and Conflict Resolution - -Tests the `EnvVarName` field and `_1`, `_2` suffix logic. Mirrors the 48 frontend test cases in `code-utils.spec.ts`. - -```go -func TestEnvVarNaming(t *testing.T) { - tt := []struct { - name string - driver string - propKey string - envVarName string // PropertySpec.EnvVarName override - existingEnv map[string]bool - want string - }{ - // Schema-driven names (EnvVarName set) - {name: "s3 access key", driver: "s3", propKey: "aws_access_key_id", envVarName: "AWS_ACCESS_KEY_ID", want: "AWS_ACCESS_KEY_ID"}, - {name: "bigquery creds", driver: "bigquery", propKey: "google_application_credentials", envVarName: "GOOGLE_APPLICATION_CREDENTIALS", want: "GOOGLE_APPLICATION_CREDENTIALS"}, - {name: "motherduck token", driver: "motherduck", propKey: "token", envVarName: "MOTHERDUCK_TOKEN", want: "MOTHERDUCK_TOKEN"}, - {name: "clickhouse password", driver: "clickhouse", propKey: "password", envVarName: "CLICKHOUSE_PASSWORD", want: "CLICKHOUSE_PASSWORD"}, - - // Fallback naming (EnvVarName empty) → DRIVER_KEY format - {name: "fallback format", driver: "custom", propKey: "api_token", want: "CUSTOM_API_TOKEN"}, - - // Conflict resolution - {name: "first conflict", driver: "bigquery", propKey: "google_application_credentials", envVarName: "GOOGLE_APPLICATION_CREDENTIALS", - existingEnv: map[string]bool{"GOOGLE_APPLICATION_CREDENTIALS": true}, - want: "GOOGLE_APPLICATION_CREDENTIALS_1"}, - {name: "second conflict", driver: "bigquery", propKey: "google_application_credentials", envVarName: "GOOGLE_APPLICATION_CREDENTIALS", - existingEnv: map[string]bool{"GOOGLE_APPLICATION_CREDENTIALS": true, "GOOGLE_APPLICATION_CREDENTIALS_1": true}, - want: "GOOGLE_APPLICATION_CREDENTIALS_2"}, - {name: "multi-key conflict (s3)", driver: "s3", propKey: "aws_access_key_id", envVarName: "AWS_ACCESS_KEY_ID", - existingEnv: map[string]bool{"AWS_ACCESS_KEY_ID": true}, - want: "AWS_ACCESS_KEY_ID_1"}, - } - // ... -} -``` - -#### Test 6: Property Validation - -```go -func TestValidateProperties(t *testing.T) { - tt := []struct { - name string - driver string - resourceType string - props map[string]any - wantErr string - }{ - {name: "valid connector props", driver: "clickhouse", resourceType: "connector", props: map[string]any{"host": "x"}, wantErr: ""}, - {name: "unknown prop rejected", driver: "clickhouse", resourceType: "connector", props: map[string]any{"bogus": "x"}, wantErr: `unknown property "bogus"`}, - {name: "source prop on connector rejected", driver: "duckdb", resourceType: "connector", props: map[string]any{"sql": "SELECT 1"}, wantErr: `unknown property "sql"`}, - {name: "source prop on model accepted", driver: "duckdb", resourceType: "model", props: map[string]any{"sql": "SELECT 1"}, wantErr: ""}, - } - // ... -} -``` - -#### Test 7: Handler Integration Test - -End-to-end test through the RPC handler, using the same test infrastructure as `generate_metrics_view_test.go`. - -```go -func TestGenerateTemplate(t *testing.T) { - rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ - Files: map[string]string{"rill.yaml": ""}, - }) - server, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) - require.NoError(t, err) - - tt := []struct { - name string - req *runtimev1.GenerateTemplateRequest - wantContains []string - wantEnvVars map[string]string - wantDriver string // response driver (after rewrite) - wantResType string // response resource_type - wantErr codes.Code - }{ - { - name: "clickhouse connector", - req: &runtimev1.GenerateTemplateRequest{ - InstanceId: instanceID, - ResourceType: "connector", - Driver: "clickhouse", - Properties: structpb("host", "ch.example.com", "password", "secret123"), - }, - wantContains: []string{"type: connector", "driver: clickhouse", `{{ .env.CLICKHOUSE_PASSWORD }}`}, - wantEnvVars: map[string]string{"CLICKHOUSE_PASSWORD": "secret123"}, - wantDriver: "clickhouse", - wantResType: "connector", - }, - { - name: "s3 model rewritten to duckdb", - req: &runtimev1.GenerateTemplateRequest{ - InstanceId: instanceID, - ResourceType: "model", - Driver: "s3", - Properties: structpb("path", "s3://bucket/data.parquet"), - ConnectorName: "my_s3", - }, - wantContains: []string{"type: model", "connector: duckdb", "read_parquet", "create_secrets_from_connectors: my_s3"}, - wantDriver: "duckdb", - wantResType: "model", - }, - { - name: "unknown driver rejected", - req: &runtimev1.GenerateTemplateRequest{ - InstanceId: instanceID, - ResourceType: "connector", - Driver: "nonexistent", - Properties: structpb(), - }, - wantErr: codes.InvalidArgument, - }, - { - name: "unknown property rejected", - req: &runtimev1.GenerateTemplateRequest{ - InstanceId: instanceID, - ResourceType: "connector", - Driver: "clickhouse", - Properties: structpb("bogus_key", "value"), - }, - wantErr: codes.InvalidArgument, - }, - { - name: "secret values never in error messages", - req: &runtimev1.GenerateTemplateRequest{ - InstanceId: instanceID, - ResourceType: "connector", - Driver: "clickhouse", - Properties: structpb("bogus_key", "super_secret_value"), - }, - wantErr: codes.InvalidArgument, - // Additionally assert: !strings.Contains(err.Error(), "super_secret_value") - }, - } - // ... -} -``` - -#### Test 8: Env Var Conflict With Existing `.env` - -Tests that the handler reads existing `.env` via `repo.Get()` and resolves conflicts correctly. - -```go -func TestGenerateTemplateEnvConflict(t *testing.T) { - rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ - Files: map[string]string{ - "rill.yaml": "", - ".env": "CLICKHOUSE_PASSWORD=old_value\n", - }, - }) - // ... call GenerateTemplate with clickhouse password - // Assert env_vars returns CLICKHOUSE_PASSWORD_1 (not CLICKHOUSE_PASSWORD) -} -``` - -#### Test Matrix Summary - -| Test | What it validates | Cases | -|---|---|---| -| PropertySpec.Secret flags | Backend secret metadata matches frontend | 15 drivers | -| Connector YAML rendering | Full connector YAML output per driver | ~20 cases (16 drivers × 1-2 variants) | -| Model YAML rendering | Model output with dev section, SQL formatting | ~8 cases (warehouse drivers + DuckDB) | -| DuckDB rewrite | Driver/property transformation for object/file stores | ~15 cases (6 drivers × extension variants) | -| Env var naming | EnvVarName field, fallback format, conflict suffixes | ~10 cases | -| Property validation | Reject unknown keys, accept valid keys | ~5 cases | -| Handler integration | End-to-end RPC with test runtime | ~8 cases | -| Env conflict resolution | `.env` read + suffix logic | ~3 cases | - -**Total: ~85 test cases** in `runtime/server/generate_template_test.go`. - -## Alternative Approach Considered - -### Consolidate Frontend Functions Only - -Merge `compileConnectorYAML` and `compileSourceYAML` into a unified `compileResourceYAML()` on the frontend. - -**Why rejected:** Doesn't solve the root problem (frontend owns YAML format knowledge), special cases keep accumulating, YAML string building is inherently fragile. - -**When to reconsider:** If backend bandwidth is severely limited and we need a quick win. - -## Acceptance Criteria - -### Functional Requirements - -- [ ] `GenerateTemplate` RPC produces valid YAML for all connectors and sources/models -- [ ] Output matches current frontend output for all connectors (verified by golden file tests) -- [ ] Object store drivers (s3, gcs, azure), file store drivers (https, local_file), and sqlite are rewritten to DuckDB models with correct SQL -- [ ] File extension → DuckDB read function mapping matches current frontend behavior (csv/tsv/txt → `read_csv`, parquet → `read_parquet`, json/ndjson → `read_json`, HTTPS default → `read_json`) -- [ ] Response `resource_type` and `driver` reflect actual values after rewrite -- [ ] Secret values replaced with `{{ .env.VAR }}` placeholders -- [ ] Env var names match current naming (including `EnvVarName` overrides) -- [ ] Env var conflicts resolved with `_1`, `_2`, etc. suffixes -- [ ] Unknown property keys rejected with `InvalidArgument` - -### Quality Gates - -- [ ] ~85 Go unit tests across 8 test categories (see Testing Strategy) -- [ ] `TestPropertySpecSecretFlags` passes for all 15 drivers -- [ ] `TestBuildConnectorYAML` covers all 16 form-relevant drivers -- [ ] `TestMaybeRewriteToDuckDB` covers all 6 rewritable drivers × file extension variants -- [ ] `TestGenerateTemplate` integration tests pass through full RPC handler -- [ ] Proto definitions pass `buf lint` -- [ ] No regression in existing connector creation flows -- [ ] Error messages never contain property values or secret data - -## Dependencies & Prerequisites - -- **Backend PropertySpec updates** — `EnvVarName` field and automated Secret flag test must be done before handler implementation -- **Proto generation pipeline** — `buf generate` must produce updated TypeScript bindings before frontend migration -- **Version rollout** — runtime deploys before UI; no backward-compatibility fallback needed - -## Risk Analysis & Mitigation - -| Risk | Severity | Mitigation | -|---|---|---| -| YAML output differs subtly from frontend | High | Golden file tests for every driver | -| Backend `PropertySpec.Secret` doesn't match frontend `x-secret` | High | Automated Go test asserting Secret flags | -| Env var naming changes break existing `.env` files | High | `EnvVarName` field matches exact current naming; test against real `.env` files | -| Dual-metadata divergence (PropertySpec vs frontend JSON Schemas) | Medium | Pre-ship audit; long-term: generate frontend schemas from PropertySpec | -| DuckDB rewrite SQL differs from frontend | High | Golden file tests for every rewritable driver (s3, gcs, azure, https, local_file, sqlite) with each file extension | -| TOCTOU race in `.env` (concurrent connector creations) | Medium | Backend reads `.env` directly; future: atomic read-modify-write | - -## Technical Debt - -1. **Dual-metadata problem:** `PropertySpec` (Go) and frontend JSON Schemas (TypeScript) describe overlapping property metadata. Generate frontend schemas from `PropertySpec` to eliminate this divergence. -2. **File path generation stays in frontend:** `getName()` and `getFileAPIPathFromNameAndType()` remain frontend-owned. Could eventually use response `driver` to infer path server-side. -3. **`rill.yaml` OLAP connector update stays in frontend:** Orchestration, not template rendering. - -## References - -- Brainstorm: `docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md` -- Frontend YAML builders: `web-common/src/features/sources/sourceUtils.ts:24-113`, `web-common/src/features/connectors/code-utils.ts:158-256` -- Submission flow: `web-common/src/features/sources/modal/submitAddDataForm.ts` -- Existing Generate* RPCs: `runtime/server/generate_metrics_view.go`, `runtime/server/generate_resolver.go`, `runtime/server/generate_chart.go`, `runtime/server/generate_canvas_dashboard.go` -- Driver PropertySpec: `runtime/drivers/connectors.go:19-64` -- ClickHouse driver spec: `runtime/drivers/clickhouse/clickhouse.go:43+` -- Frontend schemas: `web-common/src/features/templates/schemas/*.ts` -- DuckDB rewrite (moving to backend): `web-common/src/features/sources/sourceUtils.ts:209-275` -- Backend driver specs with ObjectStore/FileStore flags: `runtime/drivers/s3/s3.go`, `runtime/drivers/gcs/gcs.go`, `runtime/drivers/azure/azure.go`, `runtime/drivers/https/https.go`, `runtime/drivers/file/file.go` -- Env var naming: `web-common/src/features/connectors/code-utils.ts:403-495` From 776d9200169161edfce2d78d5c000d4d57bcac78 Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Fri, 20 Feb 2026 16:19:05 -0800 Subject: [PATCH 05/62] docs(runtime): explain why EnvVarName can't be inferred The mapping from property Key to env var name doesn't follow a mechanical pattern. Well-known names are shared across drivers (AWS_ACCESS_KEY_ID), some add infixes (AZURE_STORAGE_*), and others diverge entirely (GCS key_id -> GCP_ACCESS_KEY_ID). Each driver must specify explicitly. Also remove personal docs from .gitignore. --- .gitignore | 5 ----- runtime/drivers/connectors.go | 6 +++++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index ca3cbc01861..dca5a1cc6b8 100644 --- a/.gitignore +++ b/.gitignore @@ -98,11 +98,6 @@ latest.txt .claude/plans/ .claude/worktrees/ -# Personal docs and config (do not commit) -docs/brainstorms/ -docs/plans/ -.mcp.json - # Vite temp files vite.config.ts.timestamp-* diff --git a/runtime/drivers/connectors.go b/runtime/drivers/connectors.go index 9de7edb97a1..ade41ab4871 100644 --- a/runtime/drivers/connectors.go +++ b/runtime/drivers/connectors.go @@ -46,7 +46,11 @@ type PropertySpec struct { Hint string Default string Placeholder string - Secret bool + Secret bool + // EnvVarName is the conventional env var name for this property (e.g. AWS_ACCESS_KEY_ID, GOOGLE_APPLICATION_CREDENTIALS). + // It must be specified explicitly because the mapping doesn't follow a mechanical pattern; + // some keys use well-known names shared across drivers (AWS_*), others add infixes (AZURE_STORAGE_*), + // and others diverge entirely from the key name (GCS key_id -> GCP_ACCESS_KEY_ID). EnvVarName string NoPrompt bool } From d82fd9f9aa995a91a5677cfcb38775fe0fd4cc5f Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Fri, 20 Feb 2026 16:43:59 -0800 Subject: [PATCH 06/62] fix: resolve golangci-lint, gofmt, and ESLint errors - Fix gofmt alignment in connectors.go PropertySpec struct - Remove unused connectorName param from renderDuckDBModelYAML - Use const instead of let for newEnvBlob and connectorYamlBlob --- runtime/drivers/connectors.go | 2 +- runtime/server/generate_template.go | 4 ++-- web-common/src/features/sources/modal/submitAddDataForm.ts | 7 ++----- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/runtime/drivers/connectors.go b/runtime/drivers/connectors.go index ade41ab4871..1d32ab1ee60 100644 --- a/runtime/drivers/connectors.go +++ b/runtime/drivers/connectors.go @@ -46,7 +46,7 @@ type PropertySpec struct { Hint string Default string Placeholder string - Secret bool + Secret bool // EnvVarName is the conventional env var name for this property (e.g. AWS_ACCESS_KEY_ID, GOOGLE_APPLICATION_CREDENTIALS). // It must be specified explicitly because the mapping doesn't follow a mechanical pattern; // some keys use well-known names shared across drivers (AWS_*), others add infixes (AZURE_STORAGE_*), diff --git a/runtime/server/generate_template.go b/runtime/server/generate_template.go index b6e572fd082..ff7e64bc126 100644 --- a/runtime/server/generate_template.go +++ b/runtime/server/generate_template.go @@ -87,7 +87,7 @@ func (s *Server) GenerateTemplate(ctx context.Context, req *runtimev1.GenerateTe blob = renderModelYAML(spec, actualDriver, props, req.ConnectorName, existingEnv, envVars) } else { // Rewritten to DuckDB - blob = renderDuckDBModelYAML(props, req.ConnectorName) + blob = renderDuckDBModelYAML(props) } } @@ -297,7 +297,7 @@ func renderModelYAML(spec drivers.Spec, driverName string, props map[string]any, } // renderDuckDBModelYAML builds a DuckDB model YAML file for rewritten object/file store drivers. -func renderDuckDBModelYAML(props map[string]any, connectorName string) string { +func renderDuckDBModelYAML(props map[string]any) string { doc := &yaml.Node{Kind: yaml.DocumentNode} mapping := &yaml.Node{Kind: yaml.MappingNode} mapping.HeadComment = "Model YAML\nReference documentation: https://docs.rilldata.com/developers/build/connectors/olap/duckdb" diff --git a/web-common/src/features/sources/modal/submitAddDataForm.ts b/web-common/src/features/sources/modal/submitAddDataForm.ts index 11eac7cb11c..4234e7c5110 100644 --- a/web-common/src/features/sources/modal/submitAddDataForm.ts +++ b/web-common/src/features/sources/modal/submitAddDataForm.ts @@ -244,9 +244,6 @@ export async function submitAddConnectorForm( throw new Error("Operation cancelled"); } - let newEnvBlob: string; - let connectorYamlBlob: string; - const templateResponse = await generateTemplate(instanceId, { resourceType: "connector", driver: connector.name as string, @@ -256,9 +253,9 @@ export async function submitAddConnectorForm( queryClient, templateResponse.envVars ?? {}, ); - newEnvBlob = envResult.newBlob; + const newEnvBlob = envResult.newBlob; originalEnvBlob = envResult.originalBlob; - connectorYamlBlob = templateResponse.blob ?? ""; + const connectorYamlBlob = templateResponse.blob ?? ""; if (saveAnyway) { // Save Anyway: bypass reconciliation entirely via centralized helper From 033d1e550b4f012557467e29ef6af74e634926fe Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Fri, 20 Feb 2026 16:52:04 -0800 Subject: [PATCH 07/62] fix: remove trailing newline in generate_template_test.go --- runtime/server/generate_template_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/server/generate_template_test.go b/runtime/server/generate_template_test.go index a8d672fa562..040328dfc1d 100644 --- a/runtime/server/generate_template_test.go +++ b/runtime/server/generate_template_test.go @@ -1016,4 +1016,3 @@ func mustStruct(m map[string]any) *structpb.Struct { } return s } - From 66b617de9ea5a5807e8a757169a6fd0d160361a0 Mon Sep 17 00:00:00 2001 From: Cyrus Goh Date: Thu, 26 Feb 2026 10:27:56 -0800 Subject: [PATCH 08/62] brainstorm, plan --- ...-02-16-generate-template-api-brainstorm.md | 260 +++++ ...6-02-16-feat-generate-template-rpc-plan.md | 915 ++++++++++++++++++ 2 files changed, 1175 insertions(+) create mode 100644 docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md create mode 100644 docs/plans/2026-02-16-feat-generate-template-rpc-plan.md diff --git a/docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md b/docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md new file mode 100644 index 00000000000..f88010bf869 --- /dev/null +++ b/docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md @@ -0,0 +1,260 @@ +# Tech Design: YAML Generation — Imperative Functions vs. GenerateTemplate API + +**Date:** 2026-02-16 +**Status:** Brainstorm +**Author:** Cyrus Goh + +--- + +## Problem Statement + +The frontend has two imperative YAML builder functions — `compileSourceYAML()` and `compileConnectorYAML()` — that share overlapping logic but diverge in subtle ways. This creates: + +1. **Duplication:** Both functions handle secret extraction (`{{ .env.* }}` placeholders), string quoting, empty-value filtering, and property ordering — but with separate, slightly different implementations. +2. **Maintenance burden:** Adding a new connector or field type requires touching complex conditional logic with many special cases (ClickHouse `managed: false` exclusion, DuckDB SQL rewriting, HTTP header formatting, etc.). +3. **Frontend owns YAML format:** The frontend knows too much about what valid YAML looks like for each resource type. This knowledge should live closer to the backend, which actually parses and validates these files. + +### Current Architecture + +``` +Form Data → compileSourceYAML() / compileConnectorYAML() → YAML string → PutFile RPC → Backend + (imperative string builder) +``` + +**Key files:** +- `web-common/src/features/sources/sourceUtils.ts` — `compileSourceYAML()` (~90 lines) +- `web-common/src/features/connectors/code-utils.ts` — `compileConnectorYAML()` (~100 lines) +- `web-common/src/features/sources/modal/submitAddDataForm.ts` — primary caller +- `web-common/src/features/sources/modal/AddDataFormManager.ts` — YAML preview caller + +### Shared Logic (duplicated between the two functions) + +| Concern | compileSourceYAML | compileConnectorYAML | +|---------|-------------------|----------------------| +| YAML header with doc link | Yes | Yes | +| Secret → `{{ .env.VAR }}` | Yes | Yes | +| String property quoting | Yes | Yes | +| Empty value filtering | Yes | Yes | +| Env var name generation | Via `makeEnvVarKey()` | Via `makeEnvVarKey()` | +| SQL multi-line formatting | Yes | No | +| Headers map formatting | No | Yes | +| Property ordering | Implicit (object key order) | Explicit (orderedProperties) | +| Field filtering | Implicit (step-based) | Explicit (fieldFilter function) | +| Dev section | Yes (with Redshift exception) | No | + +--- + +## Approach A: Consolidate Imperative Functions (Frontend-Only Refactor) + +Merge `compileConnectorYAML` and `compileSourceYAML` into a unified `compileResourceYAML()` function that handles all resource types through configuration. + +### Design + +```typescript +interface ResourceYAMLOptions { + resourceType: "connector" | "source" | "model"; + driver: string; + formValues: Record; + orderedProperties?: ConnectorDriverProperty[]; + fieldFilter?: (property: ConnectorDriverProperty) => boolean; + secretKeys?: string[]; + stringKeys?: string[]; + connectorInstanceName?: string; + schema?: { properties?: Record }; + existingEnvBlob?: string; + includeDevSection?: boolean; + originalDriverName?: string; +} + +function compileResourceYAML(opts: ResourceYAMLOptions): string { + // Unified logic: + // 1. Generate header (type + driver + doc link) + // 2. Filter properties (by step, field filter, empty values) + // 3. Order properties (explicit or implicit) + // 4. Format each property: + // - Secrets → {{ .env.VAR }} + // - Strings → quoted + // - SQL → multi-line + // - Headers → YAML map + // - Default → raw value + // 5. Optional dev section + // 6. Return assembled YAML +} +``` + +### Migration Path + +1. Create `compileResourceYAML()` with all shared logic +2. Re-implement `compileSourceYAML()` and `compileConnectorYAML()` as thin wrappers +3. Gradually migrate callers to the unified function +4. Remove wrappers once all callers are migrated + +### Pros + +- No backend changes required +- Incremental, low-risk refactor +- Eliminates duplication between the two functions +- Can be done in a single PR + +### Cons + +- Frontend still owns YAML format knowledge — can drift from backend expectations +- Special cases keep accumulating as connectors are added +- Doesn't extend to other resource types (explores, dashboards, etc.) without growing the function +- YAML string building is inherently fragile (indentation, quoting, escaping) + +### Effort Estimate + +Small — 1-2 days of frontend work. + +--- + +## Approach B: Backend `GenerateTemplate` RPC (Recommended) + +New backend endpoint that accepts structured data and returns rendered YAML. The frontend becomes a thin form layer. + +### Design + +#### New RPC + +```protobuf +// GenerateTemplate renders a YAML file from structured input. +// Supports all resource types: connector, source, model, explore, dashboard, etc. +rpc GenerateTemplate(GenerateTemplateRequest) returns (GenerateTemplateResponse) { + option (google.api.http) = { + post: "/v1/instances/{instance_id}/generate/template", + body: "*" + }; +} + +message GenerateTemplateRequest { + string instance_id = 1; + // Resource type: "connector", "source", "model", "explore", "metrics_view", etc. + string resource_type = 2; + // Driver name (for connectors/sources): "clickhouse", "s3", "duckdb", etc. + string driver = 3; + // Structured key-value properties from the form + google.protobuf.Struct properties = 4; + // Optional: connector instance name (for sources that reference a connector) + string connector_name = 5; + // Optional: fields that should be treated as secrets (extracted to .env) + repeated string secret_keys = 6; +} + +message GenerateTemplateResponse { + // Rendered YAML blob, ready to write via PutFile + string blob = 1; + // Environment variables to write to .env (key → value) + map env_vars = 2; +} +``` + +#### New Architecture + +``` +Form Data → GenerateTemplate RPC → { blob, env_vars } → PutFile RPC (blob) + update .env (env_vars) + (backend) +``` + +#### Backend Implementation + +The backend would: +1. Look up a Go template for the given `resource_type` + `driver` combination +2. Apply structured properties to the template +3. Handle secret extraction: replace secret values with `{{ .env.VAR }}` and return the real values in `env_vars` +4. Return the rendered YAML blob + +Templates could be Go `text/template` files or a simple struct-to-YAML mapper using the `gopkg.in/yaml.v3` library. + +#### Frontend Changes + +```typescript +// Before (imperative) +const blob = compileConnectorYAML(connector, formValues, { ...options }); +await runtimeServicePutFile(instanceId, { path, blob, create: true }); +await updateDotEnvWithSecrets(instanceId, connector, formValues, options); + +// After (declarative) +const { blob, envVars } = await runtimeServiceGenerateTemplate(instanceId, { + resourceType: "connector", + driver: connector.name, + properties: formValues, + secretKeys: schemaSecretKeys, +}); +await runtimeServicePutFile(instanceId, { path, blob, create: true }); +await writeDotEnv(instanceId, envVars); +``` + +### Migration Path + +1. **Phase 1:** Implement `GenerateTemplate` RPC for connectors +2. **Phase 2:** Migrate `compileConnectorYAML()` callers to use the RPC +3. **Phase 3:** Add source/model support, migrate `compileSourceYAML()` callers +4. **Phase 4:** Extend to other resource types (explores, dashboards, etc.) +5. **Phase 5:** Remove frontend compile functions + +Each phase can be a separate PR. Old and new paths can coexist during migration. + +### Pros + +- Backend owns the canonical YAML format — single source of truth +- Frontend complexity drops dramatically — no YAML string building, quoting, or escaping +- Generalizes to all resource types (connectors, sources, models, explores, dashboards, APIs, canvases, themes, reports, alerts) +- Aligns with existing backend generation patterns (`GenerateMetricsViewFile`, `GenerateCanvas`, `GenerateResolver`) +- Secret handling can be co-located with template logic +- Backend can validate property completeness before rendering + +### Cons + +- Requires backend work (new RPC, template registry, tests) +- Larger scope — multi-phase migration across frontend and backend +- YAML preview in the form is lost (acceptable per discussion — not critical) +- Network round-trip for template rendering (acceptable — only on submit) +- Need to decide where templates live (Go code, embedded files, or database) + +### Effort Estimate + +Medium — 1-2 weeks across backend + frontend. + +--- + +## Open Questions + +1. **Secret handling ownership:** Should the backend fully own env var naming and `.env` file writes? Or should it just return `env_vars` and let the frontend write them? + - Option A: Backend returns `env_vars` map, frontend writes to `.env` (simpler, frontend already has this code) + - Option B: Backend writes `.env` directly as part of `GenerateTemplate` (cleaner, but couples template rendering with file I/O) + +2. **Template storage:** Where do the YAML templates live? + - Go struct-to-YAML mapping (type-safe, no template files) + - Embedded Go `text/template` files (flexible, easy to edit) + - Hardcoded strings in Go (simple, like current frontend approach but server-side) + +3. **DuckDB rewriting:** Currently `maybeRewriteToDuckDb()` transforms S3/GCS/HTTPS sources into DuckDB SQL. Should this logic move to the backend too, or stay as a frontend preprocessing step? + +4. **Connector property metadata:** The frontend schemas define `x-secret`, `x-string`, `x-env-var-name` extensions. Should the backend be the source of truth for these, or should the frontend continue to pass `secretKeys`/`stringKeys` in the request? + +5. **Backward compatibility:** Do we need to support both old (imperative) and new (RPC) paths simultaneously during migration? Or can we cut over all at once? + +--- + +## Recommendation + +**Approach B (Backend `GenerateTemplate` RPC)** is recommended because: + +- It addresses the root cause: the frontend shouldn't own YAML format knowledge +- It's a natural extension of existing backend patterns (`GenerateMetricsViewFile`, etc.) +- It generalizes to all resource types, not just connectors/sources +- The migration can be incremental (phase by phase) +- Loss of YAML preview is acceptable + +Approach A is a valid stopgap if backend bandwidth is limited, but it doesn't solve the fundamental problem of frontend-owned YAML format. + +--- + +## Key Decisions Made + +- **Motivation:** Duplication and maintenance burden in `compileSourceYAML`/`compileConnectorYAML` +- **Direction:** Backend RPC over frontend-only refactor +- **Scope:** All resource types (design wide), implement connectors/sources first +- **YAML Preview:** Can be dropped — not critical for users +- **Secret handling:** Open question to resolve during planning diff --git a/docs/plans/2026-02-16-feat-generate-template-rpc-plan.md b/docs/plans/2026-02-16-feat-generate-template-rpc-plan.md new file mode 100644 index 00000000000..723e0e47e37 --- /dev/null +++ b/docs/plans/2026-02-16-feat-generate-template-rpc-plan.md @@ -0,0 +1,915 @@ +--- +title: "feat: Backend GenerateTemplate RPC for declarative YAML generation" +type: feat +date: 2026-02-16 +--- + +# Backend GenerateTemplate RPC for Declarative YAML Generation + +## Overview + +Replace the frontend's imperative `compileSourceYAML()` and `compileConnectorYAML()` string-building functions with a backend `GenerateTemplate` RPC endpoint. The backend becomes the single source of truth for YAML file format, using driver `PropertySpec` metadata to render YAML from structured form data. This includes absorbing the `maybeRewriteToDuckDb()` logic — the backend uses `Spec.ImplementsObjectStore` / `ImplementsFileStore` to detect when a driver should be rewritten to a DuckDB model, builds the appropriate SQL query, and returns the rewritten resource type. Scoped to connectors and sources/models — skeleton resource YAML (explores, dashboards, etc.) remains as frontend constants. + +## Problem Statement + +The frontend has two imperative YAML builder functions that share overlapping logic but diverge in subtle ways: + +| Shared Concern | `compileSourceYAML` | `compileConnectorYAML` | +|---|---|---| +| YAML header + doc link | Yes | Yes | +| Secret -> `{{ .env.VAR }}` | Yes | Yes | +| String quoting | Yes | Yes | +| Empty value filtering | Yes | Yes | +| SQL multi-line formatting | Yes | No | +| Headers map formatting | No | Yes | +| Property ordering | Implicit | Explicit (`orderedProperties`) | +| Dev section | Yes (except Redshift) | No | + +**Pain points:** +1. **Duplication** — both functions reimplement secret handling, quoting, and value filtering +2. **Maintenance burden** — adding a new connector requires touching complex conditional logic with special cases (ClickHouse `managed: false`, DuckDB SQL rewriting, HTTP auth scheme splitting) +3. **Frontend owns format** — the frontend knows too much about what valid YAML looks like; this knowledge should live server-side +4. **Frontend owns driver rewriting** — `maybeRewriteToDuckDb()` makes resource-type decisions (connector → model) and driver decisions (s3 → duckdb) that belong server-side. The backend already has the signals it needs (`Spec.ImplementsObjectStore`, `Spec.ImplementsFileStore`) + +## Proposed Solution + +**Before:** +``` +Form Data -> compileSourceYAML() / compileConnectorYAML() -> YAML string -> PutFile RPC -> Backend + (imperative string builder) +``` + +**After:** +``` +Form Data -> GenerateTemplate RPC -> { blob, env_vars } -> PutFile RPC (blob) + merge .env (env_vars) + (backend) +``` + +## Technical Approach + +### Proto Definition + +```protobuf +rpc GenerateTemplate(GenerateTemplateRequest) returns (GenerateTemplateResponse) { + option (google.api.http) = { + post: "/v1/instances/{instance_id}/generate/template", + body: "*" + }; +} + +message GenerateTemplateRequest { + string instance_id = 1 [(validate.rules).string = {pattern: "^[_\\-a-zA-Z0-9]+$"}]; + string resource_type = 2 [(validate.rules).string = {in: ["connector", "model"]}]; + string driver = 3 [(validate.rules).string = {pattern: "^[a-z][a-z0-9_]*$"}]; + google.protobuf.Struct properties = 4; + string connector_name = 5; +} + +message GenerateTemplateResponse { + string blob = 1; + map env_vars = 2; + // Actual resource type used — may differ from request when driver is rewritten + // (e.g., s3 model request → duckdb model with SQL wrapping the s3 path) + string resource_type = 3; + // Actual driver used — may differ from request when rewritten to duckdb + string driver = 4; +} +``` + +`google.protobuf.Struct` matches existing codebase patterns (used in 11 places across `api.proto`). `resource_type` scoped to `"connector"` and `"model"` only. The response echoes the actual `resource_type` and `driver` used after any rewrites, so the frontend knows the correct file path and directory. + +### Backend Handler + +New file: `runtime/server/generate_template.go` + +```go +func (s *Server) GenerateTemplate(ctx context.Context, req *runtimev1.GenerateTemplateRequest) (*runtimev1.GenerateTemplateResponse, error) { + // 1. Permission check + if !auth.GetClaims(ctx, req.InstanceId).Can(runtime.EditRepo) { + return nil, ErrForbidden + } + + // 2. Validate driver exists + driver, ok := drivers.Connectors[req.Driver] + if !ok { + return nil, status.Errorf(codes.InvalidArgument, "unknown driver: %s", req.Driver) + } + spec := driver.Spec() + + // 3. Validate properties against original driver spec (reject unknown keys) + props := req.Properties.AsMap() + if err := validateProperties(spec, req.ResourceType, props); err != nil { + return nil, status.Errorf(codes.InvalidArgument, "%s", err) + } + + // 4. DuckDB rewrite for object store / file store / sqlite drivers + // Rewrite happens AFTER validation against the original driver spec, + // since the request properties match the original driver (e.g., s3's "path"). + actualDriver, actualResourceType := req.Driver, req.ResourceType + if req.ResourceType == "model" { + actualDriver, props = maybeRewriteToDuckDB(spec, req.Driver, props, req.ConnectorName) + } + + // 5. Read existing .env for env var conflict resolution + repo, release, err := s.runtime.Repo(ctx, req.InstanceId) + if err != nil { + return nil, err + } + defer release() + existingEnv := readEnvKeys(repo, ctx) + + // 6. Render YAML + extract secrets (using rewritten driver/props) + blob, envVars := renderYAML(spec, actualDriver, actualResourceType, props, existingEnv) + + return &runtimev1.GenerateTemplateResponse{ + Blob: blob, + EnvVars: envVars, + ResourceType: actualResourceType, + Driver: actualDriver, + }, nil +} +``` + +The handler reads `.env` via `repo.Get()` rather than accepting it as a request field. This eliminates sending ALL project secrets over the wire and removes the TOCTOU race between frontend read and backend use. + +### YAML Rendering Engine + +The backend renders YAML using the driver's `PropertySpec` metadata: + +1. **Property ordering**: Use `ConfigProperties` / `SourceProperties` order from the driver `Spec` +2. **Secret detection**: Use `PropertySpec.Secret` (backend is source of truth) +3. **Env var naming**: Use new `PropertySpec.EnvVarName` field (falls back to `DRIVER_KEY` format) +4. **String quoting**: Use `PropertySpec.Type == StringPropertyType` +5. **Value filtering**: Skip empty/nil values, skip properties not in request +6. **Property validation**: Reject unknown property keys not in driver's `PropertySpec` +7. **Header comment**: Generate `# Connector YAML\n# Reference documentation: ` +8. **Dev section**: Auto-generate for warehouse drivers (except Redshift) with `limit 10000` + +Build the `yaml.Node` tree directly rather than the marshal-unmarshal-encode triple-pass used in `generate_metrics_view.go:549-582`: + +```go +func buildConnectorYAML(spec drivers.Spec, driverName string, props map[string]any, envVarMap map[string]string) *yaml.Node { + doc := &yaml.Node{Kind: yaml.DocumentNode} + mapping := &yaml.Node{Kind: yaml.MappingNode} + mapping.HeadComment = fmt.Sprintf("Connector YAML\nReference documentation: %s", spec.DocsURL) + + addScalarPair(mapping, "type", "connector") + addScalarPair(mapping, "driver", driverName) + + for _, propSpec := range spec.ConfigProperties { + val, ok := props[propSpec.Key] + if !ok || isEmpty(val) { + continue + } + if propSpec.Secret { + addScalarPair(mapping, propSpec.Key, fmt.Sprintf("{{ .env.%s }}", envVarMap[propSpec.Key])) + } else if propSpec.Type == drivers.StringPropertyType { + addQuotedPair(mapping, propSpec.Key, fmt.Sprintf("%v", val)) + } else { + addScalarPair(mapping, propSpec.Key, fmt.Sprintf("%v", val)) + } + } + + doc.Content = append(doc.Content, mapping) + return doc +} + +func addScalarPair(m *yaml.Node, key, value string) { + m.Content = append(m.Content, + &yaml.Node{Kind: yaml.ScalarNode, Value: key}, + &yaml.Node{Kind: yaml.ScalarNode, Value: value}, + ) +} + +func addQuotedPair(m *yaml.Node, key, value string) { + m.Content = append(m.Content, + &yaml.Node{Kind: yaml.ScalarNode, Value: key}, + &yaml.Node{Kind: yaml.ScalarNode, Value: value, Style: yaml.DoubleQuotedStyle}, + ) +} + +func validateProperties(spec drivers.Spec, resourceType string, properties map[string]any) error { + allowed := make(map[string]bool) + props := spec.ConfigProperties + if resourceType == "model" { + props = spec.SourceProperties + } + for _, p := range props { + allowed[p.Key] = true + } + for key := range properties { + if !allowed[key] { + return fmt.Errorf("unknown property %q for driver", key) + } + } + return nil +} +``` + +### Key Design Decisions + +#### 1. DuckDB Rewrite Moves to Backend + +`maybeRewriteToDuckDb()` transforms S3/GCS/Azure/HTTPS/SQLite/local_file into DuckDB model files. This logic moves to the backend because: + +- The backend already has the signals: `Spec.ImplementsObjectStore` (s3, gcs, azure), `Spec.ImplementsFileStore` (https, local_file), and driver name (`sqlite`) +- The rewrite is a resource-type decision that the backend should own +- The `buildDuckDbQuery()` file-extension → read function mapping is ~20 lines of Go +- The `create_secrets_from_connectors` wiring is ~5 lines + +The frontend sends the **original** driver and properties (e.g., `driver: "s3"`, `properties: {path: "s3://bucket/file.parquet"}`). The backend detects the rewrite case, builds the DuckDB SQL, and returns the actual driver/resource_type used in the response so the frontend knows the correct file path. + +```go +func maybeRewriteToDuckDB(spec drivers.Spec, driverName string, props map[string]any, connectorName string) (string, map[string]any) { + if !spec.ImplementsObjectStore && !spec.ImplementsFileStore && driverName != "sqlite" { + return driverName, props + } + + rewritten := make(map[string]any, len(props)) + for k, v := range props { + rewritten[k] = v + } + + switch { + case spec.ImplementsObjectStore: // s3, gcs, azure + if connectorName != "" { + rewritten["create_secrets_from_connectors"] = connectorName + } + rewritten["sql"] = buildDuckDBQuery(strVal(props["path"]), false) + delete(rewritten, "path") + + case spec.ImplementsFileStore && driverName == "https": + if connectorName != "" { + rewritten["create_secrets_from_connectors"] = connectorName + } + rewritten["sql"] = buildDuckDBQuery(strVal(props["path"]), true) + delete(rewritten, "path") + + case spec.ImplementsFileStore: // local_file + rewritten["sql"] = buildDuckDBQuery(strVal(props["path"]), false) + delete(rewritten, "path") + + case driverName == "sqlite": + rewritten["sql"] = fmt.Sprintf("SELECT * FROM sqlite_scan('%s', '%s');", + strVal(props["db"]), strVal(props["table"])) + delete(rewritten, "db") + delete(rewritten, "table") + } + + return "duckdb", rewritten +} + +func buildDuckDBQuery(path string, defaultToJSON bool) string { + ext := strings.ToLower(filepath.Ext(path)) + switch { + case containsExt(ext, ".csv", ".tsv", ".txt"): + return fmt.Sprintf("select * from read_csv('%s', auto_detect=true, ignore_errors=1, header=true)", path) + case containsExt(ext, ".parquet"): + return fmt.Sprintf("select * from read_parquet('%s')", path) + case containsExt(ext, ".json", ".ndjson"): + return fmt.Sprintf("select * from read_json('%s', auto_detect=true, format='auto')", path) + default: + if defaultToJSON { + return fmt.Sprintf("select * from read_json('%s', auto_detect=true, format='auto')", path) + } + return fmt.Sprintf("select * from '%s'", path) + } +} +``` + +Note: `containsExt` checks if the full extension (e.g., `.v1.parquet.gz`) contains the target part, matching the current frontend behavior of `extensionContainsParts()`. + +#### 2. Backend Is Source of Truth for Secrets + +Backend uses `PropertySpec.Secret` to identify secrets. No `secret_keys` in the request. Automated Go test asserts Secret flags match expected values for all drivers before shipping. + +#### 3. Env Var Naming Uses New `EnvVarName` Field + +Add `EnvVarName string` to `PropertySpec`. When set, use it (e.g., S3's `aws_access_key_id` -> `AWS_ACCESS_KEY_ID`). When empty, fall back to `DRIVER_KEY` format. Must match current frontend naming exactly or existing `.env` files break on upgrade. + +#### 4. Backend Reads `.env` Directly + +Backend reads `.env` via `repo.Get()` and parses key names into a `map[string]bool` for O(1) conflict detection. Response `env_vars` is a delta. Frontend merges with existing `.env` using `replaceOrAddEnvVariable()`. + +#### 5. Frontend Strips x-ui-only Fields + +Fields like `deployment_type`, `connection_mode`, `auth_method` are stripped before calling `GenerateTemplate`. Backend validates and rejects unknown keys. Postgres DSN-vs-parameters tabs are handled by `filterSchemaValuesForSubmit()`. + +#### 6. `GenerateTemplate` Does Not Write Files + +Returns blob + env_vars. Frontend calls `PutFile` separately. This enables rollback (restore original `.env` on reconciliation failure) and the "Save Anyway" bypass flow. + +#### 7. No Backward Compatibility Fallback + +Runtime deploys before UI. No catch-UNIMPLEMENTED fallback needed. Old frontend compile functions are removed immediately after migration. + +### Implementation + +**Scope:** All connectors (including HTTPS), all sources/models, and cleanup — shipped as one unit. + +**Backend tasks:** +- [ ] Add `EnvVarName string` field to `PropertySpec` in `runtime/drivers/connectors.go` +- [ ] Add `EnvVarName` values to drivers with custom env var names (S3, GCS, BigQuery, etc.) +- [ ] Write automated Go test asserting `PropertySpec.Secret` matches expected values for all drivers; fix discrepancies +- [ ] Define `GenerateTemplateRequest`/`GenerateTemplateResponse` in `proto/rill/runtime/v1/api.proto` with validation annotations +- [ ] Run `buf generate` to regenerate Go and TypeScript proto bindings +- [ ] Implement `GenerateTemplate` handler in `runtime/server/generate_template.go` + - Permission check (`EditRepo`) + - Driver validation (must exist in `drivers.Connectors`) + - Property validation (reject unknown keys) + - `.env` read via `repo.Get()` for conflict resolution + - YAML rendering via `yaml.Node` direct construction + - Secret -> `{{ .env.VAR }}` replacement using `PropertySpec.Secret` + - Env var naming from `PropertySpec.EnvVarName` with conflict suffix + - Header comment with driver `DocsURL` + - Value filtering (empty/nil) + - String quoting for `StringPropertyType` + - ClickHouse: exclude `managed: false` when default + - Redshift: skip dev section + - Model type: `type: model`, `materialize: true`, `connector:`, `sql:`, dev section + - HTTPS headers: `formatHeadersAsYamlMap()` equivalent with auth-scheme splitting + - DuckDB rewrite: detect `ImplementsObjectStore`/`ImplementsFileStore`/sqlite, build SQL from path + file extension, set `create_secrets_from_connectors` + - Return actual `resource_type` and `driver` in response (may differ from request after rewrite) +- [ ] Write Go unit tests (see Testing Strategy below) +- [ ] Never include property values or env var values in error messages + +**Frontend tasks:** +- [ ] Update `submitAddDataForm.ts` to call `GenerateTemplate` for all connectors +- [ ] Update `submitAddDataForm.ts` to call `GenerateTemplate` for source/model creation (send original driver + properties, no preprocessing) +- [ ] Use response `resource_type` and `driver` to determine file path (replaces frontend rewrite logic for path calculation) +- [ ] Strip `x-ui-only` fields from form values before sending (using `filterSchemaValuesForSubmit()`) +- [ ] Update `.env` merge logic to use `env_vars` response delta +- [ ] Remove `compileConnectorYAML()` and `compileSourceYAML()` (dead code) +- [ ] Remove `maybeRewriteToDuckDb()`, `buildDuckDbQuery()`, `extensionContainsParts()`, `prepareSourceFormData()` (dead code) +- [ ] Remove `updateDotEnvWithSecrets()`, `makeEnvVarKey()`, `findAvailableEnvVarName()`, `getGenericEnvVarName()` (dead code) + +**Success criteria:** +- [ ] Creating any connector via the form produces identical YAML as before +- [ ] Creating any source/model via the form produces identical YAML as before +- [ ] S3/GCS/Azure/HTTPS/local_file/SQLite sources are correctly rewritten to DuckDB models with proper SQL +- [ ] `create_secrets_from_connectors` is set correctly for object store and HTTPS sources +- [ ] `.env` file is correctly updated with secrets +- [ ] All auth method variants work (S3 access_keys vs public, ClickHouse parameters vs DSN, etc.) +- [ ] HTTPS headers with sensitive auth tokens correctly extracted to `.env` +- [ ] Zero frontend YAML string building or driver rewriting remains + +### Testing Strategy + +New file: `runtime/server/generate_template_test.go` + +Tests follow the codebase's existing pattern: table-driven tests using `testruntime.NewInstanceWithOptions()` and `server.NewServer()`, with `require.Contains()` / `require.Equal()` assertions on YAML output. + +Note: The frontend functions being replaced (`compileSourceYAML`, `compileConnectorYAML`, `maybeRewriteToDuckDb`, `buildDuckDbQuery`) have **zero direct unit tests**. Only env var helpers are tested. The backend tests here are net-new coverage — there is no existing frontend test output to port. + +#### Test 1: PropertySpec.Secret Flag Assertion + +Automated test that asserts `PropertySpec.Secret` matches expected values for every registered driver. Catches drift between backend metadata and frontend `x-secret` annotations. + +```go +func TestPropertySpecSecretFlags(t *testing.T) { + // Expected secret keys per driver, derived from frontend x-secret annotations + expected := map[string][]string{ + "s3": {"aws_access_key_id", "aws_secret_access_key", "aws_role_arn", "aws_role_session_name", "aws_external_id"}, + "gcs": {"google_application_credentials", "key_id", "secret"}, + "azure": {"azure_storage_account", "azure_storage_key", "azure_storage_sas_token", "azure_storage_connection_string"}, + "clickhouse": {"dsn", "password", "write_dsn"}, + "postgres": {"dsn", "password"}, + "bigquery": {"google_application_credentials"}, + "snowflake": {"dsn", "password", "privateKey"}, + "redshift": {"aws_access_key_id", "aws_secret_access_key"}, + "motherduck": {"token"}, + "athena": {"aws_access_key_id", "aws_secret_access_key"}, + "mysql": {"dsn", "password"}, + "druid": {"dsn", "password"}, + "pinot": {"dsn", "password"}, + "starrocks": {"dsn", "password"}, + "salesforce": {"password", "key"}, + } + + for driverName, driver := range drivers.Connectors { + spec := driver.Spec() + expectedKeys, ok := expected[driverName] + if !ok { + continue // AI/notifier drivers not relevant to GenerateTemplate + } + actualSecrets := secretKeys(spec.ConfigProperties) + require.ElementsMatch(t, expectedKeys, actualSecrets, "driver %s", driverName) + } +} +``` + +#### Test 2: Connector YAML Rendering (Table-Driven) + +One test case per driver, covering the most common form submission for each. Validates the full YAML blob output. + +```go +func TestBuildConnectorYAML(t *testing.T) { + tt := []struct { + name string + driver string + props map[string]any + contains []string // key substrings that must appear in output + excludes []string // substrings that must NOT appear + }{ + { + name: "clickhouse with parameters", + driver: "clickhouse", + props: map[string]any{"host": "ch.example.com", "port": "9000", "password": "secret123"}, + contains: []string{ + "type: connector", + "driver: clickhouse", + `host: "ch.example.com"`, + "port: 9000", + `password: "{{ .env.CLICKHOUSE_PASSWORD }}"`, + "# Connector YAML", + "Reference documentation: https://docs.rilldata.com", + }, + excludes: []string{"secret123"}, // actual secret value must never appear + }, + { + name: "clickhouse with dsn", + driver: "clickhouse", + props: map[string]any{"dsn": "clickhouse://user:pass@host:9000/db"}, + contains: []string{ + `dsn: "{{ .env.CLICKHOUSE_DSN }}"`, + }, + excludes: []string{"clickhouse://user:pass"}, + }, + { + name: "s3 connector", + driver: "s3", + props: map[string]any{"aws_access_key_id": "AKIA...", "aws_secret_access_key": "secret"}, + contains: []string{ + "driver: s3", + `aws_access_key_id: "{{ .env.AWS_ACCESS_KEY_ID }}"`, + `aws_secret_access_key: "{{ .env.AWS_SECRET_ACCESS_KEY }}"`, + }, + excludes: []string{"AKIA", "secret"}, + }, + { + name: "bigquery connector", + driver: "bigquery", + props: map[string]any{"project_id": "my-project", "google_application_credentials": `{"type":"service_account"}`}, + contains: []string{ + "driver: bigquery", + `project_id: "my-project"`, + `google_application_credentials: "{{ .env.GOOGLE_APPLICATION_CREDENTIALS }}"`, + }, + }, + { + name: "postgres with individual params", + driver: "postgres", + props: map[string]any{"host": "db.example.com", "port": "5432", "password": "pass"}, + contains: []string{ + "driver: postgres", + `host: "db.example.com"`, + `password: "{{ .env.POSTGRES_PASSWORD }}"`, + }, + }, + { + name: "empty values filtered", + driver: "clickhouse", + props: map[string]any{"host": "ch.example.com", "port": "", "database": ""}, + contains: []string{"host:"}, + excludes: []string{"port:", "database:"}, + }, + { + name: "clickhouse managed false excluded when default", + driver: "clickhouse", + props: map[string]any{"host": "ch.example.com", "managed": false}, + excludes: []string{"managed"}, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + // ... render and assert + }) + } +} +``` + +**Drivers to cover:** clickhouse (params + DSN), postgres (params + DSN), s3, gcs, azure, bigquery, snowflake, redshift, athena, motherduck, duckdb, druid, pinot, starrocks, mysql, salesforce. That's 16 drivers × 1-2 variants each. + +#### Test 3: Model YAML Rendering (Table-Driven) + +Validates model output including `type: model`, `materialize: true`, `connector:`, SQL formatting, and dev section. + +```go +func TestBuildModelYAML(t *testing.T) { + tt := []struct { + name string + driver string + props map[string]any + connName string + contains []string + excludes []string + }{ + { + name: "clickhouse model with dev section", + driver: "clickhouse", + props: map[string]any{"sql": "SELECT * FROM events"}, + connName: "clickhouse_prod", + contains: []string{ + "type: model", + "materialize: true", + "connector: clickhouse_prod", + "sql: |", + " SELECT * FROM events", + "dev:", + "limit 10000", + "# Model YAML", + }, + }, + { + name: "redshift model without dev section", + driver: "redshift", + props: map[string]any{"sql": "SELECT * FROM events"}, + connName: "redshift_prod", + contains: []string{"type: model", "connector: redshift_prod"}, + excludes: []string{"dev:"}, + }, + { + name: "bigquery model with dev section", + driver: "bigquery", + props: map[string]any{"sql": "SELECT * FROM `project.dataset.table`"}, + connName: "bq_prod", + contains: []string{"dev:", "limit 10000"}, + }, + } + // ... +} +``` + +#### Test 4: DuckDB Rewrite (Table-Driven) + +Tests `maybeRewriteToDuckDB` and `buildDuckDBQuery` — the logic moving from frontend. + +```go +func TestMaybeRewriteToDuckDB(t *testing.T) { + tt := []struct { + name string + driver string + props map[string]any + connectorName string + wantDriver string + wantSQL string + wantSecrets string // expected create_secrets_from_connectors value + wantDeleted []string // keys that should be removed from props + }{ + // Object store drivers + { + name: "s3 csv", + driver: "s3", + props: map[string]any{"path": "s3://bucket/data.csv"}, + connectorName: "my_s3", + wantDriver: "duckdb", + wantSQL: "select * from read_csv('s3://bucket/data.csv', auto_detect=true, ignore_errors=1, header=true)", + wantSecrets: "my_s3", + wantDeleted: []string{"path"}, + }, + { + name: "s3 parquet", + driver: "s3", + props: map[string]any{"path": "s3://bucket/data.parquet"}, + wantDriver: "duckdb", + wantSQL: "select * from read_parquet('s3://bucket/data.parquet')", + }, + { + name: "s3 compressed parquet", + driver: "s3", + props: map[string]any{"path": "s3://bucket/data.v1.parquet.gz"}, + wantDriver: "duckdb", + wantSQL: "select * from read_parquet('s3://bucket/data.v1.parquet.gz')", + }, + { + name: "gcs json", + driver: "gcs", + props: map[string]any{"path": "gs://bucket/data.json"}, + wantDriver: "duckdb", + wantSQL: "select * from read_json('gs://bucket/data.json', auto_detect=true, format='auto')", + }, + { + name: "gcs ndjson", + driver: "gcs", + props: map[string]any{"path": "gs://bucket/data.ndjson"}, + wantDriver: "duckdb", + wantSQL: "select * from read_json('gs://bucket/data.ndjson', auto_detect=true, format='auto')", + }, + { + name: "azure tsv", + driver: "azure", + props: map[string]any{"path": "azure://container/data.tsv"}, + wantDriver: "duckdb", + wantSQL: "select * from read_csv('azure://container/data.tsv', auto_detect=true, ignore_errors=1, header=true)", + }, + { + name: "s3 unknown extension falls through", + driver: "s3", + props: map[string]any{"path": "s3://bucket/data.avro"}, + wantDriver: "duckdb", + wantSQL: "select * from 's3://bucket/data.avro'", + }, + + // File store drivers + { + name: "https defaults to json", + driver: "https", + props: map[string]any{"path": "https://api.example.com/data"}, + wantDriver: "duckdb", + wantSQL: "select * from read_json('https://api.example.com/data', auto_detect=true, format='auto')", + }, + { + name: "https with csv extension", + driver: "https", + props: map[string]any{"path": "https://example.com/data.csv"}, + wantDriver: "duckdb", + wantSQL: "select * from read_csv('https://example.com/data.csv', auto_detect=true, ignore_errors=1, header=true)", + }, + { + name: "https with connector name sets secrets", + driver: "https", + props: map[string]any{"path": "https://api.example.com/data"}, + connectorName: "my_http", + wantSecrets: "my_http", + }, + { + name: "local_file csv", + driver: "local_file", + props: map[string]any{"path": "/data/file.csv"}, + wantDriver: "duckdb", + wantSQL: "select * from read_csv('/data/file.csv', auto_detect=true, ignore_errors=1, header=true)", + wantSecrets: "", // no create_secrets_from_connectors for local_file + }, + + // SQLite + { + name: "sqlite", + driver: "sqlite", + props: map[string]any{"db": "/data/app.db", "table": "users"}, + wantDriver: "duckdb", + wantSQL: "SELECT * FROM sqlite_scan('/data/app.db', 'users');", + wantDeleted: []string{"db", "table"}, + }, + + // Non-rewritable drivers pass through + { + name: "clickhouse not rewritten", + driver: "clickhouse", + props: map[string]any{"sql": "SELECT 1"}, + wantDriver: "clickhouse", + }, + { + name: "postgres not rewritten", + driver: "postgres", + props: map[string]any{"sql": "SELECT 1"}, + wantDriver: "postgres", + }, + } + // ... +} +``` + +#### Test 5: Env Var Naming and Conflict Resolution + +Tests the `EnvVarName` field and `_1`, `_2` suffix logic. Mirrors the 48 frontend test cases in `code-utils.spec.ts`. + +```go +func TestEnvVarNaming(t *testing.T) { + tt := []struct { + name string + driver string + propKey string + envVarName string // PropertySpec.EnvVarName override + existingEnv map[string]bool + want string + }{ + // Schema-driven names (EnvVarName set) + {name: "s3 access key", driver: "s3", propKey: "aws_access_key_id", envVarName: "AWS_ACCESS_KEY_ID", want: "AWS_ACCESS_KEY_ID"}, + {name: "bigquery creds", driver: "bigquery", propKey: "google_application_credentials", envVarName: "GOOGLE_APPLICATION_CREDENTIALS", want: "GOOGLE_APPLICATION_CREDENTIALS"}, + {name: "motherduck token", driver: "motherduck", propKey: "token", envVarName: "MOTHERDUCK_TOKEN", want: "MOTHERDUCK_TOKEN"}, + {name: "clickhouse password", driver: "clickhouse", propKey: "password", envVarName: "CLICKHOUSE_PASSWORD", want: "CLICKHOUSE_PASSWORD"}, + + // Fallback naming (EnvVarName empty) → DRIVER_KEY format + {name: "fallback format", driver: "custom", propKey: "api_token", want: "CUSTOM_API_TOKEN"}, + + // Conflict resolution + {name: "first conflict", driver: "bigquery", propKey: "google_application_credentials", envVarName: "GOOGLE_APPLICATION_CREDENTIALS", + existingEnv: map[string]bool{"GOOGLE_APPLICATION_CREDENTIALS": true}, + want: "GOOGLE_APPLICATION_CREDENTIALS_1"}, + {name: "second conflict", driver: "bigquery", propKey: "google_application_credentials", envVarName: "GOOGLE_APPLICATION_CREDENTIALS", + existingEnv: map[string]bool{"GOOGLE_APPLICATION_CREDENTIALS": true, "GOOGLE_APPLICATION_CREDENTIALS_1": true}, + want: "GOOGLE_APPLICATION_CREDENTIALS_2"}, + {name: "multi-key conflict (s3)", driver: "s3", propKey: "aws_access_key_id", envVarName: "AWS_ACCESS_KEY_ID", + existingEnv: map[string]bool{"AWS_ACCESS_KEY_ID": true}, + want: "AWS_ACCESS_KEY_ID_1"}, + } + // ... +} +``` + +#### Test 6: Property Validation + +```go +func TestValidateProperties(t *testing.T) { + tt := []struct { + name string + driver string + resourceType string + props map[string]any + wantErr string + }{ + {name: "valid connector props", driver: "clickhouse", resourceType: "connector", props: map[string]any{"host": "x"}, wantErr: ""}, + {name: "unknown prop rejected", driver: "clickhouse", resourceType: "connector", props: map[string]any{"bogus": "x"}, wantErr: `unknown property "bogus"`}, + {name: "source prop on connector rejected", driver: "duckdb", resourceType: "connector", props: map[string]any{"sql": "SELECT 1"}, wantErr: `unknown property "sql"`}, + {name: "source prop on model accepted", driver: "duckdb", resourceType: "model", props: map[string]any{"sql": "SELECT 1"}, wantErr: ""}, + } + // ... +} +``` + +#### Test 7: Handler Integration Test + +End-to-end test through the RPC handler, using the same test infrastructure as `generate_metrics_view_test.go`. + +```go +func TestGenerateTemplate(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{"rill.yaml": ""}, + }) + server, err := server.NewServer(ctx, &server.Options{}, rt, zap.NewNop(), ratelimit.NewNoop(), activity.NewNoopClient(), nil) + require.NoError(t, err) + + tt := []struct { + name string + req *runtimev1.GenerateTemplateRequest + wantContains []string + wantEnvVars map[string]string + wantDriver string // response driver (after rewrite) + wantResType string // response resource_type + wantErr codes.Code + }{ + { + name: "clickhouse connector", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: structpb("host", "ch.example.com", "password", "secret123"), + }, + wantContains: []string{"type: connector", "driver: clickhouse", `{{ .env.CLICKHOUSE_PASSWORD }}`}, + wantEnvVars: map[string]string{"CLICKHOUSE_PASSWORD": "secret123"}, + wantDriver: "clickhouse", + wantResType: "connector", + }, + { + name: "s3 model rewritten to duckdb", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "model", + Driver: "s3", + Properties: structpb("path", "s3://bucket/data.parquet"), + ConnectorName: "my_s3", + }, + wantContains: []string{"type: model", "connector: duckdb", "read_parquet", "create_secrets_from_connectors: my_s3"}, + wantDriver: "duckdb", + wantResType: "model", + }, + { + name: "unknown driver rejected", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "nonexistent", + Properties: structpb(), + }, + wantErr: codes.InvalidArgument, + }, + { + name: "unknown property rejected", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: structpb("bogus_key", "value"), + }, + wantErr: codes.InvalidArgument, + }, + { + name: "secret values never in error messages", + req: &runtimev1.GenerateTemplateRequest{ + InstanceId: instanceID, + ResourceType: "connector", + Driver: "clickhouse", + Properties: structpb("bogus_key", "super_secret_value"), + }, + wantErr: codes.InvalidArgument, + // Additionally assert: !strings.Contains(err.Error(), "super_secret_value") + }, + } + // ... +} +``` + +#### Test 8: Env Var Conflict With Existing `.env` + +Tests that the handler reads existing `.env` via `repo.Get()` and resolves conflicts correctly. + +```go +func TestGenerateTemplateEnvConflict(t *testing.T) { + rt, instanceID := testruntime.NewInstanceWithOptions(t, testruntime.InstanceOptions{ + Files: map[string]string{ + "rill.yaml": "", + ".env": "CLICKHOUSE_PASSWORD=old_value\n", + }, + }) + // ... call GenerateTemplate with clickhouse password + // Assert env_vars returns CLICKHOUSE_PASSWORD_1 (not CLICKHOUSE_PASSWORD) +} +``` + +#### Test Matrix Summary + +| Test | What it validates | Cases | +|---|---|---| +| PropertySpec.Secret flags | Backend secret metadata matches frontend | 15 drivers | +| Connector YAML rendering | Full connector YAML output per driver | ~20 cases (16 drivers × 1-2 variants) | +| Model YAML rendering | Model output with dev section, SQL formatting | ~8 cases (warehouse drivers + DuckDB) | +| DuckDB rewrite | Driver/property transformation for object/file stores | ~15 cases (6 drivers × extension variants) | +| Env var naming | EnvVarName field, fallback format, conflict suffixes | ~10 cases | +| Property validation | Reject unknown keys, accept valid keys | ~5 cases | +| Handler integration | End-to-end RPC with test runtime | ~8 cases | +| Env conflict resolution | `.env` read + suffix logic | ~3 cases | + +**Total: ~85 test cases** in `runtime/server/generate_template_test.go`. + +## Alternative Approach Considered + +### Consolidate Frontend Functions Only + +Merge `compileConnectorYAML` and `compileSourceYAML` into a unified `compileResourceYAML()` on the frontend. + +**Why rejected:** Doesn't solve the root problem (frontend owns YAML format knowledge), special cases keep accumulating, YAML string building is inherently fragile. + +**When to reconsider:** If backend bandwidth is severely limited and we need a quick win. + +## Acceptance Criteria + +### Functional Requirements + +- [ ] `GenerateTemplate` RPC produces valid YAML for all connectors and sources/models +- [ ] Output matches current frontend output for all connectors (verified by golden file tests) +- [ ] Object store drivers (s3, gcs, azure), file store drivers (https, local_file), and sqlite are rewritten to DuckDB models with correct SQL +- [ ] File extension → DuckDB read function mapping matches current frontend behavior (csv/tsv/txt → `read_csv`, parquet → `read_parquet`, json/ndjson → `read_json`, HTTPS default → `read_json`) +- [ ] Response `resource_type` and `driver` reflect actual values after rewrite +- [ ] Secret values replaced with `{{ .env.VAR }}` placeholders +- [ ] Env var names match current naming (including `EnvVarName` overrides) +- [ ] Env var conflicts resolved with `_1`, `_2`, etc. suffixes +- [ ] Unknown property keys rejected with `InvalidArgument` + +### Quality Gates + +- [ ] ~85 Go unit tests across 8 test categories (see Testing Strategy) +- [ ] `TestPropertySpecSecretFlags` passes for all 15 drivers +- [ ] `TestBuildConnectorYAML` covers all 16 form-relevant drivers +- [ ] `TestMaybeRewriteToDuckDB` covers all 6 rewritable drivers × file extension variants +- [ ] `TestGenerateTemplate` integration tests pass through full RPC handler +- [ ] Proto definitions pass `buf lint` +- [ ] No regression in existing connector creation flows +- [ ] Error messages never contain property values or secret data + +## Dependencies & Prerequisites + +- **Backend PropertySpec updates** — `EnvVarName` field and automated Secret flag test must be done before handler implementation +- **Proto generation pipeline** — `buf generate` must produce updated TypeScript bindings before frontend migration +- **Version rollout** — runtime deploys before UI; no backward-compatibility fallback needed + +## Risk Analysis & Mitigation + +| Risk | Severity | Mitigation | +|---|---|---| +| YAML output differs subtly from frontend | High | Golden file tests for every driver | +| Backend `PropertySpec.Secret` doesn't match frontend `x-secret` | High | Automated Go test asserting Secret flags | +| Env var naming changes break existing `.env` files | High | `EnvVarName` field matches exact current naming; test against real `.env` files | +| Dual-metadata divergence (PropertySpec vs frontend JSON Schemas) | Medium | Pre-ship audit; long-term: generate frontend schemas from PropertySpec | +| DuckDB rewrite SQL differs from frontend | High | Golden file tests for every rewritable driver (s3, gcs, azure, https, local_file, sqlite) with each file extension | +| TOCTOU race in `.env` (concurrent connector creations) | Medium | Backend reads `.env` directly; future: atomic read-modify-write | + +## Technical Debt + +1. **Dual-metadata problem:** `PropertySpec` (Go) and frontend JSON Schemas (TypeScript) describe overlapping property metadata. Generate frontend schemas from `PropertySpec` to eliminate this divergence. +2. **File path generation stays in frontend:** `getName()` and `getFileAPIPathFromNameAndType()` remain frontend-owned. Could eventually use response `driver` to infer path server-side. +3. **`rill.yaml` OLAP connector update stays in frontend:** Orchestration, not template rendering. + +## References + +- Brainstorm: `docs/brainstorms/2026-02-16-generate-template-api-brainstorm.md` +- Frontend YAML builders: `web-common/src/features/sources/sourceUtils.ts:24-113`, `web-common/src/features/connectors/code-utils.ts:158-256` +- Submission flow: `web-common/src/features/sources/modal/submitAddDataForm.ts` +- Existing Generate* RPCs: `runtime/server/generate_metrics_view.go`, `runtime/server/generate_resolver.go`, `runtime/server/generate_chart.go`, `runtime/server/generate_canvas_dashboard.go` +- Driver PropertySpec: `runtime/drivers/connectors.go:19-64` +- ClickHouse driver spec: `runtime/drivers/clickhouse/clickhouse.go:43+` +- Frontend schemas: `web-common/src/features/templates/schemas/*.ts` +- DuckDB rewrite (moving to backend): `web-common/src/features/sources/sourceUtils.ts:209-275` +- Backend driver specs with ObjectStore/FileStore flags: `runtime/drivers/s3/s3.go`, `runtime/drivers/gcs/gcs.go`, `runtime/drivers/azure/azure.go`, `runtime/drivers/https/https.go`, `runtime/drivers/file/file.go` +- Env var naming: `web-common/src/features/connectors/code-utils.ts:403-495` From 4345073ac564c70fdd2824fd834eca42477da6d2 Mon Sep 17 00:00:00 2001 From: royendo <67675319+royendo@users.noreply.github.com> Date: Tue, 3 Mar 2026 18:33:04 -0500 Subject: [PATCH 09/62] =?UTF-8?q?What=20was=20built=20New=20runtime/templa?= =?UTF-8?q?tes/=20package=20(7=20Go=20files)=20template.go=20=E2=80=94=20C?= =?UTF-8?q?ore=20types:=20Template,=20File,=20ProcessedProp=20registry.go?= =?UTF-8?q?=20=E2=80=94=20Registry=20with=20//go:embed=20loading=20of=20YA?= =?UTF-8?q?ML=20definitions,=20List(),=20Get(),=20ListByTags(),=20LookupBy?= =?UTF-8?q?Driver()=20render.go=20=E2=80=94=20Rendering=20engine:=20pre-pr?= =?UTF-8?q?ocesses=20properties=20(secret=20extraction,=20empty=20filterin?= =?UTF-8?q?g,=20DuckDB=20derivation),=20renders=20Go=20text/template=20wit?= =?UTF-8?q?h=20[[=20]]=20delimiters=20funcmap.go=20=E2=80=94=20Template=20?= =?UTF-8?q?functions:=20renderProps,=20indent,=20quote=20env.go=20?= =?UTF-8?q?=E2=80=94=20Extracted:=20ResolveEnvVarName,=20ReadEnvKeys=20hea?= =?UTF-8?q?ders.go=20=E2=80=94=20Extracted:=20IsSensitiveHeaderKey,=20Spli?= =?UTF-8?q?tAuthSchemePrefix,=20HeaderKeyToEnvSegment,=20ResolveHeaderEnvV?= =?UTF-8?q?arName=20(with=20fixed=20per-call=20regex=20compilation=20bug)?= =?UTF-8?q?=20duckdb.go=20=E2=80=94=20Extracted:=20BuildDuckDBQuery,=20mat?= =?UTF-8?q?chesExt=20(with=20fixed=20false=20positive=20bug=20for=20paths?= =?UTF-8?q?=20like=20parquet-archive/readme.txt)=2032=20template=20definit?= =?UTF-8?q?ions=20(runtime/templates/definitions/)=2017=20connector=20temp?= =?UTF-8?q?lates:=20s3,=20gcs,=20azure,=20https,=20postgres,=20bigquery,?= =?UTF-8?q?=20snowflake,=20mysql,=20athena,=20redshift,=20salesforce,=20cl?= =?UTF-8?q?ickhouse,=20duckdb,=20motherduck,=20druid,=20pinot,=20starrocks?= =?UTF-8?q?=207=20DuckDB=20model=20templates:=20s3-duckdb,=20gcs-duckdb,?= =?UTF-8?q?=20azure-duckdb,=20https-duckdb,=20local-file-duckdb,=20sqlite-?= =?UTF-8?q?duckdb=208=20warehouse=20model=20templates:=20clickhouse-model,?= =?UTF-8?q?=20postgres-model,=20mysql-model,=20bigquery-model,=20snowflake?= =?UTF-8?q?-model,=20athena-model,=20redshift-model,=20salesforce-model=20?= =?UTF-8?q?1=20new=20template:=20iceberg-duckdb=20(the=20motivating=20use?= =?UTF-8?q?=20case)=20Proto=20definitions=20Template,=20TemplateFile,=20Li?= =?UTF-8?q?stTemplatesRequest/Response,=20GenerateFileRequest/Response,=20?= =?UTF-8?q?GeneratedFile=20messages=20ListTemplates=20and=20GenerateFile?= =?UTF-8?q?=20RPCs=20on=20RuntimeService=20Frontend=20client=20auto-genera?= =?UTF-8?q?ted=20via=20Orval=20Server=20handlers=20(runtime/server/templat?= =?UTF-8?q?es.go)=20ListTemplates=20=E2=80=94=20returns=20templates=20filt?= =?UTF-8?q?ered=20by=20tags=20GenerateFile=20=E2=80=94=20renders=20templat?= =?UTF-8?q?e,=20optionally=20writes=20files=20+=20merges=20.env=20Tests=20?= =?UTF-8?q?(4=20test=20files,=2032+=20test=20cases)=20Registry:=20loading,?= =?UTF-8?q?=20lookup,=20tag=20filtering,=20sorted=20output,=20all=20defini?= =?UTF-8?q?tions=20valid=20Render:=20S3=20connector,=20S3-DuckDB=20model,?= =?UTF-8?q?=20Snowflake=20warehouse=20model,=20Redshift=20no-dev,=20Iceber?= =?UTF-8?q?g-DuckDB,=20env=20var=20conflicts,=20empty=20filtering,=20outpu?= =?UTF-8?q?t=20filtering,=20local=20file,=20SQLite=20Env:=20explicit=20nam?= =?UTF-8?q?e,=20fallback,=20conflict,=20double=20conflict=20DuckDB:=20quer?= =?UTF-8?q?y=20building=20for=20all=20formats,=20false=20positive=20fix=20?= =?UTF-8?q?Headers:=20sensitive=20detection,=20auth=20scheme=20splitting,?= =?UTF-8?q?=20env=20segment=20naming=20Bug=20fixes=20from=20PRD=20contains?= =?UTF-8?q?Ext=20false=20positive=20fixed=20(basename=20suffix=20check)=20?= =?UTF-8?q?headerKeyToEnvSegment=20regex=20compiled=20at=20package=20level?= =?UTF-8?q?=20Render=20errors=20propagated=20(not=20silently=20empty)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- proto/gen/rill/admin/v1/openapi.yaml | 2 +- proto/gen/rill/admin/v1/public.openapi.yaml | 2 +- proto/gen/rill/runtime/v1/api.pb.go | 4193 ++++++++++------- proto/gen/rill/runtime/v1/api.pb.gw.go | 198 + proto/gen/rill/runtime/v1/api.pb.validate.go | 885 ++++ proto/gen/rill/runtime/v1/api_grpc.pb.go | 80 + .../gen/rill/runtime/v1/runtime.swagger.yaml | 121 + proto/rill/runtime/v1/api.proto | 62 + runtime/server/server.go | 40 +- runtime/server/templates.go | 155 + .../templates/definitions/athena-model.yaml | 23 + runtime/templates/definitions/athena.yaml | 13 + .../templates/definitions/azure-duckdb.yaml | 18 + runtime/templates/definitions/azure.yaml | 13 + .../templates/definitions/bigquery-model.yaml | 23 + runtime/templates/definitions/bigquery.yaml | 13 + .../definitions/clickhouse-model.yaml | 23 + runtime/templates/definitions/clickhouse.yaml | 13 + runtime/templates/definitions/druid.yaml | 13 + runtime/templates/definitions/duckdb.yaml | 13 + runtime/templates/definitions/gcs-duckdb.yaml | 18 + runtime/templates/definitions/gcs.yaml | 13 + .../templates/definitions/https-duckdb.yaml | 18 + runtime/templates/definitions/https.yaml | 13 + .../templates/definitions/iceberg-duckdb.yaml | 26 + .../definitions/local-file-duckdb.yaml | 15 + runtime/templates/definitions/motherduck.yaml | 13 + .../templates/definitions/mysql-model.yaml | 23 + runtime/templates/definitions/mysql.yaml | 13 + runtime/templates/definitions/pinot.yaml | 13 + .../templates/definitions/postgres-model.yaml | 23 + runtime/templates/definitions/postgres.yaml | 13 + .../templates/definitions/redshift-model.yaml | 20 + runtime/templates/definitions/redshift.yaml | 13 + runtime/templates/definitions/s3-duckdb.yaml | 18 + runtime/templates/definitions/s3.yaml | 13 + .../definitions/salesforce-model.yaml | 23 + runtime/templates/definitions/salesforce.yaml | 13 + .../definitions/snowflake-model.yaml | 23 + runtime/templates/definitions/snowflake.yaml | 13 + .../templates/definitions/sqlite-duckdb.yaml | 15 + runtime/templates/definitions/starrocks.yaml | 13 + runtime/templates/duckdb.go | 48 + runtime/templates/duckdb_test.go | 50 + runtime/templates/env.go | 49 + runtime/templates/env_test.go | 45 + runtime/templates/funcmap.go | 54 + runtime/templates/headers.go | 52 + runtime/templates/headers_test.go | 56 + runtime/templates/registry.go | 132 + runtime/templates/registry_test.go | 112 + runtime/templates/render.go | 308 ++ runtime/templates/render_test.go | 392 ++ runtime/templates/template.go | 29 + .../src/proto/gen/rill/runtime/v1/api_pb.ts | 353 ++ .../src/runtime-client/gen/index.schemas.ts | 58 + .../gen/runtime-service/runtime-service.ts | 185 + 57 files changed, 6385 insertions(+), 1806 deletions(-) create mode 100644 runtime/server/templates.go create mode 100644 runtime/templates/definitions/athena-model.yaml create mode 100644 runtime/templates/definitions/athena.yaml create mode 100644 runtime/templates/definitions/azure-duckdb.yaml create mode 100644 runtime/templates/definitions/azure.yaml create mode 100644 runtime/templates/definitions/bigquery-model.yaml create mode 100644 runtime/templates/definitions/bigquery.yaml create mode 100644 runtime/templates/definitions/clickhouse-model.yaml create mode 100644 runtime/templates/definitions/clickhouse.yaml create mode 100644 runtime/templates/definitions/druid.yaml create mode 100644 runtime/templates/definitions/duckdb.yaml create mode 100644 runtime/templates/definitions/gcs-duckdb.yaml create mode 100644 runtime/templates/definitions/gcs.yaml create mode 100644 runtime/templates/definitions/https-duckdb.yaml create mode 100644 runtime/templates/definitions/https.yaml create mode 100644 runtime/templates/definitions/iceberg-duckdb.yaml create mode 100644 runtime/templates/definitions/local-file-duckdb.yaml create mode 100644 runtime/templates/definitions/motherduck.yaml create mode 100644 runtime/templates/definitions/mysql-model.yaml create mode 100644 runtime/templates/definitions/mysql.yaml create mode 100644 runtime/templates/definitions/pinot.yaml create mode 100644 runtime/templates/definitions/postgres-model.yaml create mode 100644 runtime/templates/definitions/postgres.yaml create mode 100644 runtime/templates/definitions/redshift-model.yaml create mode 100644 runtime/templates/definitions/redshift.yaml create mode 100644 runtime/templates/definitions/s3-duckdb.yaml create mode 100644 runtime/templates/definitions/s3.yaml create mode 100644 runtime/templates/definitions/salesforce-model.yaml create mode 100644 runtime/templates/definitions/salesforce.yaml create mode 100644 runtime/templates/definitions/snowflake-model.yaml create mode 100644 runtime/templates/definitions/snowflake.yaml create mode 100644 runtime/templates/definitions/sqlite-duckdb.yaml create mode 100644 runtime/templates/definitions/starrocks.yaml create mode 100644 runtime/templates/duckdb.go create mode 100644 runtime/templates/duckdb_test.go create mode 100644 runtime/templates/env.go create mode 100644 runtime/templates/env_test.go create mode 100644 runtime/templates/funcmap.go create mode 100644 runtime/templates/headers.go create mode 100644 runtime/templates/headers_test.go create mode 100644 runtime/templates/registry.go create mode 100644 runtime/templates/registry_test.go create mode 100644 runtime/templates/render.go create mode 100644 runtime/templates/render_test.go create mode 100644 runtime/templates/template.go diff --git a/proto/gen/rill/admin/v1/openapi.yaml b/proto/gen/rill/admin/v1/openapi.yaml index 83a805c9d31..9e6fd47d32d 100644 --- a/proto/gen/rill/admin/v1/openapi.yaml +++ b/proto/gen/rill/admin/v1/openapi.yaml @@ -2316,7 +2316,7 @@ externalDocs: info: description: Rill Admin API enables programmatic management of Rill Cloud resources, including organizations, projects, and user access. It provides endpoints for creating, updating, and deleting these resources, as well as managing authentication and permissions. title: Rill Admin API - version: v0.81.4 + version: v0.82.3 openapi: 3.0.3 paths: /v1/ai/complete: diff --git a/proto/gen/rill/admin/v1/public.openapi.yaml b/proto/gen/rill/admin/v1/public.openapi.yaml index b3e28d02e13..0084c542b64 100644 --- a/proto/gen/rill/admin/v1/public.openapi.yaml +++ b/proto/gen/rill/admin/v1/public.openapi.yaml @@ -2316,7 +2316,7 @@ externalDocs: info: description: Rill Admin API enables programmatic management of Rill Cloud resources, including organizations, projects, and user access. It provides endpoints for creating, updating, and deleting these resources, as well as managing authentication and permissions. title: Rill Admin API - version: v0.81.4 + version: v0.82.3 openapi: 3.0.3 paths: /v1/ai/complete: {} diff --git a/proto/gen/rill/runtime/v1/api.pb.go b/proto/gen/rill/runtime/v1/api.pb.go index 0707e164c1f..100e94a6533 100644 --- a/proto/gen/rill/runtime/v1/api.pb.go +++ b/proto/gen/rill/runtime/v1/api.pb.go @@ -238,7 +238,7 @@ func (x ConnectorDriver_Property_Type) Number() protoreflect.EnumNumber { // Deprecated: Use ConnectorDriver_Property_Type.Descriptor instead. func (ConnectorDriver_Property_Type) EnumDescriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{73, 0, 0} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{80, 0, 0} } // Request message for RuntimeService.Ping @@ -3523,6 +3523,447 @@ func (x *GenerateTemplateResponse) GetDriver() string { return "" } +// Template describes a declarative template for generating project files. +type Template struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + DisplayName string `protobuf:"bytes,2,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` + Driver string `protobuf:"bytes,3,opt,name=driver,proto3" json:"driver,omitempty"` + Olap string `protobuf:"bytes,4,opt,name=olap,proto3" json:"olap,omitempty"` + Tags []string `protobuf:"bytes,5,rep,name=tags,proto3" json:"tags,omitempty"` + Files []*TemplateFile `protobuf:"bytes,6,rep,name=files,proto3" json:"files,omitempty"` +} + +func (x *Template) Reset() { + *x = Template{} + if protoimpl.UnsafeEnabled { + mi := &file_rill_runtime_v1_api_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Template) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Template) ProtoMessage() {} + +func (x *Template) ProtoReflect() protoreflect.Message { + mi := &file_rill_runtime_v1_api_proto_msgTypes[53] + 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 Template.ProtoReflect.Descriptor instead. +func (*Template) Descriptor() ([]byte, []int) { + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{53} +} + +func (x *Template) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Template) GetDisplayName() string { + if x != nil { + return x.DisplayName + } + return "" +} + +func (x *Template) GetDriver() string { + if x != nil { + return x.Driver + } + return "" +} + +func (x *Template) GetOlap() string { + if x != nil { + return x.Olap + } + return "" +} + +func (x *Template) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *Template) GetFiles() []*TemplateFile { + if x != nil { + return x.Files + } + return nil +} + +// TemplateFile describes a single output file within a template. +type TemplateFile struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + PathPattern string `protobuf:"bytes,2,opt,name=path_pattern,json=pathPattern,proto3" json:"path_pattern,omitempty"` +} + +func (x *TemplateFile) Reset() { + *x = TemplateFile{} + if protoimpl.UnsafeEnabled { + mi := &file_rill_runtime_v1_api_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TemplateFile) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TemplateFile) ProtoMessage() {} + +func (x *TemplateFile) ProtoReflect() protoreflect.Message { + mi := &file_rill_runtime_v1_api_proto_msgTypes[54] + 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 TemplateFile.ProtoReflect.Descriptor instead. +func (*TemplateFile) Descriptor() ([]byte, []int) { + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{54} +} + +func (x *TemplateFile) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *TemplateFile) GetPathPattern() string { + if x != nil { + return x.PathPattern + } + return "" +} + +type ListTemplatesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Optional tag filter; only templates matching ALL tags are returned. + Tags []string `protobuf:"bytes,1,rep,name=tags,proto3" json:"tags,omitempty"` +} + +func (x *ListTemplatesRequest) Reset() { + *x = ListTemplatesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_rill_runtime_v1_api_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListTemplatesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListTemplatesRequest) ProtoMessage() {} + +func (x *ListTemplatesRequest) ProtoReflect() protoreflect.Message { + mi := &file_rill_runtime_v1_api_proto_msgTypes[55] + 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 ListTemplatesRequest.ProtoReflect.Descriptor instead. +func (*ListTemplatesRequest) Descriptor() ([]byte, []int) { + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{55} +} + +func (x *ListTemplatesRequest) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + +type ListTemplatesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Templates []*Template `protobuf:"bytes,1,rep,name=templates,proto3" json:"templates,omitempty"` +} + +func (x *ListTemplatesResponse) Reset() { + *x = ListTemplatesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_rill_runtime_v1_api_proto_msgTypes[56] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListTemplatesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListTemplatesResponse) ProtoMessage() {} + +func (x *ListTemplatesResponse) ProtoReflect() protoreflect.Message { + mi := &file_rill_runtime_v1_api_proto_msgTypes[56] + 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 ListTemplatesResponse.ProtoReflect.Descriptor instead. +func (*ListTemplatesResponse) Descriptor() ([]byte, []int) { + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{56} +} + +func (x *ListTemplatesResponse) GetTemplates() []*Template { + if x != nil { + return x.Templates + } + return nil +} + +type GenerateFileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + InstanceId string `protobuf:"bytes,1,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"` + // Template name (e.g. "s3", "s3-duckdb", "iceberg-duckdb") + TemplateName string `protobuf:"bytes,2,opt,name=template_name,json=templateName,proto3" json:"template_name,omitempty"` + // Output filter: "connector", "model", or empty for all files + Output string `protobuf:"bytes,3,opt,name=output,proto3" json:"output,omitempty"` + Properties *structpb.Struct `protobuf:"bytes,4,opt,name=properties,proto3" json:"properties,omitempty"` + // Connector name reference (for model outputs that reference a connector) + ConnectorName string `protobuf:"bytes,5,opt,name=connector_name,json=connectorName,proto3" json:"connector_name,omitempty"` + // If true, render without writing files (for YAML preview) + Preview bool `protobuf:"varint,6,opt,name=preview,proto3" json:"preview,omitempty"` +} + +func (x *GenerateFileRequest) Reset() { + *x = GenerateFileRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_rill_runtime_v1_api_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GenerateFileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenerateFileRequest) ProtoMessage() {} + +func (x *GenerateFileRequest) ProtoReflect() protoreflect.Message { + mi := &file_rill_runtime_v1_api_proto_msgTypes[57] + 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 GenerateFileRequest.ProtoReflect.Descriptor instead. +func (*GenerateFileRequest) Descriptor() ([]byte, []int) { + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{57} +} + +func (x *GenerateFileRequest) GetInstanceId() string { + if x != nil { + return x.InstanceId + } + return "" +} + +func (x *GenerateFileRequest) GetTemplateName() string { + if x != nil { + return x.TemplateName + } + return "" +} + +func (x *GenerateFileRequest) GetOutput() string { + if x != nil { + return x.Output + } + return "" +} + +func (x *GenerateFileRequest) GetProperties() *structpb.Struct { + if x != nil { + return x.Properties + } + return nil +} + +func (x *GenerateFileRequest) GetConnectorName() string { + if x != nil { + return x.ConnectorName + } + return "" +} + +func (x *GenerateFileRequest) GetPreview() bool { + if x != nil { + return x.Preview + } + return false +} + +type GenerateFileResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Files []*GeneratedFile `protobuf:"bytes,1,rep,name=files,proto3" json:"files,omitempty"` + EnvVars map[string]string `protobuf:"bytes,2,rep,name=env_vars,json=envVars,proto3" json:"env_vars,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *GenerateFileResponse) Reset() { + *x = GenerateFileResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_rill_runtime_v1_api_proto_msgTypes[58] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GenerateFileResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenerateFileResponse) ProtoMessage() {} + +func (x *GenerateFileResponse) ProtoReflect() protoreflect.Message { + mi := &file_rill_runtime_v1_api_proto_msgTypes[58] + 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 GenerateFileResponse.ProtoReflect.Descriptor instead. +func (*GenerateFileResponse) Descriptor() ([]byte, []int) { + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{58} +} + +func (x *GenerateFileResponse) GetFiles() []*GeneratedFile { + if x != nil { + return x.Files + } + return nil +} + +func (x *GenerateFileResponse) GetEnvVars() map[string]string { + if x != nil { + return x.EnvVars + } + return nil +} + +// GeneratedFile is a single rendered output file. +type GeneratedFile struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + Blob string `protobuf:"bytes,2,opt,name=blob,proto3" json:"blob,omitempty"` +} + +func (x *GeneratedFile) Reset() { + *x = GeneratedFile{} + if protoimpl.UnsafeEnabled { + mi := &file_rill_runtime_v1_api_proto_msgTypes[59] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GeneratedFile) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GeneratedFile) ProtoMessage() {} + +func (x *GeneratedFile) ProtoReflect() protoreflect.Message { + mi := &file_rill_runtime_v1_api_proto_msgTypes[59] + 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 GeneratedFile.ProtoReflect.Descriptor instead. +func (*GeneratedFile) Descriptor() ([]byte, []int) { + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{59} +} + +func (x *GeneratedFile) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *GeneratedFile) GetBlob() string { + if x != nil { + return x.Blob + } + return "" +} + type QueryResolverRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3538,7 +3979,7 @@ type QueryResolverRequest struct { func (x *QueryResolverRequest) Reset() { *x = QueryResolverRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[53] + mi := &file_rill_runtime_v1_api_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3551,7 +3992,7 @@ func (x *QueryResolverRequest) String() string { func (*QueryResolverRequest) ProtoMessage() {} func (x *QueryResolverRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[53] + mi := &file_rill_runtime_v1_api_proto_msgTypes[60] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3564,7 +4005,7 @@ func (x *QueryResolverRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryResolverRequest.ProtoReflect.Descriptor instead. func (*QueryResolverRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{53} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{60} } func (x *QueryResolverRequest) GetInstanceId() string { @@ -3615,7 +4056,7 @@ type QueryResolverResponse struct { func (x *QueryResolverResponse) Reset() { *x = QueryResolverResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[54] + mi := &file_rill_runtime_v1_api_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3628,7 +4069,7 @@ func (x *QueryResolverResponse) String() string { func (*QueryResolverResponse) ProtoMessage() {} func (x *QueryResolverResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[54] + mi := &file_rill_runtime_v1_api_proto_msgTypes[61] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3641,7 +4082,7 @@ func (x *QueryResolverResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use QueryResolverResponse.ProtoReflect.Descriptor instead. func (*QueryResolverResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{54} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{61} } func (x *QueryResolverResponse) GetMeta() *structpb.Struct { @@ -3679,7 +4120,7 @@ type Log struct { func (x *Log) Reset() { *x = Log{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[55] + mi := &file_rill_runtime_v1_api_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3692,7 +4133,7 @@ func (x *Log) String() string { func (*Log) ProtoMessage() {} func (x *Log) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[55] + mi := &file_rill_runtime_v1_api_proto_msgTypes[62] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3705,7 +4146,7 @@ func (x *Log) ProtoReflect() protoreflect.Message { // Deprecated: Use Log.ProtoReflect.Descriptor instead. func (*Log) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{55} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{62} } func (x *Log) GetLevel() LogLevel { @@ -3752,7 +4193,7 @@ type ModelPartition struct { func (x *ModelPartition) Reset() { *x = ModelPartition{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[56] + mi := &file_rill_runtime_v1_api_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3765,7 +4206,7 @@ func (x *ModelPartition) String() string { func (*ModelPartition) ProtoMessage() {} func (x *ModelPartition) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[56] + mi := &file_rill_runtime_v1_api_proto_msgTypes[63] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3778,7 +4219,7 @@ func (x *ModelPartition) ProtoReflect() protoreflect.Message { // Deprecated: Use ModelPartition.ProtoReflect.Descriptor instead. func (*ModelPartition) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{56} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{63} } func (x *ModelPartition) GetKey() string { @@ -3837,7 +4278,7 @@ type GetLogsRequest struct { func (x *GetLogsRequest) Reset() { *x = GetLogsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[57] + mi := &file_rill_runtime_v1_api_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3850,7 +4291,7 @@ func (x *GetLogsRequest) String() string { func (*GetLogsRequest) ProtoMessage() {} func (x *GetLogsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[57] + mi := &file_rill_runtime_v1_api_proto_msgTypes[64] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3863,7 +4304,7 @@ func (x *GetLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetLogsRequest.ProtoReflect.Descriptor instead. func (*GetLogsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{57} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{64} } func (x *GetLogsRequest) GetInstanceId() string { @@ -3905,7 +4346,7 @@ type GetLogsResponse struct { func (x *GetLogsResponse) Reset() { *x = GetLogsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[58] + mi := &file_rill_runtime_v1_api_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3918,7 +4359,7 @@ func (x *GetLogsResponse) String() string { func (*GetLogsResponse) ProtoMessage() {} func (x *GetLogsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[58] + mi := &file_rill_runtime_v1_api_proto_msgTypes[65] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3931,7 +4372,7 @@ func (x *GetLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetLogsResponse.ProtoReflect.Descriptor instead. func (*GetLogsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{58} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{65} } func (x *GetLogsResponse) GetLogs() []*Log { @@ -3955,7 +4396,7 @@ type WatchLogsRequest struct { func (x *WatchLogsRequest) Reset() { *x = WatchLogsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[59] + mi := &file_rill_runtime_v1_api_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3968,7 +4409,7 @@ func (x *WatchLogsRequest) String() string { func (*WatchLogsRequest) ProtoMessage() {} func (x *WatchLogsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[59] + mi := &file_rill_runtime_v1_api_proto_msgTypes[66] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3981,7 +4422,7 @@ func (x *WatchLogsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchLogsRequest.ProtoReflect.Descriptor instead. func (*WatchLogsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{59} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{66} } func (x *WatchLogsRequest) GetInstanceId() string { @@ -4023,7 +4464,7 @@ type WatchLogsResponse struct { func (x *WatchLogsResponse) Reset() { *x = WatchLogsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[60] + mi := &file_rill_runtime_v1_api_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4036,7 +4477,7 @@ func (x *WatchLogsResponse) String() string { func (*WatchLogsResponse) ProtoMessage() {} func (x *WatchLogsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[60] + mi := &file_rill_runtime_v1_api_proto_msgTypes[67] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4049,7 +4490,7 @@ func (x *WatchLogsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchLogsResponse.ProtoReflect.Descriptor instead. func (*WatchLogsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{60} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{67} } func (x *WatchLogsResponse) GetLog() *Log { @@ -4077,7 +4518,7 @@ type ListResourcesRequest struct { func (x *ListResourcesRequest) Reset() { *x = ListResourcesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[61] + mi := &file_rill_runtime_v1_api_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4090,7 +4531,7 @@ func (x *ListResourcesRequest) String() string { func (*ListResourcesRequest) ProtoMessage() {} func (x *ListResourcesRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[61] + mi := &file_rill_runtime_v1_api_proto_msgTypes[68] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4103,7 +4544,7 @@ func (x *ListResourcesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListResourcesRequest.ProtoReflect.Descriptor instead. func (*ListResourcesRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{61} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{68} } func (x *ListResourcesRequest) GetInstanceId() string { @@ -4145,7 +4586,7 @@ type ListResourcesResponse struct { func (x *ListResourcesResponse) Reset() { *x = ListResourcesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[62] + mi := &file_rill_runtime_v1_api_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4158,7 +4599,7 @@ func (x *ListResourcesResponse) String() string { func (*ListResourcesResponse) ProtoMessage() {} func (x *ListResourcesResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[62] + mi := &file_rill_runtime_v1_api_proto_msgTypes[69] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4171,7 +4612,7 @@ func (x *ListResourcesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListResourcesResponse.ProtoReflect.Descriptor instead. func (*ListResourcesResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{62} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{69} } func (x *ListResourcesResponse) GetResources() []*Resource { @@ -4194,7 +4635,7 @@ type WatchResourcesRequest struct { func (x *WatchResourcesRequest) Reset() { *x = WatchResourcesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[63] + mi := &file_rill_runtime_v1_api_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4207,7 +4648,7 @@ func (x *WatchResourcesRequest) String() string { func (*WatchResourcesRequest) ProtoMessage() {} func (x *WatchResourcesRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[63] + mi := &file_rill_runtime_v1_api_proto_msgTypes[70] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4220,7 +4661,7 @@ func (x *WatchResourcesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchResourcesRequest.ProtoReflect.Descriptor instead. func (*WatchResourcesRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{63} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{70} } func (x *WatchResourcesRequest) GetInstanceId() string { @@ -4257,7 +4698,7 @@ type WatchResourcesResponse struct { func (x *WatchResourcesResponse) Reset() { *x = WatchResourcesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[64] + mi := &file_rill_runtime_v1_api_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4270,7 +4711,7 @@ func (x *WatchResourcesResponse) String() string { func (*WatchResourcesResponse) ProtoMessage() {} func (x *WatchResourcesResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[64] + mi := &file_rill_runtime_v1_api_proto_msgTypes[71] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4283,7 +4724,7 @@ func (x *WatchResourcesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use WatchResourcesResponse.ProtoReflect.Descriptor instead. func (*WatchResourcesResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{64} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{71} } func (x *WatchResourcesResponse) GetEvent() ResourceEvent { @@ -4320,7 +4761,7 @@ type GetResourceRequest struct { func (x *GetResourceRequest) Reset() { *x = GetResourceRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[65] + mi := &file_rill_runtime_v1_api_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4333,7 +4774,7 @@ func (x *GetResourceRequest) String() string { func (*GetResourceRequest) ProtoMessage() {} func (x *GetResourceRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[65] + mi := &file_rill_runtime_v1_api_proto_msgTypes[72] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4346,7 +4787,7 @@ func (x *GetResourceRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetResourceRequest.ProtoReflect.Descriptor instead. func (*GetResourceRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{65} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{72} } func (x *GetResourceRequest) GetInstanceId() string { @@ -4381,7 +4822,7 @@ type GetResourceResponse struct { func (x *GetResourceResponse) Reset() { *x = GetResourceResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[66] + mi := &file_rill_runtime_v1_api_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4394,7 +4835,7 @@ func (x *GetResourceResponse) String() string { func (*GetResourceResponse) ProtoMessage() {} func (x *GetResourceResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[66] + mi := &file_rill_runtime_v1_api_proto_msgTypes[73] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4407,7 +4848,7 @@ func (x *GetResourceResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetResourceResponse.ProtoReflect.Descriptor instead. func (*GetResourceResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{66} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{73} } func (x *GetResourceResponse) GetResource() *Resource { @@ -4429,7 +4870,7 @@ type GetExploreRequest struct { func (x *GetExploreRequest) Reset() { *x = GetExploreRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[67] + mi := &file_rill_runtime_v1_api_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4442,7 +4883,7 @@ func (x *GetExploreRequest) String() string { func (*GetExploreRequest) ProtoMessage() {} func (x *GetExploreRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[67] + mi := &file_rill_runtime_v1_api_proto_msgTypes[74] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4455,7 +4896,7 @@ func (x *GetExploreRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetExploreRequest.ProtoReflect.Descriptor instead. func (*GetExploreRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{67} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{74} } func (x *GetExploreRequest) GetInstanceId() string { @@ -4484,7 +4925,7 @@ type GetExploreResponse struct { func (x *GetExploreResponse) Reset() { *x = GetExploreResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[68] + mi := &file_rill_runtime_v1_api_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4497,7 +4938,7 @@ func (x *GetExploreResponse) String() string { func (*GetExploreResponse) ProtoMessage() {} func (x *GetExploreResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[68] + mi := &file_rill_runtime_v1_api_proto_msgTypes[75] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4510,7 +4951,7 @@ func (x *GetExploreResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetExploreResponse.ProtoReflect.Descriptor instead. func (*GetExploreResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{68} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{75} } func (x *GetExploreResponse) GetExplore() *Resource { @@ -4543,7 +4984,7 @@ type GetModelPartitionsRequest struct { func (x *GetModelPartitionsRequest) Reset() { *x = GetModelPartitionsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[69] + mi := &file_rill_runtime_v1_api_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4556,7 +4997,7 @@ func (x *GetModelPartitionsRequest) String() string { func (*GetModelPartitionsRequest) ProtoMessage() {} func (x *GetModelPartitionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[69] + mi := &file_rill_runtime_v1_api_proto_msgTypes[76] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4569,7 +5010,7 @@ func (x *GetModelPartitionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetModelPartitionsRequest.ProtoReflect.Descriptor instead. func (*GetModelPartitionsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{69} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{76} } func (x *GetModelPartitionsRequest) GetInstanceId() string { @@ -4626,7 +5067,7 @@ type GetModelPartitionsResponse struct { func (x *GetModelPartitionsResponse) Reset() { *x = GetModelPartitionsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[70] + mi := &file_rill_runtime_v1_api_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4639,7 +5080,7 @@ func (x *GetModelPartitionsResponse) String() string { func (*GetModelPartitionsResponse) ProtoMessage() {} func (x *GetModelPartitionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[70] + mi := &file_rill_runtime_v1_api_proto_msgTypes[77] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4652,7 +5093,7 @@ func (x *GetModelPartitionsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetModelPartitionsResponse.ProtoReflect.Descriptor instead. func (*GetModelPartitionsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{70} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{77} } func (x *GetModelPartitionsResponse) GetPartitions() []*ModelPartition { @@ -4695,7 +5136,7 @@ type CreateTriggerRequest struct { func (x *CreateTriggerRequest) Reset() { *x = CreateTriggerRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[71] + mi := &file_rill_runtime_v1_api_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4708,7 +5149,7 @@ func (x *CreateTriggerRequest) String() string { func (*CreateTriggerRequest) ProtoMessage() {} func (x *CreateTriggerRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[71] + mi := &file_rill_runtime_v1_api_proto_msgTypes[78] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4721,7 +5162,7 @@ func (x *CreateTriggerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateTriggerRequest.ProtoReflect.Descriptor instead. func (*CreateTriggerRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{71} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{78} } func (x *CreateTriggerRequest) GetInstanceId() string { @@ -4775,7 +5216,7 @@ type CreateTriggerResponse struct { func (x *CreateTriggerResponse) Reset() { *x = CreateTriggerResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[72] + mi := &file_rill_runtime_v1_api_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4788,7 +5229,7 @@ func (x *CreateTriggerResponse) String() string { func (*CreateTriggerResponse) ProtoMessage() {} func (x *CreateTriggerResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[72] + mi := &file_rill_runtime_v1_api_proto_msgTypes[79] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4801,7 +5242,7 @@ func (x *CreateTriggerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateTriggerResponse.ProtoReflect.Descriptor instead. func (*CreateTriggerResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{72} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{79} } // ConnectorDriver represents a connector driver available in the runtime. @@ -4839,7 +5280,7 @@ type ConnectorDriver struct { func (x *ConnectorDriver) Reset() { *x = ConnectorDriver{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[73] + mi := &file_rill_runtime_v1_api_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4852,7 +5293,7 @@ func (x *ConnectorDriver) String() string { func (*ConnectorDriver) ProtoMessage() {} func (x *ConnectorDriver) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[73] + mi := &file_rill_runtime_v1_api_proto_msgTypes[80] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4865,7 +5306,7 @@ func (x *ConnectorDriver) ProtoReflect() protoreflect.Message { // Deprecated: Use ConnectorDriver.ProtoReflect.Descriptor instead. func (*ConnectorDriver) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{73} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{80} } func (x *ConnectorDriver) GetName() string { @@ -5020,7 +5461,7 @@ type AnalyzedConnector struct { func (x *AnalyzedConnector) Reset() { *x = AnalyzedConnector{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[74] + mi := &file_rill_runtime_v1_api_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5033,7 +5474,7 @@ func (x *AnalyzedConnector) String() string { func (*AnalyzedConnector) ProtoMessage() {} func (x *AnalyzedConnector) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[74] + mi := &file_rill_runtime_v1_api_proto_msgTypes[81] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5046,7 +5487,7 @@ func (x *AnalyzedConnector) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalyzedConnector.ProtoReflect.Descriptor instead. func (*AnalyzedConnector) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{74} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{81} } func (x *AnalyzedConnector) GetName() string { @@ -5136,7 +5577,7 @@ type ListConnectorDriversRequest struct { func (x *ListConnectorDriversRequest) Reset() { *x = ListConnectorDriversRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[75] + mi := &file_rill_runtime_v1_api_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5149,7 +5590,7 @@ func (x *ListConnectorDriversRequest) String() string { func (*ListConnectorDriversRequest) ProtoMessage() {} func (x *ListConnectorDriversRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[75] + mi := &file_rill_runtime_v1_api_proto_msgTypes[82] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5162,7 +5603,7 @@ func (x *ListConnectorDriversRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListConnectorDriversRequest.ProtoReflect.Descriptor instead. func (*ListConnectorDriversRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{75} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{82} } // Response message for RuntimeService.ListConnectorDrivers @@ -5177,7 +5618,7 @@ type ListConnectorDriversResponse struct { func (x *ListConnectorDriversResponse) Reset() { *x = ListConnectorDriversResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[76] + mi := &file_rill_runtime_v1_api_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5190,7 +5631,7 @@ func (x *ListConnectorDriversResponse) String() string { func (*ListConnectorDriversResponse) ProtoMessage() {} func (x *ListConnectorDriversResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[76] + mi := &file_rill_runtime_v1_api_proto_msgTypes[83] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5203,7 +5644,7 @@ func (x *ListConnectorDriversResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListConnectorDriversResponse.ProtoReflect.Descriptor instead. func (*ListConnectorDriversResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{76} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{83} } func (x *ListConnectorDriversResponse) GetConnectors() []*ConnectorDriver { @@ -5225,7 +5666,7 @@ type AnalyzeConnectorsRequest struct { func (x *AnalyzeConnectorsRequest) Reset() { *x = AnalyzeConnectorsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[77] + mi := &file_rill_runtime_v1_api_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5238,7 +5679,7 @@ func (x *AnalyzeConnectorsRequest) String() string { func (*AnalyzeConnectorsRequest) ProtoMessage() {} func (x *AnalyzeConnectorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[77] + mi := &file_rill_runtime_v1_api_proto_msgTypes[84] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5251,7 +5692,7 @@ func (x *AnalyzeConnectorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalyzeConnectorsRequest.ProtoReflect.Descriptor instead. func (*AnalyzeConnectorsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{77} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{84} } func (x *AnalyzeConnectorsRequest) GetInstanceId() string { @@ -5273,7 +5714,7 @@ type AnalyzeConnectorsResponse struct { func (x *AnalyzeConnectorsResponse) Reset() { *x = AnalyzeConnectorsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[78] + mi := &file_rill_runtime_v1_api_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5286,7 +5727,7 @@ func (x *AnalyzeConnectorsResponse) String() string { func (*AnalyzeConnectorsResponse) ProtoMessage() {} func (x *AnalyzeConnectorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[78] + mi := &file_rill_runtime_v1_api_proto_msgTypes[85] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5299,7 +5740,7 @@ func (x *AnalyzeConnectorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalyzeConnectorsResponse.ProtoReflect.Descriptor instead. func (*AnalyzeConnectorsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{78} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{85} } func (x *AnalyzeConnectorsResponse) GetConnectors() []*AnalyzedConnector { @@ -5321,7 +5762,7 @@ type ListNotifierConnectorsRequest struct { func (x *ListNotifierConnectorsRequest) Reset() { *x = ListNotifierConnectorsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[79] + mi := &file_rill_runtime_v1_api_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5334,7 +5775,7 @@ func (x *ListNotifierConnectorsRequest) String() string { func (*ListNotifierConnectorsRequest) ProtoMessage() {} func (x *ListNotifierConnectorsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[79] + mi := &file_rill_runtime_v1_api_proto_msgTypes[86] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5347,7 +5788,7 @@ func (x *ListNotifierConnectorsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListNotifierConnectorsRequest.ProtoReflect.Descriptor instead. func (*ListNotifierConnectorsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{79} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{86} } func (x *ListNotifierConnectorsRequest) GetInstanceId() string { @@ -5370,7 +5811,7 @@ type ListNotifierConnectorsResponse struct { func (x *ListNotifierConnectorsResponse) Reset() { *x = ListNotifierConnectorsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[80] + mi := &file_rill_runtime_v1_api_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5383,7 +5824,7 @@ func (x *ListNotifierConnectorsResponse) String() string { func (*ListNotifierConnectorsResponse) ProtoMessage() {} func (x *ListNotifierConnectorsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[80] + mi := &file_rill_runtime_v1_api_proto_msgTypes[87] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5396,7 +5837,7 @@ func (x *ListNotifierConnectorsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListNotifierConnectorsResponse.ProtoReflect.Descriptor instead. func (*ListNotifierConnectorsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{80} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{87} } func (x *ListNotifierConnectorsResponse) GetConnectors() []*Connector { @@ -5424,7 +5865,7 @@ type Conversation struct { func (x *Conversation) Reset() { *x = Conversation{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[81] + mi := &file_rill_runtime_v1_api_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5437,7 +5878,7 @@ func (x *Conversation) String() string { func (*Conversation) ProtoMessage() {} func (x *Conversation) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[81] + mi := &file_rill_runtime_v1_api_proto_msgTypes[88] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5450,7 +5891,7 @@ func (x *Conversation) ProtoReflect() protoreflect.Message { // Deprecated: Use Conversation.ProtoReflect.Descriptor instead. func (*Conversation) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{81} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{88} } func (x *Conversation) GetId() string { @@ -5524,7 +5965,7 @@ type Message struct { func (x *Message) Reset() { *x = Message{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[82] + mi := &file_rill_runtime_v1_api_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5537,7 +5978,7 @@ func (x *Message) String() string { func (*Message) ProtoMessage() {} func (x *Message) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[82] + mi := &file_rill_runtime_v1_api_proto_msgTypes[89] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5550,7 +5991,7 @@ func (x *Message) ProtoReflect() protoreflect.Message { // Deprecated: Use Message.ProtoReflect.Descriptor instead. func (*Message) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{82} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{89} } func (x *Message) GetId() string { @@ -5661,7 +6102,7 @@ type AnalystAgentContext struct { func (x *AnalystAgentContext) Reset() { *x = AnalystAgentContext{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[83] + mi := &file_rill_runtime_v1_api_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5674,7 +6115,7 @@ func (x *AnalystAgentContext) String() string { func (*AnalystAgentContext) ProtoMessage() {} func (x *AnalystAgentContext) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[83] + mi := &file_rill_runtime_v1_api_proto_msgTypes[90] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5687,7 +6128,7 @@ func (x *AnalystAgentContext) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalystAgentContext.ProtoReflect.Descriptor instead. func (*AnalystAgentContext) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{83} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{90} } func (x *AnalystAgentContext) GetExplore() string { @@ -5770,7 +6211,7 @@ type DeveloperAgentContext struct { func (x *DeveloperAgentContext) Reset() { *x = DeveloperAgentContext{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[84] + mi := &file_rill_runtime_v1_api_proto_msgTypes[91] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5783,7 +6224,7 @@ func (x *DeveloperAgentContext) String() string { func (*DeveloperAgentContext) ProtoMessage() {} func (x *DeveloperAgentContext) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[84] + mi := &file_rill_runtime_v1_api_proto_msgTypes[91] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5796,7 +6237,7 @@ func (x *DeveloperAgentContext) ProtoReflect() protoreflect.Message { // Deprecated: Use DeveloperAgentContext.ProtoReflect.Descriptor instead. func (*DeveloperAgentContext) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{84} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{91} } func (x *DeveloperAgentContext) GetInitProject() bool { @@ -5833,7 +6274,7 @@ type FeedbackAgentContext struct { func (x *FeedbackAgentContext) Reset() { *x = FeedbackAgentContext{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[85] + mi := &file_rill_runtime_v1_api_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5846,7 +6287,7 @@ func (x *FeedbackAgentContext) String() string { func (*FeedbackAgentContext) ProtoMessage() {} func (x *FeedbackAgentContext) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[85] + mi := &file_rill_runtime_v1_api_proto_msgTypes[92] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5859,7 +6300,7 @@ func (x *FeedbackAgentContext) ProtoReflect() protoreflect.Message { // Deprecated: Use FeedbackAgentContext.ProtoReflect.Descriptor instead. func (*FeedbackAgentContext) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{85} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{92} } func (x *FeedbackAgentContext) GetTargetMessageId() string { @@ -5904,7 +6345,7 @@ type ListConversationsRequest struct { func (x *ListConversationsRequest) Reset() { *x = ListConversationsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[86] + mi := &file_rill_runtime_v1_api_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5917,7 +6358,7 @@ func (x *ListConversationsRequest) String() string { func (*ListConversationsRequest) ProtoMessage() {} func (x *ListConversationsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[86] + mi := &file_rill_runtime_v1_api_proto_msgTypes[93] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5930,7 +6371,7 @@ func (x *ListConversationsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListConversationsRequest.ProtoReflect.Descriptor instead. func (*ListConversationsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{86} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{93} } func (x *ListConversationsRequest) GetInstanceId() string { @@ -5959,7 +6400,7 @@ type ListConversationsResponse struct { func (x *ListConversationsResponse) Reset() { *x = ListConversationsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[87] + mi := &file_rill_runtime_v1_api_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5972,7 +6413,7 @@ func (x *ListConversationsResponse) String() string { func (*ListConversationsResponse) ProtoMessage() {} func (x *ListConversationsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[87] + mi := &file_rill_runtime_v1_api_proto_msgTypes[94] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5985,7 +6426,7 @@ func (x *ListConversationsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListConversationsResponse.ProtoReflect.Descriptor instead. func (*ListConversationsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{87} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{94} } func (x *ListConversationsResponse) GetConversations() []*Conversation { @@ -6008,7 +6449,7 @@ type GetConversationRequest struct { func (x *GetConversationRequest) Reset() { *x = GetConversationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[88] + mi := &file_rill_runtime_v1_api_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6021,7 +6462,7 @@ func (x *GetConversationRequest) String() string { func (*GetConversationRequest) ProtoMessage() {} func (x *GetConversationRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[88] + mi := &file_rill_runtime_v1_api_proto_msgTypes[95] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6034,7 +6475,7 @@ func (x *GetConversationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetConversationRequest.ProtoReflect.Descriptor instead. func (*GetConversationRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{88} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{95} } func (x *GetConversationRequest) GetInstanceId() string { @@ -6065,7 +6506,7 @@ type GetConversationResponse struct { func (x *GetConversationResponse) Reset() { *x = GetConversationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[89] + mi := &file_rill_runtime_v1_api_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6078,7 +6519,7 @@ func (x *GetConversationResponse) String() string { func (*GetConversationResponse) ProtoMessage() {} func (x *GetConversationResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[89] + mi := &file_rill_runtime_v1_api_proto_msgTypes[96] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6091,7 +6532,7 @@ func (x *GetConversationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetConversationResponse.ProtoReflect.Descriptor instead. func (*GetConversationResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{89} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{96} } func (x *GetConversationResponse) GetConversation() *Conversation { @@ -6132,7 +6573,7 @@ type ShareConversationRequest struct { func (x *ShareConversationRequest) Reset() { *x = ShareConversationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[90] + mi := &file_rill_runtime_v1_api_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6145,7 +6586,7 @@ func (x *ShareConversationRequest) String() string { func (*ShareConversationRequest) ProtoMessage() {} func (x *ShareConversationRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[90] + mi := &file_rill_runtime_v1_api_proto_msgTypes[97] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6158,7 +6599,7 @@ func (x *ShareConversationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShareConversationRequest.ProtoReflect.Descriptor instead. func (*ShareConversationRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{90} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{97} } func (x *ShareConversationRequest) GetInstanceId() string { @@ -6192,7 +6633,7 @@ type ShareConversationResponse struct { func (x *ShareConversationResponse) Reset() { *x = ShareConversationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[91] + mi := &file_rill_runtime_v1_api_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6205,7 +6646,7 @@ func (x *ShareConversationResponse) String() string { func (*ShareConversationResponse) ProtoMessage() {} func (x *ShareConversationResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[91] + mi := &file_rill_runtime_v1_api_proto_msgTypes[98] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6218,7 +6659,7 @@ func (x *ShareConversationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ShareConversationResponse.ProtoReflect.Descriptor instead. func (*ShareConversationResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{91} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{98} } // Request message for RuntimeService.ForkConversation @@ -6234,7 +6675,7 @@ type ForkConversationRequest struct { func (x *ForkConversationRequest) Reset() { *x = ForkConversationRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[92] + mi := &file_rill_runtime_v1_api_proto_msgTypes[99] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6247,7 +6688,7 @@ func (x *ForkConversationRequest) String() string { func (*ForkConversationRequest) ProtoMessage() {} func (x *ForkConversationRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[92] + mi := &file_rill_runtime_v1_api_proto_msgTypes[99] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6260,7 +6701,7 @@ func (x *ForkConversationRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ForkConversationRequest.ProtoReflect.Descriptor instead. func (*ForkConversationRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{92} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{99} } func (x *ForkConversationRequest) GetInstanceId() string { @@ -6289,7 +6730,7 @@ type ForkConversationResponse struct { func (x *ForkConversationResponse) Reset() { *x = ForkConversationResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[93] + mi := &file_rill_runtime_v1_api_proto_msgTypes[100] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6302,7 +6743,7 @@ func (x *ForkConversationResponse) String() string { func (*ForkConversationResponse) ProtoMessage() {} func (x *ForkConversationResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[93] + mi := &file_rill_runtime_v1_api_proto_msgTypes[100] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6315,7 +6756,7 @@ func (x *ForkConversationResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ForkConversationResponse.ProtoReflect.Descriptor instead. func (*ForkConversationResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{93} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{100} } func (x *ForkConversationResponse) GetConversationId() string { @@ -6337,7 +6778,7 @@ type ListToolsRequest struct { func (x *ListToolsRequest) Reset() { *x = ListToolsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[94] + mi := &file_rill_runtime_v1_api_proto_msgTypes[101] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6350,7 +6791,7 @@ func (x *ListToolsRequest) String() string { func (*ListToolsRequest) ProtoMessage() {} func (x *ListToolsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[94] + mi := &file_rill_runtime_v1_api_proto_msgTypes[101] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6363,7 +6804,7 @@ func (x *ListToolsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListToolsRequest.ProtoReflect.Descriptor instead. func (*ListToolsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{94} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{101} } func (x *ListToolsRequest) GetInstanceId() string { @@ -6385,7 +6826,7 @@ type ListToolsResponse struct { func (x *ListToolsResponse) Reset() { *x = ListToolsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[95] + mi := &file_rill_runtime_v1_api_proto_msgTypes[102] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6398,7 +6839,7 @@ func (x *ListToolsResponse) String() string { func (*ListToolsResponse) ProtoMessage() {} func (x *ListToolsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[95] + mi := &file_rill_runtime_v1_api_proto_msgTypes[102] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6411,7 +6852,7 @@ func (x *ListToolsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListToolsResponse.ProtoReflect.Descriptor instead. func (*ListToolsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{95} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{102} } func (x *ListToolsResponse) GetTools() []*v1.Tool { @@ -6450,7 +6891,7 @@ type CompleteRequest struct { func (x *CompleteRequest) Reset() { *x = CompleteRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[96] + mi := &file_rill_runtime_v1_api_proto_msgTypes[103] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6463,7 +6904,7 @@ func (x *CompleteRequest) String() string { func (*CompleteRequest) ProtoMessage() {} func (x *CompleteRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[96] + mi := &file_rill_runtime_v1_api_proto_msgTypes[103] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6476,7 +6917,7 @@ func (x *CompleteRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CompleteRequest.ProtoReflect.Descriptor instead. func (*CompleteRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{96} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{103} } func (x *CompleteRequest) GetInstanceId() string { @@ -6541,7 +6982,7 @@ type CompleteResponse struct { func (x *CompleteResponse) Reset() { *x = CompleteResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[97] + mi := &file_rill_runtime_v1_api_proto_msgTypes[104] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6554,7 +6995,7 @@ func (x *CompleteResponse) String() string { func (*CompleteResponse) ProtoMessage() {} func (x *CompleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[97] + mi := &file_rill_runtime_v1_api_proto_msgTypes[104] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6567,7 +7008,7 @@ func (x *CompleteResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CompleteResponse.ProtoReflect.Descriptor instead. func (*CompleteResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{97} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{104} } func (x *CompleteResponse) GetConversationId() string { @@ -6613,7 +7054,7 @@ type CompleteStreamingRequest struct { func (x *CompleteStreamingRequest) Reset() { *x = CompleteStreamingRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[98] + mi := &file_rill_runtime_v1_api_proto_msgTypes[105] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6626,7 +7067,7 @@ func (x *CompleteStreamingRequest) String() string { func (*CompleteStreamingRequest) ProtoMessage() {} func (x *CompleteStreamingRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[98] + mi := &file_rill_runtime_v1_api_proto_msgTypes[105] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6639,7 +7080,7 @@ func (x *CompleteStreamingRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CompleteStreamingRequest.ProtoReflect.Descriptor instead. func (*CompleteStreamingRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{98} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{105} } func (x *CompleteStreamingRequest) GetInstanceId() string { @@ -6704,7 +7145,7 @@ type CompleteStreamingResponse struct { func (x *CompleteStreamingResponse) Reset() { *x = CompleteStreamingResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[99] + mi := &file_rill_runtime_v1_api_proto_msgTypes[106] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6717,7 +7158,7 @@ func (x *CompleteStreamingResponse) String() string { func (*CompleteStreamingResponse) ProtoMessage() {} func (x *CompleteStreamingResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[99] + mi := &file_rill_runtime_v1_api_proto_msgTypes[106] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6730,7 +7171,7 @@ func (x *CompleteStreamingResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CompleteStreamingResponse.ProtoReflect.Descriptor instead. func (*CompleteStreamingResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{99} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{106} } func (x *CompleteStreamingResponse) GetConversationId() string { @@ -6765,7 +7206,7 @@ type IssueDevJWTRequest struct { func (x *IssueDevJWTRequest) Reset() { *x = IssueDevJWTRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[100] + mi := &file_rill_runtime_v1_api_proto_msgTypes[107] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6778,7 +7219,7 @@ func (x *IssueDevJWTRequest) String() string { func (*IssueDevJWTRequest) ProtoMessage() {} func (x *IssueDevJWTRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[100] + mi := &file_rill_runtime_v1_api_proto_msgTypes[107] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6791,7 +7232,7 @@ func (x *IssueDevJWTRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use IssueDevJWTRequest.ProtoReflect.Descriptor instead. func (*IssueDevJWTRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{100} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{107} } func (x *IssueDevJWTRequest) GetName() string { @@ -6841,7 +7282,7 @@ type IssueDevJWTResponse struct { func (x *IssueDevJWTResponse) Reset() { *x = IssueDevJWTResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[101] + mi := &file_rill_runtime_v1_api_proto_msgTypes[108] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6854,7 +7295,7 @@ func (x *IssueDevJWTResponse) String() string { func (*IssueDevJWTResponse) ProtoMessage() {} func (x *IssueDevJWTResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[101] + mi := &file_rill_runtime_v1_api_proto_msgTypes[108] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6867,7 +7308,7 @@ func (x *IssueDevJWTResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use IssueDevJWTResponse.ProtoReflect.Descriptor instead. func (*IssueDevJWTResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{101} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{108} } func (x *IssueDevJWTResponse) GetJwt() string { @@ -6889,7 +7330,7 @@ type AnalyzeVariablesRequest struct { func (x *AnalyzeVariablesRequest) Reset() { *x = AnalyzeVariablesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[102] + mi := &file_rill_runtime_v1_api_proto_msgTypes[109] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6902,7 +7343,7 @@ func (x *AnalyzeVariablesRequest) String() string { func (*AnalyzeVariablesRequest) ProtoMessage() {} func (x *AnalyzeVariablesRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[102] + mi := &file_rill_runtime_v1_api_proto_msgTypes[109] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6915,7 +7356,7 @@ func (x *AnalyzeVariablesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalyzeVariablesRequest.ProtoReflect.Descriptor instead. func (*AnalyzeVariablesRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{102} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{109} } func (x *AnalyzeVariablesRequest) GetInstanceId() string { @@ -6937,7 +7378,7 @@ type AnalyzeVariablesResponse struct { func (x *AnalyzeVariablesResponse) Reset() { *x = AnalyzeVariablesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[103] + mi := &file_rill_runtime_v1_api_proto_msgTypes[110] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6950,7 +7391,7 @@ func (x *AnalyzeVariablesResponse) String() string { func (*AnalyzeVariablesResponse) ProtoMessage() {} func (x *AnalyzeVariablesResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[103] + mi := &file_rill_runtime_v1_api_proto_msgTypes[110] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6963,7 +7404,7 @@ func (x *AnalyzeVariablesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalyzeVariablesResponse.ProtoReflect.Descriptor instead. func (*AnalyzeVariablesResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{103} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{110} } func (x *AnalyzeVariablesResponse) GetVariables() []*AnalyzedVariable { @@ -6989,7 +7430,7 @@ type AnalyzedVariable struct { func (x *AnalyzedVariable) Reset() { *x = AnalyzedVariable{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[104] + mi := &file_rill_runtime_v1_api_proto_msgTypes[111] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7002,7 +7443,7 @@ func (x *AnalyzedVariable) String() string { func (*AnalyzedVariable) ProtoMessage() {} func (x *AnalyzedVariable) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[104] + mi := &file_rill_runtime_v1_api_proto_msgTypes[111] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7015,7 +7456,7 @@ func (x *AnalyzedVariable) ProtoReflect() protoreflect.Message { // Deprecated: Use AnalyzedVariable.ProtoReflect.Descriptor instead. func (*AnalyzedVariable) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{104} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{111} } func (x *AnalyzedVariable) GetName() string { @@ -7052,7 +7493,7 @@ type ListGitCommitsRequest struct { func (x *ListGitCommitsRequest) Reset() { *x = ListGitCommitsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[105] + mi := &file_rill_runtime_v1_api_proto_msgTypes[112] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7065,7 +7506,7 @@ func (x *ListGitCommitsRequest) String() string { func (*ListGitCommitsRequest) ProtoMessage() {} func (x *ListGitCommitsRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[105] + mi := &file_rill_runtime_v1_api_proto_msgTypes[112] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7078,7 +7519,7 @@ func (x *ListGitCommitsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListGitCommitsRequest.ProtoReflect.Descriptor instead. func (*ListGitCommitsRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{105} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{112} } func (x *ListGitCommitsRequest) GetInstanceId() string { @@ -7114,7 +7555,7 @@ type ListGitCommitsResponse struct { func (x *ListGitCommitsResponse) Reset() { *x = ListGitCommitsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[106] + mi := &file_rill_runtime_v1_api_proto_msgTypes[113] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7127,7 +7568,7 @@ func (x *ListGitCommitsResponse) String() string { func (*ListGitCommitsResponse) ProtoMessage() {} func (x *ListGitCommitsResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[106] + mi := &file_rill_runtime_v1_api_proto_msgTypes[113] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7140,7 +7581,7 @@ func (x *ListGitCommitsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListGitCommitsResponse.ProtoReflect.Descriptor instead. func (*ListGitCommitsResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{106} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{113} } func (x *ListGitCommitsResponse) GetCommits() []*GitCommit { @@ -7172,7 +7613,7 @@ type GitCommit struct { func (x *GitCommit) Reset() { *x = GitCommit{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[107] + mi := &file_rill_runtime_v1_api_proto_msgTypes[114] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7185,7 +7626,7 @@ func (x *GitCommit) String() string { func (*GitCommit) ProtoMessage() {} func (x *GitCommit) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[107] + mi := &file_rill_runtime_v1_api_proto_msgTypes[114] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7198,7 +7639,7 @@ func (x *GitCommit) ProtoReflect() protoreflect.Message { // Deprecated: Use GitCommit.ProtoReflect.Descriptor instead. func (*GitCommit) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{107} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{114} } func (x *GitCommit) GetCommitSha() string { @@ -7247,7 +7688,7 @@ type GitStatusRequest struct { func (x *GitStatusRequest) Reset() { *x = GitStatusRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[108] + mi := &file_rill_runtime_v1_api_proto_msgTypes[115] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7260,7 +7701,7 @@ func (x *GitStatusRequest) String() string { func (*GitStatusRequest) ProtoMessage() {} func (x *GitStatusRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[108] + mi := &file_rill_runtime_v1_api_proto_msgTypes[115] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7273,7 +7714,7 @@ func (x *GitStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GitStatusRequest.ProtoReflect.Descriptor instead. func (*GitStatusRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{108} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{115} } func (x *GitStatusRequest) GetInstanceId() string { @@ -7305,7 +7746,7 @@ type GitStatusResponse struct { func (x *GitStatusResponse) Reset() { *x = GitStatusResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[109] + mi := &file_rill_runtime_v1_api_proto_msgTypes[116] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7318,7 +7759,7 @@ func (x *GitStatusResponse) String() string { func (*GitStatusResponse) ProtoMessage() {} func (x *GitStatusResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[109] + mi := &file_rill_runtime_v1_api_proto_msgTypes[116] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7331,7 +7772,7 @@ func (x *GitStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GitStatusResponse.ProtoReflect.Descriptor instead. func (*GitStatusResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{109} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{116} } func (x *GitStatusResponse) GetBranch() string { @@ -7387,7 +7828,7 @@ type ListGitBranchesRequest struct { func (x *ListGitBranchesRequest) Reset() { *x = ListGitBranchesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[110] + mi := &file_rill_runtime_v1_api_proto_msgTypes[117] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7400,7 +7841,7 @@ func (x *ListGitBranchesRequest) String() string { func (*ListGitBranchesRequest) ProtoMessage() {} func (x *ListGitBranchesRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[110] + mi := &file_rill_runtime_v1_api_proto_msgTypes[117] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7413,7 +7854,7 @@ func (x *ListGitBranchesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListGitBranchesRequest.ProtoReflect.Descriptor instead. func (*ListGitBranchesRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{110} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{117} } func (x *ListGitBranchesRequest) GetInstanceId() string { @@ -7435,7 +7876,7 @@ type ListGitBranchesResponse struct { func (x *ListGitBranchesResponse) Reset() { *x = ListGitBranchesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[111] + mi := &file_rill_runtime_v1_api_proto_msgTypes[118] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7448,7 +7889,7 @@ func (x *ListGitBranchesResponse) String() string { func (*ListGitBranchesResponse) ProtoMessage() {} func (x *ListGitBranchesResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[111] + mi := &file_rill_runtime_v1_api_proto_msgTypes[118] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7461,7 +7902,7 @@ func (x *ListGitBranchesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListGitBranchesResponse.ProtoReflect.Descriptor instead. func (*ListGitBranchesResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{111} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{118} } func (x *ListGitBranchesResponse) GetCurrentBranch() string { @@ -7491,7 +7932,7 @@ type GitBranch struct { func (x *GitBranch) Reset() { *x = GitBranch{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[112] + mi := &file_rill_runtime_v1_api_proto_msgTypes[119] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7504,7 +7945,7 @@ func (x *GitBranch) String() string { func (*GitBranch) ProtoMessage() {} func (x *GitBranch) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[112] + mi := &file_rill_runtime_v1_api_proto_msgTypes[119] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7517,7 +7958,7 @@ func (x *GitBranch) ProtoReflect() protoreflect.Message { // Deprecated: Use GitBranch.ProtoReflect.Descriptor instead. func (*GitBranch) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{112} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{119} } func (x *GitBranch) GetName() string { @@ -7553,7 +7994,7 @@ type GitCommitRequest struct { func (x *GitCommitRequest) Reset() { *x = GitCommitRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[113] + mi := &file_rill_runtime_v1_api_proto_msgTypes[120] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7566,7 +8007,7 @@ func (x *GitCommitRequest) String() string { func (*GitCommitRequest) ProtoMessage() {} func (x *GitCommitRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[113] + mi := &file_rill_runtime_v1_api_proto_msgTypes[120] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7579,7 +8020,7 @@ func (x *GitCommitRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GitCommitRequest.ProtoReflect.Descriptor instead. func (*GitCommitRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{113} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{120} } func (x *GitCommitRequest) GetInstanceId() string { @@ -7607,7 +8048,7 @@ type GitCommitResponse struct { func (x *GitCommitResponse) Reset() { *x = GitCommitResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[114] + mi := &file_rill_runtime_v1_api_proto_msgTypes[121] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7620,7 +8061,7 @@ func (x *GitCommitResponse) String() string { func (*GitCommitResponse) ProtoMessage() {} func (x *GitCommitResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[114] + mi := &file_rill_runtime_v1_api_proto_msgTypes[121] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7633,7 +8074,7 @@ func (x *GitCommitResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GitCommitResponse.ProtoReflect.Descriptor instead. func (*GitCommitResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{114} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{121} } func (x *GitCommitResponse) GetCommitSha() string { @@ -7656,7 +8097,7 @@ type RestoreGitCommitRequest struct { func (x *RestoreGitCommitRequest) Reset() { *x = RestoreGitCommitRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[115] + mi := &file_rill_runtime_v1_api_proto_msgTypes[122] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7669,7 +8110,7 @@ func (x *RestoreGitCommitRequest) String() string { func (*RestoreGitCommitRequest) ProtoMessage() {} func (x *RestoreGitCommitRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[115] + mi := &file_rill_runtime_v1_api_proto_msgTypes[122] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7682,7 +8123,7 @@ func (x *RestoreGitCommitRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreGitCommitRequest.ProtoReflect.Descriptor instead. func (*RestoreGitCommitRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{115} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{122} } func (x *RestoreGitCommitRequest) GetInstanceId() string { @@ -7711,7 +8152,7 @@ type RestoreGitCommitResponse struct { func (x *RestoreGitCommitResponse) Reset() { *x = RestoreGitCommitResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[116] + mi := &file_rill_runtime_v1_api_proto_msgTypes[123] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7724,7 +8165,7 @@ func (x *RestoreGitCommitResponse) String() string { func (*RestoreGitCommitResponse) ProtoMessage() {} func (x *RestoreGitCommitResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[116] + mi := &file_rill_runtime_v1_api_proto_msgTypes[123] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7737,7 +8178,7 @@ func (x *RestoreGitCommitResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RestoreGitCommitResponse.ProtoReflect.Descriptor instead. func (*RestoreGitCommitResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{116} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{123} } func (x *RestoreGitCommitResponse) GetNewCommitSha() string { @@ -7761,7 +8202,7 @@ type GitMergeToBranchRequest struct { func (x *GitMergeToBranchRequest) Reset() { *x = GitMergeToBranchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[117] + mi := &file_rill_runtime_v1_api_proto_msgTypes[124] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7774,7 +8215,7 @@ func (x *GitMergeToBranchRequest) String() string { func (*GitMergeToBranchRequest) ProtoMessage() {} func (x *GitMergeToBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[117] + mi := &file_rill_runtime_v1_api_proto_msgTypes[124] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7787,7 +8228,7 @@ func (x *GitMergeToBranchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GitMergeToBranchRequest.ProtoReflect.Descriptor instead. func (*GitMergeToBranchRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{117} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{124} } func (x *GitMergeToBranchRequest) GetInstanceId() string { @@ -7823,7 +8264,7 @@ type GitMergeToBranchResponse struct { func (x *GitMergeToBranchResponse) Reset() { *x = GitMergeToBranchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[118] + mi := &file_rill_runtime_v1_api_proto_msgTypes[125] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7836,7 +8277,7 @@ func (x *GitMergeToBranchResponse) String() string { func (*GitMergeToBranchResponse) ProtoMessage() {} func (x *GitMergeToBranchResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[118] + mi := &file_rill_runtime_v1_api_proto_msgTypes[125] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7849,7 +8290,7 @@ func (x *GitMergeToBranchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GitMergeToBranchResponse.ProtoReflect.Descriptor instead. func (*GitMergeToBranchResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{118} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{125} } func (x *GitMergeToBranchResponse) GetOutput() string { @@ -7873,7 +8314,7 @@ type GitSwitchBranchRequest struct { func (x *GitSwitchBranchRequest) Reset() { *x = GitSwitchBranchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[119] + mi := &file_rill_runtime_v1_api_proto_msgTypes[126] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7886,7 +8327,7 @@ func (x *GitSwitchBranchRequest) String() string { func (*GitSwitchBranchRequest) ProtoMessage() {} func (x *GitSwitchBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[119] + mi := &file_rill_runtime_v1_api_proto_msgTypes[126] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7899,7 +8340,7 @@ func (x *GitSwitchBranchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GitSwitchBranchRequest.ProtoReflect.Descriptor instead. func (*GitSwitchBranchRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{119} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{126} } func (x *GitSwitchBranchRequest) GetInstanceId() string { @@ -7939,7 +8380,7 @@ type GitSwitchBranchResponse struct { func (x *GitSwitchBranchResponse) Reset() { *x = GitSwitchBranchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[120] + mi := &file_rill_runtime_v1_api_proto_msgTypes[127] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7952,7 +8393,7 @@ func (x *GitSwitchBranchResponse) String() string { func (*GitSwitchBranchResponse) ProtoMessage() {} func (x *GitSwitchBranchResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[120] + mi := &file_rill_runtime_v1_api_proto_msgTypes[127] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -7965,7 +8406,7 @@ func (x *GitSwitchBranchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GitSwitchBranchResponse.ProtoReflect.Descriptor instead. func (*GitSwitchBranchResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{120} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{127} } type GitPullRequest struct { @@ -7980,7 +8421,7 @@ type GitPullRequest struct { func (x *GitPullRequest) Reset() { *x = GitPullRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[121] + mi := &file_rill_runtime_v1_api_proto_msgTypes[128] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -7993,7 +8434,7 @@ func (x *GitPullRequest) String() string { func (*GitPullRequest) ProtoMessage() {} func (x *GitPullRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[121] + mi := &file_rill_runtime_v1_api_proto_msgTypes[128] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8006,7 +8447,7 @@ func (x *GitPullRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GitPullRequest.ProtoReflect.Descriptor instead. func (*GitPullRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{121} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{128} } func (x *GitPullRequest) GetInstanceId() string { @@ -8035,7 +8476,7 @@ type GitPullResponse struct { func (x *GitPullResponse) Reset() { *x = GitPullResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[122] + mi := &file_rill_runtime_v1_api_proto_msgTypes[129] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8048,7 +8489,7 @@ func (x *GitPullResponse) String() string { func (*GitPullResponse) ProtoMessage() {} func (x *GitPullResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[122] + mi := &file_rill_runtime_v1_api_proto_msgTypes[129] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8061,7 +8502,7 @@ func (x *GitPullResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GitPullResponse.ProtoReflect.Descriptor instead. func (*GitPullResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{122} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{129} } func (x *GitPullResponse) GetOutput() string { @@ -8084,7 +8525,7 @@ type GitPushRequest struct { func (x *GitPushRequest) Reset() { *x = GitPushRequest{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[123] + mi := &file_rill_runtime_v1_api_proto_msgTypes[130] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8097,7 +8538,7 @@ func (x *GitPushRequest) String() string { func (*GitPushRequest) ProtoMessage() {} func (x *GitPushRequest) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[123] + mi := &file_rill_runtime_v1_api_proto_msgTypes[130] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8110,7 +8551,7 @@ func (x *GitPushRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GitPushRequest.ProtoReflect.Descriptor instead. func (*GitPushRequest) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{123} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{130} } func (x *GitPushRequest) GetInstanceId() string { @@ -8143,7 +8584,7 @@ type GitPushResponse struct { func (x *GitPushResponse) Reset() { *x = GitPushResponse{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[124] + mi := &file_rill_runtime_v1_api_proto_msgTypes[131] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8156,7 +8597,7 @@ func (x *GitPushResponse) String() string { func (*GitPushResponse) ProtoMessage() {} func (x *GitPushResponse) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[124] + mi := &file_rill_runtime_v1_api_proto_msgTypes[131] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8169,7 +8610,7 @@ func (x *GitPushResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GitPushResponse.ProtoReflect.Descriptor instead. func (*GitPushResponse) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{124} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{131} } // Property represents the spec of one of the driver's config properties @@ -8205,7 +8646,7 @@ type ConnectorDriver_Property struct { func (x *ConnectorDriver_Property) Reset() { *x = ConnectorDriver_Property{} if protoimpl.UnsafeEnabled { - mi := &file_rill_runtime_v1_api_proto_msgTypes[134] + mi := &file_rill_runtime_v1_api_proto_msgTypes[142] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -8218,7 +8659,7 @@ func (x *ConnectorDriver_Property) String() string { func (*ConnectorDriver_Property) ProtoMessage() {} func (x *ConnectorDriver_Property) ProtoReflect() protoreflect.Message { - mi := &file_rill_runtime_v1_api_proto_msgTypes[134] + mi := &file_rill_runtime_v1_api_proto_msgTypes[142] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -8231,7 +8672,7 @@ func (x *ConnectorDriver_Property) ProtoReflect() protoreflect.Message { // Deprecated: Use ConnectorDriver_Property.ProtoReflect.Descriptor instead. func (*ConnectorDriver_Property) Descriptor() ([]byte, []int) { - return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{73, 0} + return file_rill_runtime_v1_api_proto_rawDescGZIP(), []int{80, 0} } func (x *ConnectorDriver_Property) GetKey() string { @@ -8843,1271 +9284,1346 @@ var file_rill_runtime_v1_api_proto_rawDesc = []byte{ 0x61, 0x72, 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, 0xf1, 0x01, 0x0a, 0x14, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, - 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, - 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, - 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x13, 0x72, 0x65, - 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, - 0x73, 0x18, 0x03, 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, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, - 0x74, 0x69, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, - 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb6, 0x01, 0x0a, 0x08, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, + 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, + 0x12, 0x12, 0x0a, 0x04, 0x6f, 0x6c, 0x61, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6f, 0x6c, 0x61, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x33, 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x45, 0x0a, + 0x0c, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61, 0x74, 0x68, 0x50, 0x61, 0x74, + 0x74, 0x65, 0x72, 0x6e, 0x22, 0x2a, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x74, 0x61, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, + 0x22, 0x50, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x09, 0x74, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x09, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x73, 0x22, 0x90, 0x02, 0x0a, 0x13, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x46, + 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, + 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x0d, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, + 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x37, 0x0a, 0x0a, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x04, 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, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x69, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, + 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x72, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x22, 0xd7, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, + 0x0a, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x08, 0x65, 0x6e, 0x76, 0x5f, 0x76, 0x61, 0x72, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x45, 0x6e, + 0x76, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x56, + 0x61, 0x72, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 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, + 0x37, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x69, 0x6c, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x62, 0x6c, 0x6f, 0x62, 0x22, 0xf1, 0x01, 0x0a, 0x14, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x48, + 0x0a, 0x13, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 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, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x41, 0x72, - 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0xa6, 0x01, 0x0a, 0x15, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, 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, 0x6d, 0x65, 0x74, 0x61, 0x12, - 0x33, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x12, 0x2b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, - 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, 0x22, 0xa3, 0x01, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, - 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, - 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x02, 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, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x79, - 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6a, 0x73, 0x6f, 0x6e, - 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xfb, 0x01, 0x0a, 0x0e, 0x4d, 0x6f, 0x64, 0x65, - 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 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, 0x12, 0x38, 0x0a, 0x09, 0x77, 0x61, 0x74, - 0x65, 0x72, 0x6d, 0x61, 0x72, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x72, 0x75, 0x63, 0x74, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x6f, + 0x6c, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x04, 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, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, + 0x65, 0x72, 0x41, 0x72, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0xa6, 0x01, 0x0a, + 0x15, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x03, + 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, 0x6d, + 0x65, 0x74, 0x61, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x2b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x02, 0x20, 0x03, 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, 0x22, 0xa3, 0x01, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x2f, 0x0a, + 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x2e, + 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 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, 0x09, 0x77, 0x61, 0x74, 0x65, 0x72, 0x6d, - 0x61, 0x72, 0x6b, 0x12, 0x3b, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x5f, - 0x6f, 0x6e, 0x18, 0x04, 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, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x64, 0x4f, 0x6e, - 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, - 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x65, 0x6c, 0x61, 0x70, - 0x73, 0x65, 0x64, 0x4d, 0x73, 0x22, 0xa8, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x73, 0x63, - 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x73, - 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x26, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x10, 0xfa, 0x42, 0x0d, 0x1a, 0x0b, 0x28, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, - 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, - 0x22, 0x3b, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0xb1, 0x01, - 0x0a, 0x10, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x12, 0x33, 0x0a, 0x0c, 0x72, - 0x65, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x05, 0x42, 0x10, 0xfa, 0x42, 0x0d, 0x1a, 0x0b, 0x28, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x01, 0x52, 0x0b, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x4c, 0x69, 0x6d, 0x69, 0x74, - 0x12, 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, - 0x6c, 0x22, 0x3b, 0x0a, 0x11, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x22, 0x91, - 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, - 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, - 0x12, 0x30, 0x0a, 0x14, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, - 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x73, 0x22, 0x50, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x09, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x15, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, - 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, - 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, - 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x22, 0xb8, 0x01, 0x0a, 0x16, 0x57, - 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, - 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6a, 0x73, 0x6f, 0x6e, + 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x6a, 0x73, 0x6f, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0xfb, 0x01, 0x0a, 0x0e, + 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 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, 0x12, 0x38, 0x0a, + 0x09, 0x77, 0x61, 0x74, 0x65, 0x72, 0x6d, 0x61, 0x72, 0x6b, 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, 0x09, 0x77, 0x61, + 0x74, 0x65, 0x72, 0x6d, 0x61, 0x72, 0x6b, 0x12, 0x3b, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x04, 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, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x65, 0x6c, + 0x61, 0x70, 0x73, 0x65, 0x64, 0x5f, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, + 0x65, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x64, 0x4d, 0x73, 0x22, 0xa8, 0x01, 0x0a, 0x0e, 0x47, 0x65, + 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x31, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x30, 0x0a, 0x14, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, - 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, - 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x73, 0x22, 0x4c, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x22, 0x48, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x87, 0x01, 0x0a, 0x12, 0x47, - 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x33, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x07, 0x65, - 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, - 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, - 0x56, 0x69, 0x65, 0x77, 0x22, 0xce, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, - 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x65, 0x6e, - 0x64, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x65, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x65, 0x64, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x65, 0x64, 0x12, 0x27, 0x0a, - 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, - 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x2a, 0x05, 0x18, 0x90, 0x4e, 0x40, 0x01, 0x52, 0x08, 0x70, 0x61, - 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x85, 0x01, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, - 0x65, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, - 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, - 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xf7, 0x01, - 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, + 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, + 0x09, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x09, 0x61, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x26, 0x0a, 0x05, 0x6c, + 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x10, 0xfa, 0x42, 0x0d, 0x1a, + 0x0b, 0x28, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x52, 0x05, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x12, 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, + 0x65, 0x76, 0x65, 0x6c, 0x22, 0x3b, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, + 0x73, 0x22, 0xb1, 0x01, 0x0a, 0x10, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x18, 0x05, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4d, 0x6f, - 0x64, 0x65, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x65, - 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x06, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, - 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, 0x12, 0x19, 0x0a, 0x08, - 0x61, 0x6c, 0x6c, 0x5f, 0x66, 0x75, 0x6c, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x61, 0x6c, 0x6c, 0x46, 0x75, 0x6c, 0x6c, 0x22, 0x17, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x96, 0x0a, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, - 0x69, 0x76, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x56, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, - 0x72, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x10, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, - 0x12, 0x56, 0x0a, 0x11, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, - 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x72, - 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, - 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, - 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, - 0x08, 0x64, 0x6f, 0x63, 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x15, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x07, 0x64, 0x6f, 0x63, 0x73, 0x55, 0x72, 0x6c, 0x12, 0x2f, 0x0a, 0x13, 0x69, 0x6d, 0x70, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x12, 0x2d, 0x0a, 0x12, 0x69, 0x6d, 0x70, - 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6d, 0x70, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x0c, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0e, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x70, - 0x6f, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, - 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x69, 0x6d, 0x70, - 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x23, 0x0a, 0x0d, - 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x61, 0x69, 0x18, 0x0e, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x41, - 0x69, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, - 0x73, 0x71, 0x6c, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x53, 0x71, 0x6c, 0x53, 0x74, - 0x6f, 0x72, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x5f, 0x6f, 0x6c, 0x61, 0x70, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6d, - 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x6c, 0x61, 0x70, 0x12, 0x36, 0x0a, 0x17, - 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x69, - 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x12, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x46, - 0x69, 0x6c, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2f, 0x0a, 0x13, 0x69, 0x6d, 0x70, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, - 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x31, 0x0a, 0x14, 0x69, 0x6d, 0x70, - 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x77, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, - 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x1a, 0xda, 0x03, 0x0a, - 0x08, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x42, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x70, - 0x65, 0x72, 0x74, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, - 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x64, - 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x19, 0x0a, 0x08, 0x64, 0x6f, 0x63, 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x64, 0x6f, 0x63, 0x73, 0x55, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x68, - 0x69, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x69, 0x6e, 0x74, 0x12, - 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x6c, 0x61, - 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, - 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x65, 0x63, - 0x72, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x5f, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, - 0x22, 0x77, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, - 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x10, 0x01, 0x12, - 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x10, - 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, - 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, - 0x04, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x52, 0x4d, - 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x05, 0x22, 0x8d, 0x05, 0x0a, 0x11, 0x41, 0x6e, - 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, - 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x2f, 0x0a, - 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 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, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, - 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, - 0x04, 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, 0x0c, - 0x70, 0x72, 0x65, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3e, 0x0a, 0x0e, - 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 0x0d, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x50, 0x0a, 0x0a, - 0x65, 0x6e, 0x76, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x31, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x45, 0x6e, 0x76, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x09, 0x65, 0x6e, 0x76, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1c, - 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3e, 0x0a, 0x0e, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x0b, - 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, 0x0d, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x14, - 0x68, 0x61, 0x73, 0x5f, 0x61, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x5f, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x68, 0x61, 0x73, 0x41, - 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x36, - 0x0a, 0x07, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x12, + 0x33, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x05, 0x42, 0x10, 0xfa, 0x42, 0x0d, 0x1a, 0x0b, 0x28, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x52, 0x0b, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x4c, + 0x69, 0x6d, 0x69, 0x74, 0x12, 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, + 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x3b, 0x0a, 0x11, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, + 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x03, 0x6c, 0x6f, + 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x03, 0x6c, + 0x6f, 0x67, 0x22, 0x91, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, + 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x70, 0x61, 0x74, 0x68, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x63, + 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x12, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x22, 0x50, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x37, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x15, 0x57, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x79, 0x22, 0xb8, + 0x01, 0x0a, 0x16, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x05, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x31, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x12, 0x47, 0x65, + 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x31, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x06, - 0x75, 0x73, 0x65, 0x64, 0x42, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x3c, 0x0a, 0x0e, 0x45, - 0x6e, 0x76, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 0x1d, 0x0a, 0x1b, 0x4c, 0x69, 0x73, - 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x60, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x0a, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x3b, 0x0a, 0x18, 0x41, 0x6e, - 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, + 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x73, 0x65, 0x63, + 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x12, 0x73, 0x6b, 0x69, 0x70, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x22, 0x4c, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x22, 0x48, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, + 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x87, + 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x6d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0b, 0x6d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x22, 0xce, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, + 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x5f, 0x0a, 0x19, 0x41, 0x6e, 0x61, 0x6c, 0x79, - 0x7a, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, - 0x7a, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x0a, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x40, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, - 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x5c, 0x0a, 0x1e, 0x4c, 0x69, - 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0a, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x18, 0x0a, + 0x07, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x65, + 0x64, 0x12, 0x27, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0d, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x2a, 0x05, 0x18, 0x90, 0x4e, 0x40, 0x01, + 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x85, 0x01, 0x0a, 0x1a, 0x47, 0x65, + 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, + 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, + 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x22, 0xf7, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x09, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x09, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x06, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, + 0x73, 0x68, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x06, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x12, 0x10, + 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x6c, 0x6c, + 0x12, 0x19, 0x0a, 0x08, 0x61, 0x6c, 0x6c, 0x5f, 0x66, 0x75, 0x6c, 0x6c, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x61, 0x6c, 0x6c, 0x46, 0x75, 0x6c, 0x6c, 0x22, 0x17, 0x0a, 0x15, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x96, 0x0a, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x56, 0x0a, 0x11, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x52, 0x10, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x69, 0x65, 0x73, 0x12, 0x56, 0x0a, 0x11, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, + 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x52, 0x10, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x6f, 0x63, 0x73, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x15, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6f, 0x63, 0x73, 0x55, 0x72, 0x6c, 0x12, 0x2f, 0x0a, 0x13, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x72, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x12, 0x2d, 0x0a, + 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x63, 0x61, 0x74, 0x61, + 0x6c, 0x6f, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x69, 0x6d, 0x70, 0x6c, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x12, 0x27, 0x0a, 0x0f, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6f, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x29, 0x0a, 0x10, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x5f, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0f, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x41, 0x64, 0x6d, 0x69, 0x6e, + 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x61, + 0x69, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x41, 0x69, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x5f, 0x73, 0x71, 0x6c, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x0f, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x53, + 0x71, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6d, 0x70, 0x6c, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x6f, 0x6c, 0x61, 0x70, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0e, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x6c, 0x61, 0x70, + 0x12, 0x36, 0x0a, 0x17, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x15, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x69, 0x6d, 0x70, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x2f, 0x0a, 0x13, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x6e, 0x6f, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x72, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x6d, 0x70, 0x6c, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x31, 0x0a, + 0x14, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5f, 0x77, 0x61, 0x72, 0x65, + 0x68, 0x6f, 0x75, 0x73, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x69, 0x6d, 0x70, + 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x57, 0x61, 0x72, 0x65, 0x68, 0x6f, 0x75, 0x73, 0x65, + 0x1a, 0xda, 0x03, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x42, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x2e, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, + 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x6f, 0x63, 0x73, 0x5f, 0x75, 0x72, 0x6c, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x6f, 0x63, 0x73, 0x55, 0x72, 0x6c, 0x12, + 0x12, 0x0a, 0x04, 0x68, 0x69, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, + 0x69, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x20, 0x0a, + 0x0b, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x5f, 0x70, 0x72, + 0x6f, 0x6d, 0x70, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x6f, 0x50, 0x72, + 0x6f, 0x6d, 0x70, 0x74, 0x22, 0x77, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x10, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, + 0x52, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, + 0x45, 0x41, 0x4e, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, + 0x52, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, + 0x49, 0x4c, 0x45, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x49, 0x4e, + 0x46, 0x4f, 0x52, 0x4d, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x05, 0x22, 0x8d, 0x05, + 0x0a, 0x11, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, + 0x72, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 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, 0x06, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x0d, 0x70, 0x72, 0x65, 0x73, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x18, 0x04, 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, 0x0c, 0x70, 0x72, 0x65, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x3e, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 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, 0x0d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x50, 0x0a, 0x0a, 0x65, 0x6e, 0x76, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x45, 0x6e, 0x76, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x65, 0x6e, 0x76, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x3e, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x72, + 0x67, 0x73, 0x18, 0x0b, 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, 0x0d, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x67, 0x73, + 0x12, 0x30, 0x0a, 0x14, 0x68, 0x61, 0x73, 0x5f, 0x61, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, + 0x73, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, + 0x68, 0x61, 0x73, 0x41, 0x6e, 0x6f, 0x6e, 0x79, 0x6d, 0x6f, 0x75, 0x73, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x12, 0x36, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x52, 0x06, 0x75, 0x73, 0x65, 0x64, 0x42, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, + 0x3c, 0x0a, 0x0e, 0x45, 0x6e, 0x76, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 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, 0x1d, 0x0a, + 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, + 0x69, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x60, 0x0a, 0x1c, + 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, + 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x0a, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x9a, 0x02, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x77, 0x6e, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x73, - 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x04, 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, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x6f, 0x6e, 0x18, 0x05, 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, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, - 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0xf8, 0x02, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x39, - 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 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, 0x09, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x04, 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, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, - 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x6f, 0x6f, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x74, 0x6f, 0x6f, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x07, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x61, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x22, 0xac, 0x04, 0x0a, 0x13, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, - 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6c, - 0x6f, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, - 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x63, 0x61, - 0x6e, 0x76, 0x61, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x43, 0x6f, 0x6d, 0x70, - 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x69, 0x6d, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, - 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, - 0x73, 0x12, 0x31, 0x0a, 0x05, 0x77, 0x68, 0x65, 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x77, - 0x68, 0x65, 0x72, 0x65, 0x12, 0x72, 0x0a, 0x16, 0x77, 0x68, 0x65, 0x72, 0x65, 0x5f, 0x70, 0x65, - 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x18, 0x0c, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, - 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x57, 0x68, 0x65, 0x72, 0x65, - 0x50, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x13, 0x77, 0x68, 0x65, 0x72, 0x65, 0x50, 0x65, 0x72, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x12, 0x39, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, - 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, + 0x32, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, + 0x65, 0x72, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x3b, + 0x0a, 0x18, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x5f, 0x0a, 0x19, 0x41, + 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, + 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x40, 0x0a, 0x1d, + 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, + 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x5c, + 0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x3a, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x9a, 0x02, 0x0a, + 0x0c, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, 0x0a, + 0x08, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x39, 0x0a, + 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x04, 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, 0x09, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x05, 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, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x65, 0x6e, 0x64, 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, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x45, 0x6e, 0x64, 0x1a, 0x63, 0x0a, 0x18, 0x57, 0x68, - 0x65, 0x72, 0x65, 0x50, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, - 0x77, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x66, 0x0a, 0x15, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, - 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x69, 0x74, - 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, - 0x69, 0x6e, 0x69, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x63, - 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x46, - 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22, 0x9a, 0x01, 0x0a, 0x14, 0x46, 0x65, 0x65, 0x64, - 0x62, 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, - 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x61, - 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, - 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, - 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, - 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x83, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, - 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, - 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x74, 0x65, - 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x75, 0x73, 0x65, 0x72, 0x41, 0x67, - 0x65, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x22, 0x60, 0x0a, 0x19, 0x4c, 0x69, - 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x76, 0x65, - 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x4f, 0x6e, 0x12, 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, + 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0xf8, 0x02, 0x0a, 0x07, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x49, 0x64, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, + 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, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x39, 0x0a, + 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x04, 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, 0x09, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x12, + 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x6f, + 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x6f, 0x6f, 0x6c, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x6f, 0x6f, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x44, 0x61, 0x74, 0x61, + 0x12, 0x32, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x61, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x07, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x22, 0xac, 0x04, 0x0a, 0x13, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x18, 0x0a, 0x07, + 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, + 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x12, 0x29, + 0x0a, 0x10, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, + 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, + 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x6d, + 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x64, + 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x61, + 0x73, 0x75, 0x72, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x61, + 0x73, 0x75, 0x72, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x05, 0x77, 0x68, 0x65, 0x72, 0x65, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x05, 0x77, 0x68, 0x65, 0x72, 0x65, 0x12, 0x72, 0x0a, 0x16, 0x77, 0x68, 0x65, 0x72, + 0x65, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x76, 0x69, + 0x65, 0x77, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, + 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x57, + 0x68, 0x65, 0x72, 0x65, 0x50, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, + 0x65, 0x77, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x77, 0x68, 0x65, 0x72, 0x65, 0x50, 0x65, + 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x12, 0x39, 0x0a, 0x0a, + 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x72, 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, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x5f, + 0x65, 0x6e, 0x64, 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, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x45, 0x6e, 0x64, 0x1a, 0x63, + 0x0a, 0x18, 0x57, 0x68, 0x65, 0x72, 0x65, 0x50, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x73, 0x56, 0x69, 0x65, 0x77, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, + 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x66, 0x0a, 0x15, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x21, 0x0a, 0x0c, + 0x69, 0x6e, 0x69, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0b, 0x69, 0x6e, 0x69, 0x74, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, + 0x2a, 0x0a, 0x11, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x5f, + 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22, 0x9a, 0x01, 0x0a, 0x14, + 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, + 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, + 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0a, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x69, 0x65, 0x73, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x83, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, + 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, + 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, + 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, + 0x12, 0x2c, 0x0a, 0x12, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x70, + 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x75, 0x73, + 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x22, 0x60, + 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0d, 0x63, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x22, 0x7c, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, + 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0xad, + 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x63, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, + 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0xb1, + 0x01, 0x0a, 0x18, 0x53, 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, + 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x75, 0x6e, 0x74, 0x69, + 0x6c, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x49, 0x64, 0x22, 0x1b, 0x0a, 0x19, 0x53, 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x86, 0x01, 0x0a, 0x17, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, + 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x43, 0x0a, 0x18, 0x46, 0x6f, 0x72, 0x6b, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x33, 0x0a, + 0x10, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x49, 0x64, 0x22, 0x3b, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x61, 0x69, + 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x22, + 0xf4, 0x03, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, + 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, + 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, + 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x12, + 0x4e, 0x0a, 0x05, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, + 0xfa, 0x42, 0x35, 0x72, 0x33, 0x52, 0x0d, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x52, 0x0f, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x5f, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x0e, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x5f, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0xd0, 0x01, 0x01, 0x52, 0x05, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x12, + 0x58, 0x0a, 0x15, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x63, - 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7c, 0x0a, 0x16, - 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x52, 0x13, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x64, 0x65, 0x76, + 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, + 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x52, 0x15, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x5b, 0x0a, 0x16, 0x66, 0x65, 0x65, + 0x64, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x65, 0x65, 0x64, + 0x62, 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x52, 0x14, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x71, 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, + 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0xfd, 0x03, 0x0a, 0x18, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0xad, 0x01, 0x0a, 0x17, 0x47, - 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, - 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x63, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, - 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x07, 0x69, 0x73, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x22, 0xb1, 0x01, 0x0a, 0x18, 0x53, - 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, - 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, - 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, - 0x72, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x5f, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, - 0x75, 0x6e, 0x74, 0x69, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x22, 0x1b, - 0x0a, 0x19, 0x53, 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x86, 0x01, 0x0a, 0x17, - 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, - 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, - 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x49, 0x64, 0x12, 0x30, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, - 0x72, 0x02, 0x10, 0x01, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x43, 0x0a, 0x18, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, - 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x33, 0x0a, 0x10, 0x4c, 0x69, 0x73, - 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, - 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x3b, - 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x61, 0x69, 0x2e, 0x76, 0x31, 0x2e, - 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x05, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x22, 0xf4, 0x03, 0x0a, 0x0f, - 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, - 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x12, 0x4e, 0x0a, 0x05, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xfa, 0x42, 0x35, 0x72, - 0x33, 0x52, 0x0d, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x52, 0x0f, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0x52, 0x0e, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x61, 0x67, 0x65, 0x6e, - 0x74, 0xd0, 0x01, 0x01, 0x52, 0x05, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x15, 0x61, - 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x78, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, - 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x52, 0x13, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, - 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, - 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x15, - 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x5b, 0x0a, 0x16, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, - 0x6b, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, - 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, - 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x14, 0x66, 0x65, - 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x22, 0x71, 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, + 0x6f, 0x6d, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6d, + 0x70, 0x74, 0x12, 0x4e, 0x0a, 0x05, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x38, 0xfa, 0x42, 0x35, 0x72, 0x33, 0x52, 0x0d, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, + 0x74, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x0f, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, + 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x0e, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, + 0x63, 0x6b, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0xd0, 0x01, 0x01, 0x52, 0x05, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x12, 0x58, 0x0a, 0x15, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x13, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x5e, 0x0a, 0x17, + 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x15, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x5b, 0x0a, 0x16, + 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, + 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x52, 0x14, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x78, 0x0a, 0x19, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, - 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0xfd, 0x03, 0x0a, 0x18, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, - 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, - 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, - 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x12, 0x4e, - 0x0a, 0x05, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x38, 0xfa, - 0x42, 0x35, 0x72, 0x33, 0x52, 0x0d, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x52, 0x0f, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0x52, 0x0e, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x61, - 0x67, 0x65, 0x6e, 0x74, 0xd0, 0x01, 0x01, 0x52, 0x05, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x58, - 0x0a, 0x15, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, - 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x52, 0x13, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x74, 0x41, 0x67, 0x65, 0x6e, - 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x64, 0x65, 0x76, 0x65, - 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x76, 0x65, - 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x52, 0x15, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, - 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x5b, 0x0a, 0x16, 0x66, 0x65, 0x65, 0x64, - 0x62, 0x61, 0x63, 0x6b, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x62, - 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, - 0x14, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x78, 0x0a, 0x19, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, - 0xb7, 0x01, 0x0a, 0x12, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x05, 0x65, 0x6d, 0x61, - 0x69, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x64, - 0x6d, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, - 0x12, 0x37, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 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, 0x0a, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x27, 0x0a, 0x13, 0x49, 0x73, 0x73, - 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x6a, 0x77, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6a, - 0x77, 0x74, 0x22, 0x3a, 0x0a, 0x17, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, - 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, - 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x5b, - 0x0a, 0x18, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x09, 0x76, 0x61, - 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, - 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x10, - 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x65, 0x66, - 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x0a, 0x07, 0x75, 0x73, 0x65, - 0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x06, 0x75, 0x73, 0x65, 0x64, 0x42, - 0x79, 0x22, 0x8e, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, - 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, - 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x22, 0x76, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x07, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, - 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xc7, 0x01, 0x0a, 0x09, 0x47, - 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x3d, 0x0a, 0x0c, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, 0x04, 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, 0x0b, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x22, 0x4d, 0x0a, 0x10, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, - 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, - 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x49, 0x64, 0x22, 0xdc, 0x01, 0x0a, 0x11, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, 0x75, 0x72, 0x6c, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x55, 0x72, 0x6c, - 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x5f, 0x67, 0x69, 0x74, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x47, 0x69, - 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, - 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x43, - 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, - 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x73, 0x22, 0x53, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, - 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x78, 0x0a, 0x17, 0x4c, 0x69, 0x73, 0x74, 0x47, - 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x75, 0x72, 0x72, - 0x65, 0x6e, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x36, 0x0a, 0x08, 0x62, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, - 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, - 0x73, 0x22, 0x77, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x68, 0x61, 0x73, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x68, 0x61, 0x73, 0x44, - 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, 0x13, 0x65, 0x64, 0x69, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x65, 0x64, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x74, 0x0a, 0x10, 0x47, 0x69, - 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, - 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, - 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x22, 0x32, 0x0a, 0x11, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, - 0x73, 0x68, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x53, 0x68, 0x61, 0x22, 0x7c, 0x0a, 0x17, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, - 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x32, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x18, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0xb7, 0x01, 0x0a, 0x12, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, + 0x4a, 0x57, 0x54, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, + 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, + 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x12, 0x14, + 0x0a, 0x05, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, + 0x64, 0x6d, 0x69, 0x6e, 0x12, 0x37, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 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, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x27, 0x0a, + 0x13, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6a, 0x77, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6a, 0x77, 0x74, 0x22, 0x3a, 0x0a, 0x17, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, + 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x49, 0x64, 0x22, 0x5b, 0x0a, 0x18, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, + 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x56, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, + 0x83, 0x01, 0x0a, 0x10, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x64, 0x56, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x0a, + 0x07, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x06, 0x75, + 0x73, 0x65, 0x64, 0x42, 0x79, 0x22, 0x8e, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0a, 0x63, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, - 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, - 0x68, 0x61, 0x22, 0x40, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, - 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x53, 0x68, 0x61, 0x22, 0x82, 0x01, 0x0a, 0x17, 0x47, 0x69, 0x74, 0x4d, 0x65, 0x72, 0x67, - 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, + 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, + 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x76, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, + 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x34, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x07, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, + 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xc7, + 0x01, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x1d, 0x0a, 0x0a, + 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61, 0x12, 0x1f, 0x0a, 0x0b, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, + 0x3d, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x5f, 0x6f, 0x6e, 0x18, + 0x04, 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, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x4f, 0x6e, 0x12, 0x18, + 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x4d, 0x0a, 0x10, 0x47, 0x69, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, + 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0xdc, 0x01, 0x0a, 0x11, 0x47, 0x69, 0x74, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x5f, + 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x5f, + 0x67, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x6d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x64, 0x47, 0x69, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x0c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, + 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x22, 0x53, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, + 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, - 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, - 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x32, 0x0a, 0x18, 0x47, 0x69, 0x74, - 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0xb5, 0x01, - 0x0a, 0x16, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, - 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, - 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x12, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, - 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x70, 0x0a, 0x0e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x78, 0x0a, 0x17, 0x4c, + 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x5f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x36, 0x0a, + 0x08, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x08, 0x62, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x65, 0x73, 0x22, 0x77, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, + 0x63, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x68, 0x61, 0x73, 0x5f, 0x64, 0x65, + 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, + 0x68, 0x61, 0x73, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x2f, 0x0a, + 0x13, 0x65, 0x64, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x65, 0x64, 0x69, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x74, + 0x0a, 0x10, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, - 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x23, 0x0a, - 0x0d, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x4c, 0x6f, 0x63, - 0x61, 0x6c, 0x22, 0x29, 0x0a, 0x0f, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x88, 0x01, - 0x0a, 0x0e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, - 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, - 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x11, 0x0a, 0x0f, 0x47, 0x69, 0x74, 0x50, - 0x75, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x54, 0x0a, 0x09, 0x46, - 0x69, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x49, 0x4c, 0x45, - 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x45, 0x56, 0x45, - 0x4e, 0x54, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x46, 0x49, - 0x4c, 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, - 0x02, 0x2a, 0x8c, 0x01, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x19, - 0x0a, 0x15, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, - 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x04, 0x12, 0x12, - 0x0a, 0x0e, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x49, 0x4e, 0x46, 0x4f, - 0x10, 0x08, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, - 0x57, 0x41, 0x52, 0x4e, 0x10, 0x0c, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, - 0x56, 0x45, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x10, 0x12, 0x13, 0x0a, 0x0f, 0x4c, - 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x10, 0x14, - 0x2a, 0x64, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x56, - 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x56, - 0x45, 0x4e, 0x54, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x52, - 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, - 0x4c, 0x45, 0x54, 0x45, 0x10, 0x02, 0x32, 0xeb, 0x3d, 0x0a, 0x0e, 0x52, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x04, 0x50, 0x69, 0x6e, - 0x67, 0x12, 0x1c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x69, 0x6e, 0x67, - 0x12, 0x5d, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1e, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, - 0x8d, 0x01, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x12, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x65, 0x61, - 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x76, 0x31, - 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, - 0x75, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, - 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x7d, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x7b, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, - 0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x73, 0x12, 0x83, 0x01, 0x0a, 0x0c, 0x45, 0x64, 0x69, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x64, 0x69, 0x74, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x32, 0x1b, 0x2f, 0x76, 0x31, - 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x89, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x25, 0x0a, + 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x22, 0x32, 0x0a, 0x11, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61, 0x22, 0x7c, 0x0a, 0x17, 0x52, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, + 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, + 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x26, + 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x09, 0x63, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61, 0x22, 0x40, 0x0a, 0x18, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x5f, 0x73, 0x68, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6e, 0x65, 0x77, 0x43, + 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x53, 0x68, 0x61, 0x22, 0x82, 0x01, 0x0a, 0x17, 0x47, 0x69, 0x74, + 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, + 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, + 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, + 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x32, 0x0a, + 0x18, 0x47, 0x69, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x22, 0xb5, 0x01, 0x0a, 0x16, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x42, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, + 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, + 0x16, 0x0a, 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x06, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x67, 0x6e, 0x6f, 0x72, + 0x65, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x4c, 0x6f, 0x63, + 0x61, 0x6c, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x47, 0x69, 0x74, + 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x70, 0x0a, 0x0e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, + 0x72, 0x13, 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, + 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, + 0x64, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x29, 0x0a, 0x0f, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, + 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x22, 0x88, 0x01, 0x0a, 0x0e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xfa, 0x42, 0x15, 0x72, 0x13, + 0x32, 0x11, 0x5e, 0x5b, 0x5f, 0x5c, 0x2d, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, + 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, + 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x11, 0x0a, 0x0f, + 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, + 0x54, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x16, + 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x46, 0x49, 0x4c, 0x45, + 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, 0x12, 0x15, + 0x0a, 0x11, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x44, 0x45, 0x4c, + 0x45, 0x54, 0x45, 0x10, 0x02, 0x2a, 0x8c, 0x01, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, + 0x65, 0x6c, 0x12, 0x19, 0x0a, 0x15, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, + 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, + 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x44, 0x45, 0x42, 0x55, 0x47, + 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, + 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x08, 0x12, 0x12, 0x0a, 0x0e, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, + 0x56, 0x45, 0x4c, 0x5f, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x0c, 0x12, 0x13, 0x0a, 0x0f, 0x4c, 0x4f, + 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x10, 0x12, + 0x13, 0x0a, 0x0f, 0x4c, 0x4f, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x46, 0x41, 0x54, + 0x41, 0x4c, 0x10, 0x14, 0x2a, 0x64, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x1a, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, + 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, + 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x01, 0x12, + 0x19, 0x0a, 0x15, 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x56, 0x45, 0x4e, + 0x54, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x02, 0x32, 0xf6, 0x3f, 0x0a, 0x0e, 0x52, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, + 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f, + 0x70, 0x69, 0x6e, 0x67, 0x12, 0x5d, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1e, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x12, 0x8d, 0x01, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, + 0x22, 0x2f, 0x76, 0x31, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2f, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x7d, 0x12, 0x75, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x73, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x76, 0x31, + 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x7d, 0x0a, 0x0b, 0x47, 0x65, + 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76, + 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x7b, 0x0a, 0x0e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x26, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x91, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x43, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x3a, 0x01, 0x2a, 0x22, 0x29, 0x2f, - 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x6c, 0x6f, 0x61, - 0x64, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x7d, 0x0a, 0x09, 0x4c, 0x69, 0x73, 0x74, - 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, - 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x29, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x23, 0x12, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x88, 0x01, 0x0a, 0x0a, 0x57, 0x61, 0x74, 0x63, - 0x68, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x46, 0x69, - 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, - 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, - 0x30, 0x01, 0x12, 0x7d, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x2e, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x83, 0x01, 0x0a, 0x0c, 0x45, 0x64, 0x69, 0x74, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, - 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, + 0x45, 0x64, 0x69, 0x74, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x32, + 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x89, 0x01, 0x0a, + 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x12, + 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x76, 0x31, + 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x91, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x6c, + 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x6f, + 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x52, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x3a, 0x01, + 0x2a, 0x22, 0x29, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, + 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, + 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x2d, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x7d, 0x0a, 0x09, + 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x29, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, 0x12, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x65, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x80, 0x01, 0x0a, 0x07, 0x50, 0x75, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x1f, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x75, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, + 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x88, 0x01, 0x0a, 0x0a, + 0x57, 0x61, 0x74, 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, + 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x75, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, 0x2a, 0x22, 0x27, 0x2f, 0x76, 0x31, + 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x65, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x96, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x64, 0x69, 0x72, 0x12, 0x86, 0x01, - 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x2a, 0x27, 0x2f, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x77, + 0x61, 0x74, 0x63, 0x68, 0x30, 0x01, 0x12, 0x7d, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, + 0x65, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x76, + 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, + 0x65, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x80, 0x01, 0x0a, 0x07, 0x50, 0x75, 0x74, 0x46, 0x69, 0x6c, + 0x65, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x75, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, 0x2a, 0x22, + 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x96, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x27, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, + 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x31, 0x2f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x64, 0x69, + 0x72, 0x12, 0x86, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, + 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x29, 0x2a, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, + 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x52, + 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x61, + 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x33, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x3a, 0x01, 0x2a, 0x22, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, - 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x8a, 0x01, 0x0a, 0x0a, 0x52, 0x65, 0x6e, 0x61, 0x6d, - 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x46, 0x69, - 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x6e, 0x61, - 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x3a, 0x01, 0x2a, 0x22, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x71, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x78, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x9b, 0x01, 0x0a, 0x0d, 0x55, 0x6e, 0x70, 0x61, 0x63, - 0x6b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x2f, 0x72, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x71, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x45, + 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x12, 0x0c, 0x2f, 0x76, + 0x31, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x9b, 0x01, 0x0a, 0x0d, 0x55, + 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x25, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, + 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x35, 0x3a, 0x01, 0x2a, 0x22, 0x30, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, + 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, + 0x2d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x0b, 0x55, 0x6e, 0x70, + 0x61, 0x63, 0x6b, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x63, - 0x6b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x35, 0x3a, - 0x01, 0x2a, 0x22, 0x30, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x2d, 0x65, 0x78, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x0b, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x70, 0x61, - 0x63, 0x6b, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x3a, 0x01, 0x2a, 0x22, 0x2e, 0x2f, 0x76, 0x31, 0x2f, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x75, 0x6e, - 0x70, 0x61, 0x63, 0x6b, 0x2d, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x12, 0xc0, 0x01, 0x0a, 0x17, 0x47, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, - 0x65, 0x77, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x2f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x46, 0x69, 0x6c, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x46, 0x69, 0x6c, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x3c, 0x3a, 0x01, 0x2a, 0x22, 0x37, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, - 0x2d, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65, 0x77, 0x12, 0xab, 0x01, - 0x0a, 0x12, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, - 0x46, 0x69, 0x6c, 0x65, 0x12, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, - 0x61, 0x6e, 0x76, 0x61, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x76, 0x61, - 0x73, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3c, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x36, 0x3a, 0x01, 0x2a, 0x22, 0x31, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, + 0x6b, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, + 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, + 0x55, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x3a, 0x01, 0x2a, 0x22, 0x2e, + 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x2f, 0x75, 0x6e, 0x70, 0x61, 0x63, 0x6b, 0x2d, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x12, 0xc0, + 0x01, 0x0a, 0x17, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x2f, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, 0x77, + 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x56, 0x69, 0x65, + 0x77, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x42, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x3c, 0x3a, 0x01, 0x2a, 0x22, 0x37, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, 0x67, 0x65, 0x6e, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x2d, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x12, 0xa1, 0x01, 0x0a, 0x10, - 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, - 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x3a, 0x01, 0x2a, - 0x22, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, - 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x65, - 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, - 0xa1, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6e, 0x64, - 0x65, 0x72, 0x65, 0x72, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x72, 0x61, 0x74, 0x65, 0x2d, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2d, 0x76, 0x69, 0x65, + 0x77, 0x12, 0xab, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x61, + 0x6e, 0x76, 0x61, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, + 0x61, 0x6e, 0x76, 0x61, 0x73, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x3c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x36, 0x3a, 0x01, 0x2a, 0x22, 0x31, 0x2f, 0x76, + 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2f, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2d, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x12, + 0xa1, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, + 0x6c, 0x76, 0x65, 0x72, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, + 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, - 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, + 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x3a, 0x01, 0x2a, 0x22, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2f, 0x72, 0x65, 0x6e, 0x64, 0x65, - 0x72, 0x65, 0x72, 0x12, 0xa1, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, - 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x6c, + 0x76, 0x65, 0x72, 0x12, 0xa1, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, - 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x52, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x3a, 0x01, 0x2a, 0x22, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2f, 0x74, - 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x95, 0x01, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, - 0x3a, 0x01, 0x2a, 0x22, 0x2a, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, - 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, - 0x76, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, - 0x64, 0x7d, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x84, 0x01, 0x0a, 0x09, 0x57, 0x61, 0x74, 0x63, - 0x68, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, - 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x30, 0x01, 0x12, 0x8d, - 0x01, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x9a, - 0x01, 0x0a, 0x0e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x12, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, - 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x76, 0x31, 0x2f, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x2f, 0x2d, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x30, 0x01, 0x12, 0x86, 0x01, 0x0a, 0x0b, - 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x23, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, - 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x8c, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, - 0x6f, 0x72, 0x65, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, - 0x6c, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x65, 0x78, 0x70, 0x6c, - 0x6f, 0x72, 0x65, 0x12, 0xac, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x6c, - 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, - 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x3d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x37, 0x12, 0x35, 0x2f, 0x76, 0x31, - 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, - 0x7b, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x7d, 0x2f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x8e, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, - 0x67, 0x67, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, - 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, 0x22, 0x23, - 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, - 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x74, 0x72, 0x69, 0x67, - 0x67, 0x65, 0x72, 0x12, 0x90, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x2e, 0x72, + 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2f, 0x72, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x12, 0xa1, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x28, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x3a, 0x01, 0x2a, 0x22, 0x2d, 0x2f, 0x76, + 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x75, 0x0a, 0x0d, 0x4c, + 0x69, 0x73, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, - 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x15, 0x12, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x12, 0xa2, 0x01, 0x0a, 0x11, 0x41, 0x6e, 0x61, 0x6c, 0x79, - 0x7a, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x29, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, - 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, - 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x12, 0x2e, 0x2f, 0x76, 0x31, + 0x69, 0x73, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x0f, 0x12, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x73, 0x12, 0x91, 0x01, 0x0a, 0x0c, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x46, + 0x69, 0x6c, 0x65, 0x12, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x46, 0x69, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x3a, 0x01, 0x2a, 0x22, 0x29, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x73, 0x2f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x12, 0xb3, 0x01, 0x0a, 0x16, - 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, - 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x12, - 0x30, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, - 0x73, 0x12, 0xa0, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, - 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x12, 0x2c, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x95, 0x01, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x3a, + 0x01, 0x2a, 0x22, 0x2a, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x72, 0x12, 0x76, + 0x0a, 0x07, 0x47, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4c, + 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x28, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x84, 0x01, 0x0a, 0x09, 0x57, 0x61, 0x74, 0x63, 0x68, + 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, 0x6f, 0x67, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x4c, + 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, + 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x30, 0x01, 0x12, 0x8d, 0x01, + 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, + 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x12, 0x25, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x12, 0xac, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, - 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x40, 0x12, 0x3e, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x9a, 0x01, + 0x0a, 0x0e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x12, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x2f, 0x2d, 0x2f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x30, 0x01, 0x12, 0x86, 0x01, 0x0a, 0x0b, 0x47, + 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x23, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, + 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x8c, 0x01, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, + 0x72, 0x65, 0x12, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x70, 0x6c, + 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, - 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x69, 0x64, 0x7d, 0x12, 0xbb, 0x01, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, 0x61, 0x72, - 0x65, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x4f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x49, 0x3a, 0x01, 0x2a, 0x22, 0x44, 0x2f, 0x76, 0x31, - 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x76, 0x65, - 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x68, 0x61, 0x72, - 0x65, 0x12, 0xb7, 0x01, 0x0a, 0x10, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, - 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, + 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x65, 0x78, 0x70, 0x6c, 0x6f, + 0x72, 0x65, 0x12, 0xac, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x50, + 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, + 0x6f, 0x64, 0x65, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x6c, + 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x3d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x37, 0x12, 0x35, 0x2f, 0x76, 0x31, 0x2f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x7b, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x7d, 0x2f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x8e, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x12, 0x25, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, + 0x67, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x28, 0x3a, 0x01, 0x2a, 0x22, 0x23, 0x2f, + 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x74, 0x72, 0x69, 0x67, 0x67, + 0x65, 0x72, 0x12, 0x90, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x73, 0x12, 0x2c, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, + 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x44, 0x72, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, + 0x12, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, + 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x12, 0xa2, 0x01, 0x0a, 0x11, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, + 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x29, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, + 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x36, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x30, 0x12, 0x2e, 0x2f, 0x76, 0x31, 0x2f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x73, 0x2f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x12, 0xb3, 0x01, 0x0a, 0x16, 0x4c, + 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x38, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x32, 0x12, 0x30, + 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x73, + 0x12, 0xa0, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x34, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x12, 0x2c, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0xac, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x48, 0x3a, 0x01, 0x2a, 0x22, 0x43, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, - 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x6f, 0x72, 0x6b, 0x12, 0x80, 0x01, 0x0a, 0x09, - 0x4c, 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, - 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x83, - 0x01, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x20, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, 0x2a, 0x22, 0x27, 0x2f, 0x76, 0x31, + 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x40, 0x12, 0x3e, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, + 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, + 0x64, 0x7d, 0x12, 0xbb, 0x01, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x4f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x49, 0x3a, 0x01, 0x2a, 0x22, 0x44, 0x2f, 0x76, 0x31, 0x2f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, + 0x12, 0xb7, 0x01, 0x0a, 0x10, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x46, 0x6f, 0x72, 0x6b, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4e, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x48, 0x3a, 0x01, 0x2a, 0x22, 0x43, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, + 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x66, 0x6f, 0x72, 0x6b, 0x12, 0x80, 0x01, 0x0a, 0x09, 0x4c, + 0x69, 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, + 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, + 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x83, 0x01, + 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x20, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x3a, 0x01, 0x2a, 0x22, 0x27, 0x2f, 0x76, 0x31, 0x2f, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, + 0x65, 0x74, 0x65, 0x12, 0xa7, 0x01, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x3a, 0x01, 0x2a, 0x22, 0x2e, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6d, 0x70, - 0x6c, 0x65, 0x74, 0x65, 0x12, 0xa7, 0x01, 0x0a, 0x11, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x29, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x3a, 0x01, 0x2a, 0x22, 0x2e, 0x2f, 0x76, + 0x6c, 0x65, 0x74, 0x65, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x30, 0x01, 0x12, 0x70, 0x0a, + 0x0b, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x12, 0x23, 0x2e, 0x72, + 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, + 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x3a, + 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x2d, 0x6a, 0x77, 0x74, 0x12, + 0x9e, 0x01, 0x0a, 0x10, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, + 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x2f, 0x12, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, + 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x76, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, + 0x12, 0x92, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x69, 0x2f, 0x63, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2f, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x30, 0x01, 0x12, 0x70, - 0x0a, 0x0b, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x12, 0x23, 0x2e, - 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, - 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x73, 0x73, 0x75, 0x65, 0x44, 0x65, 0x76, 0x4a, 0x57, 0x54, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, - 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x2d, 0x6a, 0x77, 0x74, - 0x12, 0x9e, 0x01, 0x0a, 0x10, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, 0x69, - 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, - 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x7a, 0x65, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x2f, 0x12, 0x2d, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x63, 0x6f, + 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x82, 0x01, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x28, 0x12, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, - 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x7a, - 0x65, 0x12, 0x92, 0x01, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, - 0x6d, 0x69, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x12, 0x27, 0x2f, - 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x63, - 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x82, 0x01, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2e, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x28, 0x12, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x67, 0x69, 0x74, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x96, 0x01, 0x0a, 0x0f, 0x4c, + 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x12, 0x27, + 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, + 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x76, 0x31, 0x2f, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x62, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x65, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, + 0x3a, 0x01, 0x2a, 0x22, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, - 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x96, 0x01, 0x0a, 0x0f, - 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x12, - 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, - 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x47, - 0x69, 0x74, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x76, 0x31, 0x2f, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x62, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x65, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x09, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x12, 0x21, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x2b, 0x3a, 0x01, 0x2a, 0x22, 0x26, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0xa8, 0x01, 0x0a, 0x10, + 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, + 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, + 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, + 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, 0x3a, 0x01, 0x2a, + 0x22, 0x34, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, + 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, + 0x74, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x7b, 0x63, 0x6f, 0x6d, 0x6d, 0x69, + 0x74, 0x5f, 0x73, 0x68, 0x61, 0x7d, 0x12, 0x99, 0x01, 0x0a, 0x10, 0x47, 0x69, 0x74, 0x4d, 0x65, + 0x72, 0x67, 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x28, 0x2e, 0x72, 0x69, + 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, + 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, + 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x31, + 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x6d, 0x65, 0x72, + 0x67, 0x65, 0x12, 0xa0, 0x01, 0x0a, 0x0f, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, + 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x34, 0x3a, 0x01, 0x2a, 0x22, 0x2f, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, - 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0xa8, 0x01, 0x0a, - 0x10, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x12, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, - 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, - 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x47, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x39, 0x3a, 0x01, - 0x2a, 0x22, 0x34, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, - 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, - 0x69, 0x74, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2f, 0x7b, 0x63, 0x6f, 0x6d, 0x6d, - 0x69, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x7d, 0x12, 0x99, 0x01, 0x0a, 0x10, 0x47, 0x69, 0x74, 0x4d, - 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x28, 0x2e, 0x72, - 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x69, 0x74, 0x4d, 0x65, 0x72, 0x67, 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x4d, 0x65, 0x72, 0x67, - 0x65, 0x54, 0x6f, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x3a, 0x01, 0x2a, 0x22, 0x25, 0x2f, 0x76, - 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, - 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x6d, 0x65, - 0x72, 0x67, 0x65, 0x12, 0xa0, 0x01, 0x0a, 0x0f, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, - 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x27, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, - 0x74, 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x28, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x42, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x34, 0x3a, 0x01, 0x2a, 0x22, 0x2f, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, - 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x2f, - 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x12, 0x7d, 0x0a, 0x07, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, - 0x6c, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, - 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, - 0x2f, 0x70, 0x75, 0x6c, 0x6c, 0x12, 0x7d, 0x0a, 0x07, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, + 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x2f, 0x73, + 0x77, 0x69, 0x74, 0x63, 0x68, 0x12, 0x7d, 0x0a, 0x07, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x12, 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, - 0x70, 0x75, 0x73, 0x68, 0x42, 0xbb, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x69, 0x6c, - 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x41, 0x70, - 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x69, - 0x6c, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72, 0x69, 0x6c, - 0x6c, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x52, 0x58, 0xaa, 0x02, 0x0f, 0x52, - 0x69, 0x6c, 0x6c, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, - 0x0f, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, - 0xe2, 0x02, 0x1b, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, - 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x11, 0x52, 0x69, 0x6c, 0x6c, 0x3a, 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3a, - 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x75, 0x6c, 0x6c, 0x12, 0x7d, 0x0a, 0x07, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x12, + 0x1f, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, + 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x20, 0x2e, 0x72, 0x69, 0x6c, 0x6c, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x69, 0x74, 0x50, 0x75, 0x73, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x3a, 0x01, 0x2a, 0x22, 0x24, 0x2f, + 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x67, 0x69, 0x74, 0x2f, 0x70, + 0x75, 0x73, 0x68, 0x42, 0xbb, 0x01, 0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x72, 0x69, 0x6c, 0x6c, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x08, 0x41, 0x70, 0x69, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x69, 0x6c, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x72, 0x69, 0x6c, + 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x72, 0x69, 0x6c, 0x6c, + 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x74, + 0x69, 0x6d, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x52, 0x52, 0x58, 0xaa, 0x02, 0x0f, 0x52, 0x69, + 0x6c, 0x6c, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0f, + 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0xe2, + 0x02, 0x1b, 0x52, 0x69, 0x6c, 0x6c, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, + 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, + 0x52, 0x69, 0x6c, 0x6c, 0x3a, 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3a, 0x56, + 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -10123,7 +10639,7 @@ func file_rill_runtime_v1_api_proto_rawDescGZIP() []byte { } var file_rill_runtime_v1_api_proto_enumTypes = make([]protoimpl.EnumInfo, 4) -var file_rill_runtime_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 137) +var file_rill_runtime_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 145) var file_rill_runtime_v1_api_proto_goTypes = []any{ (FileEvent)(0), // 0: rill.runtime.v1.FileEvent (LogLevel)(0), // 1: rill.runtime.v1.LogLevel @@ -10182,313 +10698,330 @@ var file_rill_runtime_v1_api_proto_goTypes = []any{ (*GenerateRendererResponse)(nil), // 54: rill.runtime.v1.GenerateRendererResponse (*GenerateTemplateRequest)(nil), // 55: rill.runtime.v1.GenerateTemplateRequest (*GenerateTemplateResponse)(nil), // 56: rill.runtime.v1.GenerateTemplateResponse - (*QueryResolverRequest)(nil), // 57: rill.runtime.v1.QueryResolverRequest - (*QueryResolverResponse)(nil), // 58: rill.runtime.v1.QueryResolverResponse - (*Log)(nil), // 59: rill.runtime.v1.Log - (*ModelPartition)(nil), // 60: rill.runtime.v1.ModelPartition - (*GetLogsRequest)(nil), // 61: rill.runtime.v1.GetLogsRequest - (*GetLogsResponse)(nil), // 62: rill.runtime.v1.GetLogsResponse - (*WatchLogsRequest)(nil), // 63: rill.runtime.v1.WatchLogsRequest - (*WatchLogsResponse)(nil), // 64: rill.runtime.v1.WatchLogsResponse - (*ListResourcesRequest)(nil), // 65: rill.runtime.v1.ListResourcesRequest - (*ListResourcesResponse)(nil), // 66: rill.runtime.v1.ListResourcesResponse - (*WatchResourcesRequest)(nil), // 67: rill.runtime.v1.WatchResourcesRequest - (*WatchResourcesResponse)(nil), // 68: rill.runtime.v1.WatchResourcesResponse - (*GetResourceRequest)(nil), // 69: rill.runtime.v1.GetResourceRequest - (*GetResourceResponse)(nil), // 70: rill.runtime.v1.GetResourceResponse - (*GetExploreRequest)(nil), // 71: rill.runtime.v1.GetExploreRequest - (*GetExploreResponse)(nil), // 72: rill.runtime.v1.GetExploreResponse - (*GetModelPartitionsRequest)(nil), // 73: rill.runtime.v1.GetModelPartitionsRequest - (*GetModelPartitionsResponse)(nil), // 74: rill.runtime.v1.GetModelPartitionsResponse - (*CreateTriggerRequest)(nil), // 75: rill.runtime.v1.CreateTriggerRequest - (*CreateTriggerResponse)(nil), // 76: rill.runtime.v1.CreateTriggerResponse - (*ConnectorDriver)(nil), // 77: rill.runtime.v1.ConnectorDriver - (*AnalyzedConnector)(nil), // 78: rill.runtime.v1.AnalyzedConnector - (*ListConnectorDriversRequest)(nil), // 79: rill.runtime.v1.ListConnectorDriversRequest - (*ListConnectorDriversResponse)(nil), // 80: rill.runtime.v1.ListConnectorDriversResponse - (*AnalyzeConnectorsRequest)(nil), // 81: rill.runtime.v1.AnalyzeConnectorsRequest - (*AnalyzeConnectorsResponse)(nil), // 82: rill.runtime.v1.AnalyzeConnectorsResponse - (*ListNotifierConnectorsRequest)(nil), // 83: rill.runtime.v1.ListNotifierConnectorsRequest - (*ListNotifierConnectorsResponse)(nil), // 84: rill.runtime.v1.ListNotifierConnectorsResponse - (*Conversation)(nil), // 85: rill.runtime.v1.Conversation - (*Message)(nil), // 86: rill.runtime.v1.Message - (*AnalystAgentContext)(nil), // 87: rill.runtime.v1.AnalystAgentContext - (*DeveloperAgentContext)(nil), // 88: rill.runtime.v1.DeveloperAgentContext - (*FeedbackAgentContext)(nil), // 89: rill.runtime.v1.FeedbackAgentContext - (*ListConversationsRequest)(nil), // 90: rill.runtime.v1.ListConversationsRequest - (*ListConversationsResponse)(nil), // 91: rill.runtime.v1.ListConversationsResponse - (*GetConversationRequest)(nil), // 92: rill.runtime.v1.GetConversationRequest - (*GetConversationResponse)(nil), // 93: rill.runtime.v1.GetConversationResponse - (*ShareConversationRequest)(nil), // 94: rill.runtime.v1.ShareConversationRequest - (*ShareConversationResponse)(nil), // 95: rill.runtime.v1.ShareConversationResponse - (*ForkConversationRequest)(nil), // 96: rill.runtime.v1.ForkConversationRequest - (*ForkConversationResponse)(nil), // 97: rill.runtime.v1.ForkConversationResponse - (*ListToolsRequest)(nil), // 98: rill.runtime.v1.ListToolsRequest - (*ListToolsResponse)(nil), // 99: rill.runtime.v1.ListToolsResponse - (*CompleteRequest)(nil), // 100: rill.runtime.v1.CompleteRequest - (*CompleteResponse)(nil), // 101: rill.runtime.v1.CompleteResponse - (*CompleteStreamingRequest)(nil), // 102: rill.runtime.v1.CompleteStreamingRequest - (*CompleteStreamingResponse)(nil), // 103: rill.runtime.v1.CompleteStreamingResponse - (*IssueDevJWTRequest)(nil), // 104: rill.runtime.v1.IssueDevJWTRequest - (*IssueDevJWTResponse)(nil), // 105: rill.runtime.v1.IssueDevJWTResponse - (*AnalyzeVariablesRequest)(nil), // 106: rill.runtime.v1.AnalyzeVariablesRequest - (*AnalyzeVariablesResponse)(nil), // 107: rill.runtime.v1.AnalyzeVariablesResponse - (*AnalyzedVariable)(nil), // 108: rill.runtime.v1.AnalyzedVariable - (*ListGitCommitsRequest)(nil), // 109: rill.runtime.v1.ListGitCommitsRequest - (*ListGitCommitsResponse)(nil), // 110: rill.runtime.v1.ListGitCommitsResponse - (*GitCommit)(nil), // 111: rill.runtime.v1.GitCommit - (*GitStatusRequest)(nil), // 112: rill.runtime.v1.GitStatusRequest - (*GitStatusResponse)(nil), // 113: rill.runtime.v1.GitStatusResponse - (*ListGitBranchesRequest)(nil), // 114: rill.runtime.v1.ListGitBranchesRequest - (*ListGitBranchesResponse)(nil), // 115: rill.runtime.v1.ListGitBranchesResponse - (*GitBranch)(nil), // 116: rill.runtime.v1.GitBranch - (*GitCommitRequest)(nil), // 117: rill.runtime.v1.GitCommitRequest - (*GitCommitResponse)(nil), // 118: rill.runtime.v1.GitCommitResponse - (*RestoreGitCommitRequest)(nil), // 119: rill.runtime.v1.RestoreGitCommitRequest - (*RestoreGitCommitResponse)(nil), // 120: rill.runtime.v1.RestoreGitCommitResponse - (*GitMergeToBranchRequest)(nil), // 121: rill.runtime.v1.GitMergeToBranchRequest - (*GitMergeToBranchResponse)(nil), // 122: rill.runtime.v1.GitMergeToBranchResponse - (*GitSwitchBranchRequest)(nil), // 123: rill.runtime.v1.GitSwitchBranchRequest - (*GitSwitchBranchResponse)(nil), // 124: rill.runtime.v1.GitSwitchBranchResponse - (*GitPullRequest)(nil), // 125: rill.runtime.v1.GitPullRequest - (*GitPullResponse)(nil), // 126: rill.runtime.v1.GitPullResponse - (*GitPushRequest)(nil), // 127: rill.runtime.v1.GitPushRequest - (*GitPushResponse)(nil), // 128: rill.runtime.v1.GitPushResponse - nil, // 129: rill.runtime.v1.HealthResponse.InstancesHealthEntry - nil, // 130: rill.runtime.v1.InstanceHealth.MetricsViewErrorsEntry - nil, // 131: rill.runtime.v1.Instance.VariablesEntry - nil, // 132: rill.runtime.v1.Instance.ProjectVariablesEntry - nil, // 133: rill.runtime.v1.Instance.FeatureFlagsEntry - nil, // 134: rill.runtime.v1.Instance.AnnotationsEntry - nil, // 135: rill.runtime.v1.CreateInstanceRequest.VariablesEntry - nil, // 136: rill.runtime.v1.CreateInstanceRequest.AnnotationsEntry - nil, // 137: rill.runtime.v1.GenerateTemplateResponse.EnvVarsEntry - (*ConnectorDriver_Property)(nil), // 138: rill.runtime.v1.ConnectorDriver.Property - nil, // 139: rill.runtime.v1.AnalyzedConnector.EnvConfigEntry - nil, // 140: rill.runtime.v1.AnalystAgentContext.WherePerMetricsViewEntry - (*timestamppb.Timestamp)(nil), // 141: google.protobuf.Timestamp - (*structpb.Struct)(nil), // 142: google.protobuf.Struct - (*StructType)(nil), // 143: rill.runtime.v1.StructType - (*Resource)(nil), // 144: rill.runtime.v1.Resource - (*ResourceName)(nil), // 145: rill.runtime.v1.ResourceName - (*RefreshModelTrigger)(nil), // 146: rill.runtime.v1.RefreshModelTrigger - (*v1.ContentBlock)(nil), // 147: rill.ai.v1.ContentBlock - (*Expression)(nil), // 148: rill.runtime.v1.Expression - (*v1.Tool)(nil), // 149: rill.ai.v1.Tool + (*Template)(nil), // 57: rill.runtime.v1.Template + (*TemplateFile)(nil), // 58: rill.runtime.v1.TemplateFile + (*ListTemplatesRequest)(nil), // 59: rill.runtime.v1.ListTemplatesRequest + (*ListTemplatesResponse)(nil), // 60: rill.runtime.v1.ListTemplatesResponse + (*GenerateFileRequest)(nil), // 61: rill.runtime.v1.GenerateFileRequest + (*GenerateFileResponse)(nil), // 62: rill.runtime.v1.GenerateFileResponse + (*GeneratedFile)(nil), // 63: rill.runtime.v1.GeneratedFile + (*QueryResolverRequest)(nil), // 64: rill.runtime.v1.QueryResolverRequest + (*QueryResolverResponse)(nil), // 65: rill.runtime.v1.QueryResolverResponse + (*Log)(nil), // 66: rill.runtime.v1.Log + (*ModelPartition)(nil), // 67: rill.runtime.v1.ModelPartition + (*GetLogsRequest)(nil), // 68: rill.runtime.v1.GetLogsRequest + (*GetLogsResponse)(nil), // 69: rill.runtime.v1.GetLogsResponse + (*WatchLogsRequest)(nil), // 70: rill.runtime.v1.WatchLogsRequest + (*WatchLogsResponse)(nil), // 71: rill.runtime.v1.WatchLogsResponse + (*ListResourcesRequest)(nil), // 72: rill.runtime.v1.ListResourcesRequest + (*ListResourcesResponse)(nil), // 73: rill.runtime.v1.ListResourcesResponse + (*WatchResourcesRequest)(nil), // 74: rill.runtime.v1.WatchResourcesRequest + (*WatchResourcesResponse)(nil), // 75: rill.runtime.v1.WatchResourcesResponse + (*GetResourceRequest)(nil), // 76: rill.runtime.v1.GetResourceRequest + (*GetResourceResponse)(nil), // 77: rill.runtime.v1.GetResourceResponse + (*GetExploreRequest)(nil), // 78: rill.runtime.v1.GetExploreRequest + (*GetExploreResponse)(nil), // 79: rill.runtime.v1.GetExploreResponse + (*GetModelPartitionsRequest)(nil), // 80: rill.runtime.v1.GetModelPartitionsRequest + (*GetModelPartitionsResponse)(nil), // 81: rill.runtime.v1.GetModelPartitionsResponse + (*CreateTriggerRequest)(nil), // 82: rill.runtime.v1.CreateTriggerRequest + (*CreateTriggerResponse)(nil), // 83: rill.runtime.v1.CreateTriggerResponse + (*ConnectorDriver)(nil), // 84: rill.runtime.v1.ConnectorDriver + (*AnalyzedConnector)(nil), // 85: rill.runtime.v1.AnalyzedConnector + (*ListConnectorDriversRequest)(nil), // 86: rill.runtime.v1.ListConnectorDriversRequest + (*ListConnectorDriversResponse)(nil), // 87: rill.runtime.v1.ListConnectorDriversResponse + (*AnalyzeConnectorsRequest)(nil), // 88: rill.runtime.v1.AnalyzeConnectorsRequest + (*AnalyzeConnectorsResponse)(nil), // 89: rill.runtime.v1.AnalyzeConnectorsResponse + (*ListNotifierConnectorsRequest)(nil), // 90: rill.runtime.v1.ListNotifierConnectorsRequest + (*ListNotifierConnectorsResponse)(nil), // 91: rill.runtime.v1.ListNotifierConnectorsResponse + (*Conversation)(nil), // 92: rill.runtime.v1.Conversation + (*Message)(nil), // 93: rill.runtime.v1.Message + (*AnalystAgentContext)(nil), // 94: rill.runtime.v1.AnalystAgentContext + (*DeveloperAgentContext)(nil), // 95: rill.runtime.v1.DeveloperAgentContext + (*FeedbackAgentContext)(nil), // 96: rill.runtime.v1.FeedbackAgentContext + (*ListConversationsRequest)(nil), // 97: rill.runtime.v1.ListConversationsRequest + (*ListConversationsResponse)(nil), // 98: rill.runtime.v1.ListConversationsResponse + (*GetConversationRequest)(nil), // 99: rill.runtime.v1.GetConversationRequest + (*GetConversationResponse)(nil), // 100: rill.runtime.v1.GetConversationResponse + (*ShareConversationRequest)(nil), // 101: rill.runtime.v1.ShareConversationRequest + (*ShareConversationResponse)(nil), // 102: rill.runtime.v1.ShareConversationResponse + (*ForkConversationRequest)(nil), // 103: rill.runtime.v1.ForkConversationRequest + (*ForkConversationResponse)(nil), // 104: rill.runtime.v1.ForkConversationResponse + (*ListToolsRequest)(nil), // 105: rill.runtime.v1.ListToolsRequest + (*ListToolsResponse)(nil), // 106: rill.runtime.v1.ListToolsResponse + (*CompleteRequest)(nil), // 107: rill.runtime.v1.CompleteRequest + (*CompleteResponse)(nil), // 108: rill.runtime.v1.CompleteResponse + (*CompleteStreamingRequest)(nil), // 109: rill.runtime.v1.CompleteStreamingRequest + (*CompleteStreamingResponse)(nil), // 110: rill.runtime.v1.CompleteStreamingResponse + (*IssueDevJWTRequest)(nil), // 111: rill.runtime.v1.IssueDevJWTRequest + (*IssueDevJWTResponse)(nil), // 112: rill.runtime.v1.IssueDevJWTResponse + (*AnalyzeVariablesRequest)(nil), // 113: rill.runtime.v1.AnalyzeVariablesRequest + (*AnalyzeVariablesResponse)(nil), // 114: rill.runtime.v1.AnalyzeVariablesResponse + (*AnalyzedVariable)(nil), // 115: rill.runtime.v1.AnalyzedVariable + (*ListGitCommitsRequest)(nil), // 116: rill.runtime.v1.ListGitCommitsRequest + (*ListGitCommitsResponse)(nil), // 117: rill.runtime.v1.ListGitCommitsResponse + (*GitCommit)(nil), // 118: rill.runtime.v1.GitCommit + (*GitStatusRequest)(nil), // 119: rill.runtime.v1.GitStatusRequest + (*GitStatusResponse)(nil), // 120: rill.runtime.v1.GitStatusResponse + (*ListGitBranchesRequest)(nil), // 121: rill.runtime.v1.ListGitBranchesRequest + (*ListGitBranchesResponse)(nil), // 122: rill.runtime.v1.ListGitBranchesResponse + (*GitBranch)(nil), // 123: rill.runtime.v1.GitBranch + (*GitCommitRequest)(nil), // 124: rill.runtime.v1.GitCommitRequest + (*GitCommitResponse)(nil), // 125: rill.runtime.v1.GitCommitResponse + (*RestoreGitCommitRequest)(nil), // 126: rill.runtime.v1.RestoreGitCommitRequest + (*RestoreGitCommitResponse)(nil), // 127: rill.runtime.v1.RestoreGitCommitResponse + (*GitMergeToBranchRequest)(nil), // 128: rill.runtime.v1.GitMergeToBranchRequest + (*GitMergeToBranchResponse)(nil), // 129: rill.runtime.v1.GitMergeToBranchResponse + (*GitSwitchBranchRequest)(nil), // 130: rill.runtime.v1.GitSwitchBranchRequest + (*GitSwitchBranchResponse)(nil), // 131: rill.runtime.v1.GitSwitchBranchResponse + (*GitPullRequest)(nil), // 132: rill.runtime.v1.GitPullRequest + (*GitPullResponse)(nil), // 133: rill.runtime.v1.GitPullResponse + (*GitPushRequest)(nil), // 134: rill.runtime.v1.GitPushRequest + (*GitPushResponse)(nil), // 135: rill.runtime.v1.GitPushResponse + nil, // 136: rill.runtime.v1.HealthResponse.InstancesHealthEntry + nil, // 137: rill.runtime.v1.InstanceHealth.MetricsViewErrorsEntry + nil, // 138: rill.runtime.v1.Instance.VariablesEntry + nil, // 139: rill.runtime.v1.Instance.ProjectVariablesEntry + nil, // 140: rill.runtime.v1.Instance.FeatureFlagsEntry + nil, // 141: rill.runtime.v1.Instance.AnnotationsEntry + nil, // 142: rill.runtime.v1.CreateInstanceRequest.VariablesEntry + nil, // 143: rill.runtime.v1.CreateInstanceRequest.AnnotationsEntry + nil, // 144: rill.runtime.v1.GenerateTemplateResponse.EnvVarsEntry + nil, // 145: rill.runtime.v1.GenerateFileResponse.EnvVarsEntry + (*ConnectorDriver_Property)(nil), // 146: rill.runtime.v1.ConnectorDriver.Property + nil, // 147: rill.runtime.v1.AnalyzedConnector.EnvConfigEntry + nil, // 148: rill.runtime.v1.AnalystAgentContext.WherePerMetricsViewEntry + (*timestamppb.Timestamp)(nil), // 149: google.protobuf.Timestamp + (*structpb.Struct)(nil), // 150: google.protobuf.Struct + (*StructType)(nil), // 151: rill.runtime.v1.StructType + (*Resource)(nil), // 152: rill.runtime.v1.Resource + (*ResourceName)(nil), // 153: rill.runtime.v1.ResourceName + (*RefreshModelTrigger)(nil), // 154: rill.runtime.v1.RefreshModelTrigger + (*v1.ContentBlock)(nil), // 155: rill.ai.v1.ContentBlock + (*Expression)(nil), // 156: rill.runtime.v1.Expression + (*v1.Tool)(nil), // 157: rill.ai.v1.Tool } var file_rill_runtime_v1_api_proto_depIdxs = []int32{ - 141, // 0: rill.runtime.v1.PingResponse.time:type_name -> google.protobuf.Timestamp - 129, // 1: rill.runtime.v1.HealthResponse.instances_health:type_name -> rill.runtime.v1.HealthResponse.InstancesHealthEntry + 149, // 0: rill.runtime.v1.PingResponse.time:type_name -> google.protobuf.Timestamp + 136, // 1: rill.runtime.v1.HealthResponse.instances_health:type_name -> rill.runtime.v1.HealthResponse.InstancesHealthEntry 10, // 2: rill.runtime.v1.InstanceHealthResponse.instance_health:type_name -> rill.runtime.v1.InstanceHealth - 130, // 3: rill.runtime.v1.InstanceHealth.metrics_view_errors:type_name -> rill.runtime.v1.InstanceHealth.MetricsViewErrorsEntry - 141, // 4: rill.runtime.v1.Instance.created_on:type_name -> google.protobuf.Timestamp - 141, // 5: rill.runtime.v1.Instance.updated_on:type_name -> google.protobuf.Timestamp + 137, // 3: rill.runtime.v1.InstanceHealth.metrics_view_errors:type_name -> rill.runtime.v1.InstanceHealth.MetricsViewErrorsEntry + 149, // 4: rill.runtime.v1.Instance.created_on:type_name -> google.protobuf.Timestamp + 149, // 5: rill.runtime.v1.Instance.updated_on:type_name -> google.protobuf.Timestamp 12, // 6: rill.runtime.v1.Instance.connectors:type_name -> rill.runtime.v1.Connector 12, // 7: rill.runtime.v1.Instance.project_connectors:type_name -> rill.runtime.v1.Connector - 131, // 8: rill.runtime.v1.Instance.variables:type_name -> rill.runtime.v1.Instance.VariablesEntry - 132, // 9: rill.runtime.v1.Instance.project_variables:type_name -> rill.runtime.v1.Instance.ProjectVariablesEntry - 133, // 10: rill.runtime.v1.Instance.feature_flags:type_name -> rill.runtime.v1.Instance.FeatureFlagsEntry - 134, // 11: rill.runtime.v1.Instance.annotations:type_name -> rill.runtime.v1.Instance.AnnotationsEntry - 142, // 12: rill.runtime.v1.Connector.config:type_name -> google.protobuf.Struct - 142, // 13: rill.runtime.v1.Connector.provision_args:type_name -> google.protobuf.Struct + 138, // 8: rill.runtime.v1.Instance.variables:type_name -> rill.runtime.v1.Instance.VariablesEntry + 139, // 9: rill.runtime.v1.Instance.project_variables:type_name -> rill.runtime.v1.Instance.ProjectVariablesEntry + 140, // 10: rill.runtime.v1.Instance.feature_flags:type_name -> rill.runtime.v1.Instance.FeatureFlagsEntry + 141, // 11: rill.runtime.v1.Instance.annotations:type_name -> rill.runtime.v1.Instance.AnnotationsEntry + 150, // 12: rill.runtime.v1.Connector.config:type_name -> google.protobuf.Struct + 150, // 13: rill.runtime.v1.Connector.provision_args:type_name -> google.protobuf.Struct 11, // 14: rill.runtime.v1.ListInstancesResponse.instances:type_name -> rill.runtime.v1.Instance 11, // 15: rill.runtime.v1.GetInstanceResponse.instance:type_name -> rill.runtime.v1.Instance 12, // 16: rill.runtime.v1.CreateInstanceRequest.connectors:type_name -> rill.runtime.v1.Connector - 135, // 17: rill.runtime.v1.CreateInstanceRequest.variables:type_name -> rill.runtime.v1.CreateInstanceRequest.VariablesEntry - 136, // 18: rill.runtime.v1.CreateInstanceRequest.annotations:type_name -> rill.runtime.v1.CreateInstanceRequest.AnnotationsEntry + 142, // 17: rill.runtime.v1.CreateInstanceRequest.variables:type_name -> rill.runtime.v1.CreateInstanceRequest.VariablesEntry + 143, // 18: rill.runtime.v1.CreateInstanceRequest.annotations:type_name -> rill.runtime.v1.CreateInstanceRequest.AnnotationsEntry 11, // 19: rill.runtime.v1.CreateInstanceResponse.instance:type_name -> rill.runtime.v1.Instance 12, // 20: rill.runtime.v1.EditInstanceRequest.connectors:type_name -> rill.runtime.v1.Connector 11, // 21: rill.runtime.v1.EditInstanceResponse.instance:type_name -> rill.runtime.v1.Instance 27, // 22: rill.runtime.v1.ListFilesResponse.files:type_name -> rill.runtime.v1.DirEntry 0, // 23: rill.runtime.v1.WatchFilesResponse.event:type_name -> rill.runtime.v1.FileEvent - 141, // 24: rill.runtime.v1.GetFileResponse.updated_on:type_name -> google.protobuf.Timestamp + 149, // 24: rill.runtime.v1.GetFileResponse.updated_on:type_name -> google.protobuf.Timestamp 40, // 25: rill.runtime.v1.ListExamplesResponse.examples:type_name -> rill.runtime.v1.Example - 142, // 26: rill.runtime.v1.GenerateResolverResponse.resolver_properties:type_name -> google.protobuf.Struct - 142, // 27: rill.runtime.v1.GenerateRendererRequest.resolver_properties:type_name -> google.protobuf.Struct - 142, // 28: rill.runtime.v1.GenerateRendererResponse.renderer_properties:type_name -> google.protobuf.Struct - 142, // 29: rill.runtime.v1.GenerateTemplateRequest.properties:type_name -> google.protobuf.Struct - 137, // 30: rill.runtime.v1.GenerateTemplateResponse.env_vars:type_name -> rill.runtime.v1.GenerateTemplateResponse.EnvVarsEntry - 142, // 31: rill.runtime.v1.QueryResolverRequest.resolver_properties:type_name -> google.protobuf.Struct - 142, // 32: rill.runtime.v1.QueryResolverRequest.resolver_args:type_name -> google.protobuf.Struct - 142, // 33: rill.runtime.v1.QueryResolverResponse.meta:type_name -> google.protobuf.Struct - 143, // 34: rill.runtime.v1.QueryResolverResponse.schema:type_name -> rill.runtime.v1.StructType - 142, // 35: rill.runtime.v1.QueryResolverResponse.data:type_name -> google.protobuf.Struct - 1, // 36: rill.runtime.v1.Log.level:type_name -> rill.runtime.v1.LogLevel - 141, // 37: rill.runtime.v1.Log.time:type_name -> google.protobuf.Timestamp - 142, // 38: rill.runtime.v1.ModelPartition.data:type_name -> google.protobuf.Struct - 141, // 39: rill.runtime.v1.ModelPartition.watermark:type_name -> google.protobuf.Timestamp - 141, // 40: rill.runtime.v1.ModelPartition.executed_on:type_name -> google.protobuf.Timestamp - 1, // 41: rill.runtime.v1.GetLogsRequest.level:type_name -> rill.runtime.v1.LogLevel - 59, // 42: rill.runtime.v1.GetLogsResponse.logs:type_name -> rill.runtime.v1.Log - 1, // 43: rill.runtime.v1.WatchLogsRequest.level:type_name -> rill.runtime.v1.LogLevel - 59, // 44: rill.runtime.v1.WatchLogsResponse.log:type_name -> rill.runtime.v1.Log - 144, // 45: rill.runtime.v1.ListResourcesResponse.resources:type_name -> rill.runtime.v1.Resource - 2, // 46: rill.runtime.v1.WatchResourcesResponse.event:type_name -> rill.runtime.v1.ResourceEvent - 145, // 47: rill.runtime.v1.WatchResourcesResponse.name:type_name -> rill.runtime.v1.ResourceName - 144, // 48: rill.runtime.v1.WatchResourcesResponse.resource:type_name -> rill.runtime.v1.Resource - 145, // 49: rill.runtime.v1.GetResourceRequest.name:type_name -> rill.runtime.v1.ResourceName - 144, // 50: rill.runtime.v1.GetResourceResponse.resource:type_name -> rill.runtime.v1.Resource - 144, // 51: rill.runtime.v1.GetExploreResponse.explore:type_name -> rill.runtime.v1.Resource - 144, // 52: rill.runtime.v1.GetExploreResponse.metrics_view:type_name -> rill.runtime.v1.Resource - 60, // 53: rill.runtime.v1.GetModelPartitionsResponse.partitions:type_name -> rill.runtime.v1.ModelPartition - 145, // 54: rill.runtime.v1.CreateTriggerRequest.resources:type_name -> rill.runtime.v1.ResourceName - 146, // 55: rill.runtime.v1.CreateTriggerRequest.models:type_name -> rill.runtime.v1.RefreshModelTrigger - 138, // 56: rill.runtime.v1.ConnectorDriver.config_properties:type_name -> rill.runtime.v1.ConnectorDriver.Property - 138, // 57: rill.runtime.v1.ConnectorDriver.source_properties:type_name -> rill.runtime.v1.ConnectorDriver.Property - 77, // 58: rill.runtime.v1.AnalyzedConnector.driver:type_name -> rill.runtime.v1.ConnectorDriver - 142, // 59: rill.runtime.v1.AnalyzedConnector.config:type_name -> google.protobuf.Struct - 142, // 60: rill.runtime.v1.AnalyzedConnector.preset_config:type_name -> google.protobuf.Struct - 142, // 61: rill.runtime.v1.AnalyzedConnector.project_config:type_name -> google.protobuf.Struct - 139, // 62: rill.runtime.v1.AnalyzedConnector.env_config:type_name -> rill.runtime.v1.AnalyzedConnector.EnvConfigEntry - 142, // 63: rill.runtime.v1.AnalyzedConnector.provision_args:type_name -> google.protobuf.Struct - 145, // 64: rill.runtime.v1.AnalyzedConnector.used_by:type_name -> rill.runtime.v1.ResourceName - 77, // 65: rill.runtime.v1.ListConnectorDriversResponse.connectors:type_name -> rill.runtime.v1.ConnectorDriver - 78, // 66: rill.runtime.v1.AnalyzeConnectorsResponse.connectors:type_name -> rill.runtime.v1.AnalyzedConnector - 12, // 67: rill.runtime.v1.ListNotifierConnectorsResponse.connectors:type_name -> rill.runtime.v1.Connector - 141, // 68: rill.runtime.v1.Conversation.created_on:type_name -> google.protobuf.Timestamp - 141, // 69: rill.runtime.v1.Conversation.updated_on:type_name -> google.protobuf.Timestamp - 86, // 70: rill.runtime.v1.Conversation.messages:type_name -> rill.runtime.v1.Message - 141, // 71: rill.runtime.v1.Message.created_on:type_name -> google.protobuf.Timestamp - 141, // 72: rill.runtime.v1.Message.updated_on:type_name -> google.protobuf.Timestamp - 147, // 73: rill.runtime.v1.Message.content:type_name -> rill.ai.v1.ContentBlock - 148, // 74: rill.runtime.v1.AnalystAgentContext.where:type_name -> rill.runtime.v1.Expression - 140, // 75: rill.runtime.v1.AnalystAgentContext.where_per_metrics_view:type_name -> rill.runtime.v1.AnalystAgentContext.WherePerMetricsViewEntry - 141, // 76: rill.runtime.v1.AnalystAgentContext.time_start:type_name -> google.protobuf.Timestamp - 141, // 77: rill.runtime.v1.AnalystAgentContext.time_end:type_name -> google.protobuf.Timestamp - 85, // 78: rill.runtime.v1.ListConversationsResponse.conversations:type_name -> rill.runtime.v1.Conversation - 85, // 79: rill.runtime.v1.GetConversationResponse.conversation:type_name -> rill.runtime.v1.Conversation - 86, // 80: rill.runtime.v1.GetConversationResponse.messages:type_name -> rill.runtime.v1.Message - 149, // 81: rill.runtime.v1.ListToolsResponse.tools:type_name -> rill.ai.v1.Tool - 87, // 82: rill.runtime.v1.CompleteRequest.analyst_agent_context:type_name -> rill.runtime.v1.AnalystAgentContext - 88, // 83: rill.runtime.v1.CompleteRequest.developer_agent_context:type_name -> rill.runtime.v1.DeveloperAgentContext - 89, // 84: rill.runtime.v1.CompleteRequest.feedback_agent_context:type_name -> rill.runtime.v1.FeedbackAgentContext - 86, // 85: rill.runtime.v1.CompleteResponse.messages:type_name -> rill.runtime.v1.Message - 87, // 86: rill.runtime.v1.CompleteStreamingRequest.analyst_agent_context:type_name -> rill.runtime.v1.AnalystAgentContext - 88, // 87: rill.runtime.v1.CompleteStreamingRequest.developer_agent_context:type_name -> rill.runtime.v1.DeveloperAgentContext - 89, // 88: rill.runtime.v1.CompleteStreamingRequest.feedback_agent_context:type_name -> rill.runtime.v1.FeedbackAgentContext - 86, // 89: rill.runtime.v1.CompleteStreamingResponse.message:type_name -> rill.runtime.v1.Message - 142, // 90: rill.runtime.v1.IssueDevJWTRequest.attributes:type_name -> google.protobuf.Struct - 108, // 91: rill.runtime.v1.AnalyzeVariablesResponse.variables:type_name -> rill.runtime.v1.AnalyzedVariable - 145, // 92: rill.runtime.v1.AnalyzedVariable.used_by:type_name -> rill.runtime.v1.ResourceName - 111, // 93: rill.runtime.v1.ListGitCommitsResponse.commits:type_name -> rill.runtime.v1.GitCommit - 141, // 94: rill.runtime.v1.GitCommit.committed_on:type_name -> google.protobuf.Timestamp - 116, // 95: rill.runtime.v1.ListGitBranchesResponse.branches:type_name -> rill.runtime.v1.GitBranch - 10, // 96: rill.runtime.v1.HealthResponse.InstancesHealthEntry.value:type_name -> rill.runtime.v1.InstanceHealth - 3, // 97: rill.runtime.v1.ConnectorDriver.Property.type:type_name -> rill.runtime.v1.ConnectorDriver.Property.Type - 148, // 98: rill.runtime.v1.AnalystAgentContext.WherePerMetricsViewEntry.value:type_name -> rill.runtime.v1.Expression - 4, // 99: rill.runtime.v1.RuntimeService.Ping:input_type -> rill.runtime.v1.PingRequest - 6, // 100: rill.runtime.v1.RuntimeService.Health:input_type -> rill.runtime.v1.HealthRequest - 8, // 101: rill.runtime.v1.RuntimeService.InstanceHealth:input_type -> rill.runtime.v1.InstanceHealthRequest - 13, // 102: rill.runtime.v1.RuntimeService.ListInstances:input_type -> rill.runtime.v1.ListInstancesRequest - 15, // 103: rill.runtime.v1.RuntimeService.GetInstance:input_type -> rill.runtime.v1.GetInstanceRequest - 17, // 104: rill.runtime.v1.RuntimeService.CreateInstance:input_type -> rill.runtime.v1.CreateInstanceRequest - 21, // 105: rill.runtime.v1.RuntimeService.EditInstance:input_type -> rill.runtime.v1.EditInstanceRequest - 19, // 106: rill.runtime.v1.RuntimeService.DeleteInstance:input_type -> rill.runtime.v1.DeleteInstanceRequest - 23, // 107: rill.runtime.v1.RuntimeService.ReloadConfig:input_type -> rill.runtime.v1.ReloadConfigRequest - 25, // 108: rill.runtime.v1.RuntimeService.ListFiles:input_type -> rill.runtime.v1.ListFilesRequest - 28, // 109: rill.runtime.v1.RuntimeService.WatchFiles:input_type -> rill.runtime.v1.WatchFilesRequest - 30, // 110: rill.runtime.v1.RuntimeService.GetFile:input_type -> rill.runtime.v1.GetFileRequest - 32, // 111: rill.runtime.v1.RuntimeService.PutFile:input_type -> rill.runtime.v1.PutFileRequest - 34, // 112: rill.runtime.v1.RuntimeService.CreateDirectory:input_type -> rill.runtime.v1.CreateDirectoryRequest - 36, // 113: rill.runtime.v1.RuntimeService.DeleteFile:input_type -> rill.runtime.v1.DeleteFileRequest - 38, // 114: rill.runtime.v1.RuntimeService.RenameFile:input_type -> rill.runtime.v1.RenameFileRequest - 41, // 115: rill.runtime.v1.RuntimeService.ListExamples:input_type -> rill.runtime.v1.ListExamplesRequest - 43, // 116: rill.runtime.v1.RuntimeService.UnpackExample:input_type -> rill.runtime.v1.UnpackExampleRequest - 45, // 117: rill.runtime.v1.RuntimeService.UnpackEmpty:input_type -> rill.runtime.v1.UnpackEmptyRequest - 47, // 118: rill.runtime.v1.RuntimeService.GenerateMetricsViewFile:input_type -> rill.runtime.v1.GenerateMetricsViewFileRequest - 49, // 119: rill.runtime.v1.RuntimeService.GenerateCanvasFile:input_type -> rill.runtime.v1.GenerateCanvasFileRequest - 51, // 120: rill.runtime.v1.RuntimeService.GenerateResolver:input_type -> rill.runtime.v1.GenerateResolverRequest - 53, // 121: rill.runtime.v1.RuntimeService.GenerateRenderer:input_type -> rill.runtime.v1.GenerateRendererRequest - 55, // 122: rill.runtime.v1.RuntimeService.GenerateTemplate:input_type -> rill.runtime.v1.GenerateTemplateRequest - 57, // 123: rill.runtime.v1.RuntimeService.QueryResolver:input_type -> rill.runtime.v1.QueryResolverRequest - 61, // 124: rill.runtime.v1.RuntimeService.GetLogs:input_type -> rill.runtime.v1.GetLogsRequest - 63, // 125: rill.runtime.v1.RuntimeService.WatchLogs:input_type -> rill.runtime.v1.WatchLogsRequest - 65, // 126: rill.runtime.v1.RuntimeService.ListResources:input_type -> rill.runtime.v1.ListResourcesRequest - 67, // 127: rill.runtime.v1.RuntimeService.WatchResources:input_type -> rill.runtime.v1.WatchResourcesRequest - 69, // 128: rill.runtime.v1.RuntimeService.GetResource:input_type -> rill.runtime.v1.GetResourceRequest - 71, // 129: rill.runtime.v1.RuntimeService.GetExplore:input_type -> rill.runtime.v1.GetExploreRequest - 73, // 130: rill.runtime.v1.RuntimeService.GetModelPartitions:input_type -> rill.runtime.v1.GetModelPartitionsRequest - 75, // 131: rill.runtime.v1.RuntimeService.CreateTrigger:input_type -> rill.runtime.v1.CreateTriggerRequest - 79, // 132: rill.runtime.v1.RuntimeService.ListConnectorDrivers:input_type -> rill.runtime.v1.ListConnectorDriversRequest - 81, // 133: rill.runtime.v1.RuntimeService.AnalyzeConnectors:input_type -> rill.runtime.v1.AnalyzeConnectorsRequest - 83, // 134: rill.runtime.v1.RuntimeService.ListNotifierConnectors:input_type -> rill.runtime.v1.ListNotifierConnectorsRequest - 90, // 135: rill.runtime.v1.RuntimeService.ListConversations:input_type -> rill.runtime.v1.ListConversationsRequest - 92, // 136: rill.runtime.v1.RuntimeService.GetConversation:input_type -> rill.runtime.v1.GetConversationRequest - 94, // 137: rill.runtime.v1.RuntimeService.ShareConversation:input_type -> rill.runtime.v1.ShareConversationRequest - 96, // 138: rill.runtime.v1.RuntimeService.ForkConversation:input_type -> rill.runtime.v1.ForkConversationRequest - 98, // 139: rill.runtime.v1.RuntimeService.ListTools:input_type -> rill.runtime.v1.ListToolsRequest - 100, // 140: rill.runtime.v1.RuntimeService.Complete:input_type -> rill.runtime.v1.CompleteRequest - 102, // 141: rill.runtime.v1.RuntimeService.CompleteStreaming:input_type -> rill.runtime.v1.CompleteStreamingRequest - 104, // 142: rill.runtime.v1.RuntimeService.IssueDevJWT:input_type -> rill.runtime.v1.IssueDevJWTRequest - 106, // 143: rill.runtime.v1.RuntimeService.AnalyzeVariables:input_type -> rill.runtime.v1.AnalyzeVariablesRequest - 109, // 144: rill.runtime.v1.RuntimeService.ListGitCommits:input_type -> rill.runtime.v1.ListGitCommitsRequest - 112, // 145: rill.runtime.v1.RuntimeService.GitStatus:input_type -> rill.runtime.v1.GitStatusRequest - 114, // 146: rill.runtime.v1.RuntimeService.ListGitBranches:input_type -> rill.runtime.v1.ListGitBranchesRequest - 117, // 147: rill.runtime.v1.RuntimeService.GitCommit:input_type -> rill.runtime.v1.GitCommitRequest - 119, // 148: rill.runtime.v1.RuntimeService.RestoreGitCommit:input_type -> rill.runtime.v1.RestoreGitCommitRequest - 121, // 149: rill.runtime.v1.RuntimeService.GitMergeToBranch:input_type -> rill.runtime.v1.GitMergeToBranchRequest - 123, // 150: rill.runtime.v1.RuntimeService.GitSwitchBranch:input_type -> rill.runtime.v1.GitSwitchBranchRequest - 125, // 151: rill.runtime.v1.RuntimeService.GitPull:input_type -> rill.runtime.v1.GitPullRequest - 127, // 152: rill.runtime.v1.RuntimeService.GitPush:input_type -> rill.runtime.v1.GitPushRequest - 5, // 153: rill.runtime.v1.RuntimeService.Ping:output_type -> rill.runtime.v1.PingResponse - 7, // 154: rill.runtime.v1.RuntimeService.Health:output_type -> rill.runtime.v1.HealthResponse - 9, // 155: rill.runtime.v1.RuntimeService.InstanceHealth:output_type -> rill.runtime.v1.InstanceHealthResponse - 14, // 156: rill.runtime.v1.RuntimeService.ListInstances:output_type -> rill.runtime.v1.ListInstancesResponse - 16, // 157: rill.runtime.v1.RuntimeService.GetInstance:output_type -> rill.runtime.v1.GetInstanceResponse - 18, // 158: rill.runtime.v1.RuntimeService.CreateInstance:output_type -> rill.runtime.v1.CreateInstanceResponse - 22, // 159: rill.runtime.v1.RuntimeService.EditInstance:output_type -> rill.runtime.v1.EditInstanceResponse - 20, // 160: rill.runtime.v1.RuntimeService.DeleteInstance:output_type -> rill.runtime.v1.DeleteInstanceResponse - 24, // 161: rill.runtime.v1.RuntimeService.ReloadConfig:output_type -> rill.runtime.v1.ReloadConfigResponse - 26, // 162: rill.runtime.v1.RuntimeService.ListFiles:output_type -> rill.runtime.v1.ListFilesResponse - 29, // 163: rill.runtime.v1.RuntimeService.WatchFiles:output_type -> rill.runtime.v1.WatchFilesResponse - 31, // 164: rill.runtime.v1.RuntimeService.GetFile:output_type -> rill.runtime.v1.GetFileResponse - 33, // 165: rill.runtime.v1.RuntimeService.PutFile:output_type -> rill.runtime.v1.PutFileResponse - 35, // 166: rill.runtime.v1.RuntimeService.CreateDirectory:output_type -> rill.runtime.v1.CreateDirectoryResponse - 37, // 167: rill.runtime.v1.RuntimeService.DeleteFile:output_type -> rill.runtime.v1.DeleteFileResponse - 39, // 168: rill.runtime.v1.RuntimeService.RenameFile:output_type -> rill.runtime.v1.RenameFileResponse - 42, // 169: rill.runtime.v1.RuntimeService.ListExamples:output_type -> rill.runtime.v1.ListExamplesResponse - 44, // 170: rill.runtime.v1.RuntimeService.UnpackExample:output_type -> rill.runtime.v1.UnpackExampleResponse - 46, // 171: rill.runtime.v1.RuntimeService.UnpackEmpty:output_type -> rill.runtime.v1.UnpackEmptyResponse - 48, // 172: rill.runtime.v1.RuntimeService.GenerateMetricsViewFile:output_type -> rill.runtime.v1.GenerateMetricsViewFileResponse - 50, // 173: rill.runtime.v1.RuntimeService.GenerateCanvasFile:output_type -> rill.runtime.v1.GenerateCanvasFileResponse - 52, // 174: rill.runtime.v1.RuntimeService.GenerateResolver:output_type -> rill.runtime.v1.GenerateResolverResponse - 54, // 175: rill.runtime.v1.RuntimeService.GenerateRenderer:output_type -> rill.runtime.v1.GenerateRendererResponse - 56, // 176: rill.runtime.v1.RuntimeService.GenerateTemplate:output_type -> rill.runtime.v1.GenerateTemplateResponse - 58, // 177: rill.runtime.v1.RuntimeService.QueryResolver:output_type -> rill.runtime.v1.QueryResolverResponse - 62, // 178: rill.runtime.v1.RuntimeService.GetLogs:output_type -> rill.runtime.v1.GetLogsResponse - 64, // 179: rill.runtime.v1.RuntimeService.WatchLogs:output_type -> rill.runtime.v1.WatchLogsResponse - 66, // 180: rill.runtime.v1.RuntimeService.ListResources:output_type -> rill.runtime.v1.ListResourcesResponse - 68, // 181: rill.runtime.v1.RuntimeService.WatchResources:output_type -> rill.runtime.v1.WatchResourcesResponse - 70, // 182: rill.runtime.v1.RuntimeService.GetResource:output_type -> rill.runtime.v1.GetResourceResponse - 72, // 183: rill.runtime.v1.RuntimeService.GetExplore:output_type -> rill.runtime.v1.GetExploreResponse - 74, // 184: rill.runtime.v1.RuntimeService.GetModelPartitions:output_type -> rill.runtime.v1.GetModelPartitionsResponse - 76, // 185: rill.runtime.v1.RuntimeService.CreateTrigger:output_type -> rill.runtime.v1.CreateTriggerResponse - 80, // 186: rill.runtime.v1.RuntimeService.ListConnectorDrivers:output_type -> rill.runtime.v1.ListConnectorDriversResponse - 82, // 187: rill.runtime.v1.RuntimeService.AnalyzeConnectors:output_type -> rill.runtime.v1.AnalyzeConnectorsResponse - 84, // 188: rill.runtime.v1.RuntimeService.ListNotifierConnectors:output_type -> rill.runtime.v1.ListNotifierConnectorsResponse - 91, // 189: rill.runtime.v1.RuntimeService.ListConversations:output_type -> rill.runtime.v1.ListConversationsResponse - 93, // 190: rill.runtime.v1.RuntimeService.GetConversation:output_type -> rill.runtime.v1.GetConversationResponse - 95, // 191: rill.runtime.v1.RuntimeService.ShareConversation:output_type -> rill.runtime.v1.ShareConversationResponse - 97, // 192: rill.runtime.v1.RuntimeService.ForkConversation:output_type -> rill.runtime.v1.ForkConversationResponse - 99, // 193: rill.runtime.v1.RuntimeService.ListTools:output_type -> rill.runtime.v1.ListToolsResponse - 101, // 194: rill.runtime.v1.RuntimeService.Complete:output_type -> rill.runtime.v1.CompleteResponse - 103, // 195: rill.runtime.v1.RuntimeService.CompleteStreaming:output_type -> rill.runtime.v1.CompleteStreamingResponse - 105, // 196: rill.runtime.v1.RuntimeService.IssueDevJWT:output_type -> rill.runtime.v1.IssueDevJWTResponse - 107, // 197: rill.runtime.v1.RuntimeService.AnalyzeVariables:output_type -> rill.runtime.v1.AnalyzeVariablesResponse - 110, // 198: rill.runtime.v1.RuntimeService.ListGitCommits:output_type -> rill.runtime.v1.ListGitCommitsResponse - 113, // 199: rill.runtime.v1.RuntimeService.GitStatus:output_type -> rill.runtime.v1.GitStatusResponse - 115, // 200: rill.runtime.v1.RuntimeService.ListGitBranches:output_type -> rill.runtime.v1.ListGitBranchesResponse - 118, // 201: rill.runtime.v1.RuntimeService.GitCommit:output_type -> rill.runtime.v1.GitCommitResponse - 120, // 202: rill.runtime.v1.RuntimeService.RestoreGitCommit:output_type -> rill.runtime.v1.RestoreGitCommitResponse - 122, // 203: rill.runtime.v1.RuntimeService.GitMergeToBranch:output_type -> rill.runtime.v1.GitMergeToBranchResponse - 124, // 204: rill.runtime.v1.RuntimeService.GitSwitchBranch:output_type -> rill.runtime.v1.GitSwitchBranchResponse - 126, // 205: rill.runtime.v1.RuntimeService.GitPull:output_type -> rill.runtime.v1.GitPullResponse - 128, // 206: rill.runtime.v1.RuntimeService.GitPush:output_type -> rill.runtime.v1.GitPushResponse - 153, // [153:207] is the sub-list for method output_type - 99, // [99:153] is the sub-list for method input_type - 99, // [99:99] is the sub-list for extension type_name - 99, // [99:99] is the sub-list for extension extendee - 0, // [0:99] is the sub-list for field type_name + 150, // 26: rill.runtime.v1.GenerateResolverResponse.resolver_properties:type_name -> google.protobuf.Struct + 150, // 27: rill.runtime.v1.GenerateRendererRequest.resolver_properties:type_name -> google.protobuf.Struct + 150, // 28: rill.runtime.v1.GenerateRendererResponse.renderer_properties:type_name -> google.protobuf.Struct + 150, // 29: rill.runtime.v1.GenerateTemplateRequest.properties:type_name -> google.protobuf.Struct + 144, // 30: rill.runtime.v1.GenerateTemplateResponse.env_vars:type_name -> rill.runtime.v1.GenerateTemplateResponse.EnvVarsEntry + 58, // 31: rill.runtime.v1.Template.files:type_name -> rill.runtime.v1.TemplateFile + 57, // 32: rill.runtime.v1.ListTemplatesResponse.templates:type_name -> rill.runtime.v1.Template + 150, // 33: rill.runtime.v1.GenerateFileRequest.properties:type_name -> google.protobuf.Struct + 63, // 34: rill.runtime.v1.GenerateFileResponse.files:type_name -> rill.runtime.v1.GeneratedFile + 145, // 35: rill.runtime.v1.GenerateFileResponse.env_vars:type_name -> rill.runtime.v1.GenerateFileResponse.EnvVarsEntry + 150, // 36: rill.runtime.v1.QueryResolverRequest.resolver_properties:type_name -> google.protobuf.Struct + 150, // 37: rill.runtime.v1.QueryResolverRequest.resolver_args:type_name -> google.protobuf.Struct + 150, // 38: rill.runtime.v1.QueryResolverResponse.meta:type_name -> google.protobuf.Struct + 151, // 39: rill.runtime.v1.QueryResolverResponse.schema:type_name -> rill.runtime.v1.StructType + 150, // 40: rill.runtime.v1.QueryResolverResponse.data:type_name -> google.protobuf.Struct + 1, // 41: rill.runtime.v1.Log.level:type_name -> rill.runtime.v1.LogLevel + 149, // 42: rill.runtime.v1.Log.time:type_name -> google.protobuf.Timestamp + 150, // 43: rill.runtime.v1.ModelPartition.data:type_name -> google.protobuf.Struct + 149, // 44: rill.runtime.v1.ModelPartition.watermark:type_name -> google.protobuf.Timestamp + 149, // 45: rill.runtime.v1.ModelPartition.executed_on:type_name -> google.protobuf.Timestamp + 1, // 46: rill.runtime.v1.GetLogsRequest.level:type_name -> rill.runtime.v1.LogLevel + 66, // 47: rill.runtime.v1.GetLogsResponse.logs:type_name -> rill.runtime.v1.Log + 1, // 48: rill.runtime.v1.WatchLogsRequest.level:type_name -> rill.runtime.v1.LogLevel + 66, // 49: rill.runtime.v1.WatchLogsResponse.log:type_name -> rill.runtime.v1.Log + 152, // 50: rill.runtime.v1.ListResourcesResponse.resources:type_name -> rill.runtime.v1.Resource + 2, // 51: rill.runtime.v1.WatchResourcesResponse.event:type_name -> rill.runtime.v1.ResourceEvent + 153, // 52: rill.runtime.v1.WatchResourcesResponse.name:type_name -> rill.runtime.v1.ResourceName + 152, // 53: rill.runtime.v1.WatchResourcesResponse.resource:type_name -> rill.runtime.v1.Resource + 153, // 54: rill.runtime.v1.GetResourceRequest.name:type_name -> rill.runtime.v1.ResourceName + 152, // 55: rill.runtime.v1.GetResourceResponse.resource:type_name -> rill.runtime.v1.Resource + 152, // 56: rill.runtime.v1.GetExploreResponse.explore:type_name -> rill.runtime.v1.Resource + 152, // 57: rill.runtime.v1.GetExploreResponse.metrics_view:type_name -> rill.runtime.v1.Resource + 67, // 58: rill.runtime.v1.GetModelPartitionsResponse.partitions:type_name -> rill.runtime.v1.ModelPartition + 153, // 59: rill.runtime.v1.CreateTriggerRequest.resources:type_name -> rill.runtime.v1.ResourceName + 154, // 60: rill.runtime.v1.CreateTriggerRequest.models:type_name -> rill.runtime.v1.RefreshModelTrigger + 146, // 61: rill.runtime.v1.ConnectorDriver.config_properties:type_name -> rill.runtime.v1.ConnectorDriver.Property + 146, // 62: rill.runtime.v1.ConnectorDriver.source_properties:type_name -> rill.runtime.v1.ConnectorDriver.Property + 84, // 63: rill.runtime.v1.AnalyzedConnector.driver:type_name -> rill.runtime.v1.ConnectorDriver + 150, // 64: rill.runtime.v1.AnalyzedConnector.config:type_name -> google.protobuf.Struct + 150, // 65: rill.runtime.v1.AnalyzedConnector.preset_config:type_name -> google.protobuf.Struct + 150, // 66: rill.runtime.v1.AnalyzedConnector.project_config:type_name -> google.protobuf.Struct + 147, // 67: rill.runtime.v1.AnalyzedConnector.env_config:type_name -> rill.runtime.v1.AnalyzedConnector.EnvConfigEntry + 150, // 68: rill.runtime.v1.AnalyzedConnector.provision_args:type_name -> google.protobuf.Struct + 153, // 69: rill.runtime.v1.AnalyzedConnector.used_by:type_name -> rill.runtime.v1.ResourceName + 84, // 70: rill.runtime.v1.ListConnectorDriversResponse.connectors:type_name -> rill.runtime.v1.ConnectorDriver + 85, // 71: rill.runtime.v1.AnalyzeConnectorsResponse.connectors:type_name -> rill.runtime.v1.AnalyzedConnector + 12, // 72: rill.runtime.v1.ListNotifierConnectorsResponse.connectors:type_name -> rill.runtime.v1.Connector + 149, // 73: rill.runtime.v1.Conversation.created_on:type_name -> google.protobuf.Timestamp + 149, // 74: rill.runtime.v1.Conversation.updated_on:type_name -> google.protobuf.Timestamp + 93, // 75: rill.runtime.v1.Conversation.messages:type_name -> rill.runtime.v1.Message + 149, // 76: rill.runtime.v1.Message.created_on:type_name -> google.protobuf.Timestamp + 149, // 77: rill.runtime.v1.Message.updated_on:type_name -> google.protobuf.Timestamp + 155, // 78: rill.runtime.v1.Message.content:type_name -> rill.ai.v1.ContentBlock + 156, // 79: rill.runtime.v1.AnalystAgentContext.where:type_name -> rill.runtime.v1.Expression + 148, // 80: rill.runtime.v1.AnalystAgentContext.where_per_metrics_view:type_name -> rill.runtime.v1.AnalystAgentContext.WherePerMetricsViewEntry + 149, // 81: rill.runtime.v1.AnalystAgentContext.time_start:type_name -> google.protobuf.Timestamp + 149, // 82: rill.runtime.v1.AnalystAgentContext.time_end:type_name -> google.protobuf.Timestamp + 92, // 83: rill.runtime.v1.ListConversationsResponse.conversations:type_name -> rill.runtime.v1.Conversation + 92, // 84: rill.runtime.v1.GetConversationResponse.conversation:type_name -> rill.runtime.v1.Conversation + 93, // 85: rill.runtime.v1.GetConversationResponse.messages:type_name -> rill.runtime.v1.Message + 157, // 86: rill.runtime.v1.ListToolsResponse.tools:type_name -> rill.ai.v1.Tool + 94, // 87: rill.runtime.v1.CompleteRequest.analyst_agent_context:type_name -> rill.runtime.v1.AnalystAgentContext + 95, // 88: rill.runtime.v1.CompleteRequest.developer_agent_context:type_name -> rill.runtime.v1.DeveloperAgentContext + 96, // 89: rill.runtime.v1.CompleteRequest.feedback_agent_context:type_name -> rill.runtime.v1.FeedbackAgentContext + 93, // 90: rill.runtime.v1.CompleteResponse.messages:type_name -> rill.runtime.v1.Message + 94, // 91: rill.runtime.v1.CompleteStreamingRequest.analyst_agent_context:type_name -> rill.runtime.v1.AnalystAgentContext + 95, // 92: rill.runtime.v1.CompleteStreamingRequest.developer_agent_context:type_name -> rill.runtime.v1.DeveloperAgentContext + 96, // 93: rill.runtime.v1.CompleteStreamingRequest.feedback_agent_context:type_name -> rill.runtime.v1.FeedbackAgentContext + 93, // 94: rill.runtime.v1.CompleteStreamingResponse.message:type_name -> rill.runtime.v1.Message + 150, // 95: rill.runtime.v1.IssueDevJWTRequest.attributes:type_name -> google.protobuf.Struct + 115, // 96: rill.runtime.v1.AnalyzeVariablesResponse.variables:type_name -> rill.runtime.v1.AnalyzedVariable + 153, // 97: rill.runtime.v1.AnalyzedVariable.used_by:type_name -> rill.runtime.v1.ResourceName + 118, // 98: rill.runtime.v1.ListGitCommitsResponse.commits:type_name -> rill.runtime.v1.GitCommit + 149, // 99: rill.runtime.v1.GitCommit.committed_on:type_name -> google.protobuf.Timestamp + 123, // 100: rill.runtime.v1.ListGitBranchesResponse.branches:type_name -> rill.runtime.v1.GitBranch + 10, // 101: rill.runtime.v1.HealthResponse.InstancesHealthEntry.value:type_name -> rill.runtime.v1.InstanceHealth + 3, // 102: rill.runtime.v1.ConnectorDriver.Property.type:type_name -> rill.runtime.v1.ConnectorDriver.Property.Type + 156, // 103: rill.runtime.v1.AnalystAgentContext.WherePerMetricsViewEntry.value:type_name -> rill.runtime.v1.Expression + 4, // 104: rill.runtime.v1.RuntimeService.Ping:input_type -> rill.runtime.v1.PingRequest + 6, // 105: rill.runtime.v1.RuntimeService.Health:input_type -> rill.runtime.v1.HealthRequest + 8, // 106: rill.runtime.v1.RuntimeService.InstanceHealth:input_type -> rill.runtime.v1.InstanceHealthRequest + 13, // 107: rill.runtime.v1.RuntimeService.ListInstances:input_type -> rill.runtime.v1.ListInstancesRequest + 15, // 108: rill.runtime.v1.RuntimeService.GetInstance:input_type -> rill.runtime.v1.GetInstanceRequest + 17, // 109: rill.runtime.v1.RuntimeService.CreateInstance:input_type -> rill.runtime.v1.CreateInstanceRequest + 21, // 110: rill.runtime.v1.RuntimeService.EditInstance:input_type -> rill.runtime.v1.EditInstanceRequest + 19, // 111: rill.runtime.v1.RuntimeService.DeleteInstance:input_type -> rill.runtime.v1.DeleteInstanceRequest + 23, // 112: rill.runtime.v1.RuntimeService.ReloadConfig:input_type -> rill.runtime.v1.ReloadConfigRequest + 25, // 113: rill.runtime.v1.RuntimeService.ListFiles:input_type -> rill.runtime.v1.ListFilesRequest + 28, // 114: rill.runtime.v1.RuntimeService.WatchFiles:input_type -> rill.runtime.v1.WatchFilesRequest + 30, // 115: rill.runtime.v1.RuntimeService.GetFile:input_type -> rill.runtime.v1.GetFileRequest + 32, // 116: rill.runtime.v1.RuntimeService.PutFile:input_type -> rill.runtime.v1.PutFileRequest + 34, // 117: rill.runtime.v1.RuntimeService.CreateDirectory:input_type -> rill.runtime.v1.CreateDirectoryRequest + 36, // 118: rill.runtime.v1.RuntimeService.DeleteFile:input_type -> rill.runtime.v1.DeleteFileRequest + 38, // 119: rill.runtime.v1.RuntimeService.RenameFile:input_type -> rill.runtime.v1.RenameFileRequest + 41, // 120: rill.runtime.v1.RuntimeService.ListExamples:input_type -> rill.runtime.v1.ListExamplesRequest + 43, // 121: rill.runtime.v1.RuntimeService.UnpackExample:input_type -> rill.runtime.v1.UnpackExampleRequest + 45, // 122: rill.runtime.v1.RuntimeService.UnpackEmpty:input_type -> rill.runtime.v1.UnpackEmptyRequest + 47, // 123: rill.runtime.v1.RuntimeService.GenerateMetricsViewFile:input_type -> rill.runtime.v1.GenerateMetricsViewFileRequest + 49, // 124: rill.runtime.v1.RuntimeService.GenerateCanvasFile:input_type -> rill.runtime.v1.GenerateCanvasFileRequest + 51, // 125: rill.runtime.v1.RuntimeService.GenerateResolver:input_type -> rill.runtime.v1.GenerateResolverRequest + 53, // 126: rill.runtime.v1.RuntimeService.GenerateRenderer:input_type -> rill.runtime.v1.GenerateRendererRequest + 55, // 127: rill.runtime.v1.RuntimeService.GenerateTemplate:input_type -> rill.runtime.v1.GenerateTemplateRequest + 59, // 128: rill.runtime.v1.RuntimeService.ListTemplates:input_type -> rill.runtime.v1.ListTemplatesRequest + 61, // 129: rill.runtime.v1.RuntimeService.GenerateFile:input_type -> rill.runtime.v1.GenerateFileRequest + 64, // 130: rill.runtime.v1.RuntimeService.QueryResolver:input_type -> rill.runtime.v1.QueryResolverRequest + 68, // 131: rill.runtime.v1.RuntimeService.GetLogs:input_type -> rill.runtime.v1.GetLogsRequest + 70, // 132: rill.runtime.v1.RuntimeService.WatchLogs:input_type -> rill.runtime.v1.WatchLogsRequest + 72, // 133: rill.runtime.v1.RuntimeService.ListResources:input_type -> rill.runtime.v1.ListResourcesRequest + 74, // 134: rill.runtime.v1.RuntimeService.WatchResources:input_type -> rill.runtime.v1.WatchResourcesRequest + 76, // 135: rill.runtime.v1.RuntimeService.GetResource:input_type -> rill.runtime.v1.GetResourceRequest + 78, // 136: rill.runtime.v1.RuntimeService.GetExplore:input_type -> rill.runtime.v1.GetExploreRequest + 80, // 137: rill.runtime.v1.RuntimeService.GetModelPartitions:input_type -> rill.runtime.v1.GetModelPartitionsRequest + 82, // 138: rill.runtime.v1.RuntimeService.CreateTrigger:input_type -> rill.runtime.v1.CreateTriggerRequest + 86, // 139: rill.runtime.v1.RuntimeService.ListConnectorDrivers:input_type -> rill.runtime.v1.ListConnectorDriversRequest + 88, // 140: rill.runtime.v1.RuntimeService.AnalyzeConnectors:input_type -> rill.runtime.v1.AnalyzeConnectorsRequest + 90, // 141: rill.runtime.v1.RuntimeService.ListNotifierConnectors:input_type -> rill.runtime.v1.ListNotifierConnectorsRequest + 97, // 142: rill.runtime.v1.RuntimeService.ListConversations:input_type -> rill.runtime.v1.ListConversationsRequest + 99, // 143: rill.runtime.v1.RuntimeService.GetConversation:input_type -> rill.runtime.v1.GetConversationRequest + 101, // 144: rill.runtime.v1.RuntimeService.ShareConversation:input_type -> rill.runtime.v1.ShareConversationRequest + 103, // 145: rill.runtime.v1.RuntimeService.ForkConversation:input_type -> rill.runtime.v1.ForkConversationRequest + 105, // 146: rill.runtime.v1.RuntimeService.ListTools:input_type -> rill.runtime.v1.ListToolsRequest + 107, // 147: rill.runtime.v1.RuntimeService.Complete:input_type -> rill.runtime.v1.CompleteRequest + 109, // 148: rill.runtime.v1.RuntimeService.CompleteStreaming:input_type -> rill.runtime.v1.CompleteStreamingRequest + 111, // 149: rill.runtime.v1.RuntimeService.IssueDevJWT:input_type -> rill.runtime.v1.IssueDevJWTRequest + 113, // 150: rill.runtime.v1.RuntimeService.AnalyzeVariables:input_type -> rill.runtime.v1.AnalyzeVariablesRequest + 116, // 151: rill.runtime.v1.RuntimeService.ListGitCommits:input_type -> rill.runtime.v1.ListGitCommitsRequest + 119, // 152: rill.runtime.v1.RuntimeService.GitStatus:input_type -> rill.runtime.v1.GitStatusRequest + 121, // 153: rill.runtime.v1.RuntimeService.ListGitBranches:input_type -> rill.runtime.v1.ListGitBranchesRequest + 124, // 154: rill.runtime.v1.RuntimeService.GitCommit:input_type -> rill.runtime.v1.GitCommitRequest + 126, // 155: rill.runtime.v1.RuntimeService.RestoreGitCommit:input_type -> rill.runtime.v1.RestoreGitCommitRequest + 128, // 156: rill.runtime.v1.RuntimeService.GitMergeToBranch:input_type -> rill.runtime.v1.GitMergeToBranchRequest + 130, // 157: rill.runtime.v1.RuntimeService.GitSwitchBranch:input_type -> rill.runtime.v1.GitSwitchBranchRequest + 132, // 158: rill.runtime.v1.RuntimeService.GitPull:input_type -> rill.runtime.v1.GitPullRequest + 134, // 159: rill.runtime.v1.RuntimeService.GitPush:input_type -> rill.runtime.v1.GitPushRequest + 5, // 160: rill.runtime.v1.RuntimeService.Ping:output_type -> rill.runtime.v1.PingResponse + 7, // 161: rill.runtime.v1.RuntimeService.Health:output_type -> rill.runtime.v1.HealthResponse + 9, // 162: rill.runtime.v1.RuntimeService.InstanceHealth:output_type -> rill.runtime.v1.InstanceHealthResponse + 14, // 163: rill.runtime.v1.RuntimeService.ListInstances:output_type -> rill.runtime.v1.ListInstancesResponse + 16, // 164: rill.runtime.v1.RuntimeService.GetInstance:output_type -> rill.runtime.v1.GetInstanceResponse + 18, // 165: rill.runtime.v1.RuntimeService.CreateInstance:output_type -> rill.runtime.v1.CreateInstanceResponse + 22, // 166: rill.runtime.v1.RuntimeService.EditInstance:output_type -> rill.runtime.v1.EditInstanceResponse + 20, // 167: rill.runtime.v1.RuntimeService.DeleteInstance:output_type -> rill.runtime.v1.DeleteInstanceResponse + 24, // 168: rill.runtime.v1.RuntimeService.ReloadConfig:output_type -> rill.runtime.v1.ReloadConfigResponse + 26, // 169: rill.runtime.v1.RuntimeService.ListFiles:output_type -> rill.runtime.v1.ListFilesResponse + 29, // 170: rill.runtime.v1.RuntimeService.WatchFiles:output_type -> rill.runtime.v1.WatchFilesResponse + 31, // 171: rill.runtime.v1.RuntimeService.GetFile:output_type -> rill.runtime.v1.GetFileResponse + 33, // 172: rill.runtime.v1.RuntimeService.PutFile:output_type -> rill.runtime.v1.PutFileResponse + 35, // 173: rill.runtime.v1.RuntimeService.CreateDirectory:output_type -> rill.runtime.v1.CreateDirectoryResponse + 37, // 174: rill.runtime.v1.RuntimeService.DeleteFile:output_type -> rill.runtime.v1.DeleteFileResponse + 39, // 175: rill.runtime.v1.RuntimeService.RenameFile:output_type -> rill.runtime.v1.RenameFileResponse + 42, // 176: rill.runtime.v1.RuntimeService.ListExamples:output_type -> rill.runtime.v1.ListExamplesResponse + 44, // 177: rill.runtime.v1.RuntimeService.UnpackExample:output_type -> rill.runtime.v1.UnpackExampleResponse + 46, // 178: rill.runtime.v1.RuntimeService.UnpackEmpty:output_type -> rill.runtime.v1.UnpackEmptyResponse + 48, // 179: rill.runtime.v1.RuntimeService.GenerateMetricsViewFile:output_type -> rill.runtime.v1.GenerateMetricsViewFileResponse + 50, // 180: rill.runtime.v1.RuntimeService.GenerateCanvasFile:output_type -> rill.runtime.v1.GenerateCanvasFileResponse + 52, // 181: rill.runtime.v1.RuntimeService.GenerateResolver:output_type -> rill.runtime.v1.GenerateResolverResponse + 54, // 182: rill.runtime.v1.RuntimeService.GenerateRenderer:output_type -> rill.runtime.v1.GenerateRendererResponse + 56, // 183: rill.runtime.v1.RuntimeService.GenerateTemplate:output_type -> rill.runtime.v1.GenerateTemplateResponse + 60, // 184: rill.runtime.v1.RuntimeService.ListTemplates:output_type -> rill.runtime.v1.ListTemplatesResponse + 62, // 185: rill.runtime.v1.RuntimeService.GenerateFile:output_type -> rill.runtime.v1.GenerateFileResponse + 65, // 186: rill.runtime.v1.RuntimeService.QueryResolver:output_type -> rill.runtime.v1.QueryResolverResponse + 69, // 187: rill.runtime.v1.RuntimeService.GetLogs:output_type -> rill.runtime.v1.GetLogsResponse + 71, // 188: rill.runtime.v1.RuntimeService.WatchLogs:output_type -> rill.runtime.v1.WatchLogsResponse + 73, // 189: rill.runtime.v1.RuntimeService.ListResources:output_type -> rill.runtime.v1.ListResourcesResponse + 75, // 190: rill.runtime.v1.RuntimeService.WatchResources:output_type -> rill.runtime.v1.WatchResourcesResponse + 77, // 191: rill.runtime.v1.RuntimeService.GetResource:output_type -> rill.runtime.v1.GetResourceResponse + 79, // 192: rill.runtime.v1.RuntimeService.GetExplore:output_type -> rill.runtime.v1.GetExploreResponse + 81, // 193: rill.runtime.v1.RuntimeService.GetModelPartitions:output_type -> rill.runtime.v1.GetModelPartitionsResponse + 83, // 194: rill.runtime.v1.RuntimeService.CreateTrigger:output_type -> rill.runtime.v1.CreateTriggerResponse + 87, // 195: rill.runtime.v1.RuntimeService.ListConnectorDrivers:output_type -> rill.runtime.v1.ListConnectorDriversResponse + 89, // 196: rill.runtime.v1.RuntimeService.AnalyzeConnectors:output_type -> rill.runtime.v1.AnalyzeConnectorsResponse + 91, // 197: rill.runtime.v1.RuntimeService.ListNotifierConnectors:output_type -> rill.runtime.v1.ListNotifierConnectorsResponse + 98, // 198: rill.runtime.v1.RuntimeService.ListConversations:output_type -> rill.runtime.v1.ListConversationsResponse + 100, // 199: rill.runtime.v1.RuntimeService.GetConversation:output_type -> rill.runtime.v1.GetConversationResponse + 102, // 200: rill.runtime.v1.RuntimeService.ShareConversation:output_type -> rill.runtime.v1.ShareConversationResponse + 104, // 201: rill.runtime.v1.RuntimeService.ForkConversation:output_type -> rill.runtime.v1.ForkConversationResponse + 106, // 202: rill.runtime.v1.RuntimeService.ListTools:output_type -> rill.runtime.v1.ListToolsResponse + 108, // 203: rill.runtime.v1.RuntimeService.Complete:output_type -> rill.runtime.v1.CompleteResponse + 110, // 204: rill.runtime.v1.RuntimeService.CompleteStreaming:output_type -> rill.runtime.v1.CompleteStreamingResponse + 112, // 205: rill.runtime.v1.RuntimeService.IssueDevJWT:output_type -> rill.runtime.v1.IssueDevJWTResponse + 114, // 206: rill.runtime.v1.RuntimeService.AnalyzeVariables:output_type -> rill.runtime.v1.AnalyzeVariablesResponse + 117, // 207: rill.runtime.v1.RuntimeService.ListGitCommits:output_type -> rill.runtime.v1.ListGitCommitsResponse + 120, // 208: rill.runtime.v1.RuntimeService.GitStatus:output_type -> rill.runtime.v1.GitStatusResponse + 122, // 209: rill.runtime.v1.RuntimeService.ListGitBranches:output_type -> rill.runtime.v1.ListGitBranchesResponse + 125, // 210: rill.runtime.v1.RuntimeService.GitCommit:output_type -> rill.runtime.v1.GitCommitResponse + 127, // 211: rill.runtime.v1.RuntimeService.RestoreGitCommit:output_type -> rill.runtime.v1.RestoreGitCommitResponse + 129, // 212: rill.runtime.v1.RuntimeService.GitMergeToBranch:output_type -> rill.runtime.v1.GitMergeToBranchResponse + 131, // 213: rill.runtime.v1.RuntimeService.GitSwitchBranch:output_type -> rill.runtime.v1.GitSwitchBranchResponse + 133, // 214: rill.runtime.v1.RuntimeService.GitPull:output_type -> rill.runtime.v1.GitPullResponse + 135, // 215: rill.runtime.v1.RuntimeService.GitPush:output_type -> rill.runtime.v1.GitPushResponse + 160, // [160:216] is the sub-list for method output_type + 104, // [104:160] is the sub-list for method input_type + 104, // [104:104] is the sub-list for extension type_name + 104, // [104:104] is the sub-list for extension extendee + 0, // [0:104] is the sub-list for field type_name } func init() { file_rill_runtime_v1_api_proto_init() } @@ -11137,7 +11670,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[53].Exporter = func(v any, i int) any { - switch v := v.(*QueryResolverRequest); i { + switch v := v.(*Template); i { case 0: return &v.state case 1: @@ -11149,7 +11682,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[54].Exporter = func(v any, i int) any { - switch v := v.(*QueryResolverResponse); i { + switch v := v.(*TemplateFile); i { case 0: return &v.state case 1: @@ -11161,7 +11694,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[55].Exporter = func(v any, i int) any { - switch v := v.(*Log); i { + switch v := v.(*ListTemplatesRequest); i { case 0: return &v.state case 1: @@ -11173,7 +11706,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[56].Exporter = func(v any, i int) any { - switch v := v.(*ModelPartition); i { + switch v := v.(*ListTemplatesResponse); i { case 0: return &v.state case 1: @@ -11185,7 +11718,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[57].Exporter = func(v any, i int) any { - switch v := v.(*GetLogsRequest); i { + switch v := v.(*GenerateFileRequest); i { case 0: return &v.state case 1: @@ -11197,7 +11730,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[58].Exporter = func(v any, i int) any { - switch v := v.(*GetLogsResponse); i { + switch v := v.(*GenerateFileResponse); i { case 0: return &v.state case 1: @@ -11209,7 +11742,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[59].Exporter = func(v any, i int) any { - switch v := v.(*WatchLogsRequest); i { + switch v := v.(*GeneratedFile); i { case 0: return &v.state case 1: @@ -11221,7 +11754,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[60].Exporter = func(v any, i int) any { - switch v := v.(*WatchLogsResponse); i { + switch v := v.(*QueryResolverRequest); i { case 0: return &v.state case 1: @@ -11233,7 +11766,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[61].Exporter = func(v any, i int) any { - switch v := v.(*ListResourcesRequest); i { + switch v := v.(*QueryResolverResponse); i { case 0: return &v.state case 1: @@ -11245,7 +11778,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[62].Exporter = func(v any, i int) any { - switch v := v.(*ListResourcesResponse); i { + switch v := v.(*Log); i { case 0: return &v.state case 1: @@ -11257,7 +11790,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[63].Exporter = func(v any, i int) any { - switch v := v.(*WatchResourcesRequest); i { + switch v := v.(*ModelPartition); i { case 0: return &v.state case 1: @@ -11269,7 +11802,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[64].Exporter = func(v any, i int) any { - switch v := v.(*WatchResourcesResponse); i { + switch v := v.(*GetLogsRequest); i { case 0: return &v.state case 1: @@ -11281,7 +11814,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[65].Exporter = func(v any, i int) any { - switch v := v.(*GetResourceRequest); i { + switch v := v.(*GetLogsResponse); i { case 0: return &v.state case 1: @@ -11293,7 +11826,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[66].Exporter = func(v any, i int) any { - switch v := v.(*GetResourceResponse); i { + switch v := v.(*WatchLogsRequest); i { case 0: return &v.state case 1: @@ -11305,7 +11838,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[67].Exporter = func(v any, i int) any { - switch v := v.(*GetExploreRequest); i { + switch v := v.(*WatchLogsResponse); i { case 0: return &v.state case 1: @@ -11317,7 +11850,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[68].Exporter = func(v any, i int) any { - switch v := v.(*GetExploreResponse); i { + switch v := v.(*ListResourcesRequest); i { case 0: return &v.state case 1: @@ -11329,7 +11862,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[69].Exporter = func(v any, i int) any { - switch v := v.(*GetModelPartitionsRequest); i { + switch v := v.(*ListResourcesResponse); i { case 0: return &v.state case 1: @@ -11341,7 +11874,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[70].Exporter = func(v any, i int) any { - switch v := v.(*GetModelPartitionsResponse); i { + switch v := v.(*WatchResourcesRequest); i { case 0: return &v.state case 1: @@ -11353,7 +11886,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[71].Exporter = func(v any, i int) any { - switch v := v.(*CreateTriggerRequest); i { + switch v := v.(*WatchResourcesResponse); i { case 0: return &v.state case 1: @@ -11365,7 +11898,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[72].Exporter = func(v any, i int) any { - switch v := v.(*CreateTriggerResponse); i { + switch v := v.(*GetResourceRequest); i { case 0: return &v.state case 1: @@ -11377,7 +11910,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[73].Exporter = func(v any, i int) any { - switch v := v.(*ConnectorDriver); i { + switch v := v.(*GetResourceResponse); i { case 0: return &v.state case 1: @@ -11389,7 +11922,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[74].Exporter = func(v any, i int) any { - switch v := v.(*AnalyzedConnector); i { + switch v := v.(*GetExploreRequest); i { case 0: return &v.state case 1: @@ -11401,7 +11934,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[75].Exporter = func(v any, i int) any { - switch v := v.(*ListConnectorDriversRequest); i { + switch v := v.(*GetExploreResponse); i { case 0: return &v.state case 1: @@ -11413,7 +11946,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[76].Exporter = func(v any, i int) any { - switch v := v.(*ListConnectorDriversResponse); i { + switch v := v.(*GetModelPartitionsRequest); i { case 0: return &v.state case 1: @@ -11425,7 +11958,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[77].Exporter = func(v any, i int) any { - switch v := v.(*AnalyzeConnectorsRequest); i { + switch v := v.(*GetModelPartitionsResponse); i { case 0: return &v.state case 1: @@ -11437,7 +11970,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[78].Exporter = func(v any, i int) any { - switch v := v.(*AnalyzeConnectorsResponse); i { + switch v := v.(*CreateTriggerRequest); i { case 0: return &v.state case 1: @@ -11449,7 +11982,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[79].Exporter = func(v any, i int) any { - switch v := v.(*ListNotifierConnectorsRequest); i { + switch v := v.(*CreateTriggerResponse); i { case 0: return &v.state case 1: @@ -11461,7 +11994,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[80].Exporter = func(v any, i int) any { - switch v := v.(*ListNotifierConnectorsResponse); i { + switch v := v.(*ConnectorDriver); i { case 0: return &v.state case 1: @@ -11473,7 +12006,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[81].Exporter = func(v any, i int) any { - switch v := v.(*Conversation); i { + switch v := v.(*AnalyzedConnector); i { case 0: return &v.state case 1: @@ -11485,7 +12018,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[82].Exporter = func(v any, i int) any { - switch v := v.(*Message); i { + switch v := v.(*ListConnectorDriversRequest); i { case 0: return &v.state case 1: @@ -11497,7 +12030,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[83].Exporter = func(v any, i int) any { - switch v := v.(*AnalystAgentContext); i { + switch v := v.(*ListConnectorDriversResponse); i { case 0: return &v.state case 1: @@ -11509,7 +12042,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[84].Exporter = func(v any, i int) any { - switch v := v.(*DeveloperAgentContext); i { + switch v := v.(*AnalyzeConnectorsRequest); i { case 0: return &v.state case 1: @@ -11521,7 +12054,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[85].Exporter = func(v any, i int) any { - switch v := v.(*FeedbackAgentContext); i { + switch v := v.(*AnalyzeConnectorsResponse); i { case 0: return &v.state case 1: @@ -11533,7 +12066,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[86].Exporter = func(v any, i int) any { - switch v := v.(*ListConversationsRequest); i { + switch v := v.(*ListNotifierConnectorsRequest); i { case 0: return &v.state case 1: @@ -11545,7 +12078,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[87].Exporter = func(v any, i int) any { - switch v := v.(*ListConversationsResponse); i { + switch v := v.(*ListNotifierConnectorsResponse); i { case 0: return &v.state case 1: @@ -11557,7 +12090,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[88].Exporter = func(v any, i int) any { - switch v := v.(*GetConversationRequest); i { + switch v := v.(*Conversation); i { case 0: return &v.state case 1: @@ -11569,7 +12102,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[89].Exporter = func(v any, i int) any { - switch v := v.(*GetConversationResponse); i { + switch v := v.(*Message); i { case 0: return &v.state case 1: @@ -11581,7 +12114,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[90].Exporter = func(v any, i int) any { - switch v := v.(*ShareConversationRequest); i { + switch v := v.(*AnalystAgentContext); i { case 0: return &v.state case 1: @@ -11593,7 +12126,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[91].Exporter = func(v any, i int) any { - switch v := v.(*ShareConversationResponse); i { + switch v := v.(*DeveloperAgentContext); i { case 0: return &v.state case 1: @@ -11605,7 +12138,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[92].Exporter = func(v any, i int) any { - switch v := v.(*ForkConversationRequest); i { + switch v := v.(*FeedbackAgentContext); i { case 0: return &v.state case 1: @@ -11617,7 +12150,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[93].Exporter = func(v any, i int) any { - switch v := v.(*ForkConversationResponse); i { + switch v := v.(*ListConversationsRequest); i { case 0: return &v.state case 1: @@ -11629,7 +12162,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[94].Exporter = func(v any, i int) any { - switch v := v.(*ListToolsRequest); i { + switch v := v.(*ListConversationsResponse); i { case 0: return &v.state case 1: @@ -11641,7 +12174,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[95].Exporter = func(v any, i int) any { - switch v := v.(*ListToolsResponse); i { + switch v := v.(*GetConversationRequest); i { case 0: return &v.state case 1: @@ -11653,7 +12186,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[96].Exporter = func(v any, i int) any { - switch v := v.(*CompleteRequest); i { + switch v := v.(*GetConversationResponse); i { case 0: return &v.state case 1: @@ -11665,7 +12198,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[97].Exporter = func(v any, i int) any { - switch v := v.(*CompleteResponse); i { + switch v := v.(*ShareConversationRequest); i { case 0: return &v.state case 1: @@ -11677,7 +12210,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[98].Exporter = func(v any, i int) any { - switch v := v.(*CompleteStreamingRequest); i { + switch v := v.(*ShareConversationResponse); i { case 0: return &v.state case 1: @@ -11689,7 +12222,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[99].Exporter = func(v any, i int) any { - switch v := v.(*CompleteStreamingResponse); i { + switch v := v.(*ForkConversationRequest); i { case 0: return &v.state case 1: @@ -11701,7 +12234,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[100].Exporter = func(v any, i int) any { - switch v := v.(*IssueDevJWTRequest); i { + switch v := v.(*ForkConversationResponse); i { case 0: return &v.state case 1: @@ -11713,7 +12246,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[101].Exporter = func(v any, i int) any { - switch v := v.(*IssueDevJWTResponse); i { + switch v := v.(*ListToolsRequest); i { case 0: return &v.state case 1: @@ -11725,7 +12258,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[102].Exporter = func(v any, i int) any { - switch v := v.(*AnalyzeVariablesRequest); i { + switch v := v.(*ListToolsResponse); i { case 0: return &v.state case 1: @@ -11737,7 +12270,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[103].Exporter = func(v any, i int) any { - switch v := v.(*AnalyzeVariablesResponse); i { + switch v := v.(*CompleteRequest); i { case 0: return &v.state case 1: @@ -11749,7 +12282,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[104].Exporter = func(v any, i int) any { - switch v := v.(*AnalyzedVariable); i { + switch v := v.(*CompleteResponse); i { case 0: return &v.state case 1: @@ -11761,7 +12294,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[105].Exporter = func(v any, i int) any { - switch v := v.(*ListGitCommitsRequest); i { + switch v := v.(*CompleteStreamingRequest); i { case 0: return &v.state case 1: @@ -11773,7 +12306,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[106].Exporter = func(v any, i int) any { - switch v := v.(*ListGitCommitsResponse); i { + switch v := v.(*CompleteStreamingResponse); i { case 0: return &v.state case 1: @@ -11785,7 +12318,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[107].Exporter = func(v any, i int) any { - switch v := v.(*GitCommit); i { + switch v := v.(*IssueDevJWTRequest); i { case 0: return &v.state case 1: @@ -11797,7 +12330,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[108].Exporter = func(v any, i int) any { - switch v := v.(*GitStatusRequest); i { + switch v := v.(*IssueDevJWTResponse); i { case 0: return &v.state case 1: @@ -11809,7 +12342,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[109].Exporter = func(v any, i int) any { - switch v := v.(*GitStatusResponse); i { + switch v := v.(*AnalyzeVariablesRequest); i { case 0: return &v.state case 1: @@ -11821,7 +12354,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[110].Exporter = func(v any, i int) any { - switch v := v.(*ListGitBranchesRequest); i { + switch v := v.(*AnalyzeVariablesResponse); i { case 0: return &v.state case 1: @@ -11833,7 +12366,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[111].Exporter = func(v any, i int) any { - switch v := v.(*ListGitBranchesResponse); i { + switch v := v.(*AnalyzedVariable); i { case 0: return &v.state case 1: @@ -11845,7 +12378,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[112].Exporter = func(v any, i int) any { - switch v := v.(*GitBranch); i { + switch v := v.(*ListGitCommitsRequest); i { case 0: return &v.state case 1: @@ -11857,7 +12390,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[113].Exporter = func(v any, i int) any { - switch v := v.(*GitCommitRequest); i { + switch v := v.(*ListGitCommitsResponse); i { case 0: return &v.state case 1: @@ -11869,7 +12402,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[114].Exporter = func(v any, i int) any { - switch v := v.(*GitCommitResponse); i { + switch v := v.(*GitCommit); i { case 0: return &v.state case 1: @@ -11881,7 +12414,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[115].Exporter = func(v any, i int) any { - switch v := v.(*RestoreGitCommitRequest); i { + switch v := v.(*GitStatusRequest); i { case 0: return &v.state case 1: @@ -11893,7 +12426,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[116].Exporter = func(v any, i int) any { - switch v := v.(*RestoreGitCommitResponse); i { + switch v := v.(*GitStatusResponse); i { case 0: return &v.state case 1: @@ -11905,7 +12438,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[117].Exporter = func(v any, i int) any { - switch v := v.(*GitMergeToBranchRequest); i { + switch v := v.(*ListGitBranchesRequest); i { case 0: return &v.state case 1: @@ -11917,7 +12450,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[118].Exporter = func(v any, i int) any { - switch v := v.(*GitMergeToBranchResponse); i { + switch v := v.(*ListGitBranchesResponse); i { case 0: return &v.state case 1: @@ -11929,7 +12462,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[119].Exporter = func(v any, i int) any { - switch v := v.(*GitSwitchBranchRequest); i { + switch v := v.(*GitBranch); i { case 0: return &v.state case 1: @@ -11941,7 +12474,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[120].Exporter = func(v any, i int) any { - switch v := v.(*GitSwitchBranchResponse); i { + switch v := v.(*GitCommitRequest); i { case 0: return &v.state case 1: @@ -11953,7 +12486,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[121].Exporter = func(v any, i int) any { - switch v := v.(*GitPullRequest); i { + switch v := v.(*GitCommitResponse); i { case 0: return &v.state case 1: @@ -11965,7 +12498,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[122].Exporter = func(v any, i int) any { - switch v := v.(*GitPullResponse); i { + switch v := v.(*RestoreGitCommitRequest); i { case 0: return &v.state case 1: @@ -11977,7 +12510,7 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[123].Exporter = func(v any, i int) any { - switch v := v.(*GitPushRequest); i { + switch v := v.(*RestoreGitCommitResponse); i { case 0: return &v.state case 1: @@ -11989,6 +12522,90 @@ func file_rill_runtime_v1_api_proto_init() { } } file_rill_runtime_v1_api_proto_msgTypes[124].Exporter = func(v any, i int) any { + switch v := v.(*GitMergeToBranchRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rill_runtime_v1_api_proto_msgTypes[125].Exporter = func(v any, i int) any { + switch v := v.(*GitMergeToBranchResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rill_runtime_v1_api_proto_msgTypes[126].Exporter = func(v any, i int) any { + switch v := v.(*GitSwitchBranchRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rill_runtime_v1_api_proto_msgTypes[127].Exporter = func(v any, i int) any { + switch v := v.(*GitSwitchBranchResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rill_runtime_v1_api_proto_msgTypes[128].Exporter = func(v any, i int) any { + switch v := v.(*GitPullRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rill_runtime_v1_api_proto_msgTypes[129].Exporter = func(v any, i int) any { + switch v := v.(*GitPullResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rill_runtime_v1_api_proto_msgTypes[130].Exporter = func(v any, i int) any { + switch v := v.(*GitPushRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_rill_runtime_v1_api_proto_msgTypes[131].Exporter = func(v any, i int) any { switch v := v.(*GitPushResponse); i { case 0: return &v.state @@ -12000,7 +12617,7 @@ func file_rill_runtime_v1_api_proto_init() { return nil } } - file_rill_runtime_v1_api_proto_msgTypes[134].Exporter = func(v any, i int) any { + file_rill_runtime_v1_api_proto_msgTypes[142].Exporter = func(v any, i int) any { switch v := v.(*ConnectorDriver_Property); i { case 0: return &v.state @@ -12020,7 +12637,7 @@ func file_rill_runtime_v1_api_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_rill_runtime_v1_api_proto_rawDesc, NumEnums: 4, - NumMessages: 137, + NumMessages: 145, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/gen/rill/runtime/v1/api.pb.gw.go b/proto/gen/rill/runtime/v1/api.pb.gw.go index aa1b607955c..e18b49566b2 100644 --- a/proto/gen/rill/runtime/v1/api.pb.gw.go +++ b/proto/gen/rill/runtime/v1/api.pb.gw.go @@ -1304,6 +1304,102 @@ func local_request_RuntimeService_GenerateTemplate_0(ctx context.Context, marsha } +var ( + filter_RuntimeService_ListTemplates_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_RuntimeService_ListTemplates_0(ctx context.Context, marshaler runtime.Marshaler, client RuntimeServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListTemplatesRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RuntimeService_ListTemplates_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListTemplates(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RuntimeService_ListTemplates_0(ctx context.Context, marshaler runtime.Marshaler, server RuntimeServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListTemplatesRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_RuntimeService_ListTemplates_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListTemplates(ctx, &protoReq) + return msg, metadata, err + +} + +func request_RuntimeService_GenerateFile_0(ctx context.Context, marshaler runtime.Marshaler, client RuntimeServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GenerateFileRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["instance_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "instance_id") + } + + protoReq.InstanceId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "instance_id", err) + } + + msg, err := client.GenerateFile(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_RuntimeService_GenerateFile_0(ctx context.Context, marshaler runtime.Marshaler, server RuntimeServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq GenerateFileRequest + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["instance_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "instance_id") + } + + protoReq.InstanceId, err = runtime.String(val) + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "instance_id", err) + } + + msg, err := server.GenerateFile(ctx, &protoReq) + return msg, metadata, err + +} + func request_RuntimeService_QueryResolver_0(ctx context.Context, marshaler runtime.Marshaler, client RuntimeServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QueryResolverRequest var metadata runtime.ServerMetadata @@ -3679,6 +3775,56 @@ func RegisterRuntimeServiceHandlerServer(ctx context.Context, mux *runtime.Serve }) + mux.Handle("GET", pattern_RuntimeService_ListTemplates_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/rill.runtime.v1.RuntimeService/ListTemplates", runtime.WithHTTPPathPattern("/v1/templates")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RuntimeService_ListTemplates_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_RuntimeService_ListTemplates_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RuntimeService_GenerateFile_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/rill.runtime.v1.RuntimeService/GenerateFile", runtime.WithHTTPPathPattern("/v1/instances/{instance_id}/generate/file")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_RuntimeService_GenerateFile_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_RuntimeService_GenerateFile_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_RuntimeService_QueryResolver_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -4944,6 +5090,50 @@ func RegisterRuntimeServiceHandlerClient(ctx context.Context, mux *runtime.Serve }) + mux.Handle("GET", pattern_RuntimeService_ListTemplates_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/rill.runtime.v1.RuntimeService/ListTemplates", runtime.WithHTTPPathPattern("/v1/templates")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RuntimeService_ListTemplates_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_RuntimeService_ListTemplates_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_RuntimeService_GenerateFile_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/rill.runtime.v1.RuntimeService/GenerateFile", runtime.WithHTTPPathPattern("/v1/instances/{instance_id}/generate/file")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_RuntimeService_GenerateFile_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_RuntimeService_GenerateFile_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("POST", pattern_RuntimeService_QueryResolver_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -5656,6 +5846,10 @@ var ( pattern_RuntimeService_GenerateTemplate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 2, 4}, []string{"v1", "instances", "instance_id", "generate", "template"}, "")) + pattern_RuntimeService_ListTemplates_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "templates"}, "")) + + pattern_RuntimeService_GenerateFile_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 2, 4}, []string{"v1", "instances", "instance_id", "generate", "file"}, "")) + pattern_RuntimeService_QueryResolver_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3, 2, 4}, []string{"v1", "instances", "instance_id", "query", "resolver"}, "")) pattern_RuntimeService_GetLogs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"v1", "instances", "instance_id", "logs"}, "")) @@ -5766,6 +5960,10 @@ var ( forward_RuntimeService_GenerateTemplate_0 = runtime.ForwardResponseMessage + forward_RuntimeService_ListTemplates_0 = runtime.ForwardResponseMessage + + forward_RuntimeService_GenerateFile_0 = runtime.ForwardResponseMessage + forward_RuntimeService_QueryResolver_0 = runtime.ForwardResponseMessage forward_RuntimeService_GetLogs_0 = runtime.ForwardResponseMessage diff --git a/proto/gen/rill/runtime/v1/api.pb.validate.go b/proto/gen/rill/runtime/v1/api.pb.validate.go index 675999a8149..1dbe6f8b8ce 100644 --- a/proto/gen/rill/runtime/v1/api.pb.validate.go +++ b/proto/gen/rill/runtime/v1/api.pb.validate.go @@ -6671,6 +6671,891 @@ var _ interface { ErrorName() string } = GenerateTemplateResponseValidationError{} +// Validate checks the field values on Template with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *Template) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on Template with the rules defined in +// the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in TemplateMultiError, or nil +// if none found. +func (m *Template) ValidateAll() error { + return m.validate(true) +} + +func (m *Template) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Name + + // no validation rules for DisplayName + + // no validation rules for Driver + + // no validation rules for Olap + + for idx, item := range m.GetFiles() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, TemplateValidationError{ + field: fmt.Sprintf("Files[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, TemplateValidationError{ + field: fmt.Sprintf("Files[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return TemplateValidationError{ + field: fmt.Sprintf("Files[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return TemplateMultiError(errors) + } + + return nil +} + +// TemplateMultiError is an error wrapping multiple validation errors returned +// by Template.ValidateAll() if the designated constraints aren't met. +type TemplateMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m TemplateMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m TemplateMultiError) AllErrors() []error { return m } + +// TemplateValidationError is the validation error returned by +// Template.Validate if the designated constraints aren't met. +type TemplateValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e TemplateValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e TemplateValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e TemplateValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e TemplateValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e TemplateValidationError) ErrorName() string { return "TemplateValidationError" } + +// Error satisfies the builtin error interface +func (e TemplateValidationError) 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 %sTemplate.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = TemplateValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = TemplateValidationError{} + +// Validate checks the field values on TemplateFile with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *TemplateFile) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on TemplateFile with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in TemplateFileMultiError, or +// nil if none found. +func (m *TemplateFile) ValidateAll() error { + return m.validate(true) +} + +func (m *TemplateFile) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Name + + // no validation rules for PathPattern + + if len(errors) > 0 { + return TemplateFileMultiError(errors) + } + + return nil +} + +// TemplateFileMultiError is an error wrapping multiple validation errors +// returned by TemplateFile.ValidateAll() if the designated constraints aren't met. +type TemplateFileMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m TemplateFileMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m TemplateFileMultiError) AllErrors() []error { return m } + +// TemplateFileValidationError is the validation error returned by +// TemplateFile.Validate if the designated constraints aren't met. +type TemplateFileValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e TemplateFileValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e TemplateFileValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e TemplateFileValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e TemplateFileValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e TemplateFileValidationError) ErrorName() string { return "TemplateFileValidationError" } + +// Error satisfies the builtin error interface +func (e TemplateFileValidationError) 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 %sTemplateFile.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = TemplateFileValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = TemplateFileValidationError{} + +// Validate checks the field values on ListTemplatesRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ListTemplatesRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListTemplatesRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListTemplatesRequestMultiError, or nil if none found. +func (m *ListTemplatesRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *ListTemplatesRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if len(errors) > 0 { + return ListTemplatesRequestMultiError(errors) + } + + return nil +} + +// ListTemplatesRequestMultiError is an error wrapping multiple validation +// errors returned by ListTemplatesRequest.ValidateAll() if the designated +// constraints aren't met. +type ListTemplatesRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListTemplatesRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListTemplatesRequestMultiError) AllErrors() []error { return m } + +// ListTemplatesRequestValidationError is the validation error returned by +// ListTemplatesRequest.Validate if the designated constraints aren't met. +type ListTemplatesRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListTemplatesRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListTemplatesRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListTemplatesRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListTemplatesRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListTemplatesRequestValidationError) ErrorName() string { + return "ListTemplatesRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e ListTemplatesRequestValidationError) 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 %sListTemplatesRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListTemplatesRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListTemplatesRequestValidationError{} + +// Validate checks the field values on ListTemplatesResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *ListTemplatesResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on ListTemplatesResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// ListTemplatesResponseMultiError, or nil if none found. +func (m *ListTemplatesResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *ListTemplatesResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + for idx, item := range m.GetTemplates() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ListTemplatesResponseValidationError{ + field: fmt.Sprintf("Templates[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ListTemplatesResponseValidationError{ + field: fmt.Sprintf("Templates[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ListTemplatesResponseValidationError{ + field: fmt.Sprintf("Templates[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if len(errors) > 0 { + return ListTemplatesResponseMultiError(errors) + } + + return nil +} + +// ListTemplatesResponseMultiError is an error wrapping multiple validation +// errors returned by ListTemplatesResponse.ValidateAll() if the designated +// constraints aren't met. +type ListTemplatesResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m ListTemplatesResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m ListTemplatesResponseMultiError) AllErrors() []error { return m } + +// ListTemplatesResponseValidationError is the validation error returned by +// ListTemplatesResponse.Validate if the designated constraints aren't met. +type ListTemplatesResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ListTemplatesResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ListTemplatesResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ListTemplatesResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ListTemplatesResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ListTemplatesResponseValidationError) ErrorName() string { + return "ListTemplatesResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e ListTemplatesResponseValidationError) 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 %sListTemplatesResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ListTemplatesResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ListTemplatesResponseValidationError{} + +// Validate checks the field values on GenerateFileRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GenerateFileRequest) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GenerateFileRequest with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GenerateFileRequestMultiError, or nil if none found. +func (m *GenerateFileRequest) ValidateAll() error { + return m.validate(true) +} + +func (m *GenerateFileRequest) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if !_GenerateFileRequest_InstanceId_Pattern.MatchString(m.GetInstanceId()) { + err := GenerateFileRequestValidationError{ + field: "InstanceId", + reason: "value does not match regex pattern \"^[_\\\\-a-zA-Z0-9]+$\"", + } + if !all { + return err + } + errors = append(errors, err) + } + + if utf8.RuneCountInString(m.GetTemplateName()) < 1 { + err := GenerateFileRequestValidationError{ + field: "TemplateName", + reason: "value length must be at least 1 runes", + } + if !all { + return err + } + errors = append(errors, err) + } + + // no validation rules for Output + + if all { + switch v := interface{}(m.GetProperties()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GenerateFileRequestValidationError{ + field: "Properties", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GenerateFileRequestValidationError{ + field: "Properties", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetProperties()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GenerateFileRequestValidationError{ + field: "Properties", + reason: "embedded message failed validation", + cause: err, + } + } + } + + // no validation rules for ConnectorName + + // no validation rules for Preview + + if len(errors) > 0 { + return GenerateFileRequestMultiError(errors) + } + + return nil +} + +// GenerateFileRequestMultiError is an error wrapping multiple validation +// errors returned by GenerateFileRequest.ValidateAll() if the designated +// constraints aren't met. +type GenerateFileRequestMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GenerateFileRequestMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GenerateFileRequestMultiError) AllErrors() []error { return m } + +// GenerateFileRequestValidationError is the validation error returned by +// GenerateFileRequest.Validate if the designated constraints aren't met. +type GenerateFileRequestValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GenerateFileRequestValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GenerateFileRequestValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GenerateFileRequestValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GenerateFileRequestValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GenerateFileRequestValidationError) ErrorName() string { + return "GenerateFileRequestValidationError" +} + +// Error satisfies the builtin error interface +func (e GenerateFileRequestValidationError) 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 %sGenerateFileRequest.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GenerateFileRequestValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GenerateFileRequestValidationError{} + +var _GenerateFileRequest_InstanceId_Pattern = regexp.MustCompile("^[_\\-a-zA-Z0-9]+$") + +// Validate checks the field values on GenerateFileResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the first error encountered is returned, or nil if there are no violations. +func (m *GenerateFileResponse) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GenerateFileResponse with the rules +// defined in the proto definition for this message. If any rules are +// violated, the result is a list of violation errors wrapped in +// GenerateFileResponseMultiError, or nil if none found. +func (m *GenerateFileResponse) ValidateAll() error { + return m.validate(true) +} + +func (m *GenerateFileResponse) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + for idx, item := range m.GetFiles() { + _, _ = idx, item + + if all { + switch v := interface{}(item).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, GenerateFileResponseValidationError{ + field: fmt.Sprintf("Files[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, GenerateFileResponseValidationError{ + field: fmt.Sprintf("Files[%v]", idx), + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return GenerateFileResponseValidationError{ + field: fmt.Sprintf("Files[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + // no validation rules for EnvVars + + if len(errors) > 0 { + return GenerateFileResponseMultiError(errors) + } + + return nil +} + +// GenerateFileResponseMultiError is an error wrapping multiple validation +// errors returned by GenerateFileResponse.ValidateAll() if the designated +// constraints aren't met. +type GenerateFileResponseMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GenerateFileResponseMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GenerateFileResponseMultiError) AllErrors() []error { return m } + +// GenerateFileResponseValidationError is the validation error returned by +// GenerateFileResponse.Validate if the designated constraints aren't met. +type GenerateFileResponseValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GenerateFileResponseValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GenerateFileResponseValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GenerateFileResponseValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GenerateFileResponseValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GenerateFileResponseValidationError) ErrorName() string { + return "GenerateFileResponseValidationError" +} + +// Error satisfies the builtin error interface +func (e GenerateFileResponseValidationError) 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 %sGenerateFileResponse.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GenerateFileResponseValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GenerateFileResponseValidationError{} + +// Validate checks the field values on GeneratedFile with the rules defined in +// the proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *GeneratedFile) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on GeneratedFile with the rules defined +// in the proto definition for this message. If any rules are violated, the +// result is a list of violation errors wrapped in GeneratedFileMultiError, or +// nil if none found. +func (m *GeneratedFile) ValidateAll() error { + return m.validate(true) +} + +func (m *GeneratedFile) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + // no validation rules for Path + + // no validation rules for Blob + + if len(errors) > 0 { + return GeneratedFileMultiError(errors) + } + + return nil +} + +// GeneratedFileMultiError is an error wrapping multiple validation errors +// returned by GeneratedFile.ValidateAll() if the designated constraints +// aren't met. +type GeneratedFileMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m GeneratedFileMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m GeneratedFileMultiError) AllErrors() []error { return m } + +// GeneratedFileValidationError is the validation error returned by +// GeneratedFile.Validate if the designated constraints aren't met. +type GeneratedFileValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GeneratedFileValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GeneratedFileValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GeneratedFileValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GeneratedFileValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GeneratedFileValidationError) ErrorName() string { return "GeneratedFileValidationError" } + +// Error satisfies the builtin error interface +func (e GeneratedFileValidationError) 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 %sGeneratedFile.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GeneratedFileValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GeneratedFileValidationError{} + // Validate checks the field values on QueryResolverRequest with the rules // defined in the proto definition for this message. If any rules are // violated, the first error encountered is returned, or nil if there are no violations. diff --git a/proto/gen/rill/runtime/v1/api_grpc.pb.go b/proto/gen/rill/runtime/v1/api_grpc.pb.go index ea3fda78d06..3c682d6de37 100644 --- a/proto/gen/rill/runtime/v1/api_grpc.pb.go +++ b/proto/gen/rill/runtime/v1/api_grpc.pb.go @@ -43,6 +43,8 @@ const ( RuntimeService_GenerateResolver_FullMethodName = "/rill.runtime.v1.RuntimeService/GenerateResolver" RuntimeService_GenerateRenderer_FullMethodName = "/rill.runtime.v1.RuntimeService/GenerateRenderer" RuntimeService_GenerateTemplate_FullMethodName = "/rill.runtime.v1.RuntimeService/GenerateTemplate" + RuntimeService_ListTemplates_FullMethodName = "/rill.runtime.v1.RuntimeService/ListTemplates" + RuntimeService_GenerateFile_FullMethodName = "/rill.runtime.v1.RuntimeService/GenerateFile" RuntimeService_QueryResolver_FullMethodName = "/rill.runtime.v1.RuntimeService/QueryResolver" RuntimeService_GetLogs_FullMethodName = "/rill.runtime.v1.RuntimeService/GetLogs" RuntimeService_WatchLogs_FullMethodName = "/rill.runtime.v1.RuntimeService/WatchLogs" @@ -132,6 +134,10 @@ type RuntimeServiceClient interface { GenerateRenderer(ctx context.Context, in *GenerateRendererRequest, opts ...grpc.CallOption) (*GenerateRendererResponse, error) // GenerateTemplate generates a connector or model YAML file from structured form data GenerateTemplate(ctx context.Context, in *GenerateTemplateRequest, opts ...grpc.CallOption) (*GenerateTemplateResponse, error) + // ListTemplates returns available template definitions for generating project files + ListTemplates(ctx context.Context, in *ListTemplatesRequest, opts ...grpc.CallOption) (*ListTemplatesResponse, error) + // GenerateFile renders a template with properties and optionally writes the resulting files + GenerateFile(ctx context.Context, in *GenerateFileRequest, opts ...grpc.CallOption) (*GenerateFileResponse, error) // QueryResolver queries a resolver with the given properties and arguments QueryResolver(ctx context.Context, in *QueryResolverRequest, opts ...grpc.CallOption) (*QueryResolverResponse, error) // GetLogs returns recent logs from a controller @@ -459,6 +465,26 @@ func (c *runtimeServiceClient) GenerateTemplate(ctx context.Context, in *Generat return out, nil } +func (c *runtimeServiceClient) ListTemplates(ctx context.Context, in *ListTemplatesRequest, opts ...grpc.CallOption) (*ListTemplatesResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListTemplatesResponse) + err := c.cc.Invoke(ctx, RuntimeService_ListTemplates_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *runtimeServiceClient) GenerateFile(ctx context.Context, in *GenerateFileRequest, opts ...grpc.CallOption) (*GenerateFileResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GenerateFileResponse) + err := c.cc.Invoke(ctx, RuntimeService_GenerateFile_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *runtimeServiceClient) QueryResolver(ctx context.Context, in *QueryResolverRequest, opts ...grpc.CallOption) (*QueryResolverResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(QueryResolverResponse) @@ -843,6 +869,10 @@ type RuntimeServiceServer interface { GenerateRenderer(context.Context, *GenerateRendererRequest) (*GenerateRendererResponse, error) // GenerateTemplate generates a connector or model YAML file from structured form data GenerateTemplate(context.Context, *GenerateTemplateRequest) (*GenerateTemplateResponse, error) + // ListTemplates returns available template definitions for generating project files + ListTemplates(context.Context, *ListTemplatesRequest) (*ListTemplatesResponse, error) + // GenerateFile renders a template with properties and optionally writes the resulting files + GenerateFile(context.Context, *GenerateFileRequest) (*GenerateFileResponse, error) // QueryResolver queries a resolver with the given properties and arguments QueryResolver(context.Context, *QueryResolverRequest) (*QueryResolverResponse, error) // GetLogs returns recent logs from a controller @@ -993,6 +1023,12 @@ func (UnimplementedRuntimeServiceServer) GenerateRenderer(context.Context, *Gene func (UnimplementedRuntimeServiceServer) GenerateTemplate(context.Context, *GenerateTemplateRequest) (*GenerateTemplateResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GenerateTemplate not implemented") } +func (UnimplementedRuntimeServiceServer) ListTemplates(context.Context, *ListTemplatesRequest) (*ListTemplatesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListTemplates not implemented") +} +func (UnimplementedRuntimeServiceServer) GenerateFile(context.Context, *GenerateFileRequest) (*GenerateFileResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GenerateFile not implemented") +} func (UnimplementedRuntimeServiceServer) QueryResolver(context.Context, *QueryResolverRequest) (*QueryResolverResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryResolver not implemented") } @@ -1529,6 +1565,42 @@ func _RuntimeService_GenerateTemplate_Handler(srv interface{}, ctx context.Conte return interceptor(ctx, in, info, handler) } +func _RuntimeService_ListTemplates_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListTemplatesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RuntimeServiceServer).ListTemplates(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: RuntimeService_ListTemplates_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RuntimeServiceServer).ListTemplates(ctx, req.(*ListTemplatesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _RuntimeService_GenerateFile_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GenerateFileRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RuntimeServiceServer).GenerateFile(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: RuntimeService_GenerateFile_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RuntimeServiceServer).GenerateFile(ctx, req.(*GenerateFileRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _RuntimeService_QueryResolver_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryResolverRequest) if err := dec(in); err != nil { @@ -2147,6 +2219,14 @@ var RuntimeService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GenerateTemplate", Handler: _RuntimeService_GenerateTemplate_Handler, }, + { + MethodName: "ListTemplates", + Handler: _RuntimeService_ListTemplates_Handler, + }, + { + MethodName: "GenerateFile", + Handler: _RuntimeService_GenerateFile_Handler, + }, { MethodName: "QueryResolver", Handler: _RuntimeService_QueryResolver_Handler, diff --git a/proto/gen/rill/runtime/v1/runtime.swagger.yaml b/proto/gen/rill/runtime/v1/runtime.swagger.yaml index f03f3ea0dd0..45475a0c06e 100644 --- a/proto/gen/rill/runtime/v1/runtime.swagger.yaml +++ b/proto/gen/rill/runtime/v1/runtime.swagger.yaml @@ -1129,6 +1129,46 @@ paths: type: boolean tags: - RuntimeService + /v1/instances/{instanceId}/generate/file: + post: + summary: GenerateFile renders a template with properties and optionally writes the resulting files + operationId: RuntimeService_GenerateFile + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/v1GenerateFileResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpcStatus' + parameters: + - name: instanceId + in: path + required: true + type: string + - name: body + in: body + required: true + schema: + type: object + properties: + templateName: + type: string + title: Template name (e.g. "s3", "s3-duckdb", "iceberg-duckdb") + output: + type: string + title: 'Output filter: "connector", "model", or empty for all files' + properties: + type: object + connectorName: + type: string + title: Connector name reference (for model outputs that reference a connector) + preview: + type: boolean + title: If true, render without writing files (for YAML preview) + tags: + - RuntimeService /v1/instances/{instanceId}/generate/renderer: post: summary: GenerateRenderer generates a component renderer and renderer properties from a resolver and resolver properties @@ -3600,6 +3640,30 @@ paths: $ref: '#/definitions/rpcStatus' tags: - RuntimeService + /v1/templates: + get: + summary: ListTemplates returns available template definitions for generating project files + operationId: RuntimeService_ListTemplates + responses: + "200": + description: A successful response. + schema: + $ref: '#/definitions/v1ListTemplatesResponse' + default: + description: An unexpected error response. + schema: + $ref: '#/definitions/rpcStatus' + parameters: + - name: tags + description: Optional tag filter; only templates matching ALL tags are returned. + in: query + required: false + type: array + items: + type: string + collectionFormat: multi + tags: + - RuntimeService definitions: ColumnTimeSeriesRequestBasicMeasure: type: object @@ -5338,6 +5402,18 @@ definitions: type: boolean description: Indicates if AI-based generation succeeded. If it failed, it falls back to the simpler heuristic approach. title: Response message for RuntimeService.GenerateCanvasFile + v1GenerateFileResponse: + type: object + properties: + files: + type: array + items: + type: object + $ref: '#/definitions/v1GeneratedFile' + envVars: + type: object + additionalProperties: + type: string v1GenerateMetricsViewFileResponse: type: object properties: @@ -5374,6 +5450,14 @@ definitions: driver: type: string title: Actual driver used; may differ from request when rewritten to duckdb + v1GeneratedFile: + type: object + properties: + path: + type: string + blob: + type: string + description: GeneratedFile is a single rendered output file. v1GetConversationResponse: type: object properties: @@ -5764,6 +5848,14 @@ definitions: $ref: '#/definitions/v1TableInfo' nextPageToken: type: string + v1ListTemplatesResponse: + type: object + properties: + templates: + type: array + items: + type: object + $ref: '#/definitions/v1Template' v1ListToolsResponse: type: object properties: @@ -7742,6 +7834,35 @@ definitions: type: array items: type: object + v1Template: + type: object + properties: + name: + type: string + displayName: + type: string + driver: + type: string + olap: + type: string + tags: + type: array + items: + type: string + files: + type: array + items: + type: object + $ref: '#/definitions/v1TemplateFile' + description: Template describes a declarative template for generating project files. + v1TemplateFile: + type: object + properties: + name: + type: string + pathPattern: + type: string + description: TemplateFile describes a single output file within a template. v1Theme: type: object properties: diff --git a/proto/rill/runtime/v1/api.proto b/proto/rill/runtime/v1/api.proto index 7bb2e88c758..cf74978c700 100644 --- a/proto/rill/runtime/v1/api.proto +++ b/proto/rill/runtime/v1/api.proto @@ -181,6 +181,19 @@ service RuntimeService { }; } + // ListTemplates returns available template definitions for generating project files + rpc ListTemplates(ListTemplatesRequest) returns (ListTemplatesResponse) { + option (google.api.http) = {get: "/v1/templates"}; + } + + // GenerateFile renders a template with properties and optionally writes the resulting files + rpc GenerateFile(GenerateFileRequest) returns (GenerateFileResponse) { + option (google.api.http) = { + post: "/v1/instances/{instance_id}/generate/file", + body: "*" + }; + } + // QueryResolver queries a resolver with the given properties and arguments rpc QueryResolver(QueryResolverRequest) returns (QueryResolverResponse) { option (google.api.http) = { @@ -783,6 +796,55 @@ message GenerateTemplateResponse { string driver = 4; } +// Template describes a declarative template for generating project files. +message Template { + string name = 1; + string display_name = 2; + string driver = 3; + string olap = 4; + repeated string tags = 5; + repeated TemplateFile files = 6; +} + +// TemplateFile describes a single output file within a template. +message TemplateFile { + string name = 1; + string path_pattern = 2; +} + +message ListTemplatesRequest { + // Optional tag filter; only templates matching ALL tags are returned. + repeated string tags = 1; +} + +message ListTemplatesResponse { + repeated Template templates = 1; +} + +message GenerateFileRequest { + string instance_id = 1 [(validate.rules).string = {pattern: "^[_\\-a-zA-Z0-9]+$"}]; + // Template name (e.g. "s3", "s3-duckdb", "iceberg-duckdb") + string template_name = 2 [(validate.rules).string.min_len = 1]; + // Output filter: "connector", "model", or empty for all files + string output = 3; + google.protobuf.Struct properties = 4; + // Connector name reference (for model outputs that reference a connector) + string connector_name = 5; + // If true, render without writing files (for YAML preview) + bool preview = 6; +} + +message GenerateFileResponse { + repeated GeneratedFile files = 1; + map env_vars = 2; +} + +// GeneratedFile is a single rendered output file. +message GeneratedFile { + string path = 1; + string blob = 2; +} + message QueryResolverRequest { string instance_id = 1; string resolver = 2; diff --git a/runtime/server/server.go b/runtime/server/server.go index 5bb0e2f7c29..fe30a1e53b9 100644 --- a/runtime/server/server.go +++ b/runtime/server/server.go @@ -27,6 +27,7 @@ import ( "github.com/rilldata/rill/runtime/pkg/securetoken" "github.com/rilldata/rill/runtime/queries" "github.com/rilldata/rill/runtime/server/auth" + "github.com/rilldata/rill/runtime/templates" "github.com/rs/cors" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" "go.uber.org/zap" @@ -55,14 +56,15 @@ type Server struct { runtimev1.UnsafeRuntimeServiceServer runtimev1.UnsafeQueryServiceServer runtimev1.UnsafeConnectorServiceServer - runtime *runtime.Runtime - opts *Options - logger *zap.Logger - aud *auth.Audience - codec *securetoken.Codec - limiter ratelimit.Limiter - activity *activity.Client - ai *ai.Runner + runtime *runtime.Runtime + opts *Options + logger *zap.Logger + aud *auth.Audience + codec *securetoken.Codec + limiter ratelimit.Limiter + activity *activity.Client + ai *ai.Runner + templateRegistry *templates.Registry // set for local runtimes adminOverride drivers.AdminService } @@ -85,15 +87,21 @@ func NewServer(ctx context.Context, opts *Options, rt *runtime.Runtime, logger * codec = securetoken.NewCodec(opts.SessionKeyPairs) } + tmplRegistry, err := templates.NewRegistry() + if err != nil { + return nil, fmt.Errorf("loading template registry: %w", err) + } + srv := &Server{ - runtime: rt, - opts: opts, - logger: logger, - codec: codec, - limiter: limiter, - activity: activityClient, - ai: ai.NewRunner(rt, activityClient), - adminOverride: adminOverride, + runtime: rt, + opts: opts, + logger: logger, + codec: codec, + limiter: limiter, + activity: activityClient, + ai: ai.NewRunner(rt, activityClient), + templateRegistry: tmplRegistry, + adminOverride: adminOverride, } if opts.AuthEnable { diff --git a/runtime/server/templates.go b/runtime/server/templates.go new file mode 100644 index 00000000000..86c3d49bc5e --- /dev/null +++ b/runtime/server/templates.go @@ -0,0 +1,155 @@ +package server + +import ( + "context" + "fmt" + "strings" + + runtimev1 "github.com/rilldata/rill/proto/gen/rill/runtime/v1" + "github.com/rilldata/rill/runtime" + "github.com/rilldata/rill/runtime/drivers" + "github.com/rilldata/rill/runtime/pkg/observability" + "github.com/rilldata/rill/runtime/server/auth" + "github.com/rilldata/rill/runtime/templates" + "go.opentelemetry.io/otel/attribute" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// ListTemplates returns available template definitions, optionally filtered by tags. +func (s *Server) ListTemplates(ctx context.Context, req *runtimev1.ListTemplatesRequest) (*runtimev1.ListTemplatesResponse, error) { + tmplList := s.templateRegistry.ListByTags(req.Tags) + + pbs := make([]*runtimev1.Template, len(tmplList)) + for i, t := range tmplList { + files := make([]*runtimev1.TemplateFile, len(t.Files)) + for j, f := range t.Files { + files[j] = &runtimev1.TemplateFile{ + Name: f.Name, + PathPattern: f.PathTemplate, + } + } + pbs[i] = &runtimev1.Template{ + Name: t.Name, + DisplayName: t.DisplayName, + Driver: t.Driver, + Olap: t.OLAP, + Tags: t.Tags, + Files: files, + } + } + + return &runtimev1.ListTemplatesResponse{Templates: pbs}, nil +} + +// GenerateFile renders a template and optionally writes the resulting files. +func (s *Server) GenerateFile(ctx context.Context, req *runtimev1.GenerateFileRequest) (*runtimev1.GenerateFileResponse, error) { + observability.AddRequestAttributes(ctx, + attribute.String("args.instance_id", req.InstanceId), + attribute.String("args.template_name", req.TemplateName), + attribute.String("args.output", req.Output), + attribute.String("args.connector_name", req.ConnectorName), + attribute.Bool("args.preview", req.Preview), + ) + s.addInstanceRequestAttributes(ctx, req.InstanceId) + + if !auth.GetClaims(ctx, req.InstanceId).Can(runtime.EditRepo) { + return nil, ErrForbidden + } + + // Look up template + tmpl, ok := s.templateRegistry.Get(req.TemplateName) + if !ok { + return nil, status.Errorf(codes.InvalidArgument, "unknown template %q", req.TemplateName) + } + + // Look up driver spec (nil for driverless templates like iceberg-duckdb) + var driverSpec *drivers.Spec + if tmpl.Driver != "" { + drv, ok := drivers.Connectors[tmpl.Driver] + if !ok { + return nil, status.Errorf(codes.Internal, "template %q references unknown driver %q", req.TemplateName, tmpl.Driver) + } + spec := drv.Spec() + driverSpec = &spec + } + + // Convert properties + var props map[string]any + if req.Properties != nil { + props = req.Properties.AsMap() + } else { + props = make(map[string]any) + } + + // Read existing .env for conflict resolution + existingEnv := make(map[string]bool) + repo, release, err := s.runtime.Repo(ctx, req.InstanceId) + if err == nil { + existingEnv = templates.ReadEnvKeys(ctx, repo) + release() + } + + // Render + result, err := templates.Render(&templates.RenderInput{ + Template: tmpl, + Output: req.Output, + DriverSpec: driverSpec, + Properties: props, + ConnectorName: req.ConnectorName, + ExistingEnv: existingEnv, + }) + if err != nil { + return nil, status.Errorf(codes.Internal, "rendering template: %s", err) + } + + // Write files if not preview mode + if !req.Preview { + repo, release, err := s.runtime.Repo(ctx, req.InstanceId) + if err != nil { + return nil, status.Errorf(codes.Internal, "opening repo: %s", err) + } + defer release() + + // Write rendered files + for _, f := range result.Files { + if err := repo.Put(ctx, f.Path, strings.NewReader(f.Blob)); err != nil { + return nil, status.Errorf(codes.Internal, "writing file %q: %s", f.Path, err) + } + } + + // Merge env vars into .env + if len(result.EnvVars) > 0 { + envContent, _ := repo.Get(ctx, ".env") + for key, val := range result.EnvVars { + envContent = appendEnvVar(envContent, key, val) + } + if err := repo.Put(ctx, ".env", strings.NewReader(envContent)); err != nil { + return nil, status.Errorf(codes.Internal, "writing .env: %s", err) + } + } + } + + // Build response + pbFiles := make([]*runtimev1.GeneratedFile, len(result.Files)) + for i, f := range result.Files { + pbFiles[i] = &runtimev1.GeneratedFile{ + Path: f.Path, + Blob: f.Blob, + } + } + + return &runtimev1.GenerateFileResponse{ + Files: pbFiles, + EnvVars: result.EnvVars, + }, nil +} + +// appendEnvVar appends or updates an env var in .env content. +func appendEnvVar(content, key, value string) string { + // Simple append; the frontend already handles deduplication + if content != "" && content[len(content)-1] != '\n' { + content += "\n" + } + return fmt.Sprintf("%s%s=%s\n", content, key, value) +} diff --git a/runtime/templates/definitions/athena-model.yaml b/runtime/templates/definitions/athena-model.yaml new file mode 100644 index 00000000000..7e88b2c863a --- /dev/null +++ b/runtime/templates/definitions/athena-model.yaml @@ -0,0 +1,23 @@ +name: athena-model +display_name: "Amazon Athena" +driver: athena +tags: ["athena", "aws", "warehouse", "source", "model"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/athena + type: model + [[ if .connector_name -]] + connector: "[[ .connector_name ]]" + [[ end -]] + materialize: true + [[ renderProps .source_props -]] + [[ if .sql -]] + sql: | + [[ .sql | indent 2 ]] + [[ end -]] + dev: + sql: | + select * from {{ ref "self" }} limit 10000 diff --git a/runtime/templates/definitions/athena.yaml b/runtime/templates/definitions/athena.yaml new file mode 100644 index 00000000000..972f08ecbc6 --- /dev/null +++ b/runtime/templates/definitions/athena.yaml @@ -0,0 +1,13 @@ +name: athena +display_name: "Amazon Athena" +driver: athena +tags: ["athena", "aws", "warehouse", "source", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/athena + type: connector + driver: athena + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/azure-duckdb.yaml b/runtime/templates/definitions/azure-duckdb.yaml new file mode 100644 index 00000000000..081995c1c8c --- /dev/null +++ b/runtime/templates/definitions/azure-duckdb.yaml @@ -0,0 +1,18 @@ +name: azure-duckdb +display_name: "Azure (DuckDB)" +driver: azure +olap: duckdb +tags: ["azure", "microsoft", "object-storage", "duckdb", "source"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/azure + type: model + connector: duckdb + [[ if .create_secrets_from_connectors -]] + create_secrets_from_connectors: "[[ .create_secrets_from_connectors ]]" + [[ end -]] + sql: | + [[ .sql ]] diff --git a/runtime/templates/definitions/azure.yaml b/runtime/templates/definitions/azure.yaml new file mode 100644 index 00000000000..e7ed450ffcb --- /dev/null +++ b/runtime/templates/definitions/azure.yaml @@ -0,0 +1,13 @@ +name: azure +display_name: "Azure Blob Storage" +driver: azure +tags: ["azure", "microsoft", "object-storage", "source", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/azure + type: connector + driver: azure + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/bigquery-model.yaml b/runtime/templates/definitions/bigquery-model.yaml new file mode 100644 index 00000000000..de82f119524 --- /dev/null +++ b/runtime/templates/definitions/bigquery-model.yaml @@ -0,0 +1,23 @@ +name: bigquery-model +display_name: "BigQuery" +driver: bigquery +tags: ["bigquery", "google", "warehouse", "source", "model"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/bigquery + type: model + [[ if .connector_name -]] + connector: "[[ .connector_name ]]" + [[ end -]] + materialize: true + [[ renderProps .source_props -]] + [[ if .sql -]] + sql: | + [[ .sql | indent 2 ]] + [[ end -]] + dev: + sql: | + select * from {{ ref "self" }} limit 10000 diff --git a/runtime/templates/definitions/bigquery.yaml b/runtime/templates/definitions/bigquery.yaml new file mode 100644 index 00000000000..dbead446375 --- /dev/null +++ b/runtime/templates/definitions/bigquery.yaml @@ -0,0 +1,13 @@ +name: bigquery +display_name: "BigQuery" +driver: bigquery +tags: ["bigquery", "google", "warehouse", "source", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/bigquery + type: connector + driver: bigquery + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/clickhouse-model.yaml b/runtime/templates/definitions/clickhouse-model.yaml new file mode 100644 index 00000000000..65f86543783 --- /dev/null +++ b/runtime/templates/definitions/clickhouse-model.yaml @@ -0,0 +1,23 @@ +name: clickhouse-model +display_name: "ClickHouse" +driver: clickhouse +tags: ["clickhouse", "olap", "source", "model"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/olap/clickhouse + type: model + [[ if .connector_name -]] + connector: "[[ .connector_name ]]" + [[ end -]] + materialize: true + [[ renderProps .source_props -]] + [[ if .sql -]] + sql: | + [[ .sql | indent 2 ]] + [[ end -]] + dev: + sql: | + select * from {{ ref "self" }} limit 10000 diff --git a/runtime/templates/definitions/clickhouse.yaml b/runtime/templates/definitions/clickhouse.yaml new file mode 100644 index 00000000000..a6c111ae654 --- /dev/null +++ b/runtime/templates/definitions/clickhouse.yaml @@ -0,0 +1,13 @@ +name: clickhouse +display_name: "ClickHouse" +driver: clickhouse +tags: ["clickhouse", "olap", "analytics", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/olap/clickhouse + type: connector + driver: clickhouse + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/druid.yaml b/runtime/templates/definitions/druid.yaml new file mode 100644 index 00000000000..195500f3214 --- /dev/null +++ b/runtime/templates/definitions/druid.yaml @@ -0,0 +1,13 @@ +name: druid +display_name: "Druid" +driver: druid +tags: ["druid", "olap", "analytics", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/olap/druid + type: connector + driver: druid + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/duckdb.yaml b/runtime/templates/definitions/duckdb.yaml new file mode 100644 index 00000000000..b62690fbcfb --- /dev/null +++ b/runtime/templates/definitions/duckdb.yaml @@ -0,0 +1,13 @@ +name: duckdb +display_name: "DuckDB" +driver: duckdb +tags: ["duckdb", "olap", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/olap/duckdb + type: connector + driver: duckdb + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/gcs-duckdb.yaml b/runtime/templates/definitions/gcs-duckdb.yaml new file mode 100644 index 00000000000..4f8b5fcf534 --- /dev/null +++ b/runtime/templates/definitions/gcs-duckdb.yaml @@ -0,0 +1,18 @@ +name: gcs-duckdb +display_name: "GCS (DuckDB)" +driver: gcs +olap: duckdb +tags: ["gcs", "google", "object-storage", "duckdb", "source"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/gcs + type: model + connector: duckdb + [[ if .create_secrets_from_connectors -]] + create_secrets_from_connectors: "[[ .create_secrets_from_connectors ]]" + [[ end -]] + sql: | + [[ .sql ]] diff --git a/runtime/templates/definitions/gcs.yaml b/runtime/templates/definitions/gcs.yaml new file mode 100644 index 00000000000..4e6a057df3b --- /dev/null +++ b/runtime/templates/definitions/gcs.yaml @@ -0,0 +1,13 @@ +name: gcs +display_name: "Google Cloud Storage" +driver: gcs +tags: ["gcs", "google", "object-storage", "source", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/gcs + type: connector + driver: gcs + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/https-duckdb.yaml b/runtime/templates/definitions/https-duckdb.yaml new file mode 100644 index 00000000000..9e0a81c581e --- /dev/null +++ b/runtime/templates/definitions/https-duckdb.yaml @@ -0,0 +1,18 @@ +name: https-duckdb +display_name: "HTTPS (DuckDB)" +driver: https +olap: duckdb +tags: ["https", "http", "url", "file-store", "duckdb", "source"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connect/#adding-a-remote-source + type: model + connector: duckdb + [[ if .create_secrets_from_connectors -]] + create_secrets_from_connectors: "[[ .create_secrets_from_connectors ]]" + [[ end -]] + sql: | + [[ .sql ]] diff --git a/runtime/templates/definitions/https.yaml b/runtime/templates/definitions/https.yaml new file mode 100644 index 00000000000..ee75a5c6d16 --- /dev/null +++ b/runtime/templates/definitions/https.yaml @@ -0,0 +1,13 @@ +name: https +display_name: "HTTPS" +driver: https +tags: ["https", "http", "url", "file-store", "source", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connect/#adding-a-remote-source + type: connector + driver: https + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/iceberg-duckdb.yaml b/runtime/templates/definitions/iceberg-duckdb.yaml new file mode 100644 index 00000000000..76ac669f1a8 --- /dev/null +++ b/runtime/templates/definitions/iceberg-duckdb.yaml @@ -0,0 +1,26 @@ +name: iceberg-duckdb +display_name: "Iceberg (DuckDB)" +driver: "" +olap: duckdb +tags: ["iceberg", "table-format", "duckdb", "source"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + type: model + materialize: true + pre_exec: | + INSTALL ICEBERG; + LOAD ICEBERG; + CREATE SECRET IF NOT EXISTS ( + TYPE S3, + KEY_ID '[[ .aws_access_key_id ]]', + SECRET '[[ .aws_secret_access_key ]]', + REGION '[[ .aws_region ]]' + ) + sql: | + SELECT * + FROM iceberg_scan( + 's3://[[ .bucket ]]/[[ .path ]]', + allow_moved_paths = true + ); diff --git a/runtime/templates/definitions/local-file-duckdb.yaml b/runtime/templates/definitions/local-file-duckdb.yaml new file mode 100644 index 00000000000..dda2b29ed6f --- /dev/null +++ b/runtime/templates/definitions/local-file-duckdb.yaml @@ -0,0 +1,15 @@ +name: local-file-duckdb +display_name: "Local File (DuckDB)" +driver: local_file +olap: duckdb +tags: ["local-file", "file", "file-store", "duckdb", "source"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/olap/duckdb + type: model + connector: duckdb + sql: | + [[ .sql ]] diff --git a/runtime/templates/definitions/motherduck.yaml b/runtime/templates/definitions/motherduck.yaml new file mode 100644 index 00000000000..d98b39d6bdd --- /dev/null +++ b/runtime/templates/definitions/motherduck.yaml @@ -0,0 +1,13 @@ +name: motherduck +display_name: "MotherDuck" +driver: motherduck +tags: ["motherduck", "duckdb", "olap", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/olap/motherduck + type: connector + driver: motherduck + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/mysql-model.yaml b/runtime/templates/definitions/mysql-model.yaml new file mode 100644 index 00000000000..659c30079ad --- /dev/null +++ b/runtime/templates/definitions/mysql-model.yaml @@ -0,0 +1,23 @@ +name: mysql-model +display_name: "MySQL" +driver: mysql +tags: ["mysql", "database", "source", "model"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/mysql + type: model + [[ if .connector_name -]] + connector: "[[ .connector_name ]]" + [[ end -]] + materialize: true + [[ renderProps .source_props -]] + [[ if .sql -]] + sql: | + [[ .sql | indent 2 ]] + [[ end -]] + dev: + sql: | + select * from {{ ref "self" }} limit 10000 diff --git a/runtime/templates/definitions/mysql.yaml b/runtime/templates/definitions/mysql.yaml new file mode 100644 index 00000000000..41c8249330c --- /dev/null +++ b/runtime/templates/definitions/mysql.yaml @@ -0,0 +1,13 @@ +name: mysql +display_name: "MySQL" +driver: mysql +tags: ["mysql", "database", "sql-store", "source", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/mysql + type: connector + driver: mysql + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/pinot.yaml b/runtime/templates/definitions/pinot.yaml new file mode 100644 index 00000000000..e32f1e04b5a --- /dev/null +++ b/runtime/templates/definitions/pinot.yaml @@ -0,0 +1,13 @@ +name: pinot +display_name: "Pinot" +driver: pinot +tags: ["pinot", "olap", "analytics", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/olap/pinot + type: connector + driver: pinot + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/postgres-model.yaml b/runtime/templates/definitions/postgres-model.yaml new file mode 100644 index 00000000000..70ee7d51f4d --- /dev/null +++ b/runtime/templates/definitions/postgres-model.yaml @@ -0,0 +1,23 @@ +name: postgres-model +display_name: "Postgres" +driver: postgres +tags: ["postgres", "postgresql", "database", "source", "model"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/postgres + type: model + [[ if .connector_name -]] + connector: "[[ .connector_name ]]" + [[ end -]] + materialize: true + [[ renderProps .source_props -]] + [[ if .sql -]] + sql: | + [[ .sql | indent 2 ]] + [[ end -]] + dev: + sql: | + select * from {{ ref "self" }} limit 10000 diff --git a/runtime/templates/definitions/postgres.yaml b/runtime/templates/definitions/postgres.yaml new file mode 100644 index 00000000000..6b23274db4f --- /dev/null +++ b/runtime/templates/definitions/postgres.yaml @@ -0,0 +1,13 @@ +name: postgres +display_name: "Postgres" +driver: postgres +tags: ["postgres", "postgresql", "database", "sql-store", "source", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/postgres + type: connector + driver: postgres + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/redshift-model.yaml b/runtime/templates/definitions/redshift-model.yaml new file mode 100644 index 00000000000..df67fb1cf91 --- /dev/null +++ b/runtime/templates/definitions/redshift-model.yaml @@ -0,0 +1,20 @@ +name: redshift-model +display_name: "Amazon Redshift" +driver: redshift +tags: ["redshift", "aws", "warehouse", "source", "model"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/redshift + type: model + [[ if .connector_name -]] + connector: "[[ .connector_name ]]" + [[ end -]] + materialize: true + [[ renderProps .source_props -]] + [[ if .sql -]] + sql: | + [[ .sql | indent 2 ]] + [[ end ]] diff --git a/runtime/templates/definitions/redshift.yaml b/runtime/templates/definitions/redshift.yaml new file mode 100644 index 00000000000..f7cb84e0895 --- /dev/null +++ b/runtime/templates/definitions/redshift.yaml @@ -0,0 +1,13 @@ +name: redshift +display_name: "Amazon Redshift" +driver: redshift +tags: ["redshift", "aws", "warehouse", "source", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/redshift + type: connector + driver: redshift + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/s3-duckdb.yaml b/runtime/templates/definitions/s3-duckdb.yaml new file mode 100644 index 00000000000..462f6d912f1 --- /dev/null +++ b/runtime/templates/definitions/s3-duckdb.yaml @@ -0,0 +1,18 @@ +name: s3-duckdb +display_name: "S3 (DuckDB)" +driver: s3 +olap: duckdb +tags: ["s3", "aws", "object-storage", "duckdb", "source"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/s3 + type: model + connector: duckdb + [[ if .create_secrets_from_connectors -]] + create_secrets_from_connectors: "[[ .create_secrets_from_connectors ]]" + [[ end -]] + sql: | + [[ .sql ]] diff --git a/runtime/templates/definitions/s3.yaml b/runtime/templates/definitions/s3.yaml new file mode 100644 index 00000000000..fa3f349f50b --- /dev/null +++ b/runtime/templates/definitions/s3.yaml @@ -0,0 +1,13 @@ +name: s3 +display_name: "Amazon S3" +driver: s3 +tags: ["s3", "aws", "object-storage", "source", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/s3 + type: connector + driver: s3 + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/salesforce-model.yaml b/runtime/templates/definitions/salesforce-model.yaml new file mode 100644 index 00000000000..f2f7bfb06c4 --- /dev/null +++ b/runtime/templates/definitions/salesforce-model.yaml @@ -0,0 +1,23 @@ +name: salesforce-model +display_name: "Salesforce" +driver: salesforce +tags: ["salesforce", "crm", "warehouse", "source", "model"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/salesforce + type: model + [[ if .connector_name -]] + connector: "[[ .connector_name ]]" + [[ end -]] + materialize: true + [[ renderProps .source_props -]] + [[ if .sql -]] + sql: | + [[ .sql | indent 2 ]] + [[ end -]] + dev: + sql: | + select * from {{ ref "self" }} limit 10000 diff --git a/runtime/templates/definitions/salesforce.yaml b/runtime/templates/definitions/salesforce.yaml new file mode 100644 index 00000000000..c62c381a4b9 --- /dev/null +++ b/runtime/templates/definitions/salesforce.yaml @@ -0,0 +1,13 @@ +name: salesforce +display_name: "Salesforce" +driver: salesforce +tags: ["salesforce", "crm", "warehouse", "source", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/salesforce + type: connector + driver: salesforce + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/snowflake-model.yaml b/runtime/templates/definitions/snowflake-model.yaml new file mode 100644 index 00000000000..f2c10a29a7c --- /dev/null +++ b/runtime/templates/definitions/snowflake-model.yaml @@ -0,0 +1,23 @@ +name: snowflake-model +display_name: "Snowflake" +driver: snowflake +tags: ["snowflake", "warehouse", "source", "model"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/snowflake + type: model + [[ if .connector_name -]] + connector: "[[ .connector_name ]]" + [[ end -]] + materialize: true + [[ renderProps .source_props -]] + [[ if .sql -]] + sql: | + [[ .sql | indent 2 ]] + [[ end -]] + dev: + sql: | + select * from {{ ref "self" }} limit 10000 diff --git a/runtime/templates/definitions/snowflake.yaml b/runtime/templates/definitions/snowflake.yaml new file mode 100644 index 00000000000..e1cfe82c208 --- /dev/null +++ b/runtime/templates/definitions/snowflake.yaml @@ -0,0 +1,13 @@ +name: snowflake +display_name: "Snowflake" +driver: snowflake +tags: ["snowflake", "warehouse", "source", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/snowflake + type: connector + driver: snowflake + [[ renderProps .props ]] diff --git a/runtime/templates/definitions/sqlite-duckdb.yaml b/runtime/templates/definitions/sqlite-duckdb.yaml new file mode 100644 index 00000000000..f0dcfca79a6 --- /dev/null +++ b/runtime/templates/definitions/sqlite-duckdb.yaml @@ -0,0 +1,15 @@ +name: sqlite-duckdb +display_name: "SQLite (DuckDB)" +driver: sqlite +olap: duckdb +tags: ["sqlite", "database", "duckdb", "source"] +files: + - name: model + path_template: "models/[[ .model_name ]].yaml" + code_template: | + # Model YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/data-source/sqlite + type: model + connector: duckdb + sql: | + [[ .sql ]] diff --git a/runtime/templates/definitions/starrocks.yaml b/runtime/templates/definitions/starrocks.yaml new file mode 100644 index 00000000000..06362c24629 --- /dev/null +++ b/runtime/templates/definitions/starrocks.yaml @@ -0,0 +1,13 @@ +name: starrocks +display_name: "StarRocks" +driver: starrocks +tags: ["starrocks", "olap", "analytics", "connector"] +files: + - name: connector + path_template: "connectors/[[ .connector_name ]].yaml" + code_template: | + # Connector YAML + # Reference documentation: https://docs.rilldata.com/developers/build/connectors/olap/starrocks + type: connector + driver: starrocks + [[ renderProps .props ]] diff --git a/runtime/templates/duckdb.go b/runtime/templates/duckdb.go new file mode 100644 index 00000000000..2c6b43547ad --- /dev/null +++ b/runtime/templates/duckdb.go @@ -0,0 +1,48 @@ +package templates + +import ( + "fmt" + "path/filepath" + "strings" +) + +// BuildDuckDBQuery maps a file path + extension to a DuckDB read function call. +func BuildDuckDBQuery(path string, defaultToJSON bool) string { + switch { + case matchesExt(path, ".csv", ".tsv", ".txt"): + return fmt.Sprintf("select * from read_csv('%s', auto_detect=true, ignore_errors=1, header=true)", path) + case matchesExt(path, ".parquet"): + return fmt.Sprintf("select * from read_parquet('%s')", path) + case matchesExt(path, ".json", ".ndjson"): + return fmt.Sprintf("select * from read_json('%s', auto_detect=true, format='auto')", path) + default: + if defaultToJSON { + return fmt.Sprintf("select * from read_json('%s', auto_detect=true, format='auto')", path) + } + return fmt.Sprintf("select * from '%s'", path) + } +} + +// matchesExt checks if the file path has any of the target extensions. +// Handles compound extensions like .v1.parquet.gz by checking the basename +// for extension substrings, using suffix matching on path segments to avoid +// false positives (e.g. "parquet-archive/readme.txt" should NOT match ".parquet"). +func matchesExt(path string, targets ...string) bool { + ext := strings.ToLower(filepath.Ext(path)) + base := strings.ToLower(filepath.Base(path)) + for _, t := range targets { + if ext == t { + return true + } + // Check for compound extensions in the basename only (not the full path). + // Look for the target extension followed by a dot or end-of-string. + idx := strings.Index(base, t) + if idx > 0 { + after := idx + len(t) + if after == len(base) || base[after] == '.' { + return true + } + } + } + return false +} diff --git a/runtime/templates/duckdb_test.go b/runtime/templates/duckdb_test.go new file mode 100644 index 00000000000..7fe1b05f082 --- /dev/null +++ b/runtime/templates/duckdb_test.go @@ -0,0 +1,50 @@ +package templates + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestBuildDuckDBQuery(t *testing.T) { + tests := []struct { + name string + path string + defaultToJSON bool + wantContains string + }{ + {"parquet", "s3://bucket/data.parquet", false, "read_parquet"}, + {"csv", "s3://bucket/data.csv", false, "read_csv"}, + {"tsv", "s3://bucket/data.tsv", false, "read_csv"}, + {"json", "s3://bucket/data.json", false, "read_json"}, + {"ndjson", "s3://bucket/data.ndjson", false, "read_json"}, + {"compound parquet.gz", "s3://bucket/data.v1.parquet.gz", false, "read_parquet"}, + {"unknown default generic", "s3://bucket/data.xyz", false, "select * from 's3://bucket/data.xyz'"}, + {"unknown default json", "https://example.com/api", true, "read_json"}, + {"txt", "s3://bucket/data.txt", false, "read_csv"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + query := BuildDuckDBQuery(tt.path, tt.defaultToJSON) + require.Contains(t, query, tt.wantContains) + require.Contains(t, query, tt.path) + }) + } +} + +func TestMatchesExtFixedFalsePositive(t *testing.T) { + // This was a bug: "parquet-archive/readme.txt" should NOT match ".parquet" + require.False(t, matchesExt("s3://bucket/parquet-archive/readme.txt", ".parquet"), + "path with 'parquet' in directory name should not match .parquet extension") + + // But actual parquet files should match + require.True(t, matchesExt("s3://bucket/data.parquet", ".parquet")) + require.True(t, matchesExt("s3://bucket/data.v1.parquet.gz", ".parquet")) +} + +func TestMatchesExtCompound(t *testing.T) { + require.True(t, matchesExt("data.csv.gz", ".csv")) + require.True(t, matchesExt("data.ndjson.gz", ".ndjson")) + require.False(t, matchesExt("data.xyz", ".csv", ".json")) +} diff --git a/runtime/templates/env.go b/runtime/templates/env.go new file mode 100644 index 00000000000..17792beadbc --- /dev/null +++ b/runtime/templates/env.go @@ -0,0 +1,49 @@ +package templates + +import ( + "bufio" + "context" + "fmt" + "strings" + + "github.com/rilldata/rill/runtime/drivers" +) + +// ResolveEnvVarName determines the env var name for a secret property, resolving conflicts +// by appending _1, _2, etc. when the base name already exists in existingEnv. +func ResolveEnvVarName(driverName string, propSpec *drivers.PropertySpec, existingEnv map[string]bool) string { + var base string + if propSpec.EnvVarName != "" { + base = propSpec.EnvVarName + } else { + // Fallback: DRIVER_KEY format (SCREAMING_SNAKE_CASE) + base = strings.ToUpper(driverName) + "_" + strings.ToUpper(propSpec.Key) + } + + // Check for conflicts + candidate := base + for i := 1; existingEnv[candidate]; i++ { + candidate = fmt.Sprintf("%s_%d", base, i) + } + return candidate +} + +// ReadEnvKeys parses a .env file into a set of key names. +func ReadEnvKeys(ctx context.Context, repo drivers.RepoStore) map[string]bool { + keys := make(map[string]bool) + content, err := repo.Get(ctx, ".env") + if err != nil { + return keys + } + scanner := bufio.NewScanner(strings.NewReader(content)) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + if line == "" || strings.HasPrefix(line, "#") { + continue + } + if idx := strings.IndexByte(line, '='); idx > 0 { + keys[line[:idx]] = true + } + } + return keys +} diff --git a/runtime/templates/env_test.go b/runtime/templates/env_test.go new file mode 100644 index 00000000000..c523ab58f09 --- /dev/null +++ b/runtime/templates/env_test.go @@ -0,0 +1,45 @@ +package templates + +import ( + "testing" + + "github.com/rilldata/rill/runtime/drivers" + "github.com/stretchr/testify/require" +) + +func TestResolveEnvVarNameWithExplicitName(t *testing.T) { + prop := &drivers.PropertySpec{Key: "aws_access_key_id", EnvVarName: "AWS_ACCESS_KEY_ID"} + existing := make(map[string]bool) + + name := ResolveEnvVarName("s3", prop, existing) + require.Equal(t, "AWS_ACCESS_KEY_ID", name) +} + +func TestResolveEnvVarNameFallback(t *testing.T) { + prop := &drivers.PropertySpec{Key: "password"} + existing := make(map[string]bool) + + name := ResolveEnvVarName("starrocks", prop, existing) + require.Equal(t, "STARROCKS_PASSWORD", name) +} + +func TestResolveEnvVarNameConflict(t *testing.T) { + prop := &drivers.PropertySpec{Key: "aws_access_key_id", EnvVarName: "AWS_ACCESS_KEY_ID"} + existing := map[string]bool{ + "AWS_ACCESS_KEY_ID": true, + } + + name := ResolveEnvVarName("s3", prop, existing) + require.Equal(t, "AWS_ACCESS_KEY_ID_1", name) +} + +func TestResolveEnvVarNameDoubleConflict(t *testing.T) { + prop := &drivers.PropertySpec{Key: "aws_access_key_id", EnvVarName: "AWS_ACCESS_KEY_ID"} + existing := map[string]bool{ + "AWS_ACCESS_KEY_ID": true, + "AWS_ACCESS_KEY_ID_1": true, + } + + name := ResolveEnvVarName("s3", prop, existing) + require.Equal(t, "AWS_ACCESS_KEY_ID_2", name) +} diff --git a/runtime/templates/funcmap.go b/runtime/templates/funcmap.go new file mode 100644 index 00000000000..04198a9ade8 --- /dev/null +++ b/runtime/templates/funcmap.go @@ -0,0 +1,54 @@ +package templates + +import ( + "fmt" + "strings" + "text/template" +) + +// funcMap returns the template function map available to all template definitions. +func funcMap() template.FuncMap { + return template.FuncMap{ + "renderProps": renderProps, + "indent": indent, + "quote": quote, + } +} + +// renderProps renders a slice of ProcessedProp as YAML key-value lines. +// Each property is rendered on its own line with appropriate formatting: +// quoted values get double quotes, unquoted values are rendered as-is. +func renderProps(props []ProcessedProp) string { + if len(props) == 0 { + return "" + } + var b strings.Builder + for i, p := range props { + if i > 0 { + b.WriteByte('\n') + } + if p.Quoted { + fmt.Fprintf(&b, "%s: %q", p.Key, p.Value) + } else { + fmt.Fprintf(&b, "%s: %s", p.Key, p.Value) + } + } + return b.String() +} + +// indent prepends each line of text with n spaces. +func indent(n int, text string) string { + pad := strings.Repeat(" ", n) + lines := strings.Split(text, "\n") + for i, line := range lines { + if line != "" { + lines[i] = pad + line + } + } + return strings.Join(lines, "\n") +} + +// quote wraps a string in double quotes. +func quote(s string) string { + return fmt.Sprintf("%q", s) +} diff --git a/runtime/templates/headers.go b/runtime/templates/headers.go new file mode 100644 index 00000000000..3764b13fa7a --- /dev/null +++ b/runtime/templates/headers.go @@ -0,0 +1,52 @@ +package templates + +import ( + "fmt" + "regexp" + "strings" +) + +// sensitiveHeaderPattern matches header keys that carry secret values. +var sensitiveHeaderPattern = regexp.MustCompile( + `(?i)^(authorization|x-api-key|api-key|token|x-token|x-auth|x-secret|proxy-authorization)$`, +) + +// headerKeyCleanupPattern sanitizes a header key into a valid .env variable segment. +// Compiled at package level to avoid per-call regex compilation. +var headerKeyCleanupPattern = regexp.MustCompile(`[^a-z0-9]+`) + +// IsSensitiveHeaderKey returns true when a header key likely carries a secret value. +func IsSensitiveHeaderKey(key string) bool { + return sensitiveHeaderPattern.MatchString(strings.TrimSpace(key)) +} + +// AuthSchemePrefixes are common HTTP authentication scheme prefixes. +// When a sensitive header value starts with one of these (case-insensitive), +// only the token portion is stored in .env. +var AuthSchemePrefixes = []string{"Bearer ", "Basic ", "Token ", "Bot "} + +// SplitAuthSchemePrefix splits a value into scheme prefix and secret if it starts +// with a known auth scheme. Returns ("", "", false) when no prefix matches. +func SplitAuthSchemePrefix(value string) (scheme, secret string, ok bool) { + for _, prefix := range AuthSchemePrefixes { + if len(value) > len(prefix) && strings.EqualFold(value[:len(prefix)], prefix) { + return value[:len(prefix)], value[len(prefix):], true + } + } + return "", "", false +} + +// HeaderKeyToEnvSegment sanitizes a header key into a valid .env variable segment. +func HeaderKeyToEnvSegment(key string) string { + return headerKeyCleanupPattern.ReplaceAllString(strings.ToLower(key), "_") +} + +// ResolveHeaderEnvVarName determines the env var name for a header, resolving conflicts. +func ResolveHeaderEnvVarName(connectorName, segment string, existingEnv map[string]bool) string { + base := fmt.Sprintf("connector.%s.%s", connectorName, segment) + candidate := base + for i := 1; existingEnv[candidate]; i++ { + candidate = fmt.Sprintf("%s_%d", base, i) + } + return candidate +} diff --git a/runtime/templates/headers_test.go b/runtime/templates/headers_test.go new file mode 100644 index 00000000000..be0dc08d31b --- /dev/null +++ b/runtime/templates/headers_test.go @@ -0,0 +1,56 @@ +package templates + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestIsSensitiveHeaderKey(t *testing.T) { + sensitive := []string{"Authorization", "X-API-Key", "API-Key", "Token", "X-Token", "X-Auth", "X-Secret", "Proxy-Authorization"} + for _, key := range sensitive { + require.True(t, IsSensitiveHeaderKey(key), "expected %q to be sensitive", key) + } + + notSensitive := []string{"Content-Type", "Accept", "X-Request-ID", "User-Agent"} + for _, key := range notSensitive { + require.False(t, IsSensitiveHeaderKey(key), "expected %q to not be sensitive", key) + } +} + +func TestSplitAuthSchemePrefix(t *testing.T) { + scheme, secret, ok := SplitAuthSchemePrefix("Bearer my-token-123") + require.True(t, ok) + require.Equal(t, "Bearer ", scheme) + require.Equal(t, "my-token-123", secret) + + scheme, secret, ok = SplitAuthSchemePrefix("Basic dXNlcjpwYXNz") + require.True(t, ok) + require.Equal(t, "Basic ", scheme) + require.Equal(t, "dXNlcjpwYXNz", secret) + + // No prefix + _, _, ok = SplitAuthSchemePrefix("plain-token") + require.False(t, ok) + + // Prefix only (no token part) + _, _, ok = SplitAuthSchemePrefix("Bearer") + require.False(t, ok) +} + +func TestHeaderKeyToEnvSegment(t *testing.T) { + require.Equal(t, "x_api_key", HeaderKeyToEnvSegment("X-API-Key")) + require.Equal(t, "authorization", HeaderKeyToEnvSegment("Authorization")) + require.Equal(t, "content_type", HeaderKeyToEnvSegment("Content-Type")) +} + +func TestResolveHeaderEnvVarName(t *testing.T) { + existing := make(map[string]bool) + name := ResolveHeaderEnvVarName("my_conn", "authorization", existing) + require.Equal(t, "connector.my_conn.authorization", name) + + // Conflict + existing[name] = true + name2 := ResolveHeaderEnvVarName("my_conn", "authorization", existing) + require.Equal(t, "connector.my_conn.authorization_1", name2) +} diff --git a/runtime/templates/registry.go b/runtime/templates/registry.go new file mode 100644 index 00000000000..2214d262133 --- /dev/null +++ b/runtime/templates/registry.go @@ -0,0 +1,132 @@ +package templates + +import ( + "embed" + "fmt" + "path/filepath" + "sort" + "strings" + + "gopkg.in/yaml.v3" +) + +//go:embed definitions/*.yaml +var definitionsFS embed.FS + +// Registry holds all loaded template definitions. +type Registry struct { + templates map[string]*Template + sorted []*Template // sorted by name for stable List() output +} + +// NewRegistry loads all embedded template definitions from the definitions/ directory. +func NewRegistry() (*Registry, error) { + entries, err := definitionsFS.ReadDir("definitions") + if err != nil { + return nil, fmt.Errorf("reading template definitions: %w", err) + } + + r := &Registry{ + templates: make(map[string]*Template, len(entries)), + } + + for _, entry := range entries { + if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".yaml") { + continue + } + + data, err := definitionsFS.ReadFile(filepath.Join("definitions", entry.Name())) + if err != nil { + return nil, fmt.Errorf("reading template %s: %w", entry.Name(), err) + } + + var t Template + if err := yaml.Unmarshal(data, &t); err != nil { + return nil, fmt.Errorf("parsing template %s: %w", entry.Name(), err) + } + + if t.Name == "" { + return nil, fmt.Errorf("template %s has no name", entry.Name()) + } + + if _, exists := r.templates[t.Name]; exists { + return nil, fmt.Errorf("duplicate template name %q in %s", t.Name, entry.Name()) + } + + r.templates[t.Name] = &t + } + + // Build sorted list + r.sorted = make([]*Template, 0, len(r.templates)) + for _, t := range r.templates { + r.sorted = append(r.sorted, t) + } + sort.Slice(r.sorted, func(i, j int) bool { + return r.sorted[i].Name < r.sorted[j].Name + }) + + return r, nil +} + +// List returns all templates sorted by name. +func (r *Registry) List() []*Template { + return r.sorted +} + +// ListByTags returns templates that match ALL of the given tags. +// If tags is empty, returns all templates. +func (r *Registry) ListByTags(tags []string) []*Template { + if len(tags) == 0 { + return r.sorted + } + + var result []*Template + for _, t := range r.sorted { + if matchesAllTags(t.Tags, tags) { + result = append(result, t) + } + } + return result +} + +// Get returns a template by name, or nil and false if not found. +func (r *Registry) Get(name string) (*Template, bool) { + t, ok := r.templates[name] + return t, ok +} + +// LookupByDriver finds the template for a given driver and output type. +// This is used by the backward-compatible GenerateTemplate RPC to map +// (driver, resource_type) pairs to template names. +func (r *Registry) LookupByDriver(driver, resourceType string) (*Template, bool) { + switch resourceType { + case "connector": + // Connector templates are named after the driver + return r.Get(driver) + case "model": + // Model templates: try driver-duckdb first (DuckDB rewrite), then driver-model + if t, ok := r.Get(driver + "-duckdb"); ok { + return t, true + } + if t, ok := r.Get(driver + "-model"); ok { + return t, true + } + // Fallback: the driver itself might handle models (e.g. clickhouse-model) + return nil, false + } + return nil, false +} + +// matchesAllTags returns true if the template's tags contain all of the required tags. +func matchesAllTags(templateTags, requiredTags []string) bool { + tagSet := make(map[string]bool, len(templateTags)) + for _, t := range templateTags { + tagSet[t] = true + } + for _, req := range requiredTags { + if !tagSet[req] { + return false + } + } + return true +} diff --git a/runtime/templates/registry_test.go b/runtime/templates/registry_test.go new file mode 100644 index 00000000000..03621eeaffa --- /dev/null +++ b/runtime/templates/registry_test.go @@ -0,0 +1,112 @@ +package templates + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewRegistry(t *testing.T) { + r, err := NewRegistry() + require.NoError(t, err) + require.NotNil(t, r) + + // Verify all definitions loaded + all := r.List() + require.Greater(t, len(all), 25, "expected at least 25 template definitions") +} + +func TestRegistryGet(t *testing.T) { + r, err := NewRegistry() + require.NoError(t, err) + + // Known templates exist + for _, name := range []string{"s3", "gcs", "clickhouse", "s3-duckdb", "iceberg-duckdb", "snowflake-model"} { + t.Run(name, func(t *testing.T) { + tmpl, ok := r.Get(name) + require.True(t, ok, "template %q should exist", name) + require.Equal(t, name, tmpl.Name) + require.NotEmpty(t, tmpl.DisplayName) + require.NotEmpty(t, tmpl.Files) + }) + } + + // Unknown template doesn't exist + _, ok := r.Get("nonexistent") + require.False(t, ok) +} + +func TestRegistryListByTags(t *testing.T) { + r, err := NewRegistry() + require.NoError(t, err) + + // Filter by "duckdb" should return DuckDB-related templates + duckdbTemplates := r.ListByTags([]string{"duckdb"}) + require.Greater(t, len(duckdbTemplates), 5, "expected several duckdb-tagged templates") + for _, tmpl := range duckdbTemplates { + require.Contains(t, tmpl.Tags, "duckdb") + } + + // Filter by "olap" + "connector" should return OLAP connector templates + olapConnectors := r.ListByTags([]string{"olap", "connector"}) + require.Greater(t, len(olapConnectors), 0) + for _, tmpl := range olapConnectors { + require.Contains(t, tmpl.Tags, "olap") + require.Contains(t, tmpl.Tags, "connector") + } + + // Empty tags returns all templates + allTemplates := r.ListByTags(nil) + require.Equal(t, len(r.List()), len(allTemplates)) +} + +func TestRegistryLookupByDriver(t *testing.T) { + r, err := NewRegistry() + require.NoError(t, err) + + // Connector lookup: driver name = template name + tmpl, ok := r.LookupByDriver("s3", "connector") + require.True(t, ok) + require.Equal(t, "s3", tmpl.Name) + + // Model lookup for object stores: driver-duckdb + tmpl, ok = r.LookupByDriver("s3", "model") + require.True(t, ok) + require.Equal(t, "s3-duckdb", tmpl.Name) + + // Model lookup for warehouses: driver-model + tmpl, ok = r.LookupByDriver("snowflake", "model") + require.True(t, ok) + require.Equal(t, "snowflake-model", tmpl.Name) +} + +func TestRegistryTemplatesSorted(t *testing.T) { + r, err := NewRegistry() + require.NoError(t, err) + + all := r.List() + for i := 1; i < len(all); i++ { + require.Less(t, all[i-1].Name, all[i].Name, "templates should be sorted by name") + } +} + +func TestRegistryAllDefinitionsValid(t *testing.T) { + r, err := NewRegistry() + require.NoError(t, err) + + for _, tmpl := range r.List() { + t.Run(tmpl.Name, func(t *testing.T) { + require.NotEmpty(t, tmpl.Name) + require.NotEmpty(t, tmpl.DisplayName) + require.NotEmpty(t, tmpl.Tags) + require.NotEmpty(t, tmpl.Files) + + for _, f := range tmpl.Files { + require.NotEmpty(t, f.Name, "file name required for template %s", tmpl.Name) + require.NotEmpty(t, f.PathTemplate, "path template required for template %s file %s", tmpl.Name, f.Name) + require.NotEmpty(t, f.CodeTemplate, "code template required for template %s file %s", tmpl.Name, f.Name) + require.Contains(t, []string{"connector", "model"}, f.Name, "file name must be connector or model for template %s", tmpl.Name) + } + }) + } +} diff --git a/runtime/templates/render.go b/runtime/templates/render.go new file mode 100644 index 00000000000..d27687abfd1 --- /dev/null +++ b/runtime/templates/render.go @@ -0,0 +1,308 @@ +package templates + +import ( + "bytes" + "fmt" + "sort" + "strings" + "text/template" + + "github.com/rilldata/rill/runtime/drivers" +) + +// RenderInput contains all parameters for rendering a template. +type RenderInput struct { + Template *Template + Output string // "connector", "model", or "" for all files + DriverSpec *drivers.Spec // driver metadata; nil for driverless templates + Properties map[string]any // raw form values + ConnectorName string // for model outputs: the connector to reference + ExistingEnv map[string]bool +} + +// RenderOutput contains the result of rendering. +type RenderOutput struct { + Files []RenderedFile + EnvVars map[string]string +} + +// RenderedFile is a single rendered output file. +type RenderedFile struct { + Path string + Blob string +} + +// Render executes a template with the given input, producing rendered files and env vars. +// The rendering pipeline: +// 1. Pre-processes properties (secret extraction, empty filtering, derived fields) +// 2. Builds a template data map +// 3. Renders each matching file's path and code templates +func Render(input *RenderInput) (*RenderOutput, error) { + if input.Template == nil { + return nil, fmt.Errorf("template is nil") + } + + envVars := make(map[string]string) + existingEnv := cloneEnvMap(input.ExistingEnv) + + // Build the template data context + data := buildTemplateData(input, existingEnv, envVars) + + // Render each matching file + var files []RenderedFile + for _, f := range input.Template.Files { + if input.Output != "" && f.Name != input.Output { + continue + } + + path, err := renderString(f.Name+"_path", f.PathTemplate, data) + if err != nil { + return nil, fmt.Errorf("rendering path template for %q: %w", f.Name, err) + } + + blob, err := renderString(f.Name+"_code", f.CodeTemplate, data) + if err != nil { + return nil, fmt.Errorf("rendering code template for %q: %w", f.Name, err) + } + + files = append(files, RenderedFile{ + Path: strings.TrimSpace(path), + Blob: blob, + }) + } + + return &RenderOutput{Files: files, EnvVars: envVars}, nil +} + +// buildTemplateData creates the data map passed to Go templates. +// It pre-processes properties: extracts secrets, filters empties, adds derived fields. +func buildTemplateData(input *RenderInput, existingEnv map[string]bool, envVars map[string]string) map[string]any { + data := make(map[string]any) + + // Basic fields + data["driver"] = input.Template.Driver + data["connector_name"] = input.ConnectorName + + // Derive model_name from the "name" property if present + if name, ok := input.Properties["name"]; ok && !isEmpty(name) { + data["model_name"] = fmt.Sprintf("%v", name) + } + + // Copy all raw properties into data (pre-processed values will overwrite) + for k, v := range input.Properties { + if !isEmpty(v) { + data[k] = fmt.Sprintf("%v", v) + } + } + + if input.DriverSpec == nil { + // Driverless template (e.g. iceberg-duckdb): pass properties as-is + return data + } + + // Process config properties (for connector outputs) + configProps := processProperties(input.Template.Driver, input.DriverSpec.ConfigProperties, input.Properties, existingEnv, envVars, input.ConnectorName) + data["props"] = configProps + data["config_props"] = configProps + + // Process source properties (for model outputs) + sourceProps := processProperties(input.Template.Driver, input.DriverSpec.SourceProperties, input.Properties, existingEnv, envVars, input.ConnectorName) + data["source_props"] = sourceProps + + // DuckDB rewrite: compute SQL from path for object store, file store, and sqlite drivers + if input.Template.OLAP == "duckdb" && input.Template.Driver != "" { + applyDuckDBDerivedFields(input, data) + } + + // Special flags + data["no_dev"] = input.Template.Driver == "redshift" + data["materialize"] = input.Template.Driver != "duckdb" && input.Template.Driver != "motherduck" + + return data +} + +// processProperties pre-processes a list of PropertySpecs against raw form values. +// For each property: filters empties, extracts secrets to env vars, and determines formatting. +func processProperties( + driverName string, + specs []*drivers.PropertySpec, + rawProps map[string]any, + existingEnv map[string]bool, + envVars map[string]string, + connectorName string, +) []ProcessedProp { + var result []ProcessedProp + for _, spec := range specs { + val, ok := rawProps[spec.Key] + if !ok || isEmpty(val) { + continue + } + + // Handle map-typed properties (e.g. headers) + if mapVal, isMap := val.(map[string]any); isMap { + headerProps := processHeaders(mapVal, connectorName, existingEnv, envVars) + result = append(result, headerProps...) + continue + } + + // Skip managed: false for ClickHouse (it's the default) + if spec.Key == "managed" && !toBool(val) { + continue + } + + strVal := fmt.Sprintf("%v", val) + if spec.Secret { + envName := ResolveEnvVarName(driverName, spec, existingEnv) + existingEnv[envName] = true + envVars[envName] = strVal + result = append(result, ProcessedProp{ + Key: spec.Key, + Value: fmt.Sprintf("{{ .env.%s }}", envName), + Quoted: true, + }) + } else { + quoted := spec.Type != drivers.NumberPropertyType && spec.Type != drivers.BooleanPropertyType + result = append(result, ProcessedProp{ + Key: spec.Key, + Value: strVal, + Quoted: quoted, + }) + } + } + return result +} + +// processHeaders processes a map of header key-value pairs, extracting sensitive values. +func processHeaders(headers map[string]any, connectorName string, existingEnv map[string]bool, envVars map[string]string) []ProcessedProp { + if len(headers) == 0 { + return nil + } + + // Sort keys for deterministic output + keys := make([]string, 0, len(headers)) + for k := range headers { + keys = append(keys, k) + } + sort.Strings(keys) + + // Build a single "headers" prop whose value is a YAML mapping + var headerLines []string + for _, key := range keys { + strVal := fmt.Sprintf("%v", headers[key]) + if IsSensitiveHeaderKey(key) { + envSegment := HeaderKeyToEnvSegment(key) + envName := ResolveHeaderEnvVarName(connectorName, envSegment, existingEnv) + existingEnv[envName] = true + if scheme, secret, ok := SplitAuthSchemePrefix(strVal); ok { + envVars[envName] = secret + headerLines = append(headerLines, fmt.Sprintf(" %s: \"%s{{ .env.%s }}\"", key, scheme, envName)) + } else { + envVars[envName] = strVal + headerLines = append(headerLines, fmt.Sprintf(" %s: \"{{ .env.%s }}\"", key, envName)) + } + } else { + headerLines = append(headerLines, fmt.Sprintf(" %s: %q", key, strVal)) + } + } + + // Return as a single rendered block (the template will output it as-is) + return []ProcessedProp{{ + Key: "headers", + Value: "\n" + strings.Join(headerLines, "\n"), + Quoted: false, // The value is a nested YAML mapping, not a scalar + }} +} + +// applyDuckDBDerivedFields computes DuckDB-specific derived fields (SQL, create_secrets_from_connectors). +func applyDuckDBDerivedFields(input *RenderInput, data map[string]any) { + spec := input.DriverSpec + path := strVal(input.Properties["path"]) + + switch { + case spec.ImplementsObjectStore: // s3, gcs, azure + if input.ConnectorName != "" { + data["create_secrets_from_connectors"] = input.ConnectorName + } + data["sql"] = BuildDuckDBQuery(path, false) + + case input.Template.Driver == "https": + if input.ConnectorName != "" { + data["create_secrets_from_connectors"] = input.ConnectorName + } + data["sql"] = BuildDuckDBQuery(path, true) + + case spec.ImplementsFileStore: // local_file + data["sql"] = BuildDuckDBQuery(path, false) + + case input.Template.Driver == "sqlite": + db := strVal(input.Properties["db"]) + table := strVal(input.Properties["table"]) + data["sql"] = fmt.Sprintf("SELECT * FROM sqlite_scan('%s', '%s');", db, table) + } +} + +// renderString renders a Go template string using [[ ]] delimiters. +func renderString(name, tmplText string, data map[string]any) (string, error) { + t, err := template.New(name). + Delims("[[", "]]"). + Funcs(funcMap()). + Parse(tmplText) + if err != nil { + return "", fmt.Errorf("parsing template: %w", err) + } + + var buf bytes.Buffer + if err := t.Execute(&buf, data); err != nil { + return "", fmt.Errorf("executing template: %w", err) + } + return buf.String(), nil +} + +// isEmpty checks if a value is empty (nil, empty string, or empty map). +func isEmpty(v any) bool { + if v == nil { + return true + } + switch val := v.(type) { + case string: + return val == "" + case bool: + return false // bools are never "empty" + case map[string]any: + return len(val) == 0 + default: + return fmt.Sprintf("%v", v) == "" + } +} + +// toBool converts a value to bool. +func toBool(v any) bool { + switch val := v.(type) { + case bool: + return val + case string: + return val == "true" + default: + return false + } +} + +// strVal extracts a string value from an interface. +func strVal(v any) string { + if v == nil { + return "" + } + return fmt.Sprintf("%v", v) +} + +// cloneEnvMap creates a shallow copy of an env key map. +func cloneEnvMap(m map[string]bool) map[string]bool { + if m == nil { + return make(map[string]bool) + } + clone := make(map[string]bool, len(m)) + for k, v := range m { + clone[k] = v + } + return clone +} diff --git a/runtime/templates/render_test.go b/runtime/templates/render_test.go new file mode 100644 index 00000000000..115c0a9dff8 --- /dev/null +++ b/runtime/templates/render_test.go @@ -0,0 +1,392 @@ +package templates + +import ( + "testing" + + "github.com/rilldata/rill/runtime/drivers" + "github.com/stretchr/testify/require" +) + +func TestRenderConnectorTemplate(t *testing.T) { + registry, err := NewRegistry() + require.NoError(t, err) + + tmpl, ok := registry.Get("s3") + require.True(t, ok) + + result, err := Render(&RenderInput{ + Template: tmpl, + Output: "connector", + DriverSpec: &drivers.Spec{ + DocsURL: "https://docs.rilldata.com/developers/build/connectors/data-source/s3", + ConfigProperties: []*drivers.PropertySpec{ + {Key: "aws_access_key_id", Type: drivers.StringPropertyType, Secret: true, EnvVarName: "AWS_ACCESS_KEY_ID"}, + {Key: "aws_secret_access_key", Type: drivers.StringPropertyType, Secret: true, EnvVarName: "AWS_SECRET_ACCESS_KEY"}, + {Key: "region", Type: drivers.StringPropertyType}, + }, + }, + Properties: map[string]any{ + "aws_access_key_id": "AKIAIOSFODNN7EXAMPLE", + "aws_secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", + "region": "us-east-1", + }, + ConnectorName: "my_s3", + ExistingEnv: make(map[string]bool), + }) + require.NoError(t, err) + require.Len(t, result.Files, 1) + + blob := result.Files[0].Blob + require.Contains(t, blob, "type: connector") + require.Contains(t, blob, "driver: s3") + require.Contains(t, blob, `aws_access_key_id: "{{ .env.AWS_ACCESS_KEY_ID }}"`) + require.Contains(t, blob, `aws_secret_access_key: "{{ .env.AWS_SECRET_ACCESS_KEY }}"`) + require.Contains(t, blob, `region: "us-east-1"`) + require.NotContains(t, blob, "AKIAIOSFODNN7EXAMPLE") + + // Verify env vars extracted + require.Equal(t, "AKIAIOSFODNN7EXAMPLE", result.EnvVars["AWS_ACCESS_KEY_ID"]) + require.Equal(t, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", result.EnvVars["AWS_SECRET_ACCESS_KEY"]) + + // Verify path + require.Equal(t, "connectors/my_s3.yaml", result.Files[0].Path) +} + +func TestRenderDuckDBModelTemplate(t *testing.T) { + registry, err := NewRegistry() + require.NoError(t, err) + + tmpl, ok := registry.Get("s3-duckdb") + require.True(t, ok) + + result, err := Render(&RenderInput{ + Template: tmpl, + Output: "model", + DriverSpec: &drivers.Spec{ + ImplementsObjectStore: true, + SourceProperties: []*drivers.PropertySpec{ + {Key: "path", Type: drivers.StringPropertyType}, + {Key: "name", Type: drivers.StringPropertyType}, + }, + }, + Properties: map[string]any{ + "path": "s3://my-bucket/data/*.parquet", + "name": "my_model", + }, + ConnectorName: "my_s3_connector", + ExistingEnv: make(map[string]bool), + }) + require.NoError(t, err) + require.Len(t, result.Files, 1) + + blob := result.Files[0].Blob + require.Contains(t, blob, "type: model") + require.Contains(t, blob, "connector: duckdb") + require.Contains(t, blob, `create_secrets_from_connectors: "my_s3_connector"`) + require.Contains(t, blob, "read_parquet") + require.Contains(t, blob, "s3://my-bucket/data/*.parquet") + + // Verify path uses model_name from "name" property + require.Equal(t, "models/my_model.yaml", result.Files[0].Path) +} + +func TestRenderWarehouseModelTemplate(t *testing.T) { + registry, err := NewRegistry() + require.NoError(t, err) + + tmpl, ok := registry.Get("snowflake-model") + require.True(t, ok) + + result, err := Render(&RenderInput{ + Template: tmpl, + Output: "model", + DriverSpec: &drivers.Spec{ + ImplementsWarehouse: true, + DocsURL: "https://docs.rilldata.com/developers/build/connectors/data-source/snowflake", + SourceProperties: []*drivers.PropertySpec{}, + }, + Properties: map[string]any{ + "sql": "SELECT * FROM my_table", + "name": "snowflake_data", + }, + ConnectorName: "my_snowflake", + ExistingEnv: make(map[string]bool), + }) + require.NoError(t, err) + require.Len(t, result.Files, 1) + + blob := result.Files[0].Blob + require.Contains(t, blob, "type: model") + require.Contains(t, blob, `connector: "my_snowflake"`) + require.Contains(t, blob, "materialize: true") + require.Contains(t, blob, "SELECT * FROM my_table") + require.Contains(t, blob, `select * from {{ ref "self" }} limit 10000`) + + require.Equal(t, "models/snowflake_data.yaml", result.Files[0].Path) +} + +func TestRenderRedshiftModelNoDevSection(t *testing.T) { + registry, err := NewRegistry() + require.NoError(t, err) + + tmpl, ok := registry.Get("redshift-model") + require.True(t, ok) + + result, err := Render(&RenderInput{ + Template: tmpl, + Output: "model", + DriverSpec: &drivers.Spec{ + ImplementsWarehouse: true, + SourceProperties: []*drivers.PropertySpec{}, + }, + Properties: map[string]any{ + "sql": "SELECT * FROM my_table", + "name": "rs_data", + }, + ConnectorName: "my_redshift", + ExistingEnv: make(map[string]bool), + }) + require.NoError(t, err) + require.Len(t, result.Files, 1) + + blob := result.Files[0].Blob + require.Contains(t, blob, "type: model") + require.Contains(t, blob, `connector: "my_redshift"`) + // Redshift template should NOT have a dev section + require.NotContains(t, blob, "dev:") + require.NotContains(t, blob, `ref "self"`) +} + +func TestRenderIcebergDuckDB(t *testing.T) { + registry, err := NewRegistry() + require.NoError(t, err) + + tmpl, ok := registry.Get("iceberg-duckdb") + require.True(t, ok) + + result, err := Render(&RenderInput{ + Template: tmpl, + Output: "model", + DriverSpec: nil, // driverless + Properties: map[string]any{ + "aws_access_key_id": "AKIA123", + "aws_secret_access_key": "secret456", + "aws_region": "us-west-2", + "bucket": "my-iceberg-bucket", + "path": "warehouse/my_table", + "name": "iceberg_data", + }, + ExistingEnv: make(map[string]bool), + }) + require.NoError(t, err) + require.Len(t, result.Files, 1) + + blob := result.Files[0].Blob + require.Contains(t, blob, "type: model") + require.Contains(t, blob, "materialize: true") + require.Contains(t, blob, "INSTALL ICEBERG") + require.Contains(t, blob, "LOAD ICEBERG") + require.Contains(t, blob, "KEY_ID 'AKIA123'") + require.Contains(t, blob, "SECRET 'secret456'") + require.Contains(t, blob, "REGION 'us-west-2'") + require.Contains(t, blob, "iceberg_scan") + require.Contains(t, blob, "s3://my-iceberg-bucket/warehouse/my_table") + + require.Equal(t, "models/iceberg_data.yaml", result.Files[0].Path) +} + +func TestRenderEnvVarConflict(t *testing.T) { + registry, err := NewRegistry() + require.NoError(t, err) + + tmpl, ok := registry.Get("s3") + require.True(t, ok) + + // Pre-populate existing env to force conflict + existingEnv := map[string]bool{ + "AWS_ACCESS_KEY_ID": true, + "AWS_SECRET_ACCESS_KEY": true, + } + + result, err := Render(&RenderInput{ + Template: tmpl, + Output: "connector", + DriverSpec: &drivers.Spec{ + ConfigProperties: []*drivers.PropertySpec{ + {Key: "aws_access_key_id", Type: drivers.StringPropertyType, Secret: true, EnvVarName: "AWS_ACCESS_KEY_ID"}, + {Key: "aws_secret_access_key", Type: drivers.StringPropertyType, Secret: true, EnvVarName: "AWS_SECRET_ACCESS_KEY"}, + }, + }, + Properties: map[string]any{ + "aws_access_key_id": "AKIA_NEW", + "aws_secret_access_key": "SECRET_NEW", + }, + ConnectorName: "s3_2", + ExistingEnv: existingEnv, + }) + require.NoError(t, err) + + // Env vars should have _1 suffix due to conflict + require.Contains(t, result.EnvVars, "AWS_ACCESS_KEY_ID_1") + require.Contains(t, result.EnvVars, "AWS_SECRET_ACCESS_KEY_1") + require.Contains(t, result.Files[0].Blob, "AWS_ACCESS_KEY_ID_1") +} + +func TestRenderEmptyPropertiesFiltered(t *testing.T) { + registry, err := NewRegistry() + require.NoError(t, err) + + tmpl, ok := registry.Get("clickhouse") + require.True(t, ok) + + result, err := Render(&RenderInput{ + Template: tmpl, + Output: "connector", + DriverSpec: &drivers.Spec{ + ConfigProperties: []*drivers.PropertySpec{ + {Key: "host", Type: drivers.StringPropertyType}, + {Key: "port", Type: drivers.NumberPropertyType}, + {Key: "password", Type: drivers.StringPropertyType, Secret: true, EnvVarName: "CLICKHOUSE_PASSWORD"}, + {Key: "database", Type: drivers.StringPropertyType}, + }, + }, + Properties: map[string]any{ + "host": "localhost", + "port": 9000, + "password": "secret", + "database": "", // empty; should be filtered + }, + ConnectorName: "my_ch", + ExistingEnv: make(map[string]bool), + }) + require.NoError(t, err) + + blob := result.Files[0].Blob + require.Contains(t, blob, "host") + require.Contains(t, blob, "port") + require.Contains(t, blob, "CLICKHOUSE_PASSWORD") + require.NotContains(t, blob, "database") +} + +func TestRenderOutputFilter(t *testing.T) { + // Create a two-file template inline for testing + tmpl := &Template{ + Name: "test-multi", + DisplayName: "Test Multi-file", + Tags: []string{"test"}, + Files: []File{ + { + Name: "connector", + PathTemplate: "connectors/[[ .connector_name ]].yaml", + CodeTemplate: "type: connector\ndriver: test\n", + }, + { + Name: "model", + PathTemplate: "models/[[ .model_name ]].yaml", + CodeTemplate: "type: model\nconnector: duckdb\n", + }, + }, + } + + // All files + result, err := Render(&RenderInput{ + Template: tmpl, + Output: "", + Properties: map[string]any{"name": "test"}, + ConnectorName: "test_conn", + ExistingEnv: make(map[string]bool), + }) + require.NoError(t, err) + require.Len(t, result.Files, 2) + + // Connector only + result, err = Render(&RenderInput{ + Template: tmpl, + Output: "connector", + Properties: map[string]any{"name": "test"}, + ConnectorName: "test_conn", + ExistingEnv: make(map[string]bool), + }) + require.NoError(t, err) + require.Len(t, result.Files, 1) + require.Equal(t, "connector", "connector") // verify it's the connector file + require.Contains(t, result.Files[0].Blob, "type: connector") + + // Model only + result, err = Render(&RenderInput{ + Template: tmpl, + Output: "model", + Properties: map[string]any{"name": "test"}, + ConnectorName: "test_conn", + ExistingEnv: make(map[string]bool), + }) + require.NoError(t, err) + require.Len(t, result.Files, 1) + require.Contains(t, result.Files[0].Blob, "type: model") +} + +func TestRenderLocalFileDuckDB(t *testing.T) { + registry, err := NewRegistry() + require.NoError(t, err) + + tmpl, ok := registry.Get("local-file-duckdb") + require.True(t, ok) + + result, err := Render(&RenderInput{ + Template: tmpl, + Output: "model", + DriverSpec: &drivers.Spec{ + ImplementsFileStore: true, + SourceProperties: []*drivers.PropertySpec{ + {Key: "path", Type: drivers.StringPropertyType}, + }, + }, + Properties: map[string]any{ + "path": "data/sales.csv", + "name": "sales", + }, + ExistingEnv: make(map[string]bool), + }) + require.NoError(t, err) + require.Len(t, result.Files, 1) + + blob := result.Files[0].Blob + require.Contains(t, blob, "type: model") + require.Contains(t, blob, "connector: duckdb") + require.Contains(t, blob, "read_csv") + require.Contains(t, blob, "data/sales.csv") +} + +func TestRenderSQLiteDuckDB(t *testing.T) { + registry, err := NewRegistry() + require.NoError(t, err) + + tmpl, ok := registry.Get("sqlite-duckdb") + require.True(t, ok) + + result, err := Render(&RenderInput{ + Template: tmpl, + Output: "model", + DriverSpec: &drivers.Spec{ + SourceProperties: []*drivers.PropertySpec{ + {Key: "db", Type: drivers.StringPropertyType}, + {Key: "table", Type: drivers.StringPropertyType}, + }, + }, + Properties: map[string]any{ + "db": "/data/app.db", + "table": "users", + "name": "sqlite_users", + }, + ExistingEnv: make(map[string]bool), + }) + require.NoError(t, err) + require.Len(t, result.Files, 1) + + blob := result.Files[0].Blob + require.Contains(t, blob, "type: model") + require.Contains(t, blob, "connector: duckdb") + require.Contains(t, blob, "sqlite_scan") + require.Contains(t, blob, "/data/app.db") + require.Contains(t, blob, "users") +} diff --git a/runtime/templates/template.go b/runtime/templates/template.go new file mode 100644 index 00000000000..64989e1e8df --- /dev/null +++ b/runtime/templates/template.go @@ -0,0 +1,29 @@ +package templates + +// Template is a declarative definition for generating project files (connectors, models, etc.) +// from structured form data. Each template knows how to produce one or more output files. +type Template struct { + Name string `yaml:"name"` + DisplayName string `yaml:"display_name"` + Driver string `yaml:"driver"` // primary driver (e.g. "s3"); empty for driverless templates like iceberg + OLAP string `yaml:"olap"` // target OLAP engine (e.g. "duckdb"); empty for OLAP connector templates + Tags []string `yaml:"tags"` + Files []File `yaml:"files"` +} + +// File describes a single output file within a template. +// PathTemplate and CodeTemplate use Go text/template syntax with [[ ]] delimiters +// to avoid collision with Rill's {{ .env.VAR }} runtime syntax. +type File struct { + Name string `yaml:"name"` // output name: "connector" or "model" + PathTemplate string `yaml:"path_template"` // Go template for the file path + CodeTemplate string `yaml:"code_template"` // Go template for the file content +} + +// ProcessedProp is a property that has been pre-processed for template rendering. +// Secret values are replaced with {{ .env.VAR }} references; empty values are filtered. +type ProcessedProp struct { + Key string + Value string + Quoted bool // true for strings and secrets; false for numbers and booleans +} diff --git a/web-common/src/proto/gen/rill/runtime/v1/api_pb.ts b/web-common/src/proto/gen/rill/runtime/v1/api_pb.ts index 35713621255..40d2e144ca1 100644 --- a/web-common/src/proto/gen/rill/runtime/v1/api_pb.ts +++ b/web-common/src/proto/gen/rill/runtime/v1/api_pb.ts @@ -2758,6 +2758,359 @@ export class GenerateTemplateResponse extends Message$1 { + /** + * @generated from field: string name = 1; + */ + name = ""; + + /** + * @generated from field: string display_name = 2; + */ + displayName = ""; + + /** + * @generated from field: string driver = 3; + */ + driver = ""; + + /** + * @generated from field: string olap = 4; + */ + olap = ""; + + /** + * @generated from field: repeated string tags = 5; + */ + tags: string[] = []; + + /** + * @generated from field: repeated rill.runtime.v1.TemplateFile files = 6; + */ + files: TemplateFile[] = []; + + constructor(data?: PartialMessage