diff --git a/apps/web/lib/api.ts b/apps/web/lib/api.ts index 2767d9d0..9c26013c 100644 --- a/apps/web/lib/api.ts +++ b/apps/web/lib/api.ts @@ -165,6 +165,26 @@ export type ConnectorDefinition = { fields: ConnectorField[]; }; +export type DetectionPackRule = { + id: string; + title: string; + description: string; + severity: string; + eventTypes: string[]; + mitreTechniques: string[]; + intent: string; + tags: string[]; +}; + +export type DetectionPack = { + id: string; + provider: string; + name: string; + description: string; + version: string; + rules: DetectionPackRule[]; +}; + export type IntegrationConnection = { id: string; provider: Provider; @@ -493,6 +513,12 @@ export async function fetchConnectorCatalog() { }>; } +export async function fetchDetectionPacks(filters?: { provider?: string }) { + return aperioConnectClient.listDetectionPacks(filters) as Promise<{ + data: DetectionPack[]; + }>; +} + export async function fetchIntegrations() { return aperioConnectClient.listIntegrations() as Promise<{ data: IntegrationConnection[]; diff --git a/gen/aperio/v1/aperiov1connect/api.connect.go b/gen/aperio/v1/aperiov1connect/api.connect.go index a5b2c5f0..fef896df 100644 --- a/gen/aperio/v1/aperiov1connect/api.connect.go +++ b/gen/aperio/v1/aperiov1connect/api.connect.go @@ -107,6 +107,9 @@ const ( // AperioServiceExecuteSaasResponseActionProcedure is the fully-qualified name of the // AperioService's ExecuteSaasResponseAction RPC. AperioServiceExecuteSaasResponseActionProcedure = "/aperio.v1.AperioService/ExecuteSaasResponseAction" + // AperioServiceListDetectionPacksProcedure is the fully-qualified name of the AperioService's + // ListDetectionPacks RPC. + AperioServiceListDetectionPacksProcedure = "/aperio.v1.AperioService/ListDetectionPacks" // AperioServiceListConnectorCatalogProcedure is the fully-qualified name of the AperioService's // ListConnectorCatalog RPC. AperioServiceListConnectorCatalogProcedure = "/aperio.v1.AperioService/ListConnectorCatalog" @@ -290,6 +293,7 @@ type AperioServiceClient interface { ProposeSaasResponseAction(context.Context, *connect.Request[v1.ProposeSaasResponseActionRequest]) (*connect.Response[v1.ProposeSaasResponseActionResponse], error) ApproveSaasResponseAction(context.Context, *connect.Request[v1.ApproveSaasResponseActionRequest]) (*connect.Response[v1.ApproveSaasResponseActionResponse], error) ExecuteSaasResponseAction(context.Context, *connect.Request[v1.ExecuteSaasResponseActionRequest]) (*connect.Response[v1.ExecuteSaasResponseActionResponse], error) + ListDetectionPacks(context.Context, *connect.Request[v1.ListDetectionPacksRequest]) (*connect.Response[v1.ListDetectionPacksResponse], error) ListConnectorCatalog(context.Context, *connect.Request[v1.ListConnectorCatalogRequest]) (*connect.Response[v1.ListConnectorCatalogResponse], error) ListIntegrations(context.Context, *connect.Request[v1.ListIntegrationsRequest]) (*connect.Response[v1.ListIntegrationsResponse], error) CreateIntegration(context.Context, *connect.Request[v1.CreateIntegrationRequest]) (*connect.Response[v1.CreateIntegrationResponse], error) @@ -510,6 +514,12 @@ func NewAperioServiceClient(httpClient connect.HTTPClient, baseURL string, opts connect.WithSchema(aperioServiceMethods.ByName("ExecuteSaasResponseAction")), connect.WithClientOptions(opts...), ), + listDetectionPacks: connect.NewClient[v1.ListDetectionPacksRequest, v1.ListDetectionPacksResponse]( + httpClient, + baseURL+AperioServiceListDetectionPacksProcedure, + connect.WithSchema(aperioServiceMethods.ByName("ListDetectionPacks")), + connect.WithClientOptions(opts...), + ), listConnectorCatalog: connect.NewClient[v1.ListConnectorCatalogRequest, v1.ListConnectorCatalogResponse]( httpClient, baseURL+AperioServiceListConnectorCatalogProcedure, @@ -847,6 +857,7 @@ type aperioServiceClient struct { proposeSaasResponseAction *connect.Client[v1.ProposeSaasResponseActionRequest, v1.ProposeSaasResponseActionResponse] approveSaasResponseAction *connect.Client[v1.ApproveSaasResponseActionRequest, v1.ApproveSaasResponseActionResponse] executeSaasResponseAction *connect.Client[v1.ExecuteSaasResponseActionRequest, v1.ExecuteSaasResponseActionResponse] + listDetectionPacks *connect.Client[v1.ListDetectionPacksRequest, v1.ListDetectionPacksResponse] listConnectorCatalog *connect.Client[v1.ListConnectorCatalogRequest, v1.ListConnectorCatalogResponse] listIntegrations *connect.Client[v1.ListIntegrationsRequest, v1.ListIntegrationsResponse] createIntegration *connect.Client[v1.CreateIntegrationRequest, v1.CreateIntegrationResponse] @@ -1030,6 +1041,11 @@ func (c *aperioServiceClient) ExecuteSaasResponseAction(ctx context.Context, req return c.executeSaasResponseAction.CallUnary(ctx, req) } +// ListDetectionPacks calls aperio.v1.AperioService.ListDetectionPacks. +func (c *aperioServiceClient) ListDetectionPacks(ctx context.Context, req *connect.Request[v1.ListDetectionPacksRequest]) (*connect.Response[v1.ListDetectionPacksResponse], error) { + return c.listDetectionPacks.CallUnary(ctx, req) +} + // ListConnectorCatalog calls aperio.v1.AperioService.ListConnectorCatalog. func (c *aperioServiceClient) ListConnectorCatalog(ctx context.Context, req *connect.Request[v1.ListConnectorCatalogRequest]) (*connect.Response[v1.ListConnectorCatalogResponse], error) { return c.listConnectorCatalog.CallUnary(ctx, req) @@ -1315,6 +1331,7 @@ type AperioServiceHandler interface { ProposeSaasResponseAction(context.Context, *connect.Request[v1.ProposeSaasResponseActionRequest]) (*connect.Response[v1.ProposeSaasResponseActionResponse], error) ApproveSaasResponseAction(context.Context, *connect.Request[v1.ApproveSaasResponseActionRequest]) (*connect.Response[v1.ApproveSaasResponseActionResponse], error) ExecuteSaasResponseAction(context.Context, *connect.Request[v1.ExecuteSaasResponseActionRequest]) (*connect.Response[v1.ExecuteSaasResponseActionResponse], error) + ListDetectionPacks(context.Context, *connect.Request[v1.ListDetectionPacksRequest]) (*connect.Response[v1.ListDetectionPacksResponse], error) ListConnectorCatalog(context.Context, *connect.Request[v1.ListConnectorCatalogRequest]) (*connect.Response[v1.ListConnectorCatalogResponse], error) ListIntegrations(context.Context, *connect.Request[v1.ListIntegrationsRequest]) (*connect.Response[v1.ListIntegrationsResponse], error) CreateIntegration(context.Context, *connect.Request[v1.CreateIntegrationRequest]) (*connect.Response[v1.CreateIntegrationResponse], error) @@ -1531,6 +1548,12 @@ func NewAperioServiceHandler(svc AperioServiceHandler, opts ...connect.HandlerOp connect.WithSchema(aperioServiceMethods.ByName("ExecuteSaasResponseAction")), connect.WithHandlerOptions(opts...), ) + aperioServiceListDetectionPacksHandler := connect.NewUnaryHandler( + AperioServiceListDetectionPacksProcedure, + svc.ListDetectionPacks, + connect.WithSchema(aperioServiceMethods.ByName("ListDetectionPacks")), + connect.WithHandlerOptions(opts...), + ) aperioServiceListConnectorCatalogHandler := connect.NewUnaryHandler( AperioServiceListConnectorCatalogProcedure, svc.ListConnectorCatalog, @@ -1891,6 +1914,8 @@ func NewAperioServiceHandler(svc AperioServiceHandler, opts ...connect.HandlerOp aperioServiceApproveSaasResponseActionHandler.ServeHTTP(w, r) case AperioServiceExecuteSaasResponseActionProcedure: aperioServiceExecuteSaasResponseActionHandler.ServeHTTP(w, r) + case AperioServiceListDetectionPacksProcedure: + aperioServiceListDetectionPacksHandler.ServeHTTP(w, r) case AperioServiceListConnectorCatalogProcedure: aperioServiceListConnectorCatalogHandler.ServeHTTP(w, r) case AperioServiceListIntegrationsProcedure: @@ -2106,6 +2131,10 @@ func (UnimplementedAperioServiceHandler) ExecuteSaasResponseAction(context.Conte return nil, connect.NewError(connect.CodeUnimplemented, errors.New("aperio.v1.AperioService.ExecuteSaasResponseAction is not implemented")) } +func (UnimplementedAperioServiceHandler) ListDetectionPacks(context.Context, *connect.Request[v1.ListDetectionPacksRequest]) (*connect.Response[v1.ListDetectionPacksResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("aperio.v1.AperioService.ListDetectionPacks is not implemented")) +} + func (UnimplementedAperioServiceHandler) ListConnectorCatalog(context.Context, *connect.Request[v1.ListConnectorCatalogRequest]) (*connect.Response[v1.ListConnectorCatalogResponse], error) { return nil, connect.NewError(connect.CodeUnimplemented, errors.New("aperio.v1.AperioService.ListConnectorCatalog is not implemented")) } diff --git a/gen/aperio/v1/api.pb.go b/gen/aperio/v1/api.pb.go index 6c9b1f4a..c3fb7787 100644 --- a/gen/aperio/v1/api.pb.go +++ b/gen/aperio/v1/api.pb.go @@ -14855,6 +14855,279 @@ func (x *ConnectorBuiltInRule) GetEnabled() bool { return false } +type ListDetectionPacksRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Optional provider filter (e.g. "GOOGLE_WORKSPACE"). Empty returns every pack. + Provider string `protobuf:"bytes,1,opt,name=provider,proto3" json:"provider,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListDetectionPacksRequest) Reset() { + *x = ListDetectionPacksRequest{} + mi := &file_aperio_v1_api_proto_msgTypes[224] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListDetectionPacksRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDetectionPacksRequest) ProtoMessage() {} + +func (x *ListDetectionPacksRequest) ProtoReflect() protoreflect.Message { + mi := &file_aperio_v1_api_proto_msgTypes[224] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDetectionPacksRequest.ProtoReflect.Descriptor instead. +func (*ListDetectionPacksRequest) Descriptor() ([]byte, []int) { + return file_aperio_v1_api_proto_rawDescGZIP(), []int{224} +} + +func (x *ListDetectionPacksRequest) GetProvider() string { + if x != nil { + return x.Provider + } + return "" +} + +type ListDetectionPacksResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Data []*DetectionPack `protobuf:"bytes,1,rep,name=data,proto3" json:"data,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListDetectionPacksResponse) Reset() { + *x = ListDetectionPacksResponse{} + mi := &file_aperio_v1_api_proto_msgTypes[225] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListDetectionPacksResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDetectionPacksResponse) ProtoMessage() {} + +func (x *ListDetectionPacksResponse) ProtoReflect() protoreflect.Message { + mi := &file_aperio_v1_api_proto_msgTypes[225] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDetectionPacksResponse.ProtoReflect.Descriptor instead. +func (*ListDetectionPacksResponse) Descriptor() ([]byte, []int) { + return file_aperio_v1_api_proto_rawDescGZIP(), []int{225} +} + +func (x *ListDetectionPacksResponse) GetData() []*DetectionPack { + if x != nil { + return x.Data + } + return nil +} + +type DetectionPack struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Provider string `protobuf:"bytes,2,opt,name=provider,proto3" json:"provider,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` + Version string `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"` + Rules []*DetectionPackRule `protobuf:"bytes,6,rep,name=rules,proto3" json:"rules,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DetectionPack) Reset() { + *x = DetectionPack{} + mi := &file_aperio_v1_api_proto_msgTypes[226] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DetectionPack) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DetectionPack) ProtoMessage() {} + +func (x *DetectionPack) ProtoReflect() protoreflect.Message { + mi := &file_aperio_v1_api_proto_msgTypes[226] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DetectionPack.ProtoReflect.Descriptor instead. +func (*DetectionPack) Descriptor() ([]byte, []int) { + return file_aperio_v1_api_proto_rawDescGZIP(), []int{226} +} + +func (x *DetectionPack) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *DetectionPack) GetProvider() string { + if x != nil { + return x.Provider + } + return "" +} + +func (x *DetectionPack) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DetectionPack) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *DetectionPack) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *DetectionPack) GetRules() []*DetectionPackRule { + if x != nil { + return x.Rules + } + return nil +} + +type DetectionPackRule struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"` + Severity string `protobuf:"bytes,4,opt,name=severity,proto3" json:"severity,omitempty"` + EventTypes []string `protobuf:"bytes,5,rep,name=event_types,json=eventTypes,proto3" json:"event_types,omitempty"` + MitreTechniques []string `protobuf:"bytes,6,rep,name=mitre_techniques,json=mitreTechniques,proto3" json:"mitre_techniques,omitempty"` + Intent string `protobuf:"bytes,7,opt,name=intent,proto3" json:"intent,omitempty"` + Tags []string `protobuf:"bytes,8,rep,name=tags,proto3" json:"tags,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DetectionPackRule) Reset() { + *x = DetectionPackRule{} + mi := &file_aperio_v1_api_proto_msgTypes[227] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DetectionPackRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DetectionPackRule) ProtoMessage() {} + +func (x *DetectionPackRule) ProtoReflect() protoreflect.Message { + mi := &file_aperio_v1_api_proto_msgTypes[227] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DetectionPackRule.ProtoReflect.Descriptor instead. +func (*DetectionPackRule) Descriptor() ([]byte, []int) { + return file_aperio_v1_api_proto_rawDescGZIP(), []int{227} +} + +func (x *DetectionPackRule) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *DetectionPackRule) GetTitle() string { + if x != nil { + return x.Title + } + return "" +} + +func (x *DetectionPackRule) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +func (x *DetectionPackRule) GetSeverity() string { + if x != nil { + return x.Severity + } + return "" +} + +func (x *DetectionPackRule) GetEventTypes() []string { + if x != nil { + return x.EventTypes + } + return nil +} + +func (x *DetectionPackRule) GetMitreTechniques() []string { + if x != nil { + return x.MitreTechniques + } + return nil +} + +func (x *DetectionPackRule) GetIntent() string { + if x != nil { + return x.Intent + } + return "" +} + +func (x *DetectionPackRule) GetTags() []string { + if x != nil { + return x.Tags + } + return nil +} + type ConnectorCustomRule struct { state protoimpl.MessageState `protogen:"open.v1"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` @@ -14871,7 +15144,7 @@ type ConnectorCustomRule struct { func (x *ConnectorCustomRule) Reset() { *x = ConnectorCustomRule{} - mi := &file_aperio_v1_api_proto_msgTypes[224] + mi := &file_aperio_v1_api_proto_msgTypes[228] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14883,7 +15156,7 @@ func (x *ConnectorCustomRule) String() string { func (*ConnectorCustomRule) ProtoMessage() {} func (x *ConnectorCustomRule) ProtoReflect() protoreflect.Message { - mi := &file_aperio_v1_api_proto_msgTypes[224] + mi := &file_aperio_v1_api_proto_msgTypes[228] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14896,7 +15169,7 @@ func (x *ConnectorCustomRule) ProtoReflect() protoreflect.Message { // Deprecated: Use ConnectorCustomRule.ProtoReflect.Descriptor instead. func (*ConnectorCustomRule) Descriptor() ([]byte, []int) { - return file_aperio_v1_api_proto_rawDescGZIP(), []int{224} + return file_aperio_v1_api_proto_rawDescGZIP(), []int{228} } func (x *ConnectorCustomRule) GetId() string { @@ -14964,7 +15237,7 @@ type ListConnectorRulesRequest struct { func (x *ListConnectorRulesRequest) Reset() { *x = ListConnectorRulesRequest{} - mi := &file_aperio_v1_api_proto_msgTypes[225] + mi := &file_aperio_v1_api_proto_msgTypes[229] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -14976,7 +15249,7 @@ func (x *ListConnectorRulesRequest) String() string { func (*ListConnectorRulesRequest) ProtoMessage() {} func (x *ListConnectorRulesRequest) ProtoReflect() protoreflect.Message { - mi := &file_aperio_v1_api_proto_msgTypes[225] + mi := &file_aperio_v1_api_proto_msgTypes[229] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -14989,7 +15262,7 @@ func (x *ListConnectorRulesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ListConnectorRulesRequest.ProtoReflect.Descriptor instead. func (*ListConnectorRulesRequest) Descriptor() ([]byte, []int) { - return file_aperio_v1_api_proto_rawDescGZIP(), []int{225} + return file_aperio_v1_api_proto_rawDescGZIP(), []int{229} } func (x *ListConnectorRulesRequest) GetIntegrationId() string { @@ -15011,7 +15284,7 @@ type ListConnectorRulesResponse struct { func (x *ListConnectorRulesResponse) Reset() { *x = ListConnectorRulesResponse{} - mi := &file_aperio_v1_api_proto_msgTypes[226] + mi := &file_aperio_v1_api_proto_msgTypes[230] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15023,7 +15296,7 @@ func (x *ListConnectorRulesResponse) String() string { func (*ListConnectorRulesResponse) ProtoMessage() {} func (x *ListConnectorRulesResponse) ProtoReflect() protoreflect.Message { - mi := &file_aperio_v1_api_proto_msgTypes[226] + mi := &file_aperio_v1_api_proto_msgTypes[230] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15036,7 +15309,7 @@ func (x *ListConnectorRulesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ListConnectorRulesResponse.ProtoReflect.Descriptor instead. func (*ListConnectorRulesResponse) Descriptor() ([]byte, []int) { - return file_aperio_v1_api_proto_rawDescGZIP(), []int{226} + return file_aperio_v1_api_proto_rawDescGZIP(), []int{230} } func (x *ListConnectorRulesResponse) GetIntegrationId() string { @@ -15082,7 +15355,7 @@ type CreateCustomRuleRequest struct { func (x *CreateCustomRuleRequest) Reset() { *x = CreateCustomRuleRequest{} - mi := &file_aperio_v1_api_proto_msgTypes[227] + mi := &file_aperio_v1_api_proto_msgTypes[231] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15094,7 +15367,7 @@ func (x *CreateCustomRuleRequest) String() string { func (*CreateCustomRuleRequest) ProtoMessage() {} func (x *CreateCustomRuleRequest) ProtoReflect() protoreflect.Message { - mi := &file_aperio_v1_api_proto_msgTypes[227] + mi := &file_aperio_v1_api_proto_msgTypes[231] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15107,7 +15380,7 @@ func (x *CreateCustomRuleRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateCustomRuleRequest.ProtoReflect.Descriptor instead. func (*CreateCustomRuleRequest) Descriptor() ([]byte, []int) { - return file_aperio_v1_api_proto_rawDescGZIP(), []int{227} + return file_aperio_v1_api_proto_rawDescGZIP(), []int{231} } func (x *CreateCustomRuleRequest) GetIntegrationId() string { @@ -15168,7 +15441,7 @@ type CreateCustomRuleResponse struct { func (x *CreateCustomRuleResponse) Reset() { *x = CreateCustomRuleResponse{} - mi := &file_aperio_v1_api_proto_msgTypes[228] + mi := &file_aperio_v1_api_proto_msgTypes[232] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15180,7 +15453,7 @@ func (x *CreateCustomRuleResponse) String() string { func (*CreateCustomRuleResponse) ProtoMessage() {} func (x *CreateCustomRuleResponse) ProtoReflect() protoreflect.Message { - mi := &file_aperio_v1_api_proto_msgTypes[228] + mi := &file_aperio_v1_api_proto_msgTypes[232] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15193,7 +15466,7 @@ func (x *CreateCustomRuleResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateCustomRuleResponse.ProtoReflect.Descriptor instead. func (*CreateCustomRuleResponse) Descriptor() ([]byte, []int) { - return file_aperio_v1_api_proto_rawDescGZIP(), []int{228} + return file_aperio_v1_api_proto_rawDescGZIP(), []int{232} } func (x *CreateCustomRuleResponse) GetId() string { @@ -15219,7 +15492,7 @@ type UpdateCustomRuleRequest struct { func (x *UpdateCustomRuleRequest) Reset() { *x = UpdateCustomRuleRequest{} - mi := &file_aperio_v1_api_proto_msgTypes[229] + mi := &file_aperio_v1_api_proto_msgTypes[233] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15231,7 +15504,7 @@ func (x *UpdateCustomRuleRequest) String() string { func (*UpdateCustomRuleRequest) ProtoMessage() {} func (x *UpdateCustomRuleRequest) ProtoReflect() protoreflect.Message { - mi := &file_aperio_v1_api_proto_msgTypes[229] + mi := &file_aperio_v1_api_proto_msgTypes[233] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15244,7 +15517,7 @@ func (x *UpdateCustomRuleRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCustomRuleRequest.ProtoReflect.Descriptor instead. func (*UpdateCustomRuleRequest) Descriptor() ([]byte, []int) { - return file_aperio_v1_api_proto_rawDescGZIP(), []int{229} + return file_aperio_v1_api_proto_rawDescGZIP(), []int{233} } func (x *UpdateCustomRuleRequest) GetIntegrationId() string { @@ -15312,7 +15585,7 @@ type UpdateCustomRuleResponse struct { func (x *UpdateCustomRuleResponse) Reset() { *x = UpdateCustomRuleResponse{} - mi := &file_aperio_v1_api_proto_msgTypes[230] + mi := &file_aperio_v1_api_proto_msgTypes[234] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15324,7 +15597,7 @@ func (x *UpdateCustomRuleResponse) String() string { func (*UpdateCustomRuleResponse) ProtoMessage() {} func (x *UpdateCustomRuleResponse) ProtoReflect() protoreflect.Message { - mi := &file_aperio_v1_api_proto_msgTypes[230] + mi := &file_aperio_v1_api_proto_msgTypes[234] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15337,7 +15610,7 @@ func (x *UpdateCustomRuleResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCustomRuleResponse.ProtoReflect.Descriptor instead. func (*UpdateCustomRuleResponse) Descriptor() ([]byte, []int) { - return file_aperio_v1_api_proto_rawDescGZIP(), []int{230} + return file_aperio_v1_api_proto_rawDescGZIP(), []int{234} } func (x *UpdateCustomRuleResponse) GetId() string { @@ -15357,7 +15630,7 @@ type DeleteCustomRuleRequest struct { func (x *DeleteCustomRuleRequest) Reset() { *x = DeleteCustomRuleRequest{} - mi := &file_aperio_v1_api_proto_msgTypes[231] + mi := &file_aperio_v1_api_proto_msgTypes[235] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15369,7 +15642,7 @@ func (x *DeleteCustomRuleRequest) String() string { func (*DeleteCustomRuleRequest) ProtoMessage() {} func (x *DeleteCustomRuleRequest) ProtoReflect() protoreflect.Message { - mi := &file_aperio_v1_api_proto_msgTypes[231] + mi := &file_aperio_v1_api_proto_msgTypes[235] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15382,7 +15655,7 @@ func (x *DeleteCustomRuleRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteCustomRuleRequest.ProtoReflect.Descriptor instead. func (*DeleteCustomRuleRequest) Descriptor() ([]byte, []int) { - return file_aperio_v1_api_proto_rawDescGZIP(), []int{231} + return file_aperio_v1_api_proto_rawDescGZIP(), []int{235} } func (x *DeleteCustomRuleRequest) GetIntegrationId() string { @@ -15408,7 +15681,7 @@ type DeleteCustomRuleResponse struct { func (x *DeleteCustomRuleResponse) Reset() { *x = DeleteCustomRuleResponse{} - mi := &file_aperio_v1_api_proto_msgTypes[232] + mi := &file_aperio_v1_api_proto_msgTypes[236] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -15420,7 +15693,7 @@ func (x *DeleteCustomRuleResponse) String() string { func (*DeleteCustomRuleResponse) ProtoMessage() {} func (x *DeleteCustomRuleResponse) ProtoReflect() protoreflect.Message { - mi := &file_aperio_v1_api_proto_msgTypes[232] + mi := &file_aperio_v1_api_proto_msgTypes[236] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -15433,7 +15706,7 @@ func (x *DeleteCustomRuleResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DeleteCustomRuleResponse.ProtoReflect.Descriptor instead. func (*DeleteCustomRuleResponse) Descriptor() ([]byte, []int) { - return file_aperio_v1_api_proto_rawDescGZIP(), []int{232} + return file_aperio_v1_api_proto_rawDescGZIP(), []int{236} } func (x *DeleteCustomRuleResponse) GetId() string { @@ -16717,7 +16990,28 @@ const file_aperio_v1_api_proto_rawDesc = "" + "\bseverity\x18\x05 \x01(\tR\bseverity\x12\x1f\n" + "\vevent_types\x18\x06 \x03(\tR\n" + "eventTypes\x12\x18\n" + - "\aenabled\x18\a \x01(\bR\aenabled\"\xf9\x01\n" + + "\aenabled\x18\a \x01(\bR\aenabled\"7\n" + + "\x19ListDetectionPacksRequest\x12\x1a\n" + + "\bprovider\x18\x01 \x01(\tR\bprovider\"J\n" + + "\x1aListDetectionPacksResponse\x12,\n" + + "\x04data\x18\x01 \x03(\v2\x18.aperio.v1.DetectionPackR\x04data\"\xbf\x01\n" + + "\rDetectionPack\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x1a\n" + + "\bprovider\x18\x02 \x01(\tR\bprovider\x12\x12\n" + + "\x04name\x18\x03 \x01(\tR\x04name\x12 \n" + + "\vdescription\x18\x04 \x01(\tR\vdescription\x12\x18\n" + + "\aversion\x18\x05 \x01(\tR\aversion\x122\n" + + "\x05rules\x18\x06 \x03(\v2\x1c.aperio.v1.DetectionPackRuleR\x05rules\"\xef\x01\n" + + "\x11DetectionPackRule\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x14\n" + + "\x05title\x18\x02 \x01(\tR\x05title\x12 \n" + + "\vdescription\x18\x03 \x01(\tR\vdescription\x12\x1a\n" + + "\bseverity\x18\x04 \x01(\tR\bseverity\x12\x1f\n" + + "\vevent_types\x18\x05 \x03(\tR\n" + + "eventTypes\x12)\n" + + "\x10mitre_techniques\x18\x06 \x03(\tR\x0fmitreTechniques\x12\x16\n" + + "\x06intent\x18\a \x01(\tR\x06intent\x12\x12\n" + + "\x04tags\x18\b \x03(\tR\x04tags\"\xf9\x01\n" + "\x13ConnectorCustomRule\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12\x1a\n" + @@ -16763,7 +17057,7 @@ const file_aperio_v1_api_proto_rawDesc = "" + "\x0eintegration_id\x18\x01 \x01(\tR\rintegrationId\x12\x17\n" + "\arule_id\x18\x02 \x01(\tR\x06ruleId\"*\n" + "\x18DeleteCustomRuleResponse\x12\x0e\n" + - "\x02id\x18\x01 \x01(\tR\x02id2\xe8=\n" + + "\x02id\x18\x01 \x01(\tR\x02id2\xcb>\n" + "\rAperioService\x12@\n" + "\aCallApi\x12\x19.aperio.v1.CallApiRequest\x1a\x1a.aperio.v1.CallApiResponse\x12=\n" + "\x06Signup\x12\x18.aperio.v1.SignupRequest\x1a\x19.aperio.v1.SignupResponse\x12:\n" + @@ -16792,7 +17086,8 @@ const file_aperio_v1_api_proto_rawDesc = "" + "\x18UpdateSaasIncidentStatus\x12*.aperio.v1.UpdateSaasIncidentStatusRequest\x1a+.aperio.v1.UpdateSaasIncidentStatusResponse\x12v\n" + "\x19ProposeSaasResponseAction\x12+.aperio.v1.ProposeSaasResponseActionRequest\x1a,.aperio.v1.ProposeSaasResponseActionResponse\x12v\n" + "\x19ApproveSaasResponseAction\x12+.aperio.v1.ApproveSaasResponseActionRequest\x1a,.aperio.v1.ApproveSaasResponseActionResponse\x12v\n" + - "\x19ExecuteSaasResponseAction\x12+.aperio.v1.ExecuteSaasResponseActionRequest\x1a,.aperio.v1.ExecuteSaasResponseActionResponse\x12g\n" + + "\x19ExecuteSaasResponseAction\x12+.aperio.v1.ExecuteSaasResponseActionRequest\x1a,.aperio.v1.ExecuteSaasResponseActionResponse\x12a\n" + + "\x12ListDetectionPacks\x12$.aperio.v1.ListDetectionPacksRequest\x1a%.aperio.v1.ListDetectionPacksResponse\x12g\n" + "\x14ListConnectorCatalog\x12&.aperio.v1.ListConnectorCatalogRequest\x1a'.aperio.v1.ListConnectorCatalogResponse\x12[\n" + "\x10ListIntegrations\x12\".aperio.v1.ListIntegrationsRequest\x1a#.aperio.v1.ListIntegrationsResponse\x12^\n" + "\x11CreateIntegration\x12#.aperio.v1.CreateIntegrationRequest\x1a$.aperio.v1.CreateIntegrationResponse\x12^\n" + @@ -16857,7 +17152,7 @@ func file_aperio_v1_api_proto_rawDescGZIP() []byte { return file_aperio_v1_api_proto_rawDescData } -var file_aperio_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 233) +var file_aperio_v1_api_proto_msgTypes = make([]protoimpl.MessageInfo, 237) var file_aperio_v1_api_proto_goTypes = []any{ (*CallApiRequest)(nil), // 0: aperio.v1.CallApiRequest (*CallApiResponse)(nil), // 1: aperio.v1.CallApiResponse @@ -17083,16 +17378,20 @@ var file_aperio_v1_api_proto_goTypes = []any{ (*DeleteExecutiveReportRequest)(nil), // 221: aperio.v1.DeleteExecutiveReportRequest (*DeleteExecutiveReportResponse)(nil), // 222: aperio.v1.DeleteExecutiveReportResponse (*ConnectorBuiltInRule)(nil), // 223: aperio.v1.ConnectorBuiltInRule - (*ConnectorCustomRule)(nil), // 224: aperio.v1.ConnectorCustomRule - (*ListConnectorRulesRequest)(nil), // 225: aperio.v1.ListConnectorRulesRequest - (*ListConnectorRulesResponse)(nil), // 226: aperio.v1.ListConnectorRulesResponse - (*CreateCustomRuleRequest)(nil), // 227: aperio.v1.CreateCustomRuleRequest - (*CreateCustomRuleResponse)(nil), // 228: aperio.v1.CreateCustomRuleResponse - (*UpdateCustomRuleRequest)(nil), // 229: aperio.v1.UpdateCustomRuleRequest - (*UpdateCustomRuleResponse)(nil), // 230: aperio.v1.UpdateCustomRuleResponse - (*DeleteCustomRuleRequest)(nil), // 231: aperio.v1.DeleteCustomRuleRequest - (*DeleteCustomRuleResponse)(nil), // 232: aperio.v1.DeleteCustomRuleResponse - (*timestamppb.Timestamp)(nil), // 233: google.protobuf.Timestamp + (*ListDetectionPacksRequest)(nil), // 224: aperio.v1.ListDetectionPacksRequest + (*ListDetectionPacksResponse)(nil), // 225: aperio.v1.ListDetectionPacksResponse + (*DetectionPack)(nil), // 226: aperio.v1.DetectionPack + (*DetectionPackRule)(nil), // 227: aperio.v1.DetectionPackRule + (*ConnectorCustomRule)(nil), // 228: aperio.v1.ConnectorCustomRule + (*ListConnectorRulesRequest)(nil), // 229: aperio.v1.ListConnectorRulesRequest + (*ListConnectorRulesResponse)(nil), // 230: aperio.v1.ListConnectorRulesResponse + (*CreateCustomRuleRequest)(nil), // 231: aperio.v1.CreateCustomRuleRequest + (*CreateCustomRuleResponse)(nil), // 232: aperio.v1.CreateCustomRuleResponse + (*UpdateCustomRuleRequest)(nil), // 233: aperio.v1.UpdateCustomRuleRequest + (*UpdateCustomRuleResponse)(nil), // 234: aperio.v1.UpdateCustomRuleResponse + (*DeleteCustomRuleRequest)(nil), // 235: aperio.v1.DeleteCustomRuleRequest + (*DeleteCustomRuleResponse)(nil), // 236: aperio.v1.DeleteCustomRuleResponse + (*timestamppb.Timestamp)(nil), // 237: google.protobuf.Timestamp } var file_aperio_v1_api_proto_depIdxs = []int32{ 26, // 0: aperio.v1.SignupResponse.data:type_name -> aperio.v1.AuthSession @@ -17110,7 +17409,7 @@ var file_aperio_v1_api_proto_depIdxs = []int32{ 27, // 12: aperio.v1.AuthSession.user:type_name -> aperio.v1.AuthUser 28, // 13: aperio.v1.AuthSession.organization:type_name -> aperio.v1.AuthOrganization 29, // 14: aperio.v1.AuthSession.auth_context:type_name -> aperio.v1.AuthContext - 233, // 15: aperio.v1.CheckHealthResponse.checked_at:type_name -> google.protobuf.Timestamp + 237, // 15: aperio.v1.CheckHealthResponse.checked_at:type_name -> google.protobuf.Timestamp 35, // 16: aperio.v1.CheckHealthResponse.components:type_name -> aperio.v1.HealthComponent 38, // 17: aperio.v1.GetDashboardMetricsResponse.data:type_name -> aperio.v1.DashboardMetrics 49, // 18: aperio.v1.ListFindingsResponse.data:type_name -> aperio.v1.Finding @@ -17229,167 +17528,171 @@ var file_aperio_v1_api_proto_depIdxs = []int32{ 214, // 131: aperio.v1.ListExecutiveReportsResponse.data:type_name -> aperio.v1.ExecutiveReport 214, // 132: aperio.v1.GetExecutiveReportResponse.data:type_name -> aperio.v1.ExecutiveReport 214, // 133: aperio.v1.CreateExecutiveReportResponse.data:type_name -> aperio.v1.ExecutiveReport - 223, // 134: aperio.v1.ListConnectorRulesResponse.built_in:type_name -> aperio.v1.ConnectorBuiltInRule - 224, // 135: aperio.v1.ListConnectorRulesResponse.custom:type_name -> aperio.v1.ConnectorCustomRule - 0, // 136: aperio.v1.AperioService.CallApi:input_type -> aperio.v1.CallApiRequest - 2, // 137: aperio.v1.AperioService.Signup:input_type -> aperio.v1.SignupRequest - 4, // 138: aperio.v1.AperioService.Login:input_type -> aperio.v1.LoginRequest - 6, // 139: aperio.v1.AperioService.GetCurrentSession:input_type -> aperio.v1.GetCurrentSessionRequest - 8, // 140: aperio.v1.AperioService.LogoutCurrentSession:input_type -> aperio.v1.LogoutCurrentSessionRequest - 10, // 141: aperio.v1.AperioService.ListWorkspaces:input_type -> aperio.v1.ListWorkspacesRequest - 12, // 142: aperio.v1.AperioService.SwitchWorkspace:input_type -> aperio.v1.SwitchWorkspaceRequest - 14, // 143: aperio.v1.AperioService.RequestPasswordReset:input_type -> aperio.v1.RequestPasswordResetRequest - 16, // 144: aperio.v1.AperioService.ResetPassword:input_type -> aperio.v1.ResetPasswordRequest - 18, // 145: aperio.v1.AperioService.AcceptInvite:input_type -> aperio.v1.AcceptInviteRequest - 20, // 146: aperio.v1.AperioService.BeginMfaEnrollment:input_type -> aperio.v1.BeginMfaEnrollmentRequest - 22, // 147: aperio.v1.AperioService.EnableMfa:input_type -> aperio.v1.EnableMfaRequest - 24, // 148: aperio.v1.AperioService.DisableMfa:input_type -> aperio.v1.DisableMfaRequest - 33, // 149: aperio.v1.AperioService.CheckHealth:input_type -> aperio.v1.CheckHealthRequest - 36, // 150: aperio.v1.AperioService.GetDashboardMetrics:input_type -> aperio.v1.GetDashboardMetricsRequest - 39, // 151: aperio.v1.AperioService.ListFindings:input_type -> aperio.v1.ListFindingsRequest - 41, // 152: aperio.v1.AperioService.GetFinding:input_type -> aperio.v1.GetFindingRequest - 43, // 153: aperio.v1.AperioService.UpdateFindingStatus:input_type -> aperio.v1.UpdateFindingStatusRequest - 46, // 154: aperio.v1.AperioService.RemediateFinding:input_type -> aperio.v1.RemediateFindingRequest - 58, // 155: aperio.v1.AperioService.ListSaasIncidents:input_type -> aperio.v1.ListSaasIncidentsRequest - 60, // 156: aperio.v1.AperioService.GetSaasIncident:input_type -> aperio.v1.GetSaasIncidentRequest - 62, // 157: aperio.v1.AperioService.CreateSaasIncident:input_type -> aperio.v1.CreateSaasIncidentRequest - 64, // 158: aperio.v1.AperioService.UpdateSaasIncidentStatus:input_type -> aperio.v1.UpdateSaasIncidentStatusRequest - 66, // 159: aperio.v1.AperioService.ProposeSaasResponseAction:input_type -> aperio.v1.ProposeSaasResponseActionRequest - 68, // 160: aperio.v1.AperioService.ApproveSaasResponseAction:input_type -> aperio.v1.ApproveSaasResponseActionRequest - 70, // 161: aperio.v1.AperioService.ExecuteSaasResponseAction:input_type -> aperio.v1.ExecuteSaasResponseActionRequest - 78, // 162: aperio.v1.AperioService.ListConnectorCatalog:input_type -> aperio.v1.ListConnectorCatalogRequest - 84, // 163: aperio.v1.AperioService.ListIntegrations:input_type -> aperio.v1.ListIntegrationsRequest - 87, // 164: aperio.v1.AperioService.CreateIntegration:input_type -> aperio.v1.CreateIntegrationRequest - 90, // 165: aperio.v1.AperioService.DeleteIntegration:input_type -> aperio.v1.DeleteIntegrationRequest - 93, // 166: aperio.v1.AperioService.GetIntegrationChecks:input_type -> aperio.v1.GetIntegrationChecksRequest - 95, // 167: aperio.v1.AperioService.UpdateIntegrationChecks:input_type -> aperio.v1.UpdateIntegrationChecksRequest - 225, // 168: aperio.v1.AperioService.ListConnectorRules:input_type -> aperio.v1.ListConnectorRulesRequest - 227, // 169: aperio.v1.AperioService.CreateCustomRule:input_type -> aperio.v1.CreateCustomRuleRequest - 229, // 170: aperio.v1.AperioService.UpdateCustomRule:input_type -> aperio.v1.UpdateCustomRuleRequest - 231, // 171: aperio.v1.AperioService.DeleteCustomRule:input_type -> aperio.v1.DeleteCustomRuleRequest - 99, // 172: aperio.v1.AperioService.GetGoogleMailboxScanConfig:input_type -> aperio.v1.GetGoogleMailboxScanConfigRequest - 101, // 173: aperio.v1.AperioService.UpdateGoogleMailboxScanConfig:input_type -> aperio.v1.UpdateGoogleMailboxScanConfigRequest - 104, // 174: aperio.v1.AperioService.GetGoogleWorkspaceBigQueryConfig:input_type -> aperio.v1.GetGoogleWorkspaceBigQueryConfigRequest - 106, // 175: aperio.v1.AperioService.UpdateGoogleWorkspaceBigQueryConfig:input_type -> aperio.v1.UpdateGoogleWorkspaceBigQueryConfigRequest - 109, // 176: aperio.v1.AperioService.ValidateGoogleWorkspaceBigQueryConfig:input_type -> aperio.v1.ValidateGoogleWorkspaceBigQueryConfigRequest - 112, // 177: aperio.v1.AperioService.StartGoogleWorkspaceOAuth:input_type -> aperio.v1.StartGoogleWorkspaceOAuthRequest - 115, // 178: aperio.v1.AperioService.GetIntegrationOAuthClient:input_type -> aperio.v1.GetIntegrationOAuthClientRequest - 117, // 179: aperio.v1.AperioService.SetIntegrationOAuthClient:input_type -> aperio.v1.SetIntegrationOAuthClientRequest - 119, // 180: aperio.v1.AperioService.ClearIntegrationOAuthClient:input_type -> aperio.v1.ClearIntegrationOAuthClientRequest - 122, // 181: aperio.v1.AperioService.ForceSyncIntegration:input_type -> aperio.v1.ForceSyncIntegrationRequest - 125, // 182: aperio.v1.AperioService.GetIntegrationSyncStatus:input_type -> aperio.v1.GetIntegrationSyncStatusRequest - 127, // 183: aperio.v1.AperioService.RunIntegrationSourceSync:input_type -> aperio.v1.RunIntegrationSourceSyncRequest - 129, // 184: aperio.v1.AperioService.BackfillIntegrationSource:input_type -> aperio.v1.BackfillIntegrationSourceRequest - 134, // 185: aperio.v1.AperioService.ListSiemCatalog:input_type -> aperio.v1.ListSiemCatalogRequest - 138, // 186: aperio.v1.AperioService.ListSiemDestinations:input_type -> aperio.v1.ListSiemDestinationsRequest - 141, // 187: aperio.v1.AperioService.CreateSiemDestination:input_type -> aperio.v1.CreateSiemDestinationRequest - 143, // 188: aperio.v1.AperioService.DeleteSiemDestination:input_type -> aperio.v1.DeleteSiemDestinationRequest - 145, // 189: aperio.v1.AperioService.TestSiemDestination:input_type -> aperio.v1.TestSiemDestinationRequest - 148, // 190: aperio.v1.AperioService.ListShadowItOauthApps:input_type -> aperio.v1.ListShadowItOauthAppsRequest - 151, // 191: aperio.v1.AperioService.ListShadowItOauthAppGrants:input_type -> aperio.v1.ListShadowItOauthAppGrantsRequest - 156, // 192: aperio.v1.AperioService.GetTenantSettings:input_type -> aperio.v1.GetTenantSettingsRequest - 158, // 193: aperio.v1.AperioService.UpdateTenantSettings:input_type -> aperio.v1.UpdateTenantSettingsRequest - 161, // 194: aperio.v1.AperioService.ListTenantMembers:input_type -> aperio.v1.ListTenantMembersRequest - 163, // 195: aperio.v1.AperioService.CreateTenantMember:input_type -> aperio.v1.CreateTenantMemberRequest - 165, // 196: aperio.v1.AperioService.CreateMemberResetLink:input_type -> aperio.v1.CreateMemberResetLinkRequest - 167, // 197: aperio.v1.AperioService.UpdateMemberRole:input_type -> aperio.v1.UpdateMemberRoleRequest - 171, // 198: aperio.v1.AperioService.ListAuditLogs:input_type -> aperio.v1.ListAuditLogsRequest - 174, // 199: aperio.v1.AperioService.GetSecurityOverview:input_type -> aperio.v1.GetSecurityOverviewRequest - 186, // 200: aperio.v1.AperioService.ListEmailDomainHealth:input_type -> aperio.v1.ListEmailDomainHealthRequest - 188, // 201: aperio.v1.AperioService.GetEmailDomainHealth:input_type -> aperio.v1.GetEmailDomainHealthRequest - 190, // 202: aperio.v1.AperioService.RefreshEmailDomainHealth:input_type -> aperio.v1.RefreshEmailDomainHealthRequest - 197, // 203: aperio.v1.AperioService.ListSecurityAssets:input_type -> aperio.v1.ListSecurityAssetsRequest - 201, // 204: aperio.v1.AperioService.CreateSecurityAsset:input_type -> aperio.v1.CreateSecurityAssetRequest - 203, // 205: aperio.v1.AperioService.UpdateSecurityAsset:input_type -> aperio.v1.UpdateSecurityAssetRequest - 205, // 206: aperio.v1.AperioService.ListRiskExceptions:input_type -> aperio.v1.ListRiskExceptionsRequest - 210, // 207: aperio.v1.AperioService.CreateRiskException:input_type -> aperio.v1.CreateRiskExceptionRequest - 212, // 208: aperio.v1.AperioService.UpdateRiskException:input_type -> aperio.v1.UpdateRiskExceptionRequest - 215, // 209: aperio.v1.AperioService.ListExecutiveReports:input_type -> aperio.v1.ListExecutiveReportsRequest - 217, // 210: aperio.v1.AperioService.GetExecutiveReport:input_type -> aperio.v1.GetExecutiveReportRequest - 219, // 211: aperio.v1.AperioService.CreateExecutiveReport:input_type -> aperio.v1.CreateExecutiveReportRequest - 221, // 212: aperio.v1.AperioService.DeleteExecutiveReport:input_type -> aperio.v1.DeleteExecutiveReportRequest - 1, // 213: aperio.v1.AperioService.CallApi:output_type -> aperio.v1.CallApiResponse - 3, // 214: aperio.v1.AperioService.Signup:output_type -> aperio.v1.SignupResponse - 5, // 215: aperio.v1.AperioService.Login:output_type -> aperio.v1.LoginResponse - 7, // 216: aperio.v1.AperioService.GetCurrentSession:output_type -> aperio.v1.GetCurrentSessionResponse - 9, // 217: aperio.v1.AperioService.LogoutCurrentSession:output_type -> aperio.v1.LogoutCurrentSessionResponse - 11, // 218: aperio.v1.AperioService.ListWorkspaces:output_type -> aperio.v1.ListWorkspacesResponse - 13, // 219: aperio.v1.AperioService.SwitchWorkspace:output_type -> aperio.v1.SwitchWorkspaceResponse - 15, // 220: aperio.v1.AperioService.RequestPasswordReset:output_type -> aperio.v1.RequestPasswordResetResponse - 17, // 221: aperio.v1.AperioService.ResetPassword:output_type -> aperio.v1.ResetPasswordResponse - 19, // 222: aperio.v1.AperioService.AcceptInvite:output_type -> aperio.v1.AcceptInviteResponse - 21, // 223: aperio.v1.AperioService.BeginMfaEnrollment:output_type -> aperio.v1.BeginMfaEnrollmentResponse - 23, // 224: aperio.v1.AperioService.EnableMfa:output_type -> aperio.v1.EnableMfaResponse - 25, // 225: aperio.v1.AperioService.DisableMfa:output_type -> aperio.v1.DisableMfaResponse - 34, // 226: aperio.v1.AperioService.CheckHealth:output_type -> aperio.v1.CheckHealthResponse - 37, // 227: aperio.v1.AperioService.GetDashboardMetrics:output_type -> aperio.v1.GetDashboardMetricsResponse - 40, // 228: aperio.v1.AperioService.ListFindings:output_type -> aperio.v1.ListFindingsResponse - 42, // 229: aperio.v1.AperioService.GetFinding:output_type -> aperio.v1.GetFindingResponse - 44, // 230: aperio.v1.AperioService.UpdateFindingStatus:output_type -> aperio.v1.UpdateFindingStatusResponse - 47, // 231: aperio.v1.AperioService.RemediateFinding:output_type -> aperio.v1.RemediateFindingResponse - 59, // 232: aperio.v1.AperioService.ListSaasIncidents:output_type -> aperio.v1.ListSaasIncidentsResponse - 61, // 233: aperio.v1.AperioService.GetSaasIncident:output_type -> aperio.v1.GetSaasIncidentResponse - 63, // 234: aperio.v1.AperioService.CreateSaasIncident:output_type -> aperio.v1.CreateSaasIncidentResponse - 65, // 235: aperio.v1.AperioService.UpdateSaasIncidentStatus:output_type -> aperio.v1.UpdateSaasIncidentStatusResponse - 67, // 236: aperio.v1.AperioService.ProposeSaasResponseAction:output_type -> aperio.v1.ProposeSaasResponseActionResponse - 69, // 237: aperio.v1.AperioService.ApproveSaasResponseAction:output_type -> aperio.v1.ApproveSaasResponseActionResponse - 71, // 238: aperio.v1.AperioService.ExecuteSaasResponseAction:output_type -> aperio.v1.ExecuteSaasResponseActionResponse - 79, // 239: aperio.v1.AperioService.ListConnectorCatalog:output_type -> aperio.v1.ListConnectorCatalogResponse - 85, // 240: aperio.v1.AperioService.ListIntegrations:output_type -> aperio.v1.ListIntegrationsResponse - 89, // 241: aperio.v1.AperioService.CreateIntegration:output_type -> aperio.v1.CreateIntegrationResponse - 91, // 242: aperio.v1.AperioService.DeleteIntegration:output_type -> aperio.v1.DeleteIntegrationResponse - 94, // 243: aperio.v1.AperioService.GetIntegrationChecks:output_type -> aperio.v1.GetIntegrationChecksResponse - 96, // 244: aperio.v1.AperioService.UpdateIntegrationChecks:output_type -> aperio.v1.UpdateIntegrationChecksResponse - 226, // 245: aperio.v1.AperioService.ListConnectorRules:output_type -> aperio.v1.ListConnectorRulesResponse - 228, // 246: aperio.v1.AperioService.CreateCustomRule:output_type -> aperio.v1.CreateCustomRuleResponse - 230, // 247: aperio.v1.AperioService.UpdateCustomRule:output_type -> aperio.v1.UpdateCustomRuleResponse - 232, // 248: aperio.v1.AperioService.DeleteCustomRule:output_type -> aperio.v1.DeleteCustomRuleResponse - 100, // 249: aperio.v1.AperioService.GetGoogleMailboxScanConfig:output_type -> aperio.v1.GetGoogleMailboxScanConfigResponse - 102, // 250: aperio.v1.AperioService.UpdateGoogleMailboxScanConfig:output_type -> aperio.v1.UpdateGoogleMailboxScanConfigResponse - 105, // 251: aperio.v1.AperioService.GetGoogleWorkspaceBigQueryConfig:output_type -> aperio.v1.GetGoogleWorkspaceBigQueryConfigResponse - 107, // 252: aperio.v1.AperioService.UpdateGoogleWorkspaceBigQueryConfig:output_type -> aperio.v1.UpdateGoogleWorkspaceBigQueryConfigResponse - 110, // 253: aperio.v1.AperioService.ValidateGoogleWorkspaceBigQueryConfig:output_type -> aperio.v1.ValidateGoogleWorkspaceBigQueryConfigResponse - 113, // 254: aperio.v1.AperioService.StartGoogleWorkspaceOAuth:output_type -> aperio.v1.StartGoogleWorkspaceOAuthResponse - 116, // 255: aperio.v1.AperioService.GetIntegrationOAuthClient:output_type -> aperio.v1.GetIntegrationOAuthClientResponse - 118, // 256: aperio.v1.AperioService.SetIntegrationOAuthClient:output_type -> aperio.v1.SetIntegrationOAuthClientResponse - 120, // 257: aperio.v1.AperioService.ClearIntegrationOAuthClient:output_type -> aperio.v1.ClearIntegrationOAuthClientResponse - 123, // 258: aperio.v1.AperioService.ForceSyncIntegration:output_type -> aperio.v1.ForceSyncIntegrationResponse - 126, // 259: aperio.v1.AperioService.GetIntegrationSyncStatus:output_type -> aperio.v1.GetIntegrationSyncStatusResponse - 128, // 260: aperio.v1.AperioService.RunIntegrationSourceSync:output_type -> aperio.v1.RunIntegrationSourceSyncResponse - 130, // 261: aperio.v1.AperioService.BackfillIntegrationSource:output_type -> aperio.v1.BackfillIntegrationSourceResponse - 135, // 262: aperio.v1.AperioService.ListSiemCatalog:output_type -> aperio.v1.ListSiemCatalogResponse - 139, // 263: aperio.v1.AperioService.ListSiemDestinations:output_type -> aperio.v1.ListSiemDestinationsResponse - 142, // 264: aperio.v1.AperioService.CreateSiemDestination:output_type -> aperio.v1.CreateSiemDestinationResponse - 144, // 265: aperio.v1.AperioService.DeleteSiemDestination:output_type -> aperio.v1.DeleteSiemDestinationResponse - 146, // 266: aperio.v1.AperioService.TestSiemDestination:output_type -> aperio.v1.TestSiemDestinationResponse - 149, // 267: aperio.v1.AperioService.ListShadowItOauthApps:output_type -> aperio.v1.ListShadowItOauthAppsResponse - 152, // 268: aperio.v1.AperioService.ListShadowItOauthAppGrants:output_type -> aperio.v1.ListShadowItOauthAppGrantsResponse - 157, // 269: aperio.v1.AperioService.GetTenantSettings:output_type -> aperio.v1.GetTenantSettingsResponse - 159, // 270: aperio.v1.AperioService.UpdateTenantSettings:output_type -> aperio.v1.UpdateTenantSettingsResponse - 162, // 271: aperio.v1.AperioService.ListTenantMembers:output_type -> aperio.v1.ListTenantMembersResponse - 164, // 272: aperio.v1.AperioService.CreateTenantMember:output_type -> aperio.v1.CreateTenantMemberResponse - 166, // 273: aperio.v1.AperioService.CreateMemberResetLink:output_type -> aperio.v1.CreateMemberResetLinkResponse - 168, // 274: aperio.v1.AperioService.UpdateMemberRole:output_type -> aperio.v1.UpdateMemberRoleResponse - 172, // 275: aperio.v1.AperioService.ListAuditLogs:output_type -> aperio.v1.ListAuditLogsResponse - 175, // 276: aperio.v1.AperioService.GetSecurityOverview:output_type -> aperio.v1.GetSecurityOverviewResponse - 187, // 277: aperio.v1.AperioService.ListEmailDomainHealth:output_type -> aperio.v1.ListEmailDomainHealthResponse - 189, // 278: aperio.v1.AperioService.GetEmailDomainHealth:output_type -> aperio.v1.GetEmailDomainHealthResponse - 191, // 279: aperio.v1.AperioService.RefreshEmailDomainHealth:output_type -> aperio.v1.RefreshEmailDomainHealthResponse - 198, // 280: aperio.v1.AperioService.ListSecurityAssets:output_type -> aperio.v1.ListSecurityAssetsResponse - 202, // 281: aperio.v1.AperioService.CreateSecurityAsset:output_type -> aperio.v1.CreateSecurityAssetResponse - 204, // 282: aperio.v1.AperioService.UpdateSecurityAsset:output_type -> aperio.v1.UpdateSecurityAssetResponse - 206, // 283: aperio.v1.AperioService.ListRiskExceptions:output_type -> aperio.v1.ListRiskExceptionsResponse - 211, // 284: aperio.v1.AperioService.CreateRiskException:output_type -> aperio.v1.CreateRiskExceptionResponse - 213, // 285: aperio.v1.AperioService.UpdateRiskException:output_type -> aperio.v1.UpdateRiskExceptionResponse - 216, // 286: aperio.v1.AperioService.ListExecutiveReports:output_type -> aperio.v1.ListExecutiveReportsResponse - 218, // 287: aperio.v1.AperioService.GetExecutiveReport:output_type -> aperio.v1.GetExecutiveReportResponse - 220, // 288: aperio.v1.AperioService.CreateExecutiveReport:output_type -> aperio.v1.CreateExecutiveReportResponse - 222, // 289: aperio.v1.AperioService.DeleteExecutiveReport:output_type -> aperio.v1.DeleteExecutiveReportResponse - 213, // [213:290] is the sub-list for method output_type - 136, // [136:213] is the sub-list for method input_type - 136, // [136:136] is the sub-list for extension type_name - 136, // [136:136] is the sub-list for extension extendee - 0, // [0:136] is the sub-list for field type_name + 226, // 134: aperio.v1.ListDetectionPacksResponse.data:type_name -> aperio.v1.DetectionPack + 227, // 135: aperio.v1.DetectionPack.rules:type_name -> aperio.v1.DetectionPackRule + 223, // 136: aperio.v1.ListConnectorRulesResponse.built_in:type_name -> aperio.v1.ConnectorBuiltInRule + 228, // 137: aperio.v1.ListConnectorRulesResponse.custom:type_name -> aperio.v1.ConnectorCustomRule + 0, // 138: aperio.v1.AperioService.CallApi:input_type -> aperio.v1.CallApiRequest + 2, // 139: aperio.v1.AperioService.Signup:input_type -> aperio.v1.SignupRequest + 4, // 140: aperio.v1.AperioService.Login:input_type -> aperio.v1.LoginRequest + 6, // 141: aperio.v1.AperioService.GetCurrentSession:input_type -> aperio.v1.GetCurrentSessionRequest + 8, // 142: aperio.v1.AperioService.LogoutCurrentSession:input_type -> aperio.v1.LogoutCurrentSessionRequest + 10, // 143: aperio.v1.AperioService.ListWorkspaces:input_type -> aperio.v1.ListWorkspacesRequest + 12, // 144: aperio.v1.AperioService.SwitchWorkspace:input_type -> aperio.v1.SwitchWorkspaceRequest + 14, // 145: aperio.v1.AperioService.RequestPasswordReset:input_type -> aperio.v1.RequestPasswordResetRequest + 16, // 146: aperio.v1.AperioService.ResetPassword:input_type -> aperio.v1.ResetPasswordRequest + 18, // 147: aperio.v1.AperioService.AcceptInvite:input_type -> aperio.v1.AcceptInviteRequest + 20, // 148: aperio.v1.AperioService.BeginMfaEnrollment:input_type -> aperio.v1.BeginMfaEnrollmentRequest + 22, // 149: aperio.v1.AperioService.EnableMfa:input_type -> aperio.v1.EnableMfaRequest + 24, // 150: aperio.v1.AperioService.DisableMfa:input_type -> aperio.v1.DisableMfaRequest + 33, // 151: aperio.v1.AperioService.CheckHealth:input_type -> aperio.v1.CheckHealthRequest + 36, // 152: aperio.v1.AperioService.GetDashboardMetrics:input_type -> aperio.v1.GetDashboardMetricsRequest + 39, // 153: aperio.v1.AperioService.ListFindings:input_type -> aperio.v1.ListFindingsRequest + 41, // 154: aperio.v1.AperioService.GetFinding:input_type -> aperio.v1.GetFindingRequest + 43, // 155: aperio.v1.AperioService.UpdateFindingStatus:input_type -> aperio.v1.UpdateFindingStatusRequest + 46, // 156: aperio.v1.AperioService.RemediateFinding:input_type -> aperio.v1.RemediateFindingRequest + 58, // 157: aperio.v1.AperioService.ListSaasIncidents:input_type -> aperio.v1.ListSaasIncidentsRequest + 60, // 158: aperio.v1.AperioService.GetSaasIncident:input_type -> aperio.v1.GetSaasIncidentRequest + 62, // 159: aperio.v1.AperioService.CreateSaasIncident:input_type -> aperio.v1.CreateSaasIncidentRequest + 64, // 160: aperio.v1.AperioService.UpdateSaasIncidentStatus:input_type -> aperio.v1.UpdateSaasIncidentStatusRequest + 66, // 161: aperio.v1.AperioService.ProposeSaasResponseAction:input_type -> aperio.v1.ProposeSaasResponseActionRequest + 68, // 162: aperio.v1.AperioService.ApproveSaasResponseAction:input_type -> aperio.v1.ApproveSaasResponseActionRequest + 70, // 163: aperio.v1.AperioService.ExecuteSaasResponseAction:input_type -> aperio.v1.ExecuteSaasResponseActionRequest + 224, // 164: aperio.v1.AperioService.ListDetectionPacks:input_type -> aperio.v1.ListDetectionPacksRequest + 78, // 165: aperio.v1.AperioService.ListConnectorCatalog:input_type -> aperio.v1.ListConnectorCatalogRequest + 84, // 166: aperio.v1.AperioService.ListIntegrations:input_type -> aperio.v1.ListIntegrationsRequest + 87, // 167: aperio.v1.AperioService.CreateIntegration:input_type -> aperio.v1.CreateIntegrationRequest + 90, // 168: aperio.v1.AperioService.DeleteIntegration:input_type -> aperio.v1.DeleteIntegrationRequest + 93, // 169: aperio.v1.AperioService.GetIntegrationChecks:input_type -> aperio.v1.GetIntegrationChecksRequest + 95, // 170: aperio.v1.AperioService.UpdateIntegrationChecks:input_type -> aperio.v1.UpdateIntegrationChecksRequest + 229, // 171: aperio.v1.AperioService.ListConnectorRules:input_type -> aperio.v1.ListConnectorRulesRequest + 231, // 172: aperio.v1.AperioService.CreateCustomRule:input_type -> aperio.v1.CreateCustomRuleRequest + 233, // 173: aperio.v1.AperioService.UpdateCustomRule:input_type -> aperio.v1.UpdateCustomRuleRequest + 235, // 174: aperio.v1.AperioService.DeleteCustomRule:input_type -> aperio.v1.DeleteCustomRuleRequest + 99, // 175: aperio.v1.AperioService.GetGoogleMailboxScanConfig:input_type -> aperio.v1.GetGoogleMailboxScanConfigRequest + 101, // 176: aperio.v1.AperioService.UpdateGoogleMailboxScanConfig:input_type -> aperio.v1.UpdateGoogleMailboxScanConfigRequest + 104, // 177: aperio.v1.AperioService.GetGoogleWorkspaceBigQueryConfig:input_type -> aperio.v1.GetGoogleWorkspaceBigQueryConfigRequest + 106, // 178: aperio.v1.AperioService.UpdateGoogleWorkspaceBigQueryConfig:input_type -> aperio.v1.UpdateGoogleWorkspaceBigQueryConfigRequest + 109, // 179: aperio.v1.AperioService.ValidateGoogleWorkspaceBigQueryConfig:input_type -> aperio.v1.ValidateGoogleWorkspaceBigQueryConfigRequest + 112, // 180: aperio.v1.AperioService.StartGoogleWorkspaceOAuth:input_type -> aperio.v1.StartGoogleWorkspaceOAuthRequest + 115, // 181: aperio.v1.AperioService.GetIntegrationOAuthClient:input_type -> aperio.v1.GetIntegrationOAuthClientRequest + 117, // 182: aperio.v1.AperioService.SetIntegrationOAuthClient:input_type -> aperio.v1.SetIntegrationOAuthClientRequest + 119, // 183: aperio.v1.AperioService.ClearIntegrationOAuthClient:input_type -> aperio.v1.ClearIntegrationOAuthClientRequest + 122, // 184: aperio.v1.AperioService.ForceSyncIntegration:input_type -> aperio.v1.ForceSyncIntegrationRequest + 125, // 185: aperio.v1.AperioService.GetIntegrationSyncStatus:input_type -> aperio.v1.GetIntegrationSyncStatusRequest + 127, // 186: aperio.v1.AperioService.RunIntegrationSourceSync:input_type -> aperio.v1.RunIntegrationSourceSyncRequest + 129, // 187: aperio.v1.AperioService.BackfillIntegrationSource:input_type -> aperio.v1.BackfillIntegrationSourceRequest + 134, // 188: aperio.v1.AperioService.ListSiemCatalog:input_type -> aperio.v1.ListSiemCatalogRequest + 138, // 189: aperio.v1.AperioService.ListSiemDestinations:input_type -> aperio.v1.ListSiemDestinationsRequest + 141, // 190: aperio.v1.AperioService.CreateSiemDestination:input_type -> aperio.v1.CreateSiemDestinationRequest + 143, // 191: aperio.v1.AperioService.DeleteSiemDestination:input_type -> aperio.v1.DeleteSiemDestinationRequest + 145, // 192: aperio.v1.AperioService.TestSiemDestination:input_type -> aperio.v1.TestSiemDestinationRequest + 148, // 193: aperio.v1.AperioService.ListShadowItOauthApps:input_type -> aperio.v1.ListShadowItOauthAppsRequest + 151, // 194: aperio.v1.AperioService.ListShadowItOauthAppGrants:input_type -> aperio.v1.ListShadowItOauthAppGrantsRequest + 156, // 195: aperio.v1.AperioService.GetTenantSettings:input_type -> aperio.v1.GetTenantSettingsRequest + 158, // 196: aperio.v1.AperioService.UpdateTenantSettings:input_type -> aperio.v1.UpdateTenantSettingsRequest + 161, // 197: aperio.v1.AperioService.ListTenantMembers:input_type -> aperio.v1.ListTenantMembersRequest + 163, // 198: aperio.v1.AperioService.CreateTenantMember:input_type -> aperio.v1.CreateTenantMemberRequest + 165, // 199: aperio.v1.AperioService.CreateMemberResetLink:input_type -> aperio.v1.CreateMemberResetLinkRequest + 167, // 200: aperio.v1.AperioService.UpdateMemberRole:input_type -> aperio.v1.UpdateMemberRoleRequest + 171, // 201: aperio.v1.AperioService.ListAuditLogs:input_type -> aperio.v1.ListAuditLogsRequest + 174, // 202: aperio.v1.AperioService.GetSecurityOverview:input_type -> aperio.v1.GetSecurityOverviewRequest + 186, // 203: aperio.v1.AperioService.ListEmailDomainHealth:input_type -> aperio.v1.ListEmailDomainHealthRequest + 188, // 204: aperio.v1.AperioService.GetEmailDomainHealth:input_type -> aperio.v1.GetEmailDomainHealthRequest + 190, // 205: aperio.v1.AperioService.RefreshEmailDomainHealth:input_type -> aperio.v1.RefreshEmailDomainHealthRequest + 197, // 206: aperio.v1.AperioService.ListSecurityAssets:input_type -> aperio.v1.ListSecurityAssetsRequest + 201, // 207: aperio.v1.AperioService.CreateSecurityAsset:input_type -> aperio.v1.CreateSecurityAssetRequest + 203, // 208: aperio.v1.AperioService.UpdateSecurityAsset:input_type -> aperio.v1.UpdateSecurityAssetRequest + 205, // 209: aperio.v1.AperioService.ListRiskExceptions:input_type -> aperio.v1.ListRiskExceptionsRequest + 210, // 210: aperio.v1.AperioService.CreateRiskException:input_type -> aperio.v1.CreateRiskExceptionRequest + 212, // 211: aperio.v1.AperioService.UpdateRiskException:input_type -> aperio.v1.UpdateRiskExceptionRequest + 215, // 212: aperio.v1.AperioService.ListExecutiveReports:input_type -> aperio.v1.ListExecutiveReportsRequest + 217, // 213: aperio.v1.AperioService.GetExecutiveReport:input_type -> aperio.v1.GetExecutiveReportRequest + 219, // 214: aperio.v1.AperioService.CreateExecutiveReport:input_type -> aperio.v1.CreateExecutiveReportRequest + 221, // 215: aperio.v1.AperioService.DeleteExecutiveReport:input_type -> aperio.v1.DeleteExecutiveReportRequest + 1, // 216: aperio.v1.AperioService.CallApi:output_type -> aperio.v1.CallApiResponse + 3, // 217: aperio.v1.AperioService.Signup:output_type -> aperio.v1.SignupResponse + 5, // 218: aperio.v1.AperioService.Login:output_type -> aperio.v1.LoginResponse + 7, // 219: aperio.v1.AperioService.GetCurrentSession:output_type -> aperio.v1.GetCurrentSessionResponse + 9, // 220: aperio.v1.AperioService.LogoutCurrentSession:output_type -> aperio.v1.LogoutCurrentSessionResponse + 11, // 221: aperio.v1.AperioService.ListWorkspaces:output_type -> aperio.v1.ListWorkspacesResponse + 13, // 222: aperio.v1.AperioService.SwitchWorkspace:output_type -> aperio.v1.SwitchWorkspaceResponse + 15, // 223: aperio.v1.AperioService.RequestPasswordReset:output_type -> aperio.v1.RequestPasswordResetResponse + 17, // 224: aperio.v1.AperioService.ResetPassword:output_type -> aperio.v1.ResetPasswordResponse + 19, // 225: aperio.v1.AperioService.AcceptInvite:output_type -> aperio.v1.AcceptInviteResponse + 21, // 226: aperio.v1.AperioService.BeginMfaEnrollment:output_type -> aperio.v1.BeginMfaEnrollmentResponse + 23, // 227: aperio.v1.AperioService.EnableMfa:output_type -> aperio.v1.EnableMfaResponse + 25, // 228: aperio.v1.AperioService.DisableMfa:output_type -> aperio.v1.DisableMfaResponse + 34, // 229: aperio.v1.AperioService.CheckHealth:output_type -> aperio.v1.CheckHealthResponse + 37, // 230: aperio.v1.AperioService.GetDashboardMetrics:output_type -> aperio.v1.GetDashboardMetricsResponse + 40, // 231: aperio.v1.AperioService.ListFindings:output_type -> aperio.v1.ListFindingsResponse + 42, // 232: aperio.v1.AperioService.GetFinding:output_type -> aperio.v1.GetFindingResponse + 44, // 233: aperio.v1.AperioService.UpdateFindingStatus:output_type -> aperio.v1.UpdateFindingStatusResponse + 47, // 234: aperio.v1.AperioService.RemediateFinding:output_type -> aperio.v1.RemediateFindingResponse + 59, // 235: aperio.v1.AperioService.ListSaasIncidents:output_type -> aperio.v1.ListSaasIncidentsResponse + 61, // 236: aperio.v1.AperioService.GetSaasIncident:output_type -> aperio.v1.GetSaasIncidentResponse + 63, // 237: aperio.v1.AperioService.CreateSaasIncident:output_type -> aperio.v1.CreateSaasIncidentResponse + 65, // 238: aperio.v1.AperioService.UpdateSaasIncidentStatus:output_type -> aperio.v1.UpdateSaasIncidentStatusResponse + 67, // 239: aperio.v1.AperioService.ProposeSaasResponseAction:output_type -> aperio.v1.ProposeSaasResponseActionResponse + 69, // 240: aperio.v1.AperioService.ApproveSaasResponseAction:output_type -> aperio.v1.ApproveSaasResponseActionResponse + 71, // 241: aperio.v1.AperioService.ExecuteSaasResponseAction:output_type -> aperio.v1.ExecuteSaasResponseActionResponse + 225, // 242: aperio.v1.AperioService.ListDetectionPacks:output_type -> aperio.v1.ListDetectionPacksResponse + 79, // 243: aperio.v1.AperioService.ListConnectorCatalog:output_type -> aperio.v1.ListConnectorCatalogResponse + 85, // 244: aperio.v1.AperioService.ListIntegrations:output_type -> aperio.v1.ListIntegrationsResponse + 89, // 245: aperio.v1.AperioService.CreateIntegration:output_type -> aperio.v1.CreateIntegrationResponse + 91, // 246: aperio.v1.AperioService.DeleteIntegration:output_type -> aperio.v1.DeleteIntegrationResponse + 94, // 247: aperio.v1.AperioService.GetIntegrationChecks:output_type -> aperio.v1.GetIntegrationChecksResponse + 96, // 248: aperio.v1.AperioService.UpdateIntegrationChecks:output_type -> aperio.v1.UpdateIntegrationChecksResponse + 230, // 249: aperio.v1.AperioService.ListConnectorRules:output_type -> aperio.v1.ListConnectorRulesResponse + 232, // 250: aperio.v1.AperioService.CreateCustomRule:output_type -> aperio.v1.CreateCustomRuleResponse + 234, // 251: aperio.v1.AperioService.UpdateCustomRule:output_type -> aperio.v1.UpdateCustomRuleResponse + 236, // 252: aperio.v1.AperioService.DeleteCustomRule:output_type -> aperio.v1.DeleteCustomRuleResponse + 100, // 253: aperio.v1.AperioService.GetGoogleMailboxScanConfig:output_type -> aperio.v1.GetGoogleMailboxScanConfigResponse + 102, // 254: aperio.v1.AperioService.UpdateGoogleMailboxScanConfig:output_type -> aperio.v1.UpdateGoogleMailboxScanConfigResponse + 105, // 255: aperio.v1.AperioService.GetGoogleWorkspaceBigQueryConfig:output_type -> aperio.v1.GetGoogleWorkspaceBigQueryConfigResponse + 107, // 256: aperio.v1.AperioService.UpdateGoogleWorkspaceBigQueryConfig:output_type -> aperio.v1.UpdateGoogleWorkspaceBigQueryConfigResponse + 110, // 257: aperio.v1.AperioService.ValidateGoogleWorkspaceBigQueryConfig:output_type -> aperio.v1.ValidateGoogleWorkspaceBigQueryConfigResponse + 113, // 258: aperio.v1.AperioService.StartGoogleWorkspaceOAuth:output_type -> aperio.v1.StartGoogleWorkspaceOAuthResponse + 116, // 259: aperio.v1.AperioService.GetIntegrationOAuthClient:output_type -> aperio.v1.GetIntegrationOAuthClientResponse + 118, // 260: aperio.v1.AperioService.SetIntegrationOAuthClient:output_type -> aperio.v1.SetIntegrationOAuthClientResponse + 120, // 261: aperio.v1.AperioService.ClearIntegrationOAuthClient:output_type -> aperio.v1.ClearIntegrationOAuthClientResponse + 123, // 262: aperio.v1.AperioService.ForceSyncIntegration:output_type -> aperio.v1.ForceSyncIntegrationResponse + 126, // 263: aperio.v1.AperioService.GetIntegrationSyncStatus:output_type -> aperio.v1.GetIntegrationSyncStatusResponse + 128, // 264: aperio.v1.AperioService.RunIntegrationSourceSync:output_type -> aperio.v1.RunIntegrationSourceSyncResponse + 130, // 265: aperio.v1.AperioService.BackfillIntegrationSource:output_type -> aperio.v1.BackfillIntegrationSourceResponse + 135, // 266: aperio.v1.AperioService.ListSiemCatalog:output_type -> aperio.v1.ListSiemCatalogResponse + 139, // 267: aperio.v1.AperioService.ListSiemDestinations:output_type -> aperio.v1.ListSiemDestinationsResponse + 142, // 268: aperio.v1.AperioService.CreateSiemDestination:output_type -> aperio.v1.CreateSiemDestinationResponse + 144, // 269: aperio.v1.AperioService.DeleteSiemDestination:output_type -> aperio.v1.DeleteSiemDestinationResponse + 146, // 270: aperio.v1.AperioService.TestSiemDestination:output_type -> aperio.v1.TestSiemDestinationResponse + 149, // 271: aperio.v1.AperioService.ListShadowItOauthApps:output_type -> aperio.v1.ListShadowItOauthAppsResponse + 152, // 272: aperio.v1.AperioService.ListShadowItOauthAppGrants:output_type -> aperio.v1.ListShadowItOauthAppGrantsResponse + 157, // 273: aperio.v1.AperioService.GetTenantSettings:output_type -> aperio.v1.GetTenantSettingsResponse + 159, // 274: aperio.v1.AperioService.UpdateTenantSettings:output_type -> aperio.v1.UpdateTenantSettingsResponse + 162, // 275: aperio.v1.AperioService.ListTenantMembers:output_type -> aperio.v1.ListTenantMembersResponse + 164, // 276: aperio.v1.AperioService.CreateTenantMember:output_type -> aperio.v1.CreateTenantMemberResponse + 166, // 277: aperio.v1.AperioService.CreateMemberResetLink:output_type -> aperio.v1.CreateMemberResetLinkResponse + 168, // 278: aperio.v1.AperioService.UpdateMemberRole:output_type -> aperio.v1.UpdateMemberRoleResponse + 172, // 279: aperio.v1.AperioService.ListAuditLogs:output_type -> aperio.v1.ListAuditLogsResponse + 175, // 280: aperio.v1.AperioService.GetSecurityOverview:output_type -> aperio.v1.GetSecurityOverviewResponse + 187, // 281: aperio.v1.AperioService.ListEmailDomainHealth:output_type -> aperio.v1.ListEmailDomainHealthResponse + 189, // 282: aperio.v1.AperioService.GetEmailDomainHealth:output_type -> aperio.v1.GetEmailDomainHealthResponse + 191, // 283: aperio.v1.AperioService.RefreshEmailDomainHealth:output_type -> aperio.v1.RefreshEmailDomainHealthResponse + 198, // 284: aperio.v1.AperioService.ListSecurityAssets:output_type -> aperio.v1.ListSecurityAssetsResponse + 202, // 285: aperio.v1.AperioService.CreateSecurityAsset:output_type -> aperio.v1.CreateSecurityAssetResponse + 204, // 286: aperio.v1.AperioService.UpdateSecurityAsset:output_type -> aperio.v1.UpdateSecurityAssetResponse + 206, // 287: aperio.v1.AperioService.ListRiskExceptions:output_type -> aperio.v1.ListRiskExceptionsResponse + 211, // 288: aperio.v1.AperioService.CreateRiskException:output_type -> aperio.v1.CreateRiskExceptionResponse + 213, // 289: aperio.v1.AperioService.UpdateRiskException:output_type -> aperio.v1.UpdateRiskExceptionResponse + 216, // 290: aperio.v1.AperioService.ListExecutiveReports:output_type -> aperio.v1.ListExecutiveReportsResponse + 218, // 291: aperio.v1.AperioService.GetExecutiveReport:output_type -> aperio.v1.GetExecutiveReportResponse + 220, // 292: aperio.v1.AperioService.CreateExecutiveReport:output_type -> aperio.v1.CreateExecutiveReportResponse + 222, // 293: aperio.v1.AperioService.DeleteExecutiveReport:output_type -> aperio.v1.DeleteExecutiveReportResponse + 216, // [216:294] is the sub-list for method output_type + 138, // [138:216] is the sub-list for method input_type + 138, // [138:138] is the sub-list for extension type_name + 138, // [138:138] is the sub-list for extension extendee + 0, // [0:138] is the sub-list for field type_name } func init() { file_aperio_v1_api_proto_init() } @@ -17408,7 +17711,7 @@ func file_aperio_v1_api_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_aperio_v1_api_proto_rawDesc), len(file_aperio_v1_api_proto_rawDesc)), NumEnums: 0, - NumMessages: 233, + NumMessages: 237, NumExtensions: 0, NumServices: 1, }, diff --git a/internal/bootstrap/detection_packs.go b/internal/bootstrap/detection_packs.go new file mode 100644 index 00000000..a9b87608 --- /dev/null +++ b/internal/bootstrap/detection_packs.go @@ -0,0 +1,58 @@ +package bootstrap + +import ( + "context" + + connect "connectrpc.com/connect" + + aperiov1 "github.com/writer/aperio/gen/aperio/v1" + "github.com/writer/aperio/internal/ingestionworker" +) + +// ListDetectionPacks returns every detection pack the worker knows about, +// each hydrated with the rules it owns. The shape is intentionally flat +// so the operator UI can render the catalog in a single render pass +// without follow-up requests. Provider filter is optional; an empty +// provider returns every pack in display order. +func (a *App) ListDetectionPacks( + ctx context.Context, + req *connect.Request[aperiov1.ListDetectionPacksRequest], +) (*connect.Response[aperiov1.ListDetectionPacksResponse], error) { + if _, err := a.authenticatedOrganization(ctx, req.Header()); err != nil { + return nil, err + } + providerFilter := req.Msg.Provider + out := &aperiov1.ListDetectionPacksResponse{} + for _, pack := range ingestionworker.DetectionPacks { + if providerFilter != "" && providerFilter != pack.Provider { + continue + } + out.Data = append(out.Data, detectionPackProto(pack)) + } + return connect.NewResponse(out), nil +} + +func detectionPackProto(pack ingestionworker.DetectionPack) *aperiov1.DetectionPack { + rules := ingestionworker.RulesInPack(pack.ID) + out := &aperiov1.DetectionPack{ + Id: pack.ID, + Provider: pack.Provider, + Name: pack.Name, + Description: pack.Description, + Version: pack.Version, + Rules: make([]*aperiov1.DetectionPackRule, 0, len(rules)), + } + for _, rule := range rules { + out.Rules = append(out.Rules, &aperiov1.DetectionPackRule{ + Id: rule.ID, + Title: rule.Title, + Description: rule.Description, + Severity: rule.Severity, + EventTypes: append([]string(nil), rule.EventTypes...), + MitreTechniques: append([]string(nil), rule.MitreTechniques...), + Intent: rule.Intent, + Tags: append([]string(nil), rule.Tags...), + }) + } + return out +} diff --git a/internal/bootstrap/detection_packs_test.go b/internal/bootstrap/detection_packs_test.go new file mode 100644 index 00000000..1908bfb3 --- /dev/null +++ b/internal/bootstrap/detection_packs_test.go @@ -0,0 +1,54 @@ +package bootstrap + +import ( + "testing" + + "github.com/writer/aperio/internal/ingestionworker" +) + +// TestDetectionPackProtoHydratesRules pins the API surface: every pack +// returned to the UI must carry its full rule metadata so the catalog +// page can render in one shot. Drift here would either drop pack-level +// fields the UI relies on or leave rule arrays empty. +func TestDetectionPackProtoHydratesRules(t *testing.T) { + for _, pack := range ingestionworker.DetectionPacks { + got := detectionPackProto(pack) + if got.Id != pack.ID { + t.Errorf("pack %q: proto Id = %q", pack.ID, got.Id) + } + if got.Provider != pack.Provider { + t.Errorf("pack %q: proto Provider = %q", pack.ID, got.Provider) + } + if got.Version != pack.Version { + t.Errorf("pack %q: proto Version = %q", pack.ID, got.Version) + } + if got.Name == "" { + t.Errorf("pack %q: proto Name empty", pack.ID) + } + wantRules := ingestionworker.RulesInPack(pack.ID) + if len(got.Rules) != len(wantRules) { + t.Errorf("pack %q: rule count = %d, want %d", pack.ID, len(got.Rules), len(wantRules)) + } + for i, rule := range got.Rules { + if i >= len(wantRules) { + break + } + want := wantRules[i] + if rule.Id != want.ID { + t.Errorf("pack %q rule[%d]: Id = %q want %q", pack.ID, i, rule.Id, want.ID) + } + if rule.Severity != want.Severity { + t.Errorf("pack %q rule[%d]: Severity = %q want %q", pack.ID, i, rule.Severity, want.Severity) + } + if rule.Intent == "" { + t.Errorf("pack %q rule[%d]: Intent empty", pack.ID, i) + } + if len(rule.MitreTechniques) == 0 { + t.Errorf("pack %q rule[%d]: MitreTechniques empty", pack.ID, i) + } + if len(rule.Tags) == 0 { + t.Errorf("pack %q rule[%d]: Tags empty", pack.ID, i) + } + } + } +} diff --git a/internal/ingestionworker/detection_packs.go b/internal/ingestionworker/detection_packs.go new file mode 100644 index 00000000..d12509f5 --- /dev/null +++ b/internal/ingestionworker/detection_packs.go @@ -0,0 +1,91 @@ +package ingestionworker + +// DetectionPack is a versioned, curated bundle of built-in finding rules +// scoped to a provider and a coherent threat surface (admin-state, +// OAuth, mailbox abuse, repo hygiene, ...). Packs are how Aperio +// communicates coverage to operators: instead of a flat list of 16+ +// toggles, the UI groups by pack so a buyer can answer "what does +// Aperio detect on Google Workspace for mailbox exfiltration?" in one +// glance. +// +// Pack IDs are stable contracts; once a pack ships, never change its +// ID. Bump Version on every content change (semver). Description should +// read like a one-line analyst-facing capability statement. +type DetectionPack struct { + ID string + Provider string + Name string + Description string + Version string +} + +// DetectionPacks is the registry of every pack the worker knows about. +// Every RuleCatalogEntry.PackID must point into this table; the parity +// test in detection_packs_test.go pins the contract. +var DetectionPacks = []DetectionPack{ + { + ID: "aperio.github.core.v1", + Provider: "GITHUB", + Name: "GitHub repository hygiene", + Description: "Public repository creation events on GitHub.", + Version: "1.0.0", + }, + { + ID: "aperio.slack.core.v1", + Provider: "SLACK", + Name: "Slack workspace access", + Description: "Multi-factor authentication disablement on Slack.", + Version: "1.0.0", + }, + { + ID: "aperio.okta.core.v1", + Provider: "OKTA", + Name: "Okta identity threats", + Description: "Privileged role assignment, MFA factor reset, password policy weakening, and suspicious sign-in signals from Okta.", + Version: "1.0.0", + }, + { + ID: "aperio.google_workspace.identity.v1", + Provider: "GOOGLE_WORKSPACE", + Name: "Google Workspace identity & admin", + Description: "Super-admin and delegated-admin grants, admin MFA enforcement, and admin recovery-email risk in Google Workspace.", + Version: "1.0.0", + }, + { + ID: "aperio.google_workspace.mail.v1", + Provider: "GOOGLE_WORKSPACE", + Name: "Google Workspace mailbox exfiltration", + Description: "Mail forwarding, mailbox delegation, and legacy IMAP/SMTP auth paths attackers use to siphon Gmail.", + Version: "1.0.0", + }, + { + ID: "aperio.google_workspace.drive.v1", + Provider: "GOOGLE_WORKSPACE", + Name: "Google Workspace Drive sharing & OAuth", + Description: "External Drive sharing and risky third-party OAuth grants in Google Workspace.", + Version: "1.0.0", + }, +} + +// DetectionPackByID returns the pack with the given ID, or false if no +// pack matches. +func DetectionPackByID(id string) (DetectionPack, bool) { + for _, pack := range DetectionPacks { + if pack.ID == id { + return pack, true + } + } + return DetectionPack{}, false +} + +// RulesInPack returns every RuleCatalog entry that names the given pack +// ID, preserving catalog display order. An unknown pack returns an empty slice. +func RulesInPack(packID string) []RuleCatalogEntry { + out := make([]RuleCatalogEntry, 0, 4) + for _, entry := range RuleCatalog { + if entry.PackID == packID { + out = append(out, entry) + } + } + return out +} diff --git a/internal/ingestionworker/detection_packs_test.go b/internal/ingestionworker/detection_packs_test.go new file mode 100644 index 00000000..9ee71455 --- /dev/null +++ b/internal/ingestionworker/detection_packs_test.go @@ -0,0 +1,133 @@ +package ingestionworker + +import ( + "regexp" + "testing" +) + +// TestDetectionPackRegistryShape pins the registry's invariants the +// connectors UI and the ListDetectionPacks RPC depend on: unique IDs, +// known providers, populated names, and semver-shaped versions. A drift +// here would break operator-facing pack pages. +func TestDetectionPackRegistryShape(t *testing.T) { + if len(DetectionPacks) == 0 { + t.Fatal("DetectionPacks must not be empty") + } + knownProviders := map[string]bool{ + "GITHUB": true, + "SLACK": true, + "OKTA": true, + "GOOGLE_WORKSPACE": true, + } + semver := regexp.MustCompile(`^\d+\.\d+\.\d+$`) + seen := map[string]bool{} + for _, pack := range DetectionPacks { + if seen[pack.ID] { + t.Errorf("duplicate pack id %q", pack.ID) + } + seen[pack.ID] = true + if !knownProviders[pack.Provider] { + t.Errorf("pack %q has unknown provider %q", pack.ID, pack.Provider) + } + if pack.Name == "" { + t.Errorf("pack %q missing Name", pack.ID) + } + if pack.Description == "" { + t.Errorf("pack %q missing Description", pack.ID) + } + if !semver.MatchString(pack.Version) { + t.Errorf("pack %q version %q is not semver (MAJOR.MINOR.PATCH)", pack.ID, pack.Version) + } + } +} + +// TestRuleCatalogPackLinkage guarantees that every RuleCatalog entry +// carries pack metadata and that the referenced pack actually exists. +// This also enforces that the rule's provider matches the pack's +// provider, so an operator filtering by provider cannot end up with a +// pack containing a rule from a different SaaS. +func TestRuleCatalogPackLinkage(t *testing.T) { + for _, entry := range RuleCatalog { + if entry.PackID == "" { + t.Errorf("rule %q is missing PackID", entry.ID) + continue + } + pack, ok := DetectionPackByID(entry.PackID) + if !ok { + t.Errorf("rule %q references unknown pack %q", entry.ID, entry.PackID) + continue + } + if pack.Provider != entry.Provider { + t.Errorf("rule %q (provider=%s) is in pack %q (provider=%s)", entry.ID, entry.Provider, pack.ID, pack.Provider) + } + if entry.Intent == "" { + t.Errorf("rule %q is missing Intent", entry.ID) + } + if len(entry.MitreTechniques) == 0 { + t.Errorf("rule %q is missing MitreTechniques", entry.ID) + } + if len(entry.Tags) == 0 { + t.Errorf("rule %q is missing Tags", entry.ID) + } + } +} + +// TestRuleCatalogMitreTechniqueShape pins the MITRE technique id shape +// so an analyst can mechanically cross-reference attack.mitre.org. We +// accept top-level techniques (Txxxx) and one-level sub-techniques +// (Txxxx.yyy). Anything else is almost certainly a typo. +func TestRuleCatalogMitreTechniqueShape(t *testing.T) { + techniqueRE := regexp.MustCompile(`^T\d{4}(\.\d{3})?$`) + for _, entry := range RuleCatalog { + for _, technique := range entry.MitreTechniques { + if !techniqueRE.MatchString(technique) { + t.Errorf("rule %q has malformed MITRE technique %q (want Txxxx or Txxxx.yyy)", entry.ID, technique) + } + } + } +} + +// TestRuleCatalogTagsAreCanonical asserts every catalog Tag is a tag +// the worker actually recognizes. Adding a tag elsewhere without +// registering it in tags.go would silently route findings into an +// orphan bucket the UI cannot filter on. +func TestRuleCatalogTagsAreCanonical(t *testing.T) { + canonical := map[string]bool{} + for _, tag := range AllTags { + canonical[tag] = true + } + for _, entry := range RuleCatalog { + for _, tag := range entry.Tags { + if !canonical[tag] { + t.Errorf("rule %q references non-canonical tag %q (add it to tags.go or use an existing tag)", entry.ID, tag) + } + } + } +} + +// TestRulesInPackPreservesCatalogOrder pins the helper used to render +// each pack's rule list in the UI; alphabetical resort would scramble +// the carefully-chosen display order in RuleCatalog. +func TestRulesInPackPreservesCatalogOrder(t *testing.T) { + gotIDs := []string{} + for _, entry := range RulesInPack("aperio.google_workspace.mail.v1") { + gotIDs = append(gotIDs, entry.ID) + } + if len(gotIDs) == 0 { + t.Fatal("expected at least one rule in the mail pack") + } + wantIDs := []string{} + for _, entry := range RuleCatalog { + if entry.PackID == "aperio.google_workspace.mail.v1" { + wantIDs = append(wantIDs, entry.ID) + } + } + if len(gotIDs) != len(wantIDs) { + t.Fatalf("rules-in-pack length mismatch: got %d want %d", len(gotIDs), len(wantIDs)) + } + for i := range wantIDs { + if gotIDs[i] != wantIDs[i] { + t.Errorf("rules-in-pack order drift at %d: got %s want %s", i, gotIDs[i], wantIDs[i]) + } + } +} diff --git a/internal/ingestionworker/rules_catalog.go b/internal/ingestionworker/rules_catalog.go index 4ddaa7bc..38a580b6 100644 --- a/internal/ingestionworker/rules_catalog.go +++ b/internal/ingestionworker/rules_catalog.go @@ -7,145 +7,219 @@ package ingestionworker // rule means: (1) write the evaluator, (2) add it to Evaluate(), (3) add // it to the corresponding supportedIngestionEventTypes provider, (4) add // an entry here so it appears in the UI. +// +// Rules also carry detection-pack metadata so operators can reason about +// coverage in terms of curated, versioned bundles. PackID points into +// DetectionPacks (detection_packs.go); MITRE techniques and intent give +// the SOC immediate context when a finding fires; and Tags is the canon +// cross-provider categorization (see tags.go). type RuleCatalogEntry struct { - ID string - Provider string - Title string - Description string - Severity string - EventTypes []string + ID string + Provider string + Title string + Description string + Severity string + EventTypes []string + PackID string + MitreTechniques []string + Intent string + Tags []string } // RuleCatalog is the registered list of built-in rules. Order is the // display order in the UI. var RuleCatalog = []RuleCatalogEntry{ { - ID: "github.public_repository_created", - Provider: "GITHUB", - Title: "Public GitHub repository created", - Description: "A repository was created or changed to public visibility, which can expose source code, secrets, or customer data.", - Severity: "CRITICAL", - EventTypes: []string{"PUBLIC_REPOSITORY_CREATED", "REPOSITORY_PUBLICIZED"}, - }, - { - ID: "slack.mfa_disabled", - Provider: "SLACK", - Title: "Slack multi-factor authentication disabled", - Description: "A Slack user disabled MFA, increasing the likelihood of account takeover and lateral movement.", - Severity: "CRITICAL", - EventTypes: []string{"MFA_DISABLED", "TWO_FACTOR_AUTH_DISABLED"}, - }, - { - ID: "okta.admin_role_assigned", - Provider: "OKTA", - Title: "Okta admin role assigned", - Description: "A user was granted an Okta administrator role, expanding their tenant-wide privileges.", - Severity: "CRITICAL", - EventTypes: []string{"USER_ACCOUNT_PRIVILEGE_GRANT", "USER_ACCOUNT_PRIVILEGE_GRANTED", "ADMIN_ROLE_ASSIGNED", "ROLE_ASSIGNMENT_CREATED"}, - }, - { - ID: "okta.mfa_factor_reset", - Provider: "OKTA", - Title: "Okta MFA factor reset", - Description: "A user's MFA factors were reset, which can be abused for account-takeover bypass during phishing.", - Severity: "HIGH", - EventTypes: []string{"USER_MFA_FACTOR_RESET", "USER_MFA_FACTOR_RESET_ALL", "MFA_FACTOR_RESET"}, - }, - { - ID: "okta.password_policy_weakened", - Provider: "OKTA", - Title: "Okta password policy weakened", - Description: "An Okta password policy was changed to relax length, complexity, or rotation requirements.", - Severity: "HIGH", - EventTypes: []string{"POLICY_LIFECYCLE_UPDATE", "PASSWORD_POLICY_UPDATED"}, - }, - { - ID: "okta.suspicious_signin", - Provider: "OKTA", - Title: "Okta suspicious sign-in", - Description: "A sign-in matched Okta's suspicious-activity signal (impossible travel, anomalous device, or threat intel hit).", - Severity: "MEDIUM", - EventTypes: []string{"SECURITY_THREAT_DETECTED", "USER_AUTHENTICATION_FAILED", "USER_SESSION_START"}, - }, - { - ID: "google_workspace.external_sharing_enabled", - Provider: "GOOGLE_WORKSPACE", - Title: "Google Drive external sharing enabled", - Description: "A Drive resource was shared outside the tenant domain or set to a public visibility scope.", - Severity: "HIGH", - EventTypes: []string{"EXTERNAL_SHARING_ENABLED"}, - }, - { - ID: "google_workspace.super_admin_granted", - Provider: "GOOGLE_WORKSPACE", - Title: "Google Workspace Super Admin role granted", - Description: "A user was promoted to Super Admin, granting tenant-wide control over Workspace.", - Severity: "CRITICAL", - EventTypes: []string{"SUPER_ADMIN_GRANTED"}, - }, - { - ID: "google_workspace.admin_role_granted", - Provider: "GOOGLE_WORKSPACE", - Title: "Google Workspace admin role granted", - Description: "A user received a delegated administrator role, expanding their tenant privileges.", - Severity: "HIGH", - EventTypes: []string{"ADMIN_ROLE_GRANTED"}, - }, - { - ID: "google_workspace.risky_oauth_grant", - Provider: "GOOGLE_WORKSPACE", - Title: "Risky third-party OAuth grant", - Description: "A third-party OAuth app was authorized with sensitive scopes that broaden tenant data access.", - Severity: "HIGH", - EventTypes: []string{"RISKY_OAUTH_GRANT"}, - }, - { - ID: "google_workspace.admin_mfa_not_enforced", - Provider: "GOOGLE_WORKSPACE", - Title: "Admin MFA enforcement disabled", - Description: "Strong authentication enforcement was disabled for an admin, weakening the privileged-account perimeter.", - Severity: "HIGH", - EventTypes: []string{"ADMIN_MFA_NOT_ENFORCED"}, - }, - { - ID: "google_workspace.admin_external_recovery_email", - Provider: "GOOGLE_WORKSPACE", - Title: "Admin external recovery email set", - Description: "An admin's recovery email was changed to an external domain, creating an out-of-band account-takeover path.", - Severity: "HIGH", - EventTypes: []string{"ADMIN_EXTERNAL_RECOVERY_EMAIL"}, - }, - { - ID: "google_workspace.email_forwarding_enabled", - Provider: "GOOGLE_WORKSPACE", - Title: "Email forwarding enabled", - Description: "Mail forwarding or IMAP was enabled on a mailbox, opening a data-exfiltration channel.", - Severity: "HIGH", - EventTypes: []string{"EMAIL_FORWARDING_ENABLED"}, - }, - { - ID: "google_workspace.mailbox_delegation_granted", - Provider: "GOOGLE_WORKSPACE", - Title: "Mailbox delegation granted", - Description: "Mailbox delegation was granted, letting another account read or send mail on the mailbox owner's behalf.", - Severity: "HIGH", - EventTypes: []string{"MAILBOX_DELEGATION_GRANTED"}, - }, - { - ID: "google_workspace.legacy_mail_auth_used", - Provider: "GOOGLE_WORKSPACE", - Title: "Legacy mail authentication used", - Description: "A legacy IMAP/SMTP authentication path was used, which bypasses modern MFA and risk-based sign-in controls.", - Severity: "HIGH", - EventTypes: []string{"LEGACY_MAIL_AUTH_USED"}, - }, - { - ID: "google_workspace.forwarding_delegate_send_as_combo", - Provider: "GOOGLE_WORKSPACE", - Title: "Forwarding + delegation + send-as combo", - Description: "A mailbox simultaneously has forwarding, delegation, and send-as configured — a classic exfiltration staging pattern.", - Severity: "CRITICAL", - EventTypes: []string{"FORWARDING_DELEGATE_SEND_AS_COMBO"}, + ID: "github.public_repository_created", + Provider: "GITHUB", + Title: "Public GitHub repository created", + Description: "A repository was created or changed to public visibility, which can expose source code, secrets, or customer data.", + Severity: "CRITICAL", + EventTypes: []string{"PUBLIC_REPOSITORY_CREATED", "REPOSITORY_PUBLICIZED"}, + PackID: "aperio.github.core.v1", + MitreTechniques: []string{"T1567.001"}, + Intent: "Adversary publishes a private repo to exfiltrate source, secrets, or customer data outside the tenant boundary.", + Tags: []string{TagDataPublicExposure}, + }, + { + ID: "slack.mfa_disabled", + Provider: "SLACK", + Title: "Slack multi-factor authentication disabled", + Description: "A Slack user disabled MFA, increasing the likelihood of account takeover and lateral movement.", + Severity: "CRITICAL", + EventTypes: []string{"MFA_DISABLED", "TWO_FACTOR_AUTH_DISABLED"}, + PackID: "aperio.slack.core.v1", + MitreTechniques: []string{"T1556.006"}, + Intent: "Adversary or compromised insider weakens the account's auth posture to maintain access without triggering MFA prompts.", + Tags: []string{TagAuthMFAWeakened}, + }, + { + ID: "okta.admin_role_assigned", + Provider: "OKTA", + Title: "Okta admin role assigned", + Description: "A user was granted an Okta administrator role, expanding their tenant-wide privileges.", + Severity: "CRITICAL", + EventTypes: []string{"USER_ACCOUNT_PRIVILEGE_GRANT", "USER_ACCOUNT_PRIVILEGE_GRANTED", "ADMIN_ROLE_ASSIGNED", "ROLE_ASSIGNMENT_CREATED"}, + PackID: "aperio.okta.core.v1", + MitreTechniques: []string{"T1098.003"}, + Intent: "Adversary promotes an attacker-controlled identity to administrator to persist and broaden access across the tenant.", + Tags: []string{TagIAMPrivilegeEscalation}, + }, + { + ID: "okta.mfa_factor_reset", + Provider: "OKTA", + Title: "Okta MFA factor reset", + Description: "A user's MFA factors were reset, which can be abused for account-takeover bypass during phishing.", + Severity: "HIGH", + EventTypes: []string{"USER_MFA_FACTOR_RESET", "USER_MFA_FACTOR_RESET_ALL", "MFA_FACTOR_RESET"}, + PackID: "aperio.okta.core.v1", + MitreTechniques: []string{"T1556.006"}, + Intent: "Adversary clears MFA factors so the next sign-in can enroll an attacker-controlled device.", + Tags: []string{TagAuthMFAWeakened}, + }, + { + ID: "okta.password_policy_weakened", + Provider: "OKTA", + Title: "Okta password policy weakened", + Description: "An Okta password policy was changed to relax length, complexity, or rotation requirements.", + Severity: "HIGH", + EventTypes: []string{"POLICY_LIFECYCLE_UPDATE", "PASSWORD_POLICY_UPDATED"}, + PackID: "aperio.okta.core.v1", + MitreTechniques: []string{"T1556"}, + Intent: "Adversary reduces password strength requirements to make brute-force and credential stuffing viable.", + Tags: []string{TagAuthPassword, TagPolicyWeakened}, + }, + { + ID: "okta.suspicious_signin", + Provider: "OKTA", + Title: "Okta suspicious sign-in", + Description: "A sign-in matched Okta's suspicious-activity signal (impossible travel, anomalous device, or threat intel hit).", + Severity: "MEDIUM", + EventTypes: []string{"SECURITY_THREAT_DETECTED", "USER_AUTHENTICATION_FAILED", "USER_SESSION_START"}, + PackID: "aperio.okta.core.v1", + MitreTechniques: []string{"T1078.004"}, + Intent: "Adversary attempts to ride a compromised credential into the tenant using an anomalous device or location.", + Tags: []string{TagAuthSuspiciousLogin}, + }, + { + ID: "google_workspace.external_sharing_enabled", + Provider: "GOOGLE_WORKSPACE", + Title: "Google Drive external sharing enabled", + Description: "A Drive resource was shared outside the tenant domain or set to a public visibility scope.", + Severity: "HIGH", + EventTypes: []string{"EXTERNAL_SHARING_ENABLED"}, + PackID: "aperio.google_workspace.drive.v1", + MitreTechniques: []string{"T1530"}, + Intent: "Adversary or insider expands a Drive resource's audience to exfiltrate it through legitimate-looking sharing links.", + Tags: []string{TagDataExternalShare, TagPolicyWeakened}, + }, + { + ID: "google_workspace.super_admin_granted", + Provider: "GOOGLE_WORKSPACE", + Title: "Google Workspace Super Admin role granted", + Description: "A user was promoted to Super Admin, granting tenant-wide control over Workspace.", + Severity: "CRITICAL", + EventTypes: []string{"SUPER_ADMIN_GRANTED"}, + PackID: "aperio.google_workspace.identity.v1", + MitreTechniques: []string{"T1098.003"}, + Intent: "Adversary obtains the highest Workspace role to persist, disable controls, and reach any tenant data.", + Tags: []string{TagIAMPrivilegeEscalation}, + }, + { + ID: "google_workspace.admin_role_granted", + Provider: "GOOGLE_WORKSPACE", + Title: "Google Workspace admin role granted", + Description: "A user received a delegated administrator role, expanding their tenant privileges.", + Severity: "HIGH", + EventTypes: []string{"ADMIN_ROLE_GRANTED"}, + PackID: "aperio.google_workspace.identity.v1", + MitreTechniques: []string{"T1098.003"}, + Intent: "Adversary expands a foothold by granting an attacker-controlled account a delegated admin role.", + Tags: []string{TagIAMPrivilegeEscalation}, + }, + { + ID: "google_workspace.risky_oauth_grant", + Provider: "GOOGLE_WORKSPACE", + Title: "Risky third-party OAuth grant", + Description: "A third-party OAuth app was authorized with sensitive scopes that broaden tenant data access.", + Severity: "HIGH", + EventTypes: []string{"RISKY_OAUTH_GRANT"}, + PackID: "aperio.google_workspace.drive.v1", + MitreTechniques: []string{"T1550.001", "T1528"}, + Intent: "Adversary tricks a user into authorizing an OAuth app that grants long-lived access to mail and drive data.", + Tags: []string{TagOAuthRiskyGrant, TagDataAccess}, + }, + { + ID: "google_workspace.admin_mfa_not_enforced", + Provider: "GOOGLE_WORKSPACE", + Title: "Admin MFA enforcement disabled", + Description: "Strong authentication enforcement was disabled for an admin, weakening the privileged-account perimeter.", + Severity: "HIGH", + EventTypes: []string{"ADMIN_MFA_NOT_ENFORCED"}, + PackID: "aperio.google_workspace.identity.v1", + MitreTechniques: []string{"T1556.006"}, + Intent: "Adversary weakens the admin auth posture to keep stolen credentials viable across sessions.", + Tags: []string{TagAuthMFAWeakened, TagPolicyWeakened}, + }, + { + ID: "google_workspace.admin_external_recovery_email", + Provider: "GOOGLE_WORKSPACE", + Title: "Admin external recovery email set", + Description: "An admin's recovery email was changed to an external domain, creating an out-of-band account-takeover path.", + Severity: "HIGH", + EventTypes: []string{"ADMIN_EXTERNAL_RECOVERY_EMAIL"}, + PackID: "aperio.google_workspace.identity.v1", + MitreTechniques: []string{"T1098.001"}, + Intent: "Adversary stages an off-tenant recovery path so a future password reset hands them the admin account.", + Tags: []string{TagAuthAccountRecovery}, + }, + { + ID: "google_workspace.email_forwarding_enabled", + Provider: "GOOGLE_WORKSPACE", + Title: "Email forwarding enabled", + Description: "Mail forwarding or IMAP was enabled on a mailbox, opening a data-exfiltration channel.", + Severity: "HIGH", + EventTypes: []string{"EMAIL_FORWARDING_ENABLED"}, + PackID: "aperio.google_workspace.mail.v1", + MitreTechniques: []string{"T1114.003"}, + Intent: "Adversary auto-forwards mailbox contents to an attacker-controlled address to silently exfiltrate mail.", + Tags: []string{TagEmailForwarding, TagDataExternalShare}, + }, + { + ID: "google_workspace.mailbox_delegation_granted", + Provider: "GOOGLE_WORKSPACE", + Title: "Mailbox delegation granted", + Description: "Mailbox delegation was granted, letting another account read or send mail on the mailbox owner's behalf.", + Severity: "HIGH", + EventTypes: []string{"MAILBOX_DELEGATION_GRANTED"}, + PackID: "aperio.google_workspace.mail.v1", + MitreTechniques: []string{"T1098.002"}, + Intent: "Adversary persists access to the mailbox by delegating it to an attacker-controlled account.", + Tags: []string{TagEmailDelegation, TagDataAccess}, + }, + { + ID: "google_workspace.legacy_mail_auth_used", + Provider: "GOOGLE_WORKSPACE", + Title: "Legacy mail authentication used", + Description: "A legacy IMAP/SMTP authentication path was used, which bypasses modern MFA and risk-based sign-in controls.", + Severity: "HIGH", + EventTypes: []string{"LEGACY_MAIL_AUTH_USED"}, + PackID: "aperio.google_workspace.mail.v1", + MitreTechniques: []string{"T1078.004", "T1556.006"}, + Intent: "Adversary rides a legacy protocol that does not enforce MFA, often after harvesting an app password.", + Tags: []string{TagAuthLegacyProtocol}, + }, + { + ID: "google_workspace.forwarding_delegate_send_as_combo", + Provider: "GOOGLE_WORKSPACE", + Title: "Forwarding + delegation + send-as combo", + Description: "A mailbox simultaneously has forwarding, delegation, and send-as configured, a classic exfiltration staging pattern.", + Severity: "CRITICAL", + EventTypes: []string{"FORWARDING_DELEGATE_SEND_AS_COMBO"}, + PackID: "aperio.google_workspace.mail.v1", + MitreTechniques: []string{"T1114.003", "T1098.002"}, + Intent: "Adversary stages a multi-vector mailbox takeover that survives password rotation and silently routes mail outbound.", + Tags: []string{TagEmailForwarding, TagEmailDelegation, TagDataExternalShare}, }, } diff --git a/packages/connect/src/client.ts b/packages/connect/src/client.ts index 12ad292a..e934199f 100644 --- a/packages/connect/src/client.ts +++ b/packages/connect/src/client.ts @@ -12,6 +12,8 @@ import { type CerebroMCPContext as ProtoCerebroMCPContext, type CerebroMCPResourceTemplate as ProtoCerebroMCPResourceTemplate, type ConnectorDefinition as ProtoConnectorDefinition, + type DetectionPack as ProtoDetectionPack, + type DetectionPackRule as ProtoDetectionPackRule, type EmailDomainDkimSelector as ProtoEmailDomainDkimSelector, type EmailDomainHealth as ProtoEmailDomainHealth, type EmailDomainHealthDetail as ProtoEmailDomainHealthDetail, @@ -388,6 +390,26 @@ export type ConnectIntegrationOAuthClient = { updatedAt: string | null; }; +export type ConnectDetectionPackRule = { + id: string; + title: string; + description: string; + severity: string; + eventTypes: string[]; + mitreTechniques: string[]; + intent: string; + tags: string[]; +}; + +export type ConnectDetectionPack = { + id: string; + provider: string; + name: string; + description: string; + version: string; + rules: ConnectDetectionPackRule[]; +}; + export type ConnectConnectorDefinition = { provider: ConnectProvider; name: string; @@ -1672,6 +1694,34 @@ function integrationFromProto( }; } +function detectionPackRuleFromProto( + rule: ProtoDetectionPackRule +): ConnectDetectionPackRule { + return { + id: rule.id, + title: rule.title, + description: rule.description, + severity: rule.severity, + eventTypes: [...rule.eventTypes], + mitreTechniques: [...rule.mitreTechniques], + intent: rule.intent, + tags: [...rule.tags] + }; +} + +function detectionPackFromProto( + pack: ProtoDetectionPack +): ConnectDetectionPack { + return { + id: pack.id, + provider: pack.provider, + name: pack.name, + description: pack.description, + version: pack.version, + rules: pack.rules.map(detectionPackRuleFromProto) + }; +} + function connectorDefinitionFromProto( definition: ProtoConnectorDefinition ): ConnectConnectorDefinition { @@ -2622,6 +2672,14 @@ export const aperioConnectClient = { const response = await client.listConnectorCatalog({}); return { data: response.data.map(connectorDefinitionFromProto) }; }, + async listDetectionPacks( + filters?: { provider?: string } + ): Promise<{ data: ConnectDetectionPack[] }> { + const response = await client.listDetectionPacks({ + provider: filters?.provider ?? "" + }); + return { data: response.data.map(detectionPackFromProto) }; + }, async listIntegrations(): Promise<{ data: ConnectIntegrationConnection[] }> { const response = await client.listIntegrations({}); return { data: response.data.map(integrationFromProto) }; diff --git a/packages/connect/src/gen/aperio/v1/api_pb.ts b/packages/connect/src/gen/aperio/v1/api_pb.ts index 0eee326b..bf992c60 100644 --- a/packages/connect/src/gen/aperio/v1/api_pb.ts +++ b/packages/connect/src/gen/aperio/v1/api_pb.ts @@ -12,7 +12,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file aperio/v1/api.proto. */ export const file_aperio_v1_api: GenFile = /*@__PURE__*/ - fileDesc("ChNhcGVyaW8vdjEvYXBpLnByb3RvEglhcGVyaW8udjEiQQoOQ2FsbEFwaVJlcXVlc3QSDgoGbWV0aG9kGAEgASgJEgwKBHBhdGgYAiABKAkSEQoJYm9keV9qc29uGAMgASgJIiQKD0NhbGxBcGlSZXNwb25zZRIRCglib2R5X2pzb24YASABKAkipAEKDVNpZ251cFJlcXVlc3QSGQoRb3JnYW5pemF0aW9uX25hbWUYASABKAkSGQoRb3JnYW5pemF0aW9uX3NsdWcYAiABKAkSGgoSbm90aWZpY2F0aW9uX2VtYWlsGAMgASgJEhMKC293bmVyX2VtYWlsGAQgASgJEhoKEm93bmVyX2Rpc3BsYXlfbmFtZRgFIAEoCRIQCghwYXNzd29yZBgGIAEoCSI2Cg5TaWdudXBSZXNwb25zZRIkCgRkYXRhGAEgASgLMhYuYXBlcmlvLnYxLkF1dGhTZXNzaW9uIl0KDExvZ2luUmVxdWVzdBIZChFvcmdhbml6YXRpb25fc2x1ZxgBIAEoCRINCgVlbWFpbBgCIAEoCRIQCghwYXNzd29yZBgDIAEoCRIRCgl0b3RwX2NvZGUYBCABKAkiNQoNTG9naW5SZXNwb25zZRIkCgRkYXRhGAEgASgLMhYuYXBlcmlvLnYxLkF1dGhTZXNzaW9uIhoKGEdldEN1cnJlbnRTZXNzaW9uUmVxdWVzdCJBChlHZXRDdXJyZW50U2Vzc2lvblJlc3BvbnNlEiQKBGRhdGEYASABKAsyFi5hcGVyaW8udjEuQXV0aFNlc3Npb24iHQobTG9nb3V0Q3VycmVudFNlc3Npb25SZXF1ZXN0IkUKHExvZ291dEN1cnJlbnRTZXNzaW9uUmVzcG9uc2USJQoEZGF0YRgBIAEoCzIXLmFwZXJpby52MS5EZWxldGVSZXN1bHQiFwoVTGlzdFdvcmtzcGFjZXNSZXF1ZXN0IkYKFkxpc3RXb3Jrc3BhY2VzUmVzcG9uc2USLAoEZGF0YRgBIAMoCzIeLmFwZXJpby52MS5Xb3Jrc3BhY2VNZW1iZXJzaGlwIlgKFlN3aXRjaFdvcmtzcGFjZVJlcXVlc3QSGQoRb3JnYW5pemF0aW9uX3NsdWcYASABKAkSEQoJdG90cF9jb2RlGAIgASgJEhAKCHBhc3N3b3JkGAMgASgJIj8KF1N3aXRjaFdvcmtzcGFjZVJlc3BvbnNlEiQKBGRhdGEYASABKAsyFi5hcGVyaW8udjEuQXV0aFNlc3Npb24iRwobUmVxdWVzdFBhc3N3b3JkUmVzZXRSZXF1ZXN0EhkKEW9yZ2FuaXphdGlvbl9zbHVnGAEgASgJEg0KBWVtYWlsGAIgASgJIkwKHFJlcXVlc3RQYXNzd29yZFJlc2V0UmVzcG9uc2USLAoEZGF0YRgBIAEoCzIeLmFwZXJpby52MS5QYXNzd29yZFJlc2V0UmVzdWx0IjcKFFJlc2V0UGFzc3dvcmRSZXF1ZXN0Eg0KBXRva2VuGAEgASgJEhAKCHBhc3N3b3JkGAIgASgJIj0KFVJlc2V0UGFzc3dvcmRSZXNwb25zZRIkCgRkYXRhGAEgASgLMhYuYXBlcmlvLnYxLkF1dGhTZXNzaW9uIkwKE0FjY2VwdEludml0ZVJlcXVlc3QSDQoFdG9rZW4YASABKAkSFAoMZGlzcGxheV9uYW1lGAIgASgJEhAKCHBhc3N3b3JkGAMgASgJIjwKFEFjY2VwdEludml0ZVJlc3BvbnNlEiQKBGRhdGEYASABKAsyFi5hcGVyaW8udjEuQXV0aFNlc3Npb24iGwoZQmVnaW5NZmFFbnJvbGxtZW50UmVxdWVzdCJEChpCZWdpbk1mYUVucm9sbG1lbnRSZXNwb25zZRImCgRkYXRhGAEgASgLMhguYXBlcmlvLnYxLk1mYUVucm9sbG1lbnQiIAoQRW5hYmxlTWZhUmVxdWVzdBIMCgRjb2RlGAEgASgJIjkKEUVuYWJsZU1mYVJlc3BvbnNlEiQKBGRhdGEYASABKAsyFi5hcGVyaW8udjEuQXV0aFNlc3Npb24iMwoRRGlzYWJsZU1mYVJlcXVlc3QSEAoIcGFzc3dvcmQYASABKAkSDAoEY29kZRgCIAEoCSI6ChJEaXNhYmxlTWZhUmVzcG9uc2USJAoEZGF0YRgBIAEoCzIWLmFwZXJpby52MS5BdXRoU2Vzc2lvbiKgAQoLQXV0aFNlc3Npb24SDQoFdG9rZW4YASABKAkSIQoEdXNlchgCIAEoCzITLmFwZXJpby52MS5BdXRoVXNlchIxCgxvcmdhbml6YXRpb24YAyABKAsyGy5hcGVyaW8udjEuQXV0aE9yZ2FuaXphdGlvbhIsCgxhdXRoX2NvbnRleHQYBCABKAsyFi5hcGVyaW8udjEuQXV0aENvbnRleHQiXgoIQXV0aFVzZXISCgoCaWQYASABKAkSDQoFZW1haWwYAiABKAkSFAoMZGlzcGxheV9uYW1lGAMgASgJEhMKC21mYV9lbmFibGVkGAQgASgIEgwKBHJvbGUYBSABKAkiOgoQQXV0aE9yZ2FuaXphdGlvbhIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEgwKBHNsdWcYAyABKAkisQMKC0F1dGhDb250ZXh0EhEKCXByaW5jaXBhbBgBIAEoCRIRCgl0ZW5hbnRfaWQYAiABKAkSEwoLdGVuYW50X3NsdWcYAyABKAkSFwoPY3JlZGVudGlhbF9raW5kGAQgASgJEhEKCWF1dGhfbW9kZRgFIAEoCRIXCg90b2tlbl90cmFuc3BvcnQYBiABKAkSGAoQY2VyZWJyb19yZXNvdXJjZRgHIAEoCRIXCg9hbGxvd2VkX3RlbmFudHMYCCADKAkSFgoOY2VyZWJyb19zY29wZXMYCSADKAkSDgoGZ3JvdXBzGAogAygJEhwKFGNlcmVicm9fbWNwX3Jlc291cmNlGAsgASgJEioKImNlcmVicm9fbWNwX3Jlc291cmNlX21ldGFkYXRhX3BhdGgYDCABKAkSOAowY2VyZWJyb19vYXV0aF9hdXRob3JpemF0aW9uX3NlcnZlcl9tZXRhZGF0YV9wYXRoGA0gASgJEh8KF2NlcmVicm9fbWNwX2dyYW50X3R5cGVzGA4gAygJEiIKGmNlcmVicm9fbWNwX2JlYXJlcl9tZXRob2RzGA8gAygJIlwKE1dvcmtzcGFjZU1lbWJlcnNoaXASCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIMCgRzbHVnGAMgASgJEgwKBHJvbGUYBCABKAkSDwoHY3VycmVudBgFIAEoCCJ7ChNQYXNzd29yZFJlc2V0UmVzdWx0EhAKCGFjY2VwdGVkGAEgASgIEhAKCGRlbGl2ZXJ5GAIgASgJEhEKCXJlc2V0X3VybBgDIAEoCRISCgpleHBpcmVzX2F0GAQgASgJEhkKEW9yZ2FuaXphdGlvbl9uYW1lGAUgASgJIjQKDU1mYUVucm9sbG1lbnQSDgoGc2VjcmV0GAEgASgJEhMKC290cGF1dGhfdXJsGAIgASgJIhQKEkNoZWNrSGVhbHRoUmVxdWVzdCKWAQoTQ2hlY2tIZWFsdGhSZXNwb25zZRIOCgZzdGF0dXMYASABKAkSDwoHc2VydmljZRgCIAEoCRIuCgpjaGVja2VkX2F0GAMgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIuCgpjb21wb25lbnRzGAQgAygLMhouYXBlcmlvLnYxLkhlYWx0aENvbXBvbmVudCI/Cg9IZWFsdGhDb21wb25lbnQSDAoEbmFtZRgBIAEoCRIOCgZzdGF0dXMYAiABKAkSDgoGZGV0YWlsGAMgASgJIhwKGkdldERhc2hib2FyZE1ldHJpY3NSZXF1ZXN0IkgKG0dldERhc2hib2FyZE1ldHJpY3NSZXNwb25zZRIpCgRkYXRhGAEgASgLMhsuYXBlcmlvLnYxLkRhc2hib2FyZE1ldHJpY3MiggEKEERhc2hib2FyZE1ldHJpY3MSGAoQdG90YWxfcmlza19zY29yZRgBIAEoBRIeChZvcGVuX2NyaXRpY2FsX2ZpbmRpbmdzGAIgASgFEhYKDmNvbm5lY3RlZF9hcHBzGAMgASgFEhwKFGV2ZW50X2luZ2VzdGlvbl9yYXRlGAQgASgFIoABChNMaXN0RmluZGluZ3NSZXF1ZXN0EhAKCHNldmVyaXR5GAEgASgJEg4KBnN0YXR1cxgCIAEoCRIQCghwcm92aWRlchgDIAEoCRIWCg5pbnRlZ3JhdGlvbl9pZBgEIAEoCRINCgVsaW1pdBgFIAEoBRIOCgZjdXJzb3IYBiABKAkiYAoUTGlzdEZpbmRpbmdzUmVzcG9uc2USIAoEZGF0YRgBIAMoCzISLmFwZXJpby52MS5GaW5kaW5nEiYKCXBhZ2VfaW5mbxgCIAEoCzITLmFwZXJpby52MS5QYWdlSW5mbyIfChFHZXRGaW5kaW5nUmVxdWVzdBIKCgJpZBgBIAEoCSI2ChJHZXRGaW5kaW5nUmVzcG9uc2USIAoEZGF0YRgBIAEoCzISLmFwZXJpby52MS5GaW5kaW5nIlEKGlVwZGF0ZUZpbmRpbmdTdGF0dXNSZXF1ZXN0EgoKAmlkGAEgASgJEg4KBnN0YXR1cxgCIAEoCRIXCg9yZXNvbHV0aW9uX25vdGUYAyABKAkiSwobVXBkYXRlRmluZGluZ1N0YXR1c1Jlc3BvbnNlEiwKBGRhdGEYASABKAsyHi5hcGVyaW8udjEuRmluZGluZ1N0YXR1c1VwZGF0ZSIxChNGaW5kaW5nU3RhdHVzVXBkYXRlEgoKAmlkGAEgASgJEg4KBnN0YXR1cxgCIAEoCSJmChdSZW1lZGlhdGVGaW5kaW5nUmVxdWVzdBISCgpmaW5kaW5nX2lkGAEgASgJEg4KBmFjdGlvbhgCIAEoCRIZChF0YXJnZXRfaWRlbnRpZmllchgDIAEoCRIMCgRub3RlGAQgASgJIkYKGFJlbWVkaWF0ZUZpbmRpbmdSZXNwb25zZRIqCgRkYXRhGAEgASgLMhwuYXBlcmlvLnYxLlJlbWVkaWF0aW9uUmVzdWx0IocBChFSZW1lZGlhdGlvblJlc3VsdBISCgpmaW5kaW5nX2lkGAEgASgJEg4KBmFjdGlvbhgCIAEoCRIPCgdzdWNjZXNzGAMgASgIEg8KB21lc3NhZ2UYBCABKAkSGwoTcHJvdmlkZXJfcmVxdWVzdF9pZBgFIAEoCRIPCgdlZmZlY3RzGAYgAygJItoCCgdGaW5kaW5nEgoKAmlkGAEgASgJEhAKCGFzc2V0X2lkGAIgASgJEg0KBXRpdGxlGAMgASgJEhMKC2Rlc2NyaXB0aW9uGAQgASgJEhAKCHNldmVyaXR5GAUgASgJEg4KBnN0YXR1cxgGIAEoCRISCgpyaXNrX3Njb3JlGAcgASgFEhkKEXJlbWVkaWF0aW9uX3N0ZXBzGAggAygJEhUKDWV2aWRlbmNlX2pzb24YCSABKAkSEwoLZGV0ZWN0ZWRfYXQYCiABKAkSEwoLcmVzb2x2ZWRfYXQYCyABKAkSMgoLaW50ZWdyYXRpb24YDCABKAsyHS5hcGVyaW8udjEuRmluZGluZ0ludGVncmF0aW9uEgwKBHRhZ3MYDSADKAkSOQoPY2VyZWJyb19jb250ZXh0GA4gASgLMiAuYXBlcmlvLnYxLkZpbmRpbmdDZXJlYnJvQ29udGV4dCJIChJGaW5kaW5nSW50ZWdyYXRpb24SCgoCaWQYASABKAkSEAoIcHJvdmlkZXIYAiABKAkSFAoMZGlzcGxheV9uYW1lGAMgASgJIqsDChVGaW5kaW5nQ2VyZWJyb0NvbnRleHQSDgoGc291cmNlGAEgASgJEgwKBG1vZGUYAiABKAkSGQoRc291cmNlX3J1bnRpbWVfaWQYAyABKAkSGAoQZmluZGluZ19jb250cmFjdBgEIAEoCRIXCg9zb3VyY2VfZXZlbnRfaWQYBSABKAkSEwoLY2xhaW1fY291bnQYBiABKAUSNwoPY2xhaW1fc3VtbWFyaWVzGAcgAygLMh4uYXBlcmlvLnYxLkNlcmVicm9DbGFpbVN1bW1hcnkSNAoNZ3JhcGhfc2lnbmFscxgIIAMoCzIdLmFwZXJpby52MS5DZXJlYnJvR3JhcGhTaWduYWwSLQoIZW50aXRpZXMYCSADKAsyGy5hcGVyaW8udjEuQ2VyZWJyb0VudGl0eVJlZhIwCgtncmFwaF9wYXRocxgKIAMoCzIbLmFwZXJpby52MS5DZXJlYnJvR3JhcGhQYXRoEikKA21jcBgLIAEoCzIcLmFwZXJpby52MS5DZXJlYnJvTUNQQ29udGV4dBIWCg5yZXNwb25zZV9oaW50cxgMIAMoCSJ7ChNDZXJlYnJvQ2xhaW1TdW1tYXJ5EhIKCmNsYWltX3R5cGUYASABKAkSEQoJcHJlZGljYXRlGAIgASgJEhMKC3N1YmplY3RfdXJuGAMgASgJEhIKCm9iamVjdF91cm4YBCABKAkSFAoMc291cmNlX2V2ZW50GAUgASgJInAKEkNlcmVicm9HcmFwaFNpZ25hbBINCgVsYWJlbBgBIAEoCRIRCglwcmVkaWNhdGUYAiABKAkSEgoKY29uZmlkZW5jZRgDIAEoBRISCgplbnRpdHlfdXJuGAQgASgJEhAKCGV2aWRlbmNlGAUgASgJIk4KEENlcmVicm9FbnRpdHlSZWYSCwoDdXJuGAEgASgJEgwKBHR5cGUYAiABKAkSDQoFbGFiZWwYAyABKAkSEAoIcHJvdmlkZXIYBCABKAkiZwoQQ2VyZWJyb0dyYXBoUGF0aBIKCgJpZBgBIAEoCRINCgV0aXRsZRgCIAEoCRIMCgRyaXNrGAMgASgJEioKBW5vZGVzGAQgAygLMhsuYXBlcmlvLnYxLkNlcmVicm9FbnRpdHlSZWYingEKEUNlcmVicm9NQ1BDb250ZXh0Eg4KBnNlcnZlchgBIAEoCRIUCgxyZXNvdXJjZV91cmkYAiABKAkSEQoJbWltZV90eXBlGAMgASgJEg0KBXRvb2xzGAQgAygJEkEKEnJlc291cmNlX3RlbXBsYXRlcxgFIAMoCzIlLmFwZXJpby52MS5DZXJlYnJvTUNQUmVzb3VyY2VUZW1wbGF0ZSJoChpDZXJlYnJvTUNQUmVzb3VyY2VUZW1wbGF0ZRIUCgx1cmlfdGVtcGxhdGUYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgDIAEoCRIRCgltaW1lX3R5cGUYBCABKAkidQoYTGlzdFNhYXNJbmNpZGVudHNSZXF1ZXN0Eg4KBnN0YXR1cxgBIAEoCRIQCghzZXZlcml0eRgCIAEoCRIYChBhc3NpZ25lZV91c2VyX2lkGAMgASgJEg0KBWxpbWl0GAQgASgFEg4KBmN1cnNvchgFIAEoCSKbAQoZTGlzdFNhYXNJbmNpZGVudHNSZXNwb25zZRIlCgRkYXRhGAEgAygLMhcuYXBlcmlvLnYxLlNhYXNJbmNpZGVudBImCglwYWdlX2luZm8YAiABKAsyEy5hcGVyaW8udjEuUGFnZUluZm8SLwoHbWV0cmljcxgDIAEoCzIeLmFwZXJpby52MS5TYWFzSW5jaWRlbnRNZXRyaWNzIiQKFkdldFNhYXNJbmNpZGVudFJlcXVlc3QSCgoCaWQYASABKAkiRgoXR2V0U2Fhc0luY2lkZW50UmVzcG9uc2USKwoEZGF0YRgBIAEoCzIdLmFwZXJpby52MS5TYWFzSW5jaWRlbnREZXRhaWwikAEKGUNyZWF0ZVNhYXNJbmNpZGVudFJlcXVlc3QSDQoFdGl0bGUYASABKAkSDwoHc3VtbWFyeRgCIAEoCRIQCghzZXZlcml0eRgDIAEoCRITCgtmaW5kaW5nX2lkcxgEIAMoCRISCgpvd25lcl90ZWFtGAUgASgJEhgKEGFzc2lnbmVlX3VzZXJfaWQYBiABKAkiSQoaQ3JlYXRlU2Fhc0luY2lkZW50UmVzcG9uc2USKwoEZGF0YRgBIAEoCzIdLmFwZXJpby52MS5TYWFzSW5jaWRlbnREZXRhaWwiSwofVXBkYXRlU2Fhc0luY2lkZW50U3RhdHVzUmVxdWVzdBIKCgJpZBgBIAEoCRIOCgZzdGF0dXMYAiABKAkSDAoEbm90ZRgDIAEoCSJJCiBVcGRhdGVTYWFzSW5jaWRlbnRTdGF0dXNSZXNwb25zZRIlCgRkYXRhGAEgASgLMhcuYXBlcmlvLnYxLlNhYXNJbmNpZGVudCLmAQogUHJvcG9zZVNhYXNSZXNwb25zZUFjdGlvblJlcXVlc3QSEwoLaW5jaWRlbnRfaWQYASABKAkSEgoKZmluZGluZ19pZBgCIAEoCRIOCgZhY3Rpb24YAyABKAkSEAoIcHJvdmlkZXIYBCABKAkSEwoLdGFyZ2V0X3R5cGUYBSABKAkSGQoRdGFyZ2V0X2lkZW50aWZpZXIYBiABKAkSEQoJcmF0aW9uYWxlGAcgASgJEh4KEWFwcHJvdmFsX3JlcXVpcmVkGAggASgISACIAQFCFAoSX2FwcHJvdmFsX3JlcXVpcmVkIlAKIVByb3Bvc2VTYWFzUmVzcG9uc2VBY3Rpb25SZXNwb25zZRIrCgRkYXRhGAEgASgLMh0uYXBlcmlvLnYxLlNhYXNSZXNwb25zZUFjdGlvbiI8CiBBcHByb3ZlU2Fhc1Jlc3BvbnNlQWN0aW9uUmVxdWVzdBIKCgJpZBgBIAEoCRIMCgRub3RlGAIgASgJIlAKIUFwcHJvdmVTYWFzUmVzcG9uc2VBY3Rpb25SZXNwb25zZRIrCgRkYXRhGAEgASgLMh0uYXBlcmlvLnYxLlNhYXNSZXNwb25zZUFjdGlvbiI8CiBFeGVjdXRlU2Fhc1Jlc3BvbnNlQWN0aW9uUmVxdWVzdBIKCgJpZBgBIAEoCRIMCgRub3RlGAIgASgJIlAKIUV4ZWN1dGVTYWFzUmVzcG9uc2VBY3Rpb25SZXNwb25zZRIrCgRkYXRhGAEgASgLMh0uYXBlcmlvLnYxLlNhYXNSZXNwb25zZUFjdGlvbiKYAQoTU2Fhc0luY2lkZW50TWV0cmljcxIMCgRvcGVuGAEgASgFEhUKDWludmVzdGlnYXRpbmcYAiABKAUSEQoJY29udGFpbmVkGAMgASgFEhAKCHJlc29sdmVkGAQgASgFEhUKDWNyaXRpY2FsX29wZW4YBSABKAUSIAoYcmVzcG9uc2VfYWN0aW9uc19wZW5kaW5nGAYgASgFItkDCgxTYWFzSW5jaWRlbnQSCgoCaWQYASABKAkSDQoFdGl0bGUYAiABKAkSDwoHc3VtbWFyeRgDIAEoCRIQCghzZXZlcml0eRgEIAEoCRIOCgZzdGF0dXMYBSABKAkSGAoQY29uZmlkZW5jZV9zY29yZRgGIAEoBRISCgpvd25lcl90ZWFtGAcgASgJEi4KCGFzc2lnbmVlGAggASgLMhwuYXBlcmlvLnYxLlNlY3VyaXR5UHJpbmNpcGFsEhkKEWZpcnN0X2RldGVjdGVkX2F0GAkgASgJEhgKEGxhc3RfYWN0aXZpdHlfYXQYCiABKAkSEgoKc2xhX2R1ZV9hdBgLIAEoCRITCgtyZXNvbHZlZF9hdBgMIAEoCRIcChRjZXJlYnJvX2NvbnRleHRfanNvbhgNIAEoCRISCgpjcmVhdGVkX2F0GA4gASgJEhIKCnVwZGF0ZWRfYXQYDyABKAkSFQoNZmluZGluZ19jb3VudBgQIAEoBRIaChJvcGVuX2ZpbmRpbmdfY291bnQYESABKAUSHQoVcmVzcG9uc2VfYWN0aW9uX2NvdW50GBIgASgFEicKH2NvbXBsZXRlZF9yZXNwb25zZV9hY3Rpb25fY291bnQYEyABKAUi1gEKElNhYXNJbmNpZGVudERldGFpbBIpCghpbmNpZGVudBgBIAEoCzIXLmFwZXJpby52MS5TYWFzSW5jaWRlbnQSJAoIZmluZGluZ3MYAiADKAsyEi5hcGVyaW8udjEuRmluZGluZxI2Cgh0aW1lbGluZRgDIAMoCzIkLmFwZXJpby52MS5TYWFzSW5jaWRlbnRUaW1lbGluZUV2ZW50EjcKEHJlc3BvbnNlX2FjdGlvbnMYBCADKAsyHS5hcGVyaW8udjEuU2Fhc1Jlc3BvbnNlQWN0aW9uIv0BChlTYWFzSW5jaWRlbnRUaW1lbGluZUV2ZW50EgoKAmlkGAEgASgJEhMKC2luY2lkZW50X2lkGAIgASgJEhIKCmZpbmRpbmdfaWQYAyABKAkSGgoScmVzcG9uc2VfYWN0aW9uX2lkGAQgASgJEgwKBGtpbmQYBSABKAkSDQoFdGl0bGUYBiABKAkSEwoLZGVzY3JpcHRpb24YByABKAkSDQoFYWN0b3IYCCABKAkSDgoGc291cmNlGAkgASgJEhUKDWV2aWRlbmNlX2pzb24YCiABKAkSEwoLb2NjdXJyZWRfYXQYCyABKAkSEgoKY3JlYXRlZF9hdBgMIAEoCSLwAwoSU2Fhc1Jlc3BvbnNlQWN0aW9uEgoKAmlkGAEgASgJEhMKC2luY2lkZW50X2lkGAIgASgJEhIKCmZpbmRpbmdfaWQYAyABKAkSDgoGYWN0aW9uGAQgASgJEhAKCHByb3ZpZGVyGAUgASgJEhMKC3RhcmdldF90eXBlGAYgASgJEhkKEXRhcmdldF9pZGVudGlmaWVyGAcgASgJEg4KBnN0YXR1cxgIIAEoCRIZChFhcHByb3ZhbF9yZXF1aXJlZBgJIAEoCBIRCglyYXRpb25hbGUYCiABKAkSMQoLYXBwcm92ZWRfYnkYCyABKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlQcmluY2lwYWwSEwoLYXBwcm92ZWRfYXQYDCABKAkSEwoLZXhlY3V0ZWRfYXQYDSABKAkSFQoNZXJyb3JfbWVzc2FnZRgOIAEoCRITCgtyZXN1bHRfanNvbhgPIAEoCRISCgpjcmVhdGVkX2F0GBAgASgJEhIKCnVwZGF0ZWRfYXQYESABKAkSMQoLcHJvcG9zZWRfYnkYEiABKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlQcmluY2lwYWwSMQoLZXhlY3V0ZWRfYnkYEyABKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlQcmluY2lwYWwiLgoIUGFnZUluZm8SDQoFdG90YWwYASABKAUSEwoLbmV4dF9jdXJzb3IYAiABKAkiHQobTGlzdENvbm5lY3RvckNhdGFsb2dSZXF1ZXN0IkwKHExpc3RDb25uZWN0b3JDYXRhbG9nUmVzcG9uc2USLAoEZGF0YRgBIAMoCzIeLmFwZXJpby52MS5Db25uZWN0b3JEZWZpbml0aW9uIuQCChNDb25uZWN0b3JEZWZpbml0aW9uEhAKCHByb3ZpZGVyGAEgASgJEgwKBG5hbWUYAiABKAkSEAoIY2F0ZWdvcnkYAyABKAkSFAoMYXZhaWxhYmlsaXR5GAQgASgJEhYKDnJlYWRpbmVzc19ub3RlGAUgASgJEhMKC2Rlc2NyaXB0aW9uGAYgASgJEhMKC3JlYWRfc2NvcGVzGAcgAygJEhoKEnJlbWVkaWF0aW9uX3Njb3BlcxgIIAMoCRI5ChNyZW1lZGlhdGlvbl9hY3Rpb25zGAkgAygLMhwuYXBlcmlvLnYxLlJlbWVkaWF0aW9uQWN0aW9uEi8KDmZpbmRpbmdfY2hlY2tzGAogAygLMhcuYXBlcmlvLnYxLkZpbmRpbmdDaGVjaxIQCghkb2NzX3VybBgLIAEoCRIpCgZmaWVsZHMYDCADKAsyGS5hcGVyaW8udjEuQ29ubmVjdG9yRmllbGQigQEKDkNvbm5lY3RvckZpZWxkEgsKA2tleRgBIAEoCRINCgVsYWJlbBgCIAEoCRITCgtwbGFjZWhvbGRlchgDIAEoCRIOCgZoZWxwZXIYBCABKAkSDAoEdHlwZRgFIAEoCRIQCghyZXF1aXJlZBgGIAEoCBIOCgZzZWNyZXQYByABKAgiWwoRUmVtZWRpYXRpb25BY3Rpb24SCwoDa2V5GAEgASgJEg0KBWxhYmVsGAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJEhUKDXNldmVyaXR5X2hpbnQYBCABKAkibwoMRmluZGluZ0NoZWNrEgsKA2tleRgBIAEoCRINCgV0aXRsZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgDIAEoCRIVCg1zZXZlcml0eV9oaW50GAQgASgJEhcKD2RlZmF1bHRfZW5hYmxlZBgFIAEoCCIZChdMaXN0SW50ZWdyYXRpb25zUmVxdWVzdCJKChhMaXN0SW50ZWdyYXRpb25zUmVzcG9uc2USLgoEZGF0YRgBIAMoCzIgLmFwZXJpby52MS5JbnRlZ3JhdGlvbkNvbm5lY3Rpb24iqAIKFUludGVncmF0aW9uQ29ubmVjdGlvbhIKCgJpZBgBIAEoCRIQCghwcm92aWRlchgCIAEoCRIUCgxkaXNwbGF5X25hbWUYAyABKAkSGwoTZXh0ZXJuYWxfYWNjb3VudF9pZBgEIAEoCRIOCgZzdGF0dXMYBSABKAkSDAoEbW9kZRgGIAEoCRIOCgZzY29wZXMYByADKAkSFwoPZGlzYWJsZWRfY2hlY2tzGAggAygJEiMKG2dvb2dsZV9tYWlsYm94X3NjYW5fZW5hYmxlZBgJIAEoCBIoCiBnb29nbGVfbWFpbGJveF9zY2FuX2NsaWVudF9lbWFpbBgKIAEoCRIUCgxsYXN0X3N5bmNfYXQYCyABKAkSEgoKY3JlYXRlZF9hdBgMIAEoCSKlAQoYQ3JlYXRlSW50ZWdyYXRpb25SZXF1ZXN0EhAKCHByb3ZpZGVyGAEgASgJEhQKDGRpc3BsYXlfbmFtZRgCIAEoCRIbChNleHRlcm5hbF9hY2NvdW50X2lkGAMgASgJEgwKBG1vZGUYBCABKAkSNgoLY3JlZGVudGlhbHMYBSABKAsyIS5hcGVyaW8udjEuSW50ZWdyYXRpb25DcmVkZW50aWFscyJdChZJbnRlZ3JhdGlvbkNyZWRlbnRpYWxzEhQKDGFjY2Vzc190b2tlbhgBIAEoCRIVCg1yZWZyZXNoX3Rva2VuGAIgASgJEhYKDndlYmhvb2tfc2VjcmV0GAMgASgJIksKGUNyZWF0ZUludGVncmF0aW9uUmVzcG9uc2USLgoEZGF0YRgBIAEoCzIgLmFwZXJpby52MS5JbnRlZ3JhdGlvbkNvbm5lY3Rpb24iJgoYRGVsZXRlSW50ZWdyYXRpb25SZXF1ZXN0EgoKAmlkGAEgASgJIkIKGURlbGV0ZUludGVncmF0aW9uUmVzcG9uc2USJQoEZGF0YRgBIAEoCzIXLmFwZXJpby52MS5EZWxldGVSZXN1bHQiGgoMRGVsZXRlUmVzdWx0EgoKAm9rGAEgASgIIjUKG0dldEludGVncmF0aW9uQ2hlY2tzUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCSJOChxHZXRJbnRlZ3JhdGlvbkNoZWNrc1Jlc3BvbnNlEi4KBGRhdGEYASABKAsyIC5hcGVyaW8udjEuSW50ZWdyYXRpb25DaGVja1N0YXRlIoUBCh5VcGRhdGVJbnRlZ3JhdGlvbkNoZWNrc1JlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkSFwoPZGlzYWJsZWRfY2hlY2tzGAIgAygJEhYKDmRpc2FibGVfcmVhc29uGAMgASgJEhoKEmRpc2FibGVfZXhwaXJlc19hdBgEIAEoCSJRCh9VcGRhdGVJbnRlZ3JhdGlvbkNoZWNrc1Jlc3BvbnNlEi4KBGRhdGEYASABKAsyIC5hcGVyaW8udjEuSW50ZWdyYXRpb25DaGVja1N0YXRlIncKFUludGVncmF0aW9uQ2hlY2tTdGF0ZRIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCRIXCg9kaXNhYmxlZF9jaGVja3MYAiADKAkSLQoGY2hlY2tzGAMgAygLMh0uYXBlcmlvLnYxLkZpbmRpbmdDaGVja1N0YXR1cyKGAQoSRmluZGluZ0NoZWNrU3RhdHVzEgsKA2tleRgBIAEoCRINCgV0aXRsZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgDIAEoCRIVCg1zZXZlcml0eV9oaW50GAQgASgJEhcKD2RlZmF1bHRfZW5hYmxlZBgFIAEoCBIPCgdlbmFibGVkGAYgASgIIjsKIUdldEdvb2dsZU1haWxib3hTY2FuQ29uZmlnUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCSJWCiJHZXRHb29nbGVNYWlsYm94U2NhbkNvbmZpZ1Jlc3BvbnNlEjAKBGRhdGEYASABKAsyIi5hcGVyaW8udjEuR29vZ2xlTWFpbGJveFNjYW5Db25maWciigEKJFVwZGF0ZUdvb2dsZU1haWxib3hTY2FuQ29uZmlnUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCRIPCgdlbmFibGVkGAIgASgIEiQKHHNlcnZpY2VfYWNjb3VudF9jbGllbnRfZW1haWwYAyABKAkSEwoLcHJpdmF0ZV9rZXkYBCABKAkiWQolVXBkYXRlR29vZ2xlTWFpbGJveFNjYW5Db25maWdSZXNwb25zZRIwCgRkYXRhGAEgASgLMiIuYXBlcmlvLnYxLkdvb2dsZU1haWxib3hTY2FuQ29uZmlnIlAKF0dvb2dsZU1haWxib3hTY2FuQ29uZmlnEg8KB2VuYWJsZWQYASABKAgSJAocc2VydmljZV9hY2NvdW50X2NsaWVudF9lbWFpbBgCIAEoCSJBCidHZXRHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZ1JlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkiYgooR2V0R29vZ2xlV29ya3NwYWNlQmlnUXVlcnlDb25maWdSZXNwb25zZRI2CgRkYXRhGAEgASgLMiguYXBlcmlvLnYxLkdvb2dsZVdvcmtzcGFjZUJpZ1F1ZXJ5Q29uZmlnIv8BCipVcGRhdGVHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZ1JlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkSDwoHZW5hYmxlZBgCIAEoCBISCgpwcm9qZWN0X2lkGAMgASgJEhYKDnJhd19kYXRhc2V0X2lkGAQgASgJEhIKCmRhdGFzZXRfaWQYBSABKAkSEAoIbG9jYXRpb24YBiABKAkSHQoVc2VydmljZV9hY2NvdW50X2VtYWlsGAcgASgJEiIKGndvcmtsb2FkX2lkZW50aXR5X3Byb3ZpZGVyGAggASgJEhMKC2FjY2Vzc19tb2RlGAkgASgJImUKK1VwZGF0ZUdvb2dsZVdvcmtzcGFjZUJpZ1F1ZXJ5Q29uZmlnUmVzcG9uc2USNgoEZGF0YRgBIAEoCzIoLmFwZXJpby52MS5Hb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZyLuAQodR29vZ2xlV29ya3NwYWNlQmlnUXVlcnlDb25maWcSDwoHZW5hYmxlZBgBIAEoCBISCgpwcm9qZWN0X2lkGAIgASgJEhYKDnJhd19kYXRhc2V0X2lkGAMgASgJEhIKCmRhdGFzZXRfaWQYBCABKAkSEAoIbG9jYXRpb24YBSABKAkSHQoVc2VydmljZV9hY2NvdW50X2VtYWlsGAYgASgJEiIKGndvcmtsb2FkX2lkZW50aXR5X3Byb3ZpZGVyGAcgASgJEhMKC2FjY2Vzc19tb2RlGAggASgJEhIKCnVwZGF0ZWRfYXQYCSABKAkiRgosVmFsaWRhdGVHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZ1JlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkiawotVmFsaWRhdGVHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZ1Jlc3BvbnNlEjoKBGRhdGEYASABKAsyLC5hcGVyaW8udjEuR29vZ2xlV29ya3NwYWNlQmlnUXVlcnlWYWxpZGF0aW9uIvoBCiFHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeVZhbGlkYXRpb24SFgoOaW50ZWdyYXRpb25faWQYASABKAkSCgoCb2sYAiABKAgSDwoHbWVzc2FnZRgDIAEoCRISCgpwcm9qZWN0X2lkGAQgASgJEhIKCmRhdGFzZXRfaWQYBSABKAkSFgoOYWN0aXZpdHlfdGFibGUYBiABKAkSEwoLdGFibGVfZm91bmQYByABKAgSEwoLc2FtcGxlX3Jvd3MYCCABKAUSFwoPZXN0aW1hdGVkX2J5dGVzGAkgASgDEh0KFXJ1bnRpbWVfdG9rZW5fcHJlc2VudBgKIAEoCCIwCiBTdGFydEdvb2dsZVdvcmtzcGFjZU9BdXRoUmVxdWVzdBIMCgRtb2RlGAEgASgJIkgKIVN0YXJ0R29vZ2xlV29ya3NwYWNlT0F1dGhSZXNwb25zZRIjCgRkYXRhGAEgASgLMhUuYXBlcmlvLnYxLk9BdXRoU3RhcnQiqQEKFkludGVncmF0aW9uT0F1dGhDbGllbnQSEAoIcHJvdmlkZXIYASABKAkSEQoJY2xpZW50X2lkGAIgASgJEhQKDHJlZGlyZWN0X3VyaRgDIAEoCRISCgpjb25maWd1cmVkGAQgASgIEhwKFGRlZmF1bHRfcmVkaXJlY3RfdXJpGAUgASgJEhIKCnVwZGF0ZWRfYXQYBiABKAkSDgoGc291cmNlGAcgASgJIjQKIEdldEludGVncmF0aW9uT0F1dGhDbGllbnRSZXF1ZXN0EhAKCHByb3ZpZGVyGAEgASgJIlQKIUdldEludGVncmF0aW9uT0F1dGhDbGllbnRSZXNwb25zZRIvCgRkYXRhGAEgASgLMiEuYXBlcmlvLnYxLkludGVncmF0aW9uT0F1dGhDbGllbnQidAogU2V0SW50ZWdyYXRpb25PQXV0aENsaWVudFJlcXVlc3QSEAoIcHJvdmlkZXIYASABKAkSEQoJY2xpZW50X2lkGAIgASgJEhUKDWNsaWVudF9zZWNyZXQYAyABKAkSFAoMcmVkaXJlY3RfdXJpGAQgASgJIlQKIVNldEludGVncmF0aW9uT0F1dGhDbGllbnRSZXNwb25zZRIvCgRkYXRhGAEgASgLMiEuYXBlcmlvLnYxLkludGVncmF0aW9uT0F1dGhDbGllbnQiNgoiQ2xlYXJJbnRlZ3JhdGlvbk9BdXRoQ2xpZW50UmVxdWVzdBIQCghwcm92aWRlchgBIAEoCSJWCiNDbGVhckludGVncmF0aW9uT0F1dGhDbGllbnRSZXNwb25zZRIvCgRkYXRhGAEgASgLMiEuYXBlcmlvLnYxLkludGVncmF0aW9uT0F1dGhDbGllbnQiGQoKT0F1dGhTdGFydBILCgN1cmwYASABKAkiNQobRm9yY2VTeW5jSW50ZWdyYXRpb25SZXF1ZXN0EhYKDmludGVncmF0aW9uX2lkGAEgASgJInQKHEZvcmNlU3luY0ludGVncmF0aW9uUmVzcG9uc2USLgoEZGF0YRgBIAEoCzIgLmFwZXJpby52MS5JbnRlZ3JhdGlvbkNvbm5lY3Rpb24SJAoEc3luYxgCIAEoCzIWLmFwZXJpby52MS5TeW5jU3VtbWFyeSJmCgtTeW5jU3VtbWFyeRIUCgxzYW1wbGVfY291bnQYASABKAUSFwoPZXZlbnRzX2luZ2VzdGVkGAIgASgFEhcKD2ZpbmRpbmdzX29wZW5lZBgDIAEoBRIPCgdzb3VyY2VzGAQgAygJIjkKH0dldEludGVncmF0aW9uU3luY1N0YXR1c1JlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkiUgogR2V0SW50ZWdyYXRpb25TeW5jU3RhdHVzUmVzcG9uc2USLgoEZGF0YRgBIAEoCzIgLmFwZXJpby52MS5JbnRlZ3JhdGlvblN5bmNTdGF0dXMiYwofUnVuSW50ZWdyYXRpb25Tb3VyY2VTeW5jUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCRITCgtzb3VyY2Vfa2luZBgCIAEoCRITCgtzdHJlYW1fbmFtZRgDIAEoCSJYCiBSdW5JbnRlZ3JhdGlvblNvdXJjZVN5bmNSZXNwb25zZRI0CgRkYXRhGAEgASgLMiYuYXBlcmlvLnYxLkludGVncmF0aW9uU291cmNlU3luY0FjdGlvbiJ3CiBCYWNrZmlsbEludGVncmF0aW9uU291cmNlUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCRITCgtzb3VyY2Vfa2luZBgCIAEoCRITCgtzdHJlYW1fbmFtZRgDIAEoCRIRCglmcm9tX3RpbWUYBCABKAkiWQohQmFja2ZpbGxJbnRlZ3JhdGlvblNvdXJjZVJlc3BvbnNlEjQKBGRhdGEYASABKAsyJi5hcGVyaW8udjEuSW50ZWdyYXRpb25Tb3VyY2VTeW5jQWN0aW9uIo8BChVJbnRlZ3JhdGlvblN5bmNTdGF0dXMSFgoOaW50ZWdyYXRpb25faWQYASABKAkSEAoIcHJvdmlkZXIYAiABKAkSFAoMZ2VuZXJhdGVkX2F0GAMgASgJEjYKB3NvdXJjZXMYBCADKAsyJS5hcGVyaW8udjEuSW50ZWdyYXRpb25Tb3VyY2VTeW5jU3RhdGUiywMKGkludGVncmF0aW9uU291cmNlU3luY1N0YXRlEhMKC3NvdXJjZV9raW5kGAEgASgJEhMKC3N0cmVhbV9uYW1lGAIgASgJEhQKDGRpc3BsYXlfbmFtZRgDIAEoCRIOCgZzdGF0dXMYBCABKAkSEwoLY3Vyc29yX3RpbWUYBSABKAkSFwoPbGFzdF9hdHRlbXB0X2F0GAYgASgJEhcKD2xhc3Rfc3VjY2Vzc19hdBgHIAEoCRISCgpsYXN0X2Vycm9yGAggASgJEhMKC2xhZ19zZWNvbmRzGAkgASgDEhEKCXJvd3Nfc2VlbhgKIAEoAxIVCg1yb3dzX2VucXVldWVkGAsgASgDEhQKDHF1ZXVlX3F1ZXVlZBgMIAEoAxIVCg1xdWV1ZV9ydW5uaW5nGA0gASgDEhQKDHF1ZXVlX2ZhaWxlZBgOIAEoAxIZChFxdWV1ZV9kZWFkX2xldHRlchgPIAEoAxIXCg9xdWV1ZV9zdWNjZWVkZWQYECABKAMSGgoSc3luY19ub3dfc3VwcG9ydGVkGBEgASgIEhoKEmJhY2tmaWxsX3N1cHBvcnRlZBgSIAEoCBIUCgxxdWV1ZV9zb3VyY2UYEyABKAkilgEKG0ludGVncmF0aW9uU291cmNlU3luY0FjdGlvbhIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCRITCgtzb3VyY2Vfa2luZBgCIAEoCRITCgtzdHJlYW1fbmFtZRgDIAEoCRIOCgZxdWV1ZWQYBCABKAgSDwoHbWVzc2FnZRgFIAEoCRIUCgxyZXF1ZXN0ZWRfYXQYBiABKAkiGAoWTGlzdFNpZW1DYXRhbG9nUmVxdWVzdCJNChdMaXN0U2llbUNhdGFsb2dSZXNwb25zZRIyCgRkYXRhGAEgAygLMiQuYXBlcmlvLnYxLlNpZW1EZXN0aW5hdGlvbkRlZmluaXRpb24ivwEKGVNpZW1EZXN0aW5hdGlvbkRlZmluaXRpb24SDAoEa2luZBgBIAEoCRIMCgRuYW1lGAIgASgJEg4KBnZlbmRvchgDIAEoCRITCgtkZXNjcmlwdGlvbhgEIAEoCRIQCghjYXRlZ29yeRgFIAEoCRIQCghkb2NzX3VybBgGIAEoCRIXCg9kZWZhdWx0X3N0cmVhbXMYByADKAkSJAoGZmllbGRzGAggAygLMhQuYXBlcmlvLnYxLlNpZW1GaWVsZCJ8CglTaWVtRmllbGQSCwoDa2V5GAEgASgJEg0KBWxhYmVsGAIgASgJEhMKC3BsYWNlaG9sZGVyGAMgASgJEg4KBmhlbHBlchgEIAEoCRIMCgR0eXBlGAUgASgJEhAKCHJlcXVpcmVkGAYgASgIEg4KBnNlY3JldBgHIAEoCCIdChtMaXN0U2llbURlc3RpbmF0aW9uc1JlcXVlc3QiSAocTGlzdFNpZW1EZXN0aW5hdGlvbnNSZXNwb25zZRIoCgRkYXRhGAEgAygLMhouYXBlcmlvLnYxLlNpZW1EZXN0aW5hdGlvbiKEAgoPU2llbURlc3RpbmF0aW9uEgoKAmlkGAEgASgJEgwKBGtpbmQYAiABKAkSDAoEbmFtZRgDIAEoCRIUCgxlbmRwb2ludF91cmwYBCABKAkSEQoJZmlsZV9wYXRoGAUgASgJEg0KBWluZGV4GAYgASgJEg8KB3N0cmVhbXMYByADKAkSDgoGc3RhdHVzGAggASgJEhgKEGxhc3RfZGVsaXZlcnlfYXQYCSABKAkSEgoKbGFzdF9lcnJvchgKIAEoCRIVCg1kZWxpdmVyaWVzX29rGAsgASgFEhcKD2RlbGl2ZXJpZXNfZmFpbBgMIAEoBRISCgpjcmVhdGVkX2F0GA0gASgJIpIBChxDcmVhdGVTaWVtRGVzdGluYXRpb25SZXF1ZXN0EgwKBGtpbmQYASABKAkSDAoEbmFtZRgCIAEoCRIUCgxlbmRwb2ludF91cmwYAyABKAkSEQoJZmlsZV9wYXRoGAQgASgJEg0KBWluZGV4GAUgASgJEg0KBXRva2VuGAYgASgJEg8KB3N0cmVhbXMYByADKAkiSQodQ3JlYXRlU2llbURlc3RpbmF0aW9uUmVzcG9uc2USKAoEZGF0YRgBIAEoCzIaLmFwZXJpby52MS5TaWVtRGVzdGluYXRpb24iKgocRGVsZXRlU2llbURlc3RpbmF0aW9uUmVxdWVzdBIKCgJpZBgBIAEoCSJGCh1EZWxldGVTaWVtRGVzdGluYXRpb25SZXNwb25zZRIlCgRkYXRhGAEgASgLMhcuYXBlcmlvLnYxLkRlbGV0ZVJlc3VsdCIoChpUZXN0U2llbURlc3RpbmF0aW9uUmVxdWVzdBIKCgJpZBgBIAEoCSJGChtUZXN0U2llbURlc3RpbmF0aW9uUmVzcG9uc2USJwoEZGF0YRgBIAEoCzIZLmFwZXJpby52MS5TaWVtVGVzdFJlc3VsdCJFCg5TaWVtVGVzdFJlc3VsdBIWCg5kZXN0aW5hdGlvbl9pZBgBIAEoCRIKCgJvaxgCIAEoCBIPCgdtZXNzYWdlGAMgASgJIh4KHExpc3RTaGFkb3dJdE9hdXRoQXBwc1JlcXVlc3QiSgodTGlzdFNoYWRvd0l0T2F1dGhBcHBzUmVzcG9uc2USKQoEZGF0YRgBIAMoCzIbLmFwZXJpby52MS5TaGFkb3dJdE9hdXRoQXBwIrACChBTaGFkb3dJdE9hdXRoQXBwEgoKAmlkGAEgASgJEhAKCHByb3ZpZGVyGAIgASgJEgwKBG5hbWUYAyABKAkSDwoHc3VtbWFyeRgEIAEoCRITCgtleHRlcm5hbF9pZBgFIAEoCRIOCgZsYWJlbHMYBiADKAkSEwoLY3JpdGljYWxpdHkYByABKAkSHwoXY29udGFpbnNfc2Vuc2l0aXZlX2RhdGEYCCABKAgSEgoKcmlza19zY29yZRgJIAEoBRIYChBsYXN0X29ic2VydmVkX2F0GAogASgJEhIKCnVzZXJfY291bnQYCyABKAUSDgoGc2NvcGVzGAwgAygJEjIKC2ludGVncmF0aW9uGA0gASgLMh0uYXBlcmlvLnYxLkZpbmRpbmdJbnRlZ3JhdGlvbiI1CiFMaXN0U2hhZG93SXRPYXV0aEFwcEdyYW50c1JlcXVlc3QSEAoIYXNzZXRfaWQYASABKAkiVQoiTGlzdFNoYWRvd0l0T2F1dGhBcHBHcmFudHNSZXNwb25zZRIvCgRkYXRhGAEgASgLMiEuYXBlcmlvLnYxLlNoYWRvd0l0T2F1dGhBcHBEZXRhaWwidwoWU2hhZG93SXRPYXV0aEFwcERldGFpbBIrCgNhcHAYASABKAsyHi5hcGVyaW8udjEuU2hhZG93SXRPYXV0aEFwcFJlZhIwCgZncmFudHMYAiADKAsyIC5hcGVyaW8udjEuU2hhZG93SXRPYXV0aEFwcEdyYW50IlYKE1NoYWRvd0l0T2F1dGhBcHBSZWYSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRITCgtleHRlcm5hbF9pZBgDIAEoCRIQCghwcm92aWRlchgEIAEoCSK9AQoVU2hhZG93SXRPYXV0aEFwcEdyYW50EgoKAmlkGAEgASgJEhIKCnVzZXJfZW1haWwYAiABKAkSGAoQdXNlcl9leHRlcm5hbF9pZBgDIAEoCRIZChF1c2VyX2Rpc3BsYXlfbmFtZRgEIAEoCRIOCgZzY29wZXMYBSADKAkSEQoJYW5vbnltb3VzGAYgASgIEhIKCm5hdGl2ZV9hcHAYByABKAgSGAoQbGFzdF9vYnNlcnZlZF9hdBgIIAEoCSIaChhHZXRUZW5hbnRTZXR0aW5nc1JlcXVlc3QiRAoZR2V0VGVuYW50U2V0dGluZ3NSZXNwb25zZRInCgRkYXRhGAEgASgLMhkuYXBlcmlvLnYxLlRlbmFudFNldHRpbmdzItMDChtVcGRhdGVUZW5hbnRTZXR0aW5nc1JlcXVlc3QSEQoEbmFtZRgBIAEoCUgAiAEBEh8KEm5vdGlmaWNhdGlvbl9lbWFpbBgCIAEoCUgBiAEBEiAKE2RhdGFfcmV0ZW50aW9uX2RheXMYAyABKAVIAogBARIkChdjcml0aWNhbF9yaXNrX3RocmVzaG9sZBgEIAEoBUgDiAEBEh4KEWRlZmF1bHRfc2xhX2hvdXJzGAUgASgFSASIAQESJgoZYXV0b19yZXNvbHZlX2xvd19zZXZlcml0eRgGIAEoCEgFiAEBEh0KEGVuZm9yY2Vfc3NvX29ubHkYByABKAhIBogBARIeChF3ZWJob29rX2FsZXJ0X3VybBgIIAEoCUgHiAEBQgcKBV9uYW1lQhUKE19ub3RpZmljYXRpb25fZW1haWxCFgoUX2RhdGFfcmV0ZW50aW9uX2RheXNCGgoYX2NyaXRpY2FsX3Jpc2tfdGhyZXNob2xkQhQKEl9kZWZhdWx0X3NsYV9ob3Vyc0IcChpfYXV0b19yZXNvbHZlX2xvd19zZXZlcml0eUITChFfZW5mb3JjZV9zc29fb25seUIUChJfd2ViaG9va19hbGVydF91cmwiRwocVXBkYXRlVGVuYW50U2V0dGluZ3NSZXNwb25zZRInCgRkYXRhGAEgASgLMhkuYXBlcmlvLnYxLlRlbmFudFNldHRpbmdzIq0CCg5UZW5hbnRTZXR0aW5ncxIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEgwKBHNsdWcYAyABKAkSGgoSbm90aWZpY2F0aW9uX2VtYWlsGAQgASgJEhsKE2RhdGFfcmV0ZW50aW9uX2RheXMYBSABKAUSHwoXY3JpdGljYWxfcmlza190aHJlc2hvbGQYBiABKAUSGQoRZGVmYXVsdF9zbGFfaG91cnMYByABKAUSIQoZYXV0b19yZXNvbHZlX2xvd19zZXZlcml0eRgIIAEoCBIYChBlbmZvcmNlX3Nzb19vbmx5GAkgASgIEhkKEXdlYmhvb2tfYWxlcnRfdXJsGAogASgJEhIKCmNyZWF0ZWRfYXQYCyABKAkSEgoKdXBkYXRlZF9hdBgMIAEoCSIaChhMaXN0VGVuYW50TWVtYmVyc1JlcXVlc3QiQgoZTGlzdFRlbmFudE1lbWJlcnNSZXNwb25zZRIlCgRkYXRhGAEgAygLMhcuYXBlcmlvLnYxLlRlbmFudE1lbWJlciJTChlDcmVhdGVUZW5hbnRNZW1iZXJSZXF1ZXN0Eg0KBWVtYWlsGAEgASgJEhQKDGRpc3BsYXlfbmFtZRgCIAEoCRIRCglyb2xlX25hbWUYAyABKAkidAoaQ3JlYXRlVGVuYW50TWVtYmVyUmVzcG9uc2USJQoEZGF0YRgBIAEoCzIXLmFwZXJpby52MS5UZW5hbnRNZW1iZXISLwoKaW52aXRhdGlvbhgCIAEoCzIbLmFwZXJpby52MS5JbnZpdGF0aW9uUmVzdWx0IioKHENyZWF0ZU1lbWJlclJlc2V0TGlua1JlcXVlc3QSCgoCaWQYASABKAkicgodQ3JlYXRlTWVtYmVyUmVzZXRMaW5rUmVzcG9uc2USJQoEZGF0YRgBIAEoCzIXLmFwZXJpby52MS5UZW5hbnRNZW1iZXISKgoFcmVzZXQYAiABKAsyGy5hcGVyaW8udjEuSW52aXRhdGlvblJlc3VsdCI4ChdVcGRhdGVNZW1iZXJSb2xlUmVxdWVzdBIKCgJpZBgBIAEoCRIRCglyb2xlX25hbWUYAiABKAkiQQoYVXBkYXRlTWVtYmVyUm9sZVJlc3BvbnNlEiUKBGRhdGEYASABKAsyFy5hcGVyaW8udjEuVGVuYW50TWVtYmVyIu8BCgxUZW5hbnRNZW1iZXISCgoCaWQYASABKAkSDQoFZW1haWwYAiABKAkSFAoMZGlzcGxheV9uYW1lGAMgASgJEhEKCWlzX2FjdGl2ZRgEIAEoCBITCgttZmFfZW5hYmxlZBgFIAEoCBIVCg1sYXN0X2xvZ2luX2F0GAYgASgJEhYKDmlzX2JyZWFrX2dsYXNzGAcgASgIEgwKBHJvbGUYCCABKAkSEgoKYXV0aF9zdGF0ZRgJIAEoCRIhChlwZW5kaW5nX2FjdGlvbl9leHBpcmVzX2F0GAogASgJEhIKCmNyZWF0ZWRfYXQYCyABKAkiRQoQSW52aXRhdGlvblJlc3VsdBIQCghkZWxpdmVyeRgBIAEoCRILCgN1cmwYAiABKAkSEgoKZXhwaXJlc19hdBgDIAEoCSIWChRMaXN0QXVkaXRMb2dzUmVxdWVzdCI/ChVMaXN0QXVkaXRMb2dzUmVzcG9uc2USJgoEZGF0YRgBIAMoCzIYLmFwZXJpby52MS5BdWRpdExvZ0VudHJ5Io0BCg1BdWRpdExvZ0VudHJ5EgoKAmlkGAEgASgJEg4KBmFjdGlvbhgCIAEoCRITCgt0YXJnZXRfdHlwZRgDIAEoCRIRCgl0YXJnZXRfaWQYBCABKAkSDQoFYWN0b3IYBSABKAkSEgoKY3JlYXRlZF9hdBgGIAEoCRIVCg1tZXRhZGF0YV9qc29uGAcgASgJIhwKGkdldFNlY3VyaXR5T3ZlcnZpZXdSZXF1ZXN0IkgKG0dldFNlY3VyaXR5T3ZlcnZpZXdSZXNwb25zZRIpCgRkYXRhGAEgASgLMhsuYXBlcmlvLnYxLlNlY3VyaXR5T3ZlcnZpZXciiQQKEFNlY3VyaXR5T3ZlcnZpZXcSMwoHc3VtbWFyeRgBIAEoCzIiLmFwZXJpby52MS5TZWN1cml0eU92ZXJ2aWV3U3VtbWFyeRIvCgppZGVudGl0aWVzGAIgAygLMhsuYXBlcmlvLnYxLlNlY3VyaXR5SWRlbnRpdHkSJwoFZ3JhcGgYAyABKAsyGC5hcGVyaW8udjEuU2VjdXJpdHlHcmFwaBIsCgpvYXV0aF9hcHBzGAQgAygLMhguYXBlcmlvLnYxLlNlY3VyaXR5QXNzZXQSLQoLZGF0YV9hc3NldHMYBSADKAsyGC5hcGVyaW8udjEuU2VjdXJpdHlBc3NldBIrCgxhdHRhY2tfcGF0aHMYBiADKAsyFS5hcGVyaW8udjEuQXR0YWNrUGF0aBIwCg5vd25lcnNoaXBfZ2FwcxgHIAMoCzIYLmFwZXJpby52MS5TZWN1cml0eUFzc2V0EiwKCmV4Y2VwdGlvbnMYCCADKAsyGC5hcGVyaW8udjEuUmlza0V4Y2VwdGlvbhJAChdkb21haW5fd2lkZV9kZWxlZ2F0aW9ucxgJIAMoCzIfLmFwZXJpby52MS5Eb21haW5XaWRlRGVsZWdhdGlvbhI6Cg9jZXJlYnJvX2NvbnRleHQYCiABKAsyIS5hcGVyaW8udjEuU2VjdXJpdHlDZXJlYnJvQ29udGV4dCLoAQoXU2VjdXJpdHlPdmVydmlld1N1bW1hcnkSHQoVcHJpdmlsZWdlZF9pZGVudGl0aWVzGAEgASgFEiQKHGFkbWluX2lkZW50aXRpZXNfd2l0aG91dF9tZmEYAiABKAUSGAoQcmlza3lfb2F1dGhfYXBwcxgDIAEoBRIbChNleHBvc2VkX2RhdGFfYXNzZXRzGAQgASgFEhYKDnVub3duZWRfYXNzZXRzGAUgASgFEhkKEWFjdGl2ZV9leGNlcHRpb25zGAYgASgFEh4KFnRvcF9ibGFzdF9yYWRpdXNfc2NvcmUYByABKAUilwIKFlNlY3VyaXR5Q2VyZWJyb0NvbnRleHQSDgoGc291cmNlGAEgASgJEgwKBG1vZGUYAiABKAkSGQoRc291cmNlX3J1bnRpbWVfaWQYAyABKAkSGAoQZmluZGluZ19jb250cmFjdBgEIAEoCRITCgtjbGFpbV9jb3VudBgFIAEoBRIaChJncmFwaF9zaWduYWxfY291bnQYBiABKAUSFAoMZW50aXR5X2NvdW50GAcgASgFEhgKEGdyYXBoX3BhdGhfY291bnQYCCABKAUSMQoDbWNwGAkgASgLMiQuYXBlcmlvLnYxLlNlY3VyaXR5Q2VyZWJyb01DUENvbnRleHQSFgoOcmVzcG9uc2VfaGludHMYCiADKAkipQEKGVNlY3VyaXR5Q2VyZWJyb01DUENvbnRleHQSDgoGc2VydmVyGAEgASgJEhQKDHJlc291cmNlX3VyaRgCIAEoCRIQCghyZXNvdXJjZRgDIAEoCRINCgV0b29scxgEIAMoCRJBChJyZXNvdXJjZV90ZW1wbGF0ZXMYBSADKAsyJS5hcGVyaW8udjEuQ2VyZWJyb01DUFJlc291cmNlVGVtcGxhdGUi/gIKEFNlY3VyaXR5SWRlbnRpdHkSCgoCaWQYASABKAkSEQoJZW50aXR5X2lkGAIgASgJEgwKBGtpbmQYAyABKAkSDAoEbmFtZRgEIAEoCRINCgVlbWFpbBgFIAEoCRIQCghwcm92aWRlchgGIAEoCRIyCgtpbnRlZ3JhdGlvbhgHIAEoCzIdLmFwZXJpby52MS5GaW5kaW5nSW50ZWdyYXRpb24SDAoEcm9sZRgIIAEoCRISCgpwcml2aWxlZ2VkGAkgASgIEhMKC21mYV9lbmFibGVkGAogASgIEg4KBnN0YXR1cxgLIAEoCRITCgtpc19leHRlcm5hbBgMIAEoCBIYChBsYXN0X29ic2VydmVkX2F0GA0gASgJEhoKEmxpbmtlZF9hc3NldF9jb3VudBgOIAEoBRISCgpyaXNrX3Njb3JlGA8gASgFEh4KEW1mYV9lbmFibGVkX3N0YXRlGBAgASgISACIAQFCFAoSX21mYV9lbmFibGVkX3N0YXRlImkKDVNlY3VyaXR5R3JhcGgSKwoFbm9kZXMYASADKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlHcmFwaE5vZGUSKwoFZWRnZXMYAiADKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlHcmFwaEVkZ2UikQEKEVNlY3VyaXR5R3JhcGhOb2RlEgoKAmlkGAEgASgJEg0KBWxhYmVsGAIgASgJEgwKBGtpbmQYAyABKAkSEgoKcmlza19zY29yZRgEIAEoBRISCgpwcml2aWxlZ2VkGAUgASgIEhYKDmV4cG9zdXJlX2xldmVsGAYgASgJEhMKC2NyaXRpY2FsaXR5GAcgASgJImAKEVNlY3VyaXR5R3JhcGhFZGdlEgoKAmlkGAEgASgJEhEKCXNvdXJjZV9pZBgCIAEoCRIRCgl0YXJnZXRfaWQYAyABKAkSGQoRcmVsYXRpb25zaGlwX3R5cGUYBCABKAkizAEKCkF0dGFja1BhdGgSCgoCaWQYASABKAkSDQoFdGl0bGUYAiABKAkSDQoFc2NvcmUYAyABKAUSFQoNZmluZGluZ190aXRsZRgEIAEoCRITCgtlbnRyeV9wb2ludBgFIAEoCRIOCgZ0YXJnZXQYBiABKAkSDQoFb3duZXIYByABKAkSFgoOZXhwb3N1cmVfbGV2ZWwYCCABKAkSEwoLY3JpdGljYWxpdHkYCSABKAkSDgoGcmVhc29uGAogASgJEgwKBHBhdGgYCyADKAkirAIKFERvbWFpbldpZGVEZWxlZ2F0aW9uEhYKDmludGVncmF0aW9uX2lkGAEgASgJEhAKCHByb3ZpZGVyGAIgASgJEhQKDGRpc3BsYXlfbmFtZRgDIAEoCRIYChB3b3Jrc3BhY2VfZG9tYWluGAQgASgJEiQKHHNlcnZpY2VfYWNjb3VudF9jbGllbnRfZW1haWwYBSABKAkSDgoGc2NvcGVzGAYgAygJEg4KBnN0YXR1cxgHIAEoCRIaChJpbnRlZ3JhdGlvbl9zdGF0dXMYCCABKAkSDAoEbW9kZRgJIAEoCRIdChVvcGVuX21haWxib3hfZmluZGluZ3MYCiABKAUSFAoMbGFzdF9zeW5jX2F0GAsgASgJEhUKDWNvbmZpZ3VyZWRfYXQYDCABKAkiOAocTGlzdEVtYWlsRG9tYWluSGVhbHRoUmVxdWVzdBIYChByZWZyZXNoX2lmX3N0YWxlGAEgASgIIksKHUxpc3RFbWFpbERvbWFpbkhlYWx0aFJlc3BvbnNlEioKBGRhdGEYASADKAsyHC5hcGVyaW8udjEuRW1haWxEb21haW5IZWFsdGgiLQobR2V0RW1haWxEb21haW5IZWFsdGhSZXF1ZXN0Eg4KBmRvbWFpbhgBIAEoCSJQChxHZXRFbWFpbERvbWFpbkhlYWx0aFJlc3BvbnNlEjAKBGRhdGEYASABKAsyIi5hcGVyaW8udjEuRW1haWxEb21haW5IZWFsdGhEZXRhaWwiMQofUmVmcmVzaEVtYWlsRG9tYWluSGVhbHRoUmVxdWVzdBIOCgZkb21haW4YASABKAkiTgogUmVmcmVzaEVtYWlsRG9tYWluSGVhbHRoUmVzcG9uc2USKgoEZGF0YRgBIAMoCzIcLmFwZXJpby52MS5FbWFpbERvbWFpbkhlYWx0aCLmAQoRRW1haWxEb21haW5IZWFsdGgSDgoGZG9tYWluGAEgASgJEhgKEHByb3ZpZGVyX3NvdXJjZXMYAiADKAkSDgoGc3RhdHVzGAMgASgJEg0KBXNjb3JlGAQgASgFEhIKCnNwZl9zdGF0dXMYBSABKAkSEwoLZGtpbV9zdGF0dXMYBiABKAkSFAoMZG1hcmNfc3RhdHVzGAcgASgJEhcKD2xhc3RfY2hlY2tlZF9hdBgIIAEoCRITCgtpc3N1ZV9jb3VudBgJIAEoBRIbChNmYWlsaW5nX2lzc3VlX2NvdW50GAogASgFIo0BChZFbWFpbERvbWFpbkhlYWx0aElzc3VlEgoKAmlkGAEgASgJEhAKCHByb3RvY29sGAIgASgJEhAKCHNldmVyaXR5GAMgASgJEgwKBGNvZGUYBCABKAkSDQoFdGl0bGUYBSABKAkSDgoGZGV0YWlsGAYgASgJEhYKDnJlY29tbWVuZGF0aW9uGAcgASgJIl0KF0VtYWlsRG9tYWluRGtpbVNlbGVjdG9yEhAKCHNlbGVjdG9yGAEgASgJEg4KBnN0YXR1cxgCIAEoCRIQCghrZXlfYml0cxgDIAEoBRIOCgZyZWNvcmQYBCABKAkiZwodRW1haWxEb21haW5IZWFsdGhIaXN0b3J5UG9pbnQSEgoKY2hlY2tlZF9hdBgBIAEoCRIOCgZzdGF0dXMYAiABKAkSDQoFc2NvcmUYAyABKAUSEwoLaXNzdWVfY291bnQYBCABKAUitAMKF0VtYWlsRG9tYWluSGVhbHRoRGV0YWlsEiwKBmRvbWFpbhgBIAEoCzIcLmFwZXJpby52MS5FbWFpbERvbWFpbkhlYWx0aBITCgtzcGZfcmVjb3JkcxgCIAMoCRISCgpzcGZfcG9saWN5GAMgASgJEhgKEHNwZl9sb29rdXBfY291bnQYBCABKAUSFQoNZG1hcmNfcmVjb3JkcxgFIAMoCRIUCgxkbWFyY19wb2xpY3kYBiABKAkSEQoJZG1hcmNfcGN0GAcgASgFEhEKCWRtYXJjX3J1YRgIIAMoCRISCgpteF9yZWNvcmRzGAkgAygJEjoKDmRraW1fc2VsZWN0b3JzGAogAygLMiIuYXBlcmlvLnYxLkVtYWlsRG9tYWluRGtpbVNlbGVjdG9yEhcKD3JlbGF0ZWRfcmVjb3JkcxgLIAMoCRIxCgZpc3N1ZXMYDCADKAsyIS5hcGVyaW8udjEuRW1haWxEb21haW5IZWFsdGhJc3N1ZRI5CgdoaXN0b3J5GA0gAygLMiguYXBlcmlvLnYxLkVtYWlsRG9tYWluSGVhbHRoSGlzdG9yeVBvaW50IlsKGUxpc3RTZWN1cml0eUFzc2V0c1JlcXVlc3QSDAoEdHlwZRgBIAEoCRIYChBvd25lcnNoaXBfc3RhdHVzGAIgASgJEhYKDmludGVncmF0aW9uX2lkGAMgASgJIkQKGkxpc3RTZWN1cml0eUFzc2V0c1Jlc3BvbnNlEiYKBGRhdGEYASADKAsyGC5hcGVyaW8udjEuU2VjdXJpdHlBc3NldCKnBAoNU2VjdXJpdHlBc3NldBIKCgJpZBgBIAEoCRIMCgR0eXBlGAIgASgJEhAKCHByb3ZpZGVyGAMgASgJEgwKBG5hbWUYBCABKAkSDwoHc3VtbWFyeRgFIAEoCRITCgtleHRlcm5hbF9pZBgGIAEoCRIOCgZsYWJlbHMYByADKAkSEwoLY3JpdGljYWxpdHkYCCABKAkSFgoOZXhwb3N1cmVfbGV2ZWwYCSABKAkSGAoQb3duZXJzaGlwX3N0YXR1cxgKIAEoCRIfChdjb250YWluc19zZW5zaXRpdmVfZGF0YRgLIAEoCBIVCg1pc19wcml2aWxlZ2VkGAwgASgIEhIKCnJpc2tfc2NvcmUYDSABKAUSGAoQbGFzdF9vYnNlcnZlZF9hdBgOIAEoCRISCgpjcmVhdGVkX2F0GA8gASgJEhIKCnVwZGF0ZWRfYXQYECABKAkSMgoLaW50ZWdyYXRpb24YESABKAsyHS5hcGVyaW8udjEuRmluZGluZ0ludGVncmF0aW9uEisKBW93bmVyGBIgASgLMhwuYXBlcmlvLnYxLlNlY3VyaXR5UHJpbmNpcGFsEjQKDmJ1c2luZXNzX293bmVyGBMgASgLMhwuYXBlcmlvLnYxLlNlY3VyaXR5UHJpbmNpcGFsEhoKEm9wZW5fZmluZGluZ19jb3VudBgUIAEoBRIeChZhY3RpdmVfZXhjZXB0aW9uX2NvdW50GBUgASgFIkQKEVNlY3VyaXR5UHJpbmNpcGFsEgoKAmlkGAEgASgJEg0KBWVtYWlsGAIgASgJEhQKDGRpc3BsYXlfbmFtZRgDIAEoCSL8AgoaQ3JlYXRlU2VjdXJpdHlBc3NldFJlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkSFQoNb3duZXJfdXNlcl9pZBgCIAEoCRIeChZidXNpbmVzc19vd25lcl91c2VyX2lkGAMgASgJEgwKBHR5cGUYBCABKAkSEAoIcHJvdmlkZXIYBSABKAkSDAoEbmFtZRgGIAEoCRIPCgdzdW1tYXJ5GAcgASgJEhMKC2V4dGVybmFsX2lkGAggASgJEg4KBmxhYmVscxgJIAMoCRITCgtjcml0aWNhbGl0eRgKIAEoCRIWCg5leHBvc3VyZV9sZXZlbBgLIAEoCRIYChBvd25lcnNoaXBfc3RhdHVzGAwgASgJEh8KF2NvbnRhaW5zX3NlbnNpdGl2ZV9kYXRhGA0gASgIEhUKDWlzX3ByaXZpbGVnZWQYDiABKAgSEgoKcmlza19zY29yZRgPIAEoBRIYChBsYXN0X29ic2VydmVkX2F0GBAgASgJIkUKG0NyZWF0ZVNlY3VyaXR5QXNzZXRSZXNwb25zZRImCgRkYXRhGAEgASgLMhguYXBlcmlvLnYxLlNlY3VyaXR5QXNzZXQi8AUKGlVwZGF0ZVNlY3VyaXR5QXNzZXRSZXF1ZXN0EgoKAmlkGAEgASgJEhsKDmludGVncmF0aW9uX2lkGAIgASgJSACIAQESGgoNb3duZXJfdXNlcl9pZBgDIAEoCUgBiAEBEiMKFmJ1c2luZXNzX293bmVyX3VzZXJfaWQYBCABKAlIAogBARIRCgR0eXBlGAUgASgJSAOIAQESFQoIcHJvdmlkZXIYBiABKAlIBIgBARIRCgRuYW1lGAcgASgJSAWIAQESFAoHc3VtbWFyeRgIIAEoCUgGiAEBEhgKC2V4dGVybmFsX2lkGAkgASgJSAeIAQESDgoGbGFiZWxzGAogAygJEhYKDmxhYmVsc19wcmVzZW50GAsgASgIEhgKC2NyaXRpY2FsaXR5GAwgASgJSAiIAQESGwoOZXhwb3N1cmVfbGV2ZWwYDSABKAlICYgBARIdChBvd25lcnNoaXBfc3RhdHVzGA4gASgJSAqIAQESJAoXY29udGFpbnNfc2Vuc2l0aXZlX2RhdGEYDyABKAhIC4gBARIaCg1pc19wcml2aWxlZ2VkGBAgASgISAyIAQESFwoKcmlza19zY29yZRgRIAEoBUgNiAEBEh0KEGxhc3Rfb2JzZXJ2ZWRfYXQYEiABKAlIDogBAUIRCg9faW50ZWdyYXRpb25faWRCEAoOX293bmVyX3VzZXJfaWRCGQoXX2J1c2luZXNzX293bmVyX3VzZXJfaWRCBwoFX3R5cGVCCwoJX3Byb3ZpZGVyQgcKBV9uYW1lQgoKCF9zdW1tYXJ5Qg4KDF9leHRlcm5hbF9pZEIOCgxfY3JpdGljYWxpdHlCEQoPX2V4cG9zdXJlX2xldmVsQhMKEV9vd25lcnNoaXBfc3RhdHVzQhoKGF9jb250YWluc19zZW5zaXRpdmVfZGF0YUIQCg5faXNfcHJpdmlsZWdlZEINCgtfcmlza19zY29yZUITChFfbGFzdF9vYnNlcnZlZF9hdCJFChtVcGRhdGVTZWN1cml0eUFzc2V0UmVzcG9uc2USJgoEZGF0YRgBIAEoCzIYLmFwZXJpby52MS5TZWN1cml0eUFzc2V0IhsKGUxpc3RSaXNrRXhjZXB0aW9uc1JlcXVlc3QiRAoaTGlzdFJpc2tFeGNlcHRpb25zUmVzcG9uc2USJgoEZGF0YRgBIAMoCzIYLmFwZXJpby52MS5SaXNrRXhjZXB0aW9uIoIDCg1SaXNrRXhjZXB0aW9uEgoKAmlkGAEgASgJEg0KBXRpdGxlGAIgASgJEhEKCXJhdGlvbmFsZRgDIAEoCRIdChVjb21wZW5zYXRpbmdfY29udHJvbHMYBCADKAkSDgoGc3RhdHVzGAUgASgJEhIKCmV4cGlyZXNfYXQYBiABKAkSEwoLYXBwcm92ZWRfYXQYByABKAkSEgoKY3JlYXRlZF9hdBgIIAEoCRISCgp1cGRhdGVkX2F0GAkgASgJEiwKBWFzc2V0GAogASgLMh0uYXBlcmlvLnYxLlJpc2tFeGNlcHRpb25Bc3NldBIwCgdmaW5kaW5nGAsgASgLMh8uYXBlcmlvLnYxLlJpc2tFeGNlcHRpb25GaW5kaW5nEjAKCmNyZWF0ZWRfYnkYDCABKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlQcmluY2lwYWwSMQoLYXBwcm92ZWRfYnkYDSABKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlQcmluY2lwYWwiPAoSUmlza0V4Y2VwdGlvbkFzc2V0EgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSDAoEdHlwZRgDIAEoCSJTChRSaXNrRXhjZXB0aW9uRmluZGluZxIKCgJpZBgBIAEoCRINCgV0aXRsZRgCIAEoCRIQCghzZXZlcml0eRgDIAEoCRIOCgZzdGF0dXMYBCABKAkilwEKGkNyZWF0ZVJpc2tFeGNlcHRpb25SZXF1ZXN0EhAKCGFzc2V0X2lkGAEgASgJEhIKCmZpbmRpbmdfaWQYAiABKAkSDQoFdGl0bGUYAyABKAkSEQoJcmF0aW9uYWxlGAQgASgJEh0KFWNvbXBlbnNhdGluZ19jb250cm9scxgFIAMoCRISCgpleHBpcmVzX2F0GAYgASgJIkUKG0NyZWF0ZVJpc2tFeGNlcHRpb25SZXNwb25zZRImCgRkYXRhGAEgASgLMhguYXBlcmlvLnYxLlJpc2tFeGNlcHRpb24i+gEKGlVwZGF0ZVJpc2tFeGNlcHRpb25SZXF1ZXN0EgoKAmlkGAEgASgJEhIKBXRpdGxlGAIgASgJSACIAQESFgoJcmF0aW9uYWxlGAMgASgJSAGIAQESHQoVY29tcGVuc2F0aW5nX2NvbnRyb2xzGAQgAygJEiUKHWNvbXBlbnNhdGluZ19jb250cm9sc19wcmVzZW50GAUgASgIEhMKBnN0YXR1cxgGIAEoCUgCiAEBEhcKCmV4cGlyZXNfYXQYByABKAlIA4gBAUIICgZfdGl0bGVCDAoKX3JhdGlvbmFsZUIJCgdfc3RhdHVzQg0KC19leHBpcmVzX2F0IkUKG1VwZGF0ZVJpc2tFeGNlcHRpb25SZXNwb25zZRImCgRkYXRhGAEgASgLMhguYXBlcmlvLnYxLlJpc2tFeGNlcHRpb24i7QIKD0V4ZWN1dGl2ZVJlcG9ydBIKCgJpZBgBIAEoCRIOCgZwZXJpb2QYAiABKAkSFAoMcGVyaW9kX3N0YXJ0GAMgASgJEhIKCnBlcmlvZF9lbmQYBCABKAkSDQoFdGl0bGUYBSABKAkSDwoHc3VtbWFyeRgGIAEoCRIOCgZzdGF0dXMYByABKAkSGQoRa3BpX3NuYXBzaG90X2pzb24YCCABKAkSEAoIaGFzX2h0bWwYCSABKAgSDwoHaGFzX3BkZhgKIAEoCBIQCghodG1sX3VybBgLIAEoCRIPCgdwZGZfdXJsGAwgASgJEhIKCmNyZWF0ZWRfYXQYDSABKAkSEgoKdXBkYXRlZF9hdBgOIAEoCRIUCgxnZW5lcmF0ZWRfYXQYDyABKAkSFQoNZXJyb3JfbWVzc2FnZRgQIAEoCRIcChRyZXF1ZXN0ZWRfYnlfdXNlcl9pZBgRIAEoCRIQCgh0ZW1wbGF0ZRgSIAEoCSIdChtMaXN0RXhlY3V0aXZlUmVwb3J0c1JlcXVlc3QiSAocTGlzdEV4ZWN1dGl2ZVJlcG9ydHNSZXNwb25zZRIoCgRkYXRhGAEgAygLMhouYXBlcmlvLnYxLkV4ZWN1dGl2ZVJlcG9ydCInChlHZXRFeGVjdXRpdmVSZXBvcnRSZXF1ZXN0EgoKAmlkGAEgASgJIkYKGkdldEV4ZWN1dGl2ZVJlcG9ydFJlc3BvbnNlEigKBGRhdGEYASABKAsyGi5hcGVyaW8udjEuRXhlY3V0aXZlUmVwb3J0InkKHENyZWF0ZUV4ZWN1dGl2ZVJlcG9ydFJlcXVlc3QSDgoGcGVyaW9kGAEgASgJEg0KBXRpdGxlGAIgASgJEhQKDHBlcmlvZF9zdGFydBgDIAEoCRISCgpwZXJpb2RfZW5kGAQgASgJEhAKCHRlbXBsYXRlGAUgASgJIkkKHUNyZWF0ZUV4ZWN1dGl2ZVJlcG9ydFJlc3BvbnNlEigKBGRhdGEYASABKAsyGi5hcGVyaW8udjEuRXhlY3V0aXZlUmVwb3J0IioKHERlbGV0ZUV4ZWN1dGl2ZVJlcG9ydFJlcXVlc3QSCgoCaWQYASABKAkiMAodRGVsZXRlRXhlY3V0aXZlUmVwb3J0UmVzcG9uc2USDwoHZGVsZXRlZBgBIAEoCCKQAQoUQ29ubmVjdG9yQnVpbHRJblJ1bGUSCgoCaWQYASABKAkSEAoIcHJvdmlkZXIYAiABKAkSDQoFdGl0bGUYAyABKAkSEwoLZGVzY3JpcHRpb24YBCABKAkSEAoIc2V2ZXJpdHkYBSABKAkSEwoLZXZlbnRfdHlwZXMYBiADKAkSDwoHZW5hYmxlZBgHIAEoCCKpAQoTQ29ubmVjdG9yQ3VzdG9tUnVsZRIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEhAKCHNldmVyaXR5GAMgASgJEhIKCmV2ZW50X3R5cGUYBCABKAkSFgoOcHJlZGljYXRlX2pzb24YBSABKAkSDwoHZW5hYmxlZBgGIAEoCBISCgp1cGRhdGVkX2F0GAcgASgJEhUKDXN1YmplY3RfZmllbGQYCCABKAkiMwoZTGlzdENvbm5lY3RvclJ1bGVzUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCSKpAQoaTGlzdENvbm5lY3RvclJ1bGVzUmVzcG9uc2USFgoOaW50ZWdyYXRpb25faWQYASABKAkSEAoIcHJvdmlkZXIYAiABKAkSMQoIYnVpbHRfaW4YAyADKAsyHy5hcGVyaW8udjEuQ29ubmVjdG9yQnVpbHRJblJ1bGUSLgoGY3VzdG9tGAQgAygLMh4uYXBlcmlvLnYxLkNvbm5lY3RvckN1c3RvbVJ1bGUipQEKF0NyZWF0ZUN1c3RvbVJ1bGVSZXF1ZXN0EhYKDmludGVncmF0aW9uX2lkGAEgASgJEgwKBG5hbWUYAiABKAkSEAoIc2V2ZXJpdHkYAyABKAkSEgoKZXZlbnRfdHlwZRgEIAEoCRIWCg5wcmVkaWNhdGVfanNvbhgFIAEoCRIPCgdlbmFibGVkGAYgASgIEhUKDXN1YmplY3RfZmllbGQYByABKAkiJgoYQ3JlYXRlQ3VzdG9tUnVsZVJlc3BvbnNlEgoKAmlkGAEgASgJIrYBChdVcGRhdGVDdXN0b21SdWxlUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCRIPCgdydWxlX2lkGAIgASgJEgwKBG5hbWUYAyABKAkSEAoIc2V2ZXJpdHkYBCABKAkSEgoKZXZlbnRfdHlwZRgFIAEoCRIWCg5wcmVkaWNhdGVfanNvbhgGIAEoCRIPCgdlbmFibGVkGAcgASgIEhUKDXN1YmplY3RfZmllbGQYCCABKAkiJgoYVXBkYXRlQ3VzdG9tUnVsZVJlc3BvbnNlEgoKAmlkGAEgASgJIkIKF0RlbGV0ZUN1c3RvbVJ1bGVSZXF1ZXN0EhYKDmludGVncmF0aW9uX2lkGAEgASgJEg8KB3J1bGVfaWQYAiABKAkiJgoYRGVsZXRlQ3VzdG9tUnVsZVJlc3BvbnNlEgoKAmlkGAEgASgJMug9Cg1BcGVyaW9TZXJ2aWNlEkAKB0NhbGxBcGkSGS5hcGVyaW8udjEuQ2FsbEFwaVJlcXVlc3QaGi5hcGVyaW8udjEuQ2FsbEFwaVJlc3BvbnNlEj0KBlNpZ251cBIYLmFwZXJpby52MS5TaWdudXBSZXF1ZXN0GhkuYXBlcmlvLnYxLlNpZ251cFJlc3BvbnNlEjoKBUxvZ2luEhcuYXBlcmlvLnYxLkxvZ2luUmVxdWVzdBoYLmFwZXJpby52MS5Mb2dpblJlc3BvbnNlEl4KEUdldEN1cnJlbnRTZXNzaW9uEiMuYXBlcmlvLnYxLkdldEN1cnJlbnRTZXNzaW9uUmVxdWVzdBokLmFwZXJpby52MS5HZXRDdXJyZW50U2Vzc2lvblJlc3BvbnNlEmcKFExvZ291dEN1cnJlbnRTZXNzaW9uEiYuYXBlcmlvLnYxLkxvZ291dEN1cnJlbnRTZXNzaW9uUmVxdWVzdBonLmFwZXJpby52MS5Mb2dvdXRDdXJyZW50U2Vzc2lvblJlc3BvbnNlElUKDkxpc3RXb3Jrc3BhY2VzEiAuYXBlcmlvLnYxLkxpc3RXb3Jrc3BhY2VzUmVxdWVzdBohLmFwZXJpby52MS5MaXN0V29ya3NwYWNlc1Jlc3BvbnNlElgKD1N3aXRjaFdvcmtzcGFjZRIhLmFwZXJpby52MS5Td2l0Y2hXb3Jrc3BhY2VSZXF1ZXN0GiIuYXBlcmlvLnYxLlN3aXRjaFdvcmtzcGFjZVJlc3BvbnNlEmcKFFJlcXVlc3RQYXNzd29yZFJlc2V0EiYuYXBlcmlvLnYxLlJlcXVlc3RQYXNzd29yZFJlc2V0UmVxdWVzdBonLmFwZXJpby52MS5SZXF1ZXN0UGFzc3dvcmRSZXNldFJlc3BvbnNlElIKDVJlc2V0UGFzc3dvcmQSHy5hcGVyaW8udjEuUmVzZXRQYXNzd29yZFJlcXVlc3QaIC5hcGVyaW8udjEuUmVzZXRQYXNzd29yZFJlc3BvbnNlEk8KDEFjY2VwdEludml0ZRIeLmFwZXJpby52MS5BY2NlcHRJbnZpdGVSZXF1ZXN0Gh8uYXBlcmlvLnYxLkFjY2VwdEludml0ZVJlc3BvbnNlEmEKEkJlZ2luTWZhRW5yb2xsbWVudBIkLmFwZXJpby52MS5CZWdpbk1mYUVucm9sbG1lbnRSZXF1ZXN0GiUuYXBlcmlvLnYxLkJlZ2luTWZhRW5yb2xsbWVudFJlc3BvbnNlEkYKCUVuYWJsZU1mYRIbLmFwZXJpby52MS5FbmFibGVNZmFSZXF1ZXN0GhwuYXBlcmlvLnYxLkVuYWJsZU1mYVJlc3BvbnNlEkkKCkRpc2FibGVNZmESHC5hcGVyaW8udjEuRGlzYWJsZU1mYVJlcXVlc3QaHS5hcGVyaW8udjEuRGlzYWJsZU1mYVJlc3BvbnNlEkwKC0NoZWNrSGVhbHRoEh0uYXBlcmlvLnYxLkNoZWNrSGVhbHRoUmVxdWVzdBoeLmFwZXJpby52MS5DaGVja0hlYWx0aFJlc3BvbnNlEmQKE0dldERhc2hib2FyZE1ldHJpY3MSJS5hcGVyaW8udjEuR2V0RGFzaGJvYXJkTWV0cmljc1JlcXVlc3QaJi5hcGVyaW8udjEuR2V0RGFzaGJvYXJkTWV0cmljc1Jlc3BvbnNlEk8KDExpc3RGaW5kaW5ncxIeLmFwZXJpby52MS5MaXN0RmluZGluZ3NSZXF1ZXN0Gh8uYXBlcmlvLnYxLkxpc3RGaW5kaW5nc1Jlc3BvbnNlEkkKCkdldEZpbmRpbmcSHC5hcGVyaW8udjEuR2V0RmluZGluZ1JlcXVlc3QaHS5hcGVyaW8udjEuR2V0RmluZGluZ1Jlc3BvbnNlEmQKE1VwZGF0ZUZpbmRpbmdTdGF0dXMSJS5hcGVyaW8udjEuVXBkYXRlRmluZGluZ1N0YXR1c1JlcXVlc3QaJi5hcGVyaW8udjEuVXBkYXRlRmluZGluZ1N0YXR1c1Jlc3BvbnNlElsKEFJlbWVkaWF0ZUZpbmRpbmcSIi5hcGVyaW8udjEuUmVtZWRpYXRlRmluZGluZ1JlcXVlc3QaIy5hcGVyaW8udjEuUmVtZWRpYXRlRmluZGluZ1Jlc3BvbnNlEl4KEUxpc3RTYWFzSW5jaWRlbnRzEiMuYXBlcmlvLnYxLkxpc3RTYWFzSW5jaWRlbnRzUmVxdWVzdBokLmFwZXJpby52MS5MaXN0U2Fhc0luY2lkZW50c1Jlc3BvbnNlElgKD0dldFNhYXNJbmNpZGVudBIhLmFwZXJpby52MS5HZXRTYWFzSW5jaWRlbnRSZXF1ZXN0GiIuYXBlcmlvLnYxLkdldFNhYXNJbmNpZGVudFJlc3BvbnNlEmEKEkNyZWF0ZVNhYXNJbmNpZGVudBIkLmFwZXJpby52MS5DcmVhdGVTYWFzSW5jaWRlbnRSZXF1ZXN0GiUuYXBlcmlvLnYxLkNyZWF0ZVNhYXNJbmNpZGVudFJlc3BvbnNlEnMKGFVwZGF0ZVNhYXNJbmNpZGVudFN0YXR1cxIqLmFwZXJpby52MS5VcGRhdGVTYWFzSW5jaWRlbnRTdGF0dXNSZXF1ZXN0GisuYXBlcmlvLnYxLlVwZGF0ZVNhYXNJbmNpZGVudFN0YXR1c1Jlc3BvbnNlEnYKGVByb3Bvc2VTYWFzUmVzcG9uc2VBY3Rpb24SKy5hcGVyaW8udjEuUHJvcG9zZVNhYXNSZXNwb25zZUFjdGlvblJlcXVlc3QaLC5hcGVyaW8udjEuUHJvcG9zZVNhYXNSZXNwb25zZUFjdGlvblJlc3BvbnNlEnYKGUFwcHJvdmVTYWFzUmVzcG9uc2VBY3Rpb24SKy5hcGVyaW8udjEuQXBwcm92ZVNhYXNSZXNwb25zZUFjdGlvblJlcXVlc3QaLC5hcGVyaW8udjEuQXBwcm92ZVNhYXNSZXNwb25zZUFjdGlvblJlc3BvbnNlEnYKGUV4ZWN1dGVTYWFzUmVzcG9uc2VBY3Rpb24SKy5hcGVyaW8udjEuRXhlY3V0ZVNhYXNSZXNwb25zZUFjdGlvblJlcXVlc3QaLC5hcGVyaW8udjEuRXhlY3V0ZVNhYXNSZXNwb25zZUFjdGlvblJlc3BvbnNlEmcKFExpc3RDb25uZWN0b3JDYXRhbG9nEiYuYXBlcmlvLnYxLkxpc3RDb25uZWN0b3JDYXRhbG9nUmVxdWVzdBonLmFwZXJpby52MS5MaXN0Q29ubmVjdG9yQ2F0YWxvZ1Jlc3BvbnNlElsKEExpc3RJbnRlZ3JhdGlvbnMSIi5hcGVyaW8udjEuTGlzdEludGVncmF0aW9uc1JlcXVlc3QaIy5hcGVyaW8udjEuTGlzdEludGVncmF0aW9uc1Jlc3BvbnNlEl4KEUNyZWF0ZUludGVncmF0aW9uEiMuYXBlcmlvLnYxLkNyZWF0ZUludGVncmF0aW9uUmVxdWVzdBokLmFwZXJpby52MS5DcmVhdGVJbnRlZ3JhdGlvblJlc3BvbnNlEl4KEURlbGV0ZUludGVncmF0aW9uEiMuYXBlcmlvLnYxLkRlbGV0ZUludGVncmF0aW9uUmVxdWVzdBokLmFwZXJpby52MS5EZWxldGVJbnRlZ3JhdGlvblJlc3BvbnNlEmcKFEdldEludGVncmF0aW9uQ2hlY2tzEiYuYXBlcmlvLnYxLkdldEludGVncmF0aW9uQ2hlY2tzUmVxdWVzdBonLmFwZXJpby52MS5HZXRJbnRlZ3JhdGlvbkNoZWNrc1Jlc3BvbnNlEnAKF1VwZGF0ZUludGVncmF0aW9uQ2hlY2tzEikuYXBlcmlvLnYxLlVwZGF0ZUludGVncmF0aW9uQ2hlY2tzUmVxdWVzdBoqLmFwZXJpby52MS5VcGRhdGVJbnRlZ3JhdGlvbkNoZWNrc1Jlc3BvbnNlEmEKEkxpc3RDb25uZWN0b3JSdWxlcxIkLmFwZXJpby52MS5MaXN0Q29ubmVjdG9yUnVsZXNSZXF1ZXN0GiUuYXBlcmlvLnYxLkxpc3RDb25uZWN0b3JSdWxlc1Jlc3BvbnNlElsKEENyZWF0ZUN1c3RvbVJ1bGUSIi5hcGVyaW8udjEuQ3JlYXRlQ3VzdG9tUnVsZVJlcXVlc3QaIy5hcGVyaW8udjEuQ3JlYXRlQ3VzdG9tUnVsZVJlc3BvbnNlElsKEFVwZGF0ZUN1c3RvbVJ1bGUSIi5hcGVyaW8udjEuVXBkYXRlQ3VzdG9tUnVsZVJlcXVlc3QaIy5hcGVyaW8udjEuVXBkYXRlQ3VzdG9tUnVsZVJlc3BvbnNlElsKEERlbGV0ZUN1c3RvbVJ1bGUSIi5hcGVyaW8udjEuRGVsZXRlQ3VzdG9tUnVsZVJlcXVlc3QaIy5hcGVyaW8udjEuRGVsZXRlQ3VzdG9tUnVsZVJlc3BvbnNlEnkKGkdldEdvb2dsZU1haWxib3hTY2FuQ29uZmlnEiwuYXBlcmlvLnYxLkdldEdvb2dsZU1haWxib3hTY2FuQ29uZmlnUmVxdWVzdBotLmFwZXJpby52MS5HZXRHb29nbGVNYWlsYm94U2NhbkNvbmZpZ1Jlc3BvbnNlEoIBCh1VcGRhdGVHb29nbGVNYWlsYm94U2NhbkNvbmZpZxIvLmFwZXJpby52MS5VcGRhdGVHb29nbGVNYWlsYm94U2NhbkNvbmZpZ1JlcXVlc3QaMC5hcGVyaW8udjEuVXBkYXRlR29vZ2xlTWFpbGJveFNjYW5Db25maWdSZXNwb25zZRKLAQogR2V0R29vZ2xlV29ya3NwYWNlQmlnUXVlcnlDb25maWcSMi5hcGVyaW8udjEuR2V0R29vZ2xlV29ya3NwYWNlQmlnUXVlcnlDb25maWdSZXF1ZXN0GjMuYXBlcmlvLnYxLkdldEdvb2dsZVdvcmtzcGFjZUJpZ1F1ZXJ5Q29uZmlnUmVzcG9uc2USlAEKI1VwZGF0ZUdvb2dsZVdvcmtzcGFjZUJpZ1F1ZXJ5Q29uZmlnEjUuYXBlcmlvLnYxLlVwZGF0ZUdvb2dsZVdvcmtzcGFjZUJpZ1F1ZXJ5Q29uZmlnUmVxdWVzdBo2LmFwZXJpby52MS5VcGRhdGVHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZ1Jlc3BvbnNlEpoBCiVWYWxpZGF0ZUdvb2dsZVdvcmtzcGFjZUJpZ1F1ZXJ5Q29uZmlnEjcuYXBlcmlvLnYxLlZhbGlkYXRlR29vZ2xlV29ya3NwYWNlQmlnUXVlcnlDb25maWdSZXF1ZXN0GjguYXBlcmlvLnYxLlZhbGlkYXRlR29vZ2xlV29ya3NwYWNlQmlnUXVlcnlDb25maWdSZXNwb25zZRJ2ChlTdGFydEdvb2dsZVdvcmtzcGFjZU9BdXRoEisuYXBlcmlvLnYxLlN0YXJ0R29vZ2xlV29ya3NwYWNlT0F1dGhSZXF1ZXN0GiwuYXBlcmlvLnYxLlN0YXJ0R29vZ2xlV29ya3NwYWNlT0F1dGhSZXNwb25zZRJ2ChlHZXRJbnRlZ3JhdGlvbk9BdXRoQ2xpZW50EisuYXBlcmlvLnYxLkdldEludGVncmF0aW9uT0F1dGhDbGllbnRSZXF1ZXN0GiwuYXBlcmlvLnYxLkdldEludGVncmF0aW9uT0F1dGhDbGllbnRSZXNwb25zZRJ2ChlTZXRJbnRlZ3JhdGlvbk9BdXRoQ2xpZW50EisuYXBlcmlvLnYxLlNldEludGVncmF0aW9uT0F1dGhDbGllbnRSZXF1ZXN0GiwuYXBlcmlvLnYxLlNldEludGVncmF0aW9uT0F1dGhDbGllbnRSZXNwb25zZRJ8ChtDbGVhckludGVncmF0aW9uT0F1dGhDbGllbnQSLS5hcGVyaW8udjEuQ2xlYXJJbnRlZ3JhdGlvbk9BdXRoQ2xpZW50UmVxdWVzdBouLmFwZXJpby52MS5DbGVhckludGVncmF0aW9uT0F1dGhDbGllbnRSZXNwb25zZRJnChRGb3JjZVN5bmNJbnRlZ3JhdGlvbhImLmFwZXJpby52MS5Gb3JjZVN5bmNJbnRlZ3JhdGlvblJlcXVlc3QaJy5hcGVyaW8udjEuRm9yY2VTeW5jSW50ZWdyYXRpb25SZXNwb25zZRJzChhHZXRJbnRlZ3JhdGlvblN5bmNTdGF0dXMSKi5hcGVyaW8udjEuR2V0SW50ZWdyYXRpb25TeW5jU3RhdHVzUmVxdWVzdBorLmFwZXJpby52MS5HZXRJbnRlZ3JhdGlvblN5bmNTdGF0dXNSZXNwb25zZRJzChhSdW5JbnRlZ3JhdGlvblNvdXJjZVN5bmMSKi5hcGVyaW8udjEuUnVuSW50ZWdyYXRpb25Tb3VyY2VTeW5jUmVxdWVzdBorLmFwZXJpby52MS5SdW5JbnRlZ3JhdGlvblNvdXJjZVN5bmNSZXNwb25zZRJ2ChlCYWNrZmlsbEludGVncmF0aW9uU291cmNlEisuYXBlcmlvLnYxLkJhY2tmaWxsSW50ZWdyYXRpb25Tb3VyY2VSZXF1ZXN0GiwuYXBlcmlvLnYxLkJhY2tmaWxsSW50ZWdyYXRpb25Tb3VyY2VSZXNwb25zZRJYCg9MaXN0U2llbUNhdGFsb2cSIS5hcGVyaW8udjEuTGlzdFNpZW1DYXRhbG9nUmVxdWVzdBoiLmFwZXJpby52MS5MaXN0U2llbUNhdGFsb2dSZXNwb25zZRJnChRMaXN0U2llbURlc3RpbmF0aW9ucxImLmFwZXJpby52MS5MaXN0U2llbURlc3RpbmF0aW9uc1JlcXVlc3QaJy5hcGVyaW8udjEuTGlzdFNpZW1EZXN0aW5hdGlvbnNSZXNwb25zZRJqChVDcmVhdGVTaWVtRGVzdGluYXRpb24SJy5hcGVyaW8udjEuQ3JlYXRlU2llbURlc3RpbmF0aW9uUmVxdWVzdBooLmFwZXJpby52MS5DcmVhdGVTaWVtRGVzdGluYXRpb25SZXNwb25zZRJqChVEZWxldGVTaWVtRGVzdGluYXRpb24SJy5hcGVyaW8udjEuRGVsZXRlU2llbURlc3RpbmF0aW9uUmVxdWVzdBooLmFwZXJpby52MS5EZWxldGVTaWVtRGVzdGluYXRpb25SZXNwb25zZRJkChNUZXN0U2llbURlc3RpbmF0aW9uEiUuYXBlcmlvLnYxLlRlc3RTaWVtRGVzdGluYXRpb25SZXF1ZXN0GiYuYXBlcmlvLnYxLlRlc3RTaWVtRGVzdGluYXRpb25SZXNwb25zZRJqChVMaXN0U2hhZG93SXRPYXV0aEFwcHMSJy5hcGVyaW8udjEuTGlzdFNoYWRvd0l0T2F1dGhBcHBzUmVxdWVzdBooLmFwZXJpby52MS5MaXN0U2hhZG93SXRPYXV0aEFwcHNSZXNwb25zZRJ5ChpMaXN0U2hhZG93SXRPYXV0aEFwcEdyYW50cxIsLmFwZXJpby52MS5MaXN0U2hhZG93SXRPYXV0aEFwcEdyYW50c1JlcXVlc3QaLS5hcGVyaW8udjEuTGlzdFNoYWRvd0l0T2F1dGhBcHBHcmFudHNSZXNwb25zZRJeChFHZXRUZW5hbnRTZXR0aW5ncxIjLmFwZXJpby52MS5HZXRUZW5hbnRTZXR0aW5nc1JlcXVlc3QaJC5hcGVyaW8udjEuR2V0VGVuYW50U2V0dGluZ3NSZXNwb25zZRJnChRVcGRhdGVUZW5hbnRTZXR0aW5ncxImLmFwZXJpby52MS5VcGRhdGVUZW5hbnRTZXR0aW5nc1JlcXVlc3QaJy5hcGVyaW8udjEuVXBkYXRlVGVuYW50U2V0dGluZ3NSZXNwb25zZRJeChFMaXN0VGVuYW50TWVtYmVycxIjLmFwZXJpby52MS5MaXN0VGVuYW50TWVtYmVyc1JlcXVlc3QaJC5hcGVyaW8udjEuTGlzdFRlbmFudE1lbWJlcnNSZXNwb25zZRJhChJDcmVhdGVUZW5hbnRNZW1iZXISJC5hcGVyaW8udjEuQ3JlYXRlVGVuYW50TWVtYmVyUmVxdWVzdBolLmFwZXJpby52MS5DcmVhdGVUZW5hbnRNZW1iZXJSZXNwb25zZRJqChVDcmVhdGVNZW1iZXJSZXNldExpbmsSJy5hcGVyaW8udjEuQ3JlYXRlTWVtYmVyUmVzZXRMaW5rUmVxdWVzdBooLmFwZXJpby52MS5DcmVhdGVNZW1iZXJSZXNldExpbmtSZXNwb25zZRJbChBVcGRhdGVNZW1iZXJSb2xlEiIuYXBlcmlvLnYxLlVwZGF0ZU1lbWJlclJvbGVSZXF1ZXN0GiMuYXBlcmlvLnYxLlVwZGF0ZU1lbWJlclJvbGVSZXNwb25zZRJSCg1MaXN0QXVkaXRMb2dzEh8uYXBlcmlvLnYxLkxpc3RBdWRpdExvZ3NSZXF1ZXN0GiAuYXBlcmlvLnYxLkxpc3RBdWRpdExvZ3NSZXNwb25zZRJkChNHZXRTZWN1cml0eU92ZXJ2aWV3EiUuYXBlcmlvLnYxLkdldFNlY3VyaXR5T3ZlcnZpZXdSZXF1ZXN0GiYuYXBlcmlvLnYxLkdldFNlY3VyaXR5T3ZlcnZpZXdSZXNwb25zZRJqChVMaXN0RW1haWxEb21haW5IZWFsdGgSJy5hcGVyaW8udjEuTGlzdEVtYWlsRG9tYWluSGVhbHRoUmVxdWVzdBooLmFwZXJpby52MS5MaXN0RW1haWxEb21haW5IZWFsdGhSZXNwb25zZRJnChRHZXRFbWFpbERvbWFpbkhlYWx0aBImLmFwZXJpby52MS5HZXRFbWFpbERvbWFpbkhlYWx0aFJlcXVlc3QaJy5hcGVyaW8udjEuR2V0RW1haWxEb21haW5IZWFsdGhSZXNwb25zZRJzChhSZWZyZXNoRW1haWxEb21haW5IZWFsdGgSKi5hcGVyaW8udjEuUmVmcmVzaEVtYWlsRG9tYWluSGVhbHRoUmVxdWVzdBorLmFwZXJpby52MS5SZWZyZXNoRW1haWxEb21haW5IZWFsdGhSZXNwb25zZRJhChJMaXN0U2VjdXJpdHlBc3NldHMSJC5hcGVyaW8udjEuTGlzdFNlY3VyaXR5QXNzZXRzUmVxdWVzdBolLmFwZXJpby52MS5MaXN0U2VjdXJpdHlBc3NldHNSZXNwb25zZRJkChNDcmVhdGVTZWN1cml0eUFzc2V0EiUuYXBlcmlvLnYxLkNyZWF0ZVNlY3VyaXR5QXNzZXRSZXF1ZXN0GiYuYXBlcmlvLnYxLkNyZWF0ZVNlY3VyaXR5QXNzZXRSZXNwb25zZRJkChNVcGRhdGVTZWN1cml0eUFzc2V0EiUuYXBlcmlvLnYxLlVwZGF0ZVNlY3VyaXR5QXNzZXRSZXF1ZXN0GiYuYXBlcmlvLnYxLlVwZGF0ZVNlY3VyaXR5QXNzZXRSZXNwb25zZRJhChJMaXN0Umlza0V4Y2VwdGlvbnMSJC5hcGVyaW8udjEuTGlzdFJpc2tFeGNlcHRpb25zUmVxdWVzdBolLmFwZXJpby52MS5MaXN0Umlza0V4Y2VwdGlvbnNSZXNwb25zZRJkChNDcmVhdGVSaXNrRXhjZXB0aW9uEiUuYXBlcmlvLnYxLkNyZWF0ZVJpc2tFeGNlcHRpb25SZXF1ZXN0GiYuYXBlcmlvLnYxLkNyZWF0ZVJpc2tFeGNlcHRpb25SZXNwb25zZRJkChNVcGRhdGVSaXNrRXhjZXB0aW9uEiUuYXBlcmlvLnYxLlVwZGF0ZVJpc2tFeGNlcHRpb25SZXF1ZXN0GiYuYXBlcmlvLnYxLlVwZGF0ZVJpc2tFeGNlcHRpb25SZXNwb25zZRJnChRMaXN0RXhlY3V0aXZlUmVwb3J0cxImLmFwZXJpby52MS5MaXN0RXhlY3V0aXZlUmVwb3J0c1JlcXVlc3QaJy5hcGVyaW8udjEuTGlzdEV4ZWN1dGl2ZVJlcG9ydHNSZXNwb25zZRJhChJHZXRFeGVjdXRpdmVSZXBvcnQSJC5hcGVyaW8udjEuR2V0RXhlY3V0aXZlUmVwb3J0UmVxdWVzdBolLmFwZXJpby52MS5HZXRFeGVjdXRpdmVSZXBvcnRSZXNwb25zZRJqChVDcmVhdGVFeGVjdXRpdmVSZXBvcnQSJy5hcGVyaW8udjEuQ3JlYXRlRXhlY3V0aXZlUmVwb3J0UmVxdWVzdBooLmFwZXJpby52MS5DcmVhdGVFeGVjdXRpdmVSZXBvcnRSZXNwb25zZRJqChVEZWxldGVFeGVjdXRpdmVSZXBvcnQSJy5hcGVyaW8udjEuRGVsZXRlRXhlY3V0aXZlUmVwb3J0UmVxdWVzdBooLmFwZXJpby52MS5EZWxldGVFeGVjdXRpdmVSZXBvcnRSZXNwb25zZUIxWi9naXRodWIuY29tL3dyaXRlci9hcGVyaW8vZ2VuL2FwZXJpby92MTthcGVyaW92MWIGcHJvdG8z", [file_google_protobuf_timestamp]); + fileDesc("ChNhcGVyaW8vdjEvYXBpLnByb3RvEglhcGVyaW8udjEiQQoOQ2FsbEFwaVJlcXVlc3QSDgoGbWV0aG9kGAEgASgJEgwKBHBhdGgYAiABKAkSEQoJYm9keV9qc29uGAMgASgJIiQKD0NhbGxBcGlSZXNwb25zZRIRCglib2R5X2pzb24YASABKAkipAEKDVNpZ251cFJlcXVlc3QSGQoRb3JnYW5pemF0aW9uX25hbWUYASABKAkSGQoRb3JnYW5pemF0aW9uX3NsdWcYAiABKAkSGgoSbm90aWZpY2F0aW9uX2VtYWlsGAMgASgJEhMKC293bmVyX2VtYWlsGAQgASgJEhoKEm93bmVyX2Rpc3BsYXlfbmFtZRgFIAEoCRIQCghwYXNzd29yZBgGIAEoCSI2Cg5TaWdudXBSZXNwb25zZRIkCgRkYXRhGAEgASgLMhYuYXBlcmlvLnYxLkF1dGhTZXNzaW9uIl0KDExvZ2luUmVxdWVzdBIZChFvcmdhbml6YXRpb25fc2x1ZxgBIAEoCRINCgVlbWFpbBgCIAEoCRIQCghwYXNzd29yZBgDIAEoCRIRCgl0b3RwX2NvZGUYBCABKAkiNQoNTG9naW5SZXNwb25zZRIkCgRkYXRhGAEgASgLMhYuYXBlcmlvLnYxLkF1dGhTZXNzaW9uIhoKGEdldEN1cnJlbnRTZXNzaW9uUmVxdWVzdCJBChlHZXRDdXJyZW50U2Vzc2lvblJlc3BvbnNlEiQKBGRhdGEYASABKAsyFi5hcGVyaW8udjEuQXV0aFNlc3Npb24iHQobTG9nb3V0Q3VycmVudFNlc3Npb25SZXF1ZXN0IkUKHExvZ291dEN1cnJlbnRTZXNzaW9uUmVzcG9uc2USJQoEZGF0YRgBIAEoCzIXLmFwZXJpby52MS5EZWxldGVSZXN1bHQiFwoVTGlzdFdvcmtzcGFjZXNSZXF1ZXN0IkYKFkxpc3RXb3Jrc3BhY2VzUmVzcG9uc2USLAoEZGF0YRgBIAMoCzIeLmFwZXJpby52MS5Xb3Jrc3BhY2VNZW1iZXJzaGlwIlgKFlN3aXRjaFdvcmtzcGFjZVJlcXVlc3QSGQoRb3JnYW5pemF0aW9uX3NsdWcYASABKAkSEQoJdG90cF9jb2RlGAIgASgJEhAKCHBhc3N3b3JkGAMgASgJIj8KF1N3aXRjaFdvcmtzcGFjZVJlc3BvbnNlEiQKBGRhdGEYASABKAsyFi5hcGVyaW8udjEuQXV0aFNlc3Npb24iRwobUmVxdWVzdFBhc3N3b3JkUmVzZXRSZXF1ZXN0EhkKEW9yZ2FuaXphdGlvbl9zbHVnGAEgASgJEg0KBWVtYWlsGAIgASgJIkwKHFJlcXVlc3RQYXNzd29yZFJlc2V0UmVzcG9uc2USLAoEZGF0YRgBIAEoCzIeLmFwZXJpby52MS5QYXNzd29yZFJlc2V0UmVzdWx0IjcKFFJlc2V0UGFzc3dvcmRSZXF1ZXN0Eg0KBXRva2VuGAEgASgJEhAKCHBhc3N3b3JkGAIgASgJIj0KFVJlc2V0UGFzc3dvcmRSZXNwb25zZRIkCgRkYXRhGAEgASgLMhYuYXBlcmlvLnYxLkF1dGhTZXNzaW9uIkwKE0FjY2VwdEludml0ZVJlcXVlc3QSDQoFdG9rZW4YASABKAkSFAoMZGlzcGxheV9uYW1lGAIgASgJEhAKCHBhc3N3b3JkGAMgASgJIjwKFEFjY2VwdEludml0ZVJlc3BvbnNlEiQKBGRhdGEYASABKAsyFi5hcGVyaW8udjEuQXV0aFNlc3Npb24iGwoZQmVnaW5NZmFFbnJvbGxtZW50UmVxdWVzdCJEChpCZWdpbk1mYUVucm9sbG1lbnRSZXNwb25zZRImCgRkYXRhGAEgASgLMhguYXBlcmlvLnYxLk1mYUVucm9sbG1lbnQiIAoQRW5hYmxlTWZhUmVxdWVzdBIMCgRjb2RlGAEgASgJIjkKEUVuYWJsZU1mYVJlc3BvbnNlEiQKBGRhdGEYASABKAsyFi5hcGVyaW8udjEuQXV0aFNlc3Npb24iMwoRRGlzYWJsZU1mYVJlcXVlc3QSEAoIcGFzc3dvcmQYASABKAkSDAoEY29kZRgCIAEoCSI6ChJEaXNhYmxlTWZhUmVzcG9uc2USJAoEZGF0YRgBIAEoCzIWLmFwZXJpby52MS5BdXRoU2Vzc2lvbiKgAQoLQXV0aFNlc3Npb24SDQoFdG9rZW4YASABKAkSIQoEdXNlchgCIAEoCzITLmFwZXJpby52MS5BdXRoVXNlchIxCgxvcmdhbml6YXRpb24YAyABKAsyGy5hcGVyaW8udjEuQXV0aE9yZ2FuaXphdGlvbhIsCgxhdXRoX2NvbnRleHQYBCABKAsyFi5hcGVyaW8udjEuQXV0aENvbnRleHQiXgoIQXV0aFVzZXISCgoCaWQYASABKAkSDQoFZW1haWwYAiABKAkSFAoMZGlzcGxheV9uYW1lGAMgASgJEhMKC21mYV9lbmFibGVkGAQgASgIEgwKBHJvbGUYBSABKAkiOgoQQXV0aE9yZ2FuaXphdGlvbhIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEgwKBHNsdWcYAyABKAkisQMKC0F1dGhDb250ZXh0EhEKCXByaW5jaXBhbBgBIAEoCRIRCgl0ZW5hbnRfaWQYAiABKAkSEwoLdGVuYW50X3NsdWcYAyABKAkSFwoPY3JlZGVudGlhbF9raW5kGAQgASgJEhEKCWF1dGhfbW9kZRgFIAEoCRIXCg90b2tlbl90cmFuc3BvcnQYBiABKAkSGAoQY2VyZWJyb19yZXNvdXJjZRgHIAEoCRIXCg9hbGxvd2VkX3RlbmFudHMYCCADKAkSFgoOY2VyZWJyb19zY29wZXMYCSADKAkSDgoGZ3JvdXBzGAogAygJEhwKFGNlcmVicm9fbWNwX3Jlc291cmNlGAsgASgJEioKImNlcmVicm9fbWNwX3Jlc291cmNlX21ldGFkYXRhX3BhdGgYDCABKAkSOAowY2VyZWJyb19vYXV0aF9hdXRob3JpemF0aW9uX3NlcnZlcl9tZXRhZGF0YV9wYXRoGA0gASgJEh8KF2NlcmVicm9fbWNwX2dyYW50X3R5cGVzGA4gAygJEiIKGmNlcmVicm9fbWNwX2JlYXJlcl9tZXRob2RzGA8gAygJIlwKE1dvcmtzcGFjZU1lbWJlcnNoaXASCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIMCgRzbHVnGAMgASgJEgwKBHJvbGUYBCABKAkSDwoHY3VycmVudBgFIAEoCCJ7ChNQYXNzd29yZFJlc2V0UmVzdWx0EhAKCGFjY2VwdGVkGAEgASgIEhAKCGRlbGl2ZXJ5GAIgASgJEhEKCXJlc2V0X3VybBgDIAEoCRISCgpleHBpcmVzX2F0GAQgASgJEhkKEW9yZ2FuaXphdGlvbl9uYW1lGAUgASgJIjQKDU1mYUVucm9sbG1lbnQSDgoGc2VjcmV0GAEgASgJEhMKC290cGF1dGhfdXJsGAIgASgJIhQKEkNoZWNrSGVhbHRoUmVxdWVzdCKWAQoTQ2hlY2tIZWFsdGhSZXNwb25zZRIOCgZzdGF0dXMYASABKAkSDwoHc2VydmljZRgCIAEoCRIuCgpjaGVja2VkX2F0GAMgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIuCgpjb21wb25lbnRzGAQgAygLMhouYXBlcmlvLnYxLkhlYWx0aENvbXBvbmVudCI/Cg9IZWFsdGhDb21wb25lbnQSDAoEbmFtZRgBIAEoCRIOCgZzdGF0dXMYAiABKAkSDgoGZGV0YWlsGAMgASgJIhwKGkdldERhc2hib2FyZE1ldHJpY3NSZXF1ZXN0IkgKG0dldERhc2hib2FyZE1ldHJpY3NSZXNwb25zZRIpCgRkYXRhGAEgASgLMhsuYXBlcmlvLnYxLkRhc2hib2FyZE1ldHJpY3MiggEKEERhc2hib2FyZE1ldHJpY3MSGAoQdG90YWxfcmlza19zY29yZRgBIAEoBRIeChZvcGVuX2NyaXRpY2FsX2ZpbmRpbmdzGAIgASgFEhYKDmNvbm5lY3RlZF9hcHBzGAMgASgFEhwKFGV2ZW50X2luZ2VzdGlvbl9yYXRlGAQgASgFIoABChNMaXN0RmluZGluZ3NSZXF1ZXN0EhAKCHNldmVyaXR5GAEgASgJEg4KBnN0YXR1cxgCIAEoCRIQCghwcm92aWRlchgDIAEoCRIWCg5pbnRlZ3JhdGlvbl9pZBgEIAEoCRINCgVsaW1pdBgFIAEoBRIOCgZjdXJzb3IYBiABKAkiYAoUTGlzdEZpbmRpbmdzUmVzcG9uc2USIAoEZGF0YRgBIAMoCzISLmFwZXJpby52MS5GaW5kaW5nEiYKCXBhZ2VfaW5mbxgCIAEoCzITLmFwZXJpby52MS5QYWdlSW5mbyIfChFHZXRGaW5kaW5nUmVxdWVzdBIKCgJpZBgBIAEoCSI2ChJHZXRGaW5kaW5nUmVzcG9uc2USIAoEZGF0YRgBIAEoCzISLmFwZXJpby52MS5GaW5kaW5nIlEKGlVwZGF0ZUZpbmRpbmdTdGF0dXNSZXF1ZXN0EgoKAmlkGAEgASgJEg4KBnN0YXR1cxgCIAEoCRIXCg9yZXNvbHV0aW9uX25vdGUYAyABKAkiSwobVXBkYXRlRmluZGluZ1N0YXR1c1Jlc3BvbnNlEiwKBGRhdGEYASABKAsyHi5hcGVyaW8udjEuRmluZGluZ1N0YXR1c1VwZGF0ZSIxChNGaW5kaW5nU3RhdHVzVXBkYXRlEgoKAmlkGAEgASgJEg4KBnN0YXR1cxgCIAEoCSJmChdSZW1lZGlhdGVGaW5kaW5nUmVxdWVzdBISCgpmaW5kaW5nX2lkGAEgASgJEg4KBmFjdGlvbhgCIAEoCRIZChF0YXJnZXRfaWRlbnRpZmllchgDIAEoCRIMCgRub3RlGAQgASgJIkYKGFJlbWVkaWF0ZUZpbmRpbmdSZXNwb25zZRIqCgRkYXRhGAEgASgLMhwuYXBlcmlvLnYxLlJlbWVkaWF0aW9uUmVzdWx0IocBChFSZW1lZGlhdGlvblJlc3VsdBISCgpmaW5kaW5nX2lkGAEgASgJEg4KBmFjdGlvbhgCIAEoCRIPCgdzdWNjZXNzGAMgASgIEg8KB21lc3NhZ2UYBCABKAkSGwoTcHJvdmlkZXJfcmVxdWVzdF9pZBgFIAEoCRIPCgdlZmZlY3RzGAYgAygJItoCCgdGaW5kaW5nEgoKAmlkGAEgASgJEhAKCGFzc2V0X2lkGAIgASgJEg0KBXRpdGxlGAMgASgJEhMKC2Rlc2NyaXB0aW9uGAQgASgJEhAKCHNldmVyaXR5GAUgASgJEg4KBnN0YXR1cxgGIAEoCRISCgpyaXNrX3Njb3JlGAcgASgFEhkKEXJlbWVkaWF0aW9uX3N0ZXBzGAggAygJEhUKDWV2aWRlbmNlX2pzb24YCSABKAkSEwoLZGV0ZWN0ZWRfYXQYCiABKAkSEwoLcmVzb2x2ZWRfYXQYCyABKAkSMgoLaW50ZWdyYXRpb24YDCABKAsyHS5hcGVyaW8udjEuRmluZGluZ0ludGVncmF0aW9uEgwKBHRhZ3MYDSADKAkSOQoPY2VyZWJyb19jb250ZXh0GA4gASgLMiAuYXBlcmlvLnYxLkZpbmRpbmdDZXJlYnJvQ29udGV4dCJIChJGaW5kaW5nSW50ZWdyYXRpb24SCgoCaWQYASABKAkSEAoIcHJvdmlkZXIYAiABKAkSFAoMZGlzcGxheV9uYW1lGAMgASgJIqsDChVGaW5kaW5nQ2VyZWJyb0NvbnRleHQSDgoGc291cmNlGAEgASgJEgwKBG1vZGUYAiABKAkSGQoRc291cmNlX3J1bnRpbWVfaWQYAyABKAkSGAoQZmluZGluZ19jb250cmFjdBgEIAEoCRIXCg9zb3VyY2VfZXZlbnRfaWQYBSABKAkSEwoLY2xhaW1fY291bnQYBiABKAUSNwoPY2xhaW1fc3VtbWFyaWVzGAcgAygLMh4uYXBlcmlvLnYxLkNlcmVicm9DbGFpbVN1bW1hcnkSNAoNZ3JhcGhfc2lnbmFscxgIIAMoCzIdLmFwZXJpby52MS5DZXJlYnJvR3JhcGhTaWduYWwSLQoIZW50aXRpZXMYCSADKAsyGy5hcGVyaW8udjEuQ2VyZWJyb0VudGl0eVJlZhIwCgtncmFwaF9wYXRocxgKIAMoCzIbLmFwZXJpby52MS5DZXJlYnJvR3JhcGhQYXRoEikKA21jcBgLIAEoCzIcLmFwZXJpby52MS5DZXJlYnJvTUNQQ29udGV4dBIWCg5yZXNwb25zZV9oaW50cxgMIAMoCSJ7ChNDZXJlYnJvQ2xhaW1TdW1tYXJ5EhIKCmNsYWltX3R5cGUYASABKAkSEQoJcHJlZGljYXRlGAIgASgJEhMKC3N1YmplY3RfdXJuGAMgASgJEhIKCm9iamVjdF91cm4YBCABKAkSFAoMc291cmNlX2V2ZW50GAUgASgJInAKEkNlcmVicm9HcmFwaFNpZ25hbBINCgVsYWJlbBgBIAEoCRIRCglwcmVkaWNhdGUYAiABKAkSEgoKY29uZmlkZW5jZRgDIAEoBRISCgplbnRpdHlfdXJuGAQgASgJEhAKCGV2aWRlbmNlGAUgASgJIk4KEENlcmVicm9FbnRpdHlSZWYSCwoDdXJuGAEgASgJEgwKBHR5cGUYAiABKAkSDQoFbGFiZWwYAyABKAkSEAoIcHJvdmlkZXIYBCABKAkiZwoQQ2VyZWJyb0dyYXBoUGF0aBIKCgJpZBgBIAEoCRINCgV0aXRsZRgCIAEoCRIMCgRyaXNrGAMgASgJEioKBW5vZGVzGAQgAygLMhsuYXBlcmlvLnYxLkNlcmVicm9FbnRpdHlSZWYingEKEUNlcmVicm9NQ1BDb250ZXh0Eg4KBnNlcnZlchgBIAEoCRIUCgxyZXNvdXJjZV91cmkYAiABKAkSEQoJbWltZV90eXBlGAMgASgJEg0KBXRvb2xzGAQgAygJEkEKEnJlc291cmNlX3RlbXBsYXRlcxgFIAMoCzIlLmFwZXJpby52MS5DZXJlYnJvTUNQUmVzb3VyY2VUZW1wbGF0ZSJoChpDZXJlYnJvTUNQUmVzb3VyY2VUZW1wbGF0ZRIUCgx1cmlfdGVtcGxhdGUYASABKAkSDAoEbmFtZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgDIAEoCRIRCgltaW1lX3R5cGUYBCABKAkidQoYTGlzdFNhYXNJbmNpZGVudHNSZXF1ZXN0Eg4KBnN0YXR1cxgBIAEoCRIQCghzZXZlcml0eRgCIAEoCRIYChBhc3NpZ25lZV91c2VyX2lkGAMgASgJEg0KBWxpbWl0GAQgASgFEg4KBmN1cnNvchgFIAEoCSKbAQoZTGlzdFNhYXNJbmNpZGVudHNSZXNwb25zZRIlCgRkYXRhGAEgAygLMhcuYXBlcmlvLnYxLlNhYXNJbmNpZGVudBImCglwYWdlX2luZm8YAiABKAsyEy5hcGVyaW8udjEuUGFnZUluZm8SLwoHbWV0cmljcxgDIAEoCzIeLmFwZXJpby52MS5TYWFzSW5jaWRlbnRNZXRyaWNzIiQKFkdldFNhYXNJbmNpZGVudFJlcXVlc3QSCgoCaWQYASABKAkiRgoXR2V0U2Fhc0luY2lkZW50UmVzcG9uc2USKwoEZGF0YRgBIAEoCzIdLmFwZXJpby52MS5TYWFzSW5jaWRlbnREZXRhaWwikAEKGUNyZWF0ZVNhYXNJbmNpZGVudFJlcXVlc3QSDQoFdGl0bGUYASABKAkSDwoHc3VtbWFyeRgCIAEoCRIQCghzZXZlcml0eRgDIAEoCRITCgtmaW5kaW5nX2lkcxgEIAMoCRISCgpvd25lcl90ZWFtGAUgASgJEhgKEGFzc2lnbmVlX3VzZXJfaWQYBiABKAkiSQoaQ3JlYXRlU2Fhc0luY2lkZW50UmVzcG9uc2USKwoEZGF0YRgBIAEoCzIdLmFwZXJpby52MS5TYWFzSW5jaWRlbnREZXRhaWwiSwofVXBkYXRlU2Fhc0luY2lkZW50U3RhdHVzUmVxdWVzdBIKCgJpZBgBIAEoCRIOCgZzdGF0dXMYAiABKAkSDAoEbm90ZRgDIAEoCSJJCiBVcGRhdGVTYWFzSW5jaWRlbnRTdGF0dXNSZXNwb25zZRIlCgRkYXRhGAEgASgLMhcuYXBlcmlvLnYxLlNhYXNJbmNpZGVudCLmAQogUHJvcG9zZVNhYXNSZXNwb25zZUFjdGlvblJlcXVlc3QSEwoLaW5jaWRlbnRfaWQYASABKAkSEgoKZmluZGluZ19pZBgCIAEoCRIOCgZhY3Rpb24YAyABKAkSEAoIcHJvdmlkZXIYBCABKAkSEwoLdGFyZ2V0X3R5cGUYBSABKAkSGQoRdGFyZ2V0X2lkZW50aWZpZXIYBiABKAkSEQoJcmF0aW9uYWxlGAcgASgJEh4KEWFwcHJvdmFsX3JlcXVpcmVkGAggASgISACIAQFCFAoSX2FwcHJvdmFsX3JlcXVpcmVkIlAKIVByb3Bvc2VTYWFzUmVzcG9uc2VBY3Rpb25SZXNwb25zZRIrCgRkYXRhGAEgASgLMh0uYXBlcmlvLnYxLlNhYXNSZXNwb25zZUFjdGlvbiI8CiBBcHByb3ZlU2Fhc1Jlc3BvbnNlQWN0aW9uUmVxdWVzdBIKCgJpZBgBIAEoCRIMCgRub3RlGAIgASgJIlAKIUFwcHJvdmVTYWFzUmVzcG9uc2VBY3Rpb25SZXNwb25zZRIrCgRkYXRhGAEgASgLMh0uYXBlcmlvLnYxLlNhYXNSZXNwb25zZUFjdGlvbiI8CiBFeGVjdXRlU2Fhc1Jlc3BvbnNlQWN0aW9uUmVxdWVzdBIKCgJpZBgBIAEoCRIMCgRub3RlGAIgASgJIlAKIUV4ZWN1dGVTYWFzUmVzcG9uc2VBY3Rpb25SZXNwb25zZRIrCgRkYXRhGAEgASgLMh0uYXBlcmlvLnYxLlNhYXNSZXNwb25zZUFjdGlvbiKYAQoTU2Fhc0luY2lkZW50TWV0cmljcxIMCgRvcGVuGAEgASgFEhUKDWludmVzdGlnYXRpbmcYAiABKAUSEQoJY29udGFpbmVkGAMgASgFEhAKCHJlc29sdmVkGAQgASgFEhUKDWNyaXRpY2FsX29wZW4YBSABKAUSIAoYcmVzcG9uc2VfYWN0aW9uc19wZW5kaW5nGAYgASgFItkDCgxTYWFzSW5jaWRlbnQSCgoCaWQYASABKAkSDQoFdGl0bGUYAiABKAkSDwoHc3VtbWFyeRgDIAEoCRIQCghzZXZlcml0eRgEIAEoCRIOCgZzdGF0dXMYBSABKAkSGAoQY29uZmlkZW5jZV9zY29yZRgGIAEoBRISCgpvd25lcl90ZWFtGAcgASgJEi4KCGFzc2lnbmVlGAggASgLMhwuYXBlcmlvLnYxLlNlY3VyaXR5UHJpbmNpcGFsEhkKEWZpcnN0X2RldGVjdGVkX2F0GAkgASgJEhgKEGxhc3RfYWN0aXZpdHlfYXQYCiABKAkSEgoKc2xhX2R1ZV9hdBgLIAEoCRITCgtyZXNvbHZlZF9hdBgMIAEoCRIcChRjZXJlYnJvX2NvbnRleHRfanNvbhgNIAEoCRISCgpjcmVhdGVkX2F0GA4gASgJEhIKCnVwZGF0ZWRfYXQYDyABKAkSFQoNZmluZGluZ19jb3VudBgQIAEoBRIaChJvcGVuX2ZpbmRpbmdfY291bnQYESABKAUSHQoVcmVzcG9uc2VfYWN0aW9uX2NvdW50GBIgASgFEicKH2NvbXBsZXRlZF9yZXNwb25zZV9hY3Rpb25fY291bnQYEyABKAUi1gEKElNhYXNJbmNpZGVudERldGFpbBIpCghpbmNpZGVudBgBIAEoCzIXLmFwZXJpby52MS5TYWFzSW5jaWRlbnQSJAoIZmluZGluZ3MYAiADKAsyEi5hcGVyaW8udjEuRmluZGluZxI2Cgh0aW1lbGluZRgDIAMoCzIkLmFwZXJpby52MS5TYWFzSW5jaWRlbnRUaW1lbGluZUV2ZW50EjcKEHJlc3BvbnNlX2FjdGlvbnMYBCADKAsyHS5hcGVyaW8udjEuU2Fhc1Jlc3BvbnNlQWN0aW9uIv0BChlTYWFzSW5jaWRlbnRUaW1lbGluZUV2ZW50EgoKAmlkGAEgASgJEhMKC2luY2lkZW50X2lkGAIgASgJEhIKCmZpbmRpbmdfaWQYAyABKAkSGgoScmVzcG9uc2VfYWN0aW9uX2lkGAQgASgJEgwKBGtpbmQYBSABKAkSDQoFdGl0bGUYBiABKAkSEwoLZGVzY3JpcHRpb24YByABKAkSDQoFYWN0b3IYCCABKAkSDgoGc291cmNlGAkgASgJEhUKDWV2aWRlbmNlX2pzb24YCiABKAkSEwoLb2NjdXJyZWRfYXQYCyABKAkSEgoKY3JlYXRlZF9hdBgMIAEoCSLwAwoSU2Fhc1Jlc3BvbnNlQWN0aW9uEgoKAmlkGAEgASgJEhMKC2luY2lkZW50X2lkGAIgASgJEhIKCmZpbmRpbmdfaWQYAyABKAkSDgoGYWN0aW9uGAQgASgJEhAKCHByb3ZpZGVyGAUgASgJEhMKC3RhcmdldF90eXBlGAYgASgJEhkKEXRhcmdldF9pZGVudGlmaWVyGAcgASgJEg4KBnN0YXR1cxgIIAEoCRIZChFhcHByb3ZhbF9yZXF1aXJlZBgJIAEoCBIRCglyYXRpb25hbGUYCiABKAkSMQoLYXBwcm92ZWRfYnkYCyABKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlQcmluY2lwYWwSEwoLYXBwcm92ZWRfYXQYDCABKAkSEwoLZXhlY3V0ZWRfYXQYDSABKAkSFQoNZXJyb3JfbWVzc2FnZRgOIAEoCRITCgtyZXN1bHRfanNvbhgPIAEoCRISCgpjcmVhdGVkX2F0GBAgASgJEhIKCnVwZGF0ZWRfYXQYESABKAkSMQoLcHJvcG9zZWRfYnkYEiABKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlQcmluY2lwYWwSMQoLZXhlY3V0ZWRfYnkYEyABKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlQcmluY2lwYWwiLgoIUGFnZUluZm8SDQoFdG90YWwYASABKAUSEwoLbmV4dF9jdXJzb3IYAiABKAkiHQobTGlzdENvbm5lY3RvckNhdGFsb2dSZXF1ZXN0IkwKHExpc3RDb25uZWN0b3JDYXRhbG9nUmVzcG9uc2USLAoEZGF0YRgBIAMoCzIeLmFwZXJpby52MS5Db25uZWN0b3JEZWZpbml0aW9uIuQCChNDb25uZWN0b3JEZWZpbml0aW9uEhAKCHByb3ZpZGVyGAEgASgJEgwKBG5hbWUYAiABKAkSEAoIY2F0ZWdvcnkYAyABKAkSFAoMYXZhaWxhYmlsaXR5GAQgASgJEhYKDnJlYWRpbmVzc19ub3RlGAUgASgJEhMKC2Rlc2NyaXB0aW9uGAYgASgJEhMKC3JlYWRfc2NvcGVzGAcgAygJEhoKEnJlbWVkaWF0aW9uX3Njb3BlcxgIIAMoCRI5ChNyZW1lZGlhdGlvbl9hY3Rpb25zGAkgAygLMhwuYXBlcmlvLnYxLlJlbWVkaWF0aW9uQWN0aW9uEi8KDmZpbmRpbmdfY2hlY2tzGAogAygLMhcuYXBlcmlvLnYxLkZpbmRpbmdDaGVjaxIQCghkb2NzX3VybBgLIAEoCRIpCgZmaWVsZHMYDCADKAsyGS5hcGVyaW8udjEuQ29ubmVjdG9yRmllbGQigQEKDkNvbm5lY3RvckZpZWxkEgsKA2tleRgBIAEoCRINCgVsYWJlbBgCIAEoCRITCgtwbGFjZWhvbGRlchgDIAEoCRIOCgZoZWxwZXIYBCABKAkSDAoEdHlwZRgFIAEoCRIQCghyZXF1aXJlZBgGIAEoCBIOCgZzZWNyZXQYByABKAgiWwoRUmVtZWRpYXRpb25BY3Rpb24SCwoDa2V5GAEgASgJEg0KBWxhYmVsGAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJEhUKDXNldmVyaXR5X2hpbnQYBCABKAkibwoMRmluZGluZ0NoZWNrEgsKA2tleRgBIAEoCRINCgV0aXRsZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgDIAEoCRIVCg1zZXZlcml0eV9oaW50GAQgASgJEhcKD2RlZmF1bHRfZW5hYmxlZBgFIAEoCCIZChdMaXN0SW50ZWdyYXRpb25zUmVxdWVzdCJKChhMaXN0SW50ZWdyYXRpb25zUmVzcG9uc2USLgoEZGF0YRgBIAMoCzIgLmFwZXJpby52MS5JbnRlZ3JhdGlvbkNvbm5lY3Rpb24iqAIKFUludGVncmF0aW9uQ29ubmVjdGlvbhIKCgJpZBgBIAEoCRIQCghwcm92aWRlchgCIAEoCRIUCgxkaXNwbGF5X25hbWUYAyABKAkSGwoTZXh0ZXJuYWxfYWNjb3VudF9pZBgEIAEoCRIOCgZzdGF0dXMYBSABKAkSDAoEbW9kZRgGIAEoCRIOCgZzY29wZXMYByADKAkSFwoPZGlzYWJsZWRfY2hlY2tzGAggAygJEiMKG2dvb2dsZV9tYWlsYm94X3NjYW5fZW5hYmxlZBgJIAEoCBIoCiBnb29nbGVfbWFpbGJveF9zY2FuX2NsaWVudF9lbWFpbBgKIAEoCRIUCgxsYXN0X3N5bmNfYXQYCyABKAkSEgoKY3JlYXRlZF9hdBgMIAEoCSKlAQoYQ3JlYXRlSW50ZWdyYXRpb25SZXF1ZXN0EhAKCHByb3ZpZGVyGAEgASgJEhQKDGRpc3BsYXlfbmFtZRgCIAEoCRIbChNleHRlcm5hbF9hY2NvdW50X2lkGAMgASgJEgwKBG1vZGUYBCABKAkSNgoLY3JlZGVudGlhbHMYBSABKAsyIS5hcGVyaW8udjEuSW50ZWdyYXRpb25DcmVkZW50aWFscyJdChZJbnRlZ3JhdGlvbkNyZWRlbnRpYWxzEhQKDGFjY2Vzc190b2tlbhgBIAEoCRIVCg1yZWZyZXNoX3Rva2VuGAIgASgJEhYKDndlYmhvb2tfc2VjcmV0GAMgASgJIksKGUNyZWF0ZUludGVncmF0aW9uUmVzcG9uc2USLgoEZGF0YRgBIAEoCzIgLmFwZXJpby52MS5JbnRlZ3JhdGlvbkNvbm5lY3Rpb24iJgoYRGVsZXRlSW50ZWdyYXRpb25SZXF1ZXN0EgoKAmlkGAEgASgJIkIKGURlbGV0ZUludGVncmF0aW9uUmVzcG9uc2USJQoEZGF0YRgBIAEoCzIXLmFwZXJpby52MS5EZWxldGVSZXN1bHQiGgoMRGVsZXRlUmVzdWx0EgoKAm9rGAEgASgIIjUKG0dldEludGVncmF0aW9uQ2hlY2tzUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCSJOChxHZXRJbnRlZ3JhdGlvbkNoZWNrc1Jlc3BvbnNlEi4KBGRhdGEYASABKAsyIC5hcGVyaW8udjEuSW50ZWdyYXRpb25DaGVja1N0YXRlIoUBCh5VcGRhdGVJbnRlZ3JhdGlvbkNoZWNrc1JlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkSFwoPZGlzYWJsZWRfY2hlY2tzGAIgAygJEhYKDmRpc2FibGVfcmVhc29uGAMgASgJEhoKEmRpc2FibGVfZXhwaXJlc19hdBgEIAEoCSJRCh9VcGRhdGVJbnRlZ3JhdGlvbkNoZWNrc1Jlc3BvbnNlEi4KBGRhdGEYASABKAsyIC5hcGVyaW8udjEuSW50ZWdyYXRpb25DaGVja1N0YXRlIncKFUludGVncmF0aW9uQ2hlY2tTdGF0ZRIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCRIXCg9kaXNhYmxlZF9jaGVja3MYAiADKAkSLQoGY2hlY2tzGAMgAygLMh0uYXBlcmlvLnYxLkZpbmRpbmdDaGVja1N0YXR1cyKGAQoSRmluZGluZ0NoZWNrU3RhdHVzEgsKA2tleRgBIAEoCRINCgV0aXRsZRgCIAEoCRITCgtkZXNjcmlwdGlvbhgDIAEoCRIVCg1zZXZlcml0eV9oaW50GAQgASgJEhcKD2RlZmF1bHRfZW5hYmxlZBgFIAEoCBIPCgdlbmFibGVkGAYgASgIIjsKIUdldEdvb2dsZU1haWxib3hTY2FuQ29uZmlnUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCSJWCiJHZXRHb29nbGVNYWlsYm94U2NhbkNvbmZpZ1Jlc3BvbnNlEjAKBGRhdGEYASABKAsyIi5hcGVyaW8udjEuR29vZ2xlTWFpbGJveFNjYW5Db25maWciigEKJFVwZGF0ZUdvb2dsZU1haWxib3hTY2FuQ29uZmlnUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCRIPCgdlbmFibGVkGAIgASgIEiQKHHNlcnZpY2VfYWNjb3VudF9jbGllbnRfZW1haWwYAyABKAkSEwoLcHJpdmF0ZV9rZXkYBCABKAkiWQolVXBkYXRlR29vZ2xlTWFpbGJveFNjYW5Db25maWdSZXNwb25zZRIwCgRkYXRhGAEgASgLMiIuYXBlcmlvLnYxLkdvb2dsZU1haWxib3hTY2FuQ29uZmlnIlAKF0dvb2dsZU1haWxib3hTY2FuQ29uZmlnEg8KB2VuYWJsZWQYASABKAgSJAocc2VydmljZV9hY2NvdW50X2NsaWVudF9lbWFpbBgCIAEoCSJBCidHZXRHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZ1JlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkiYgooR2V0R29vZ2xlV29ya3NwYWNlQmlnUXVlcnlDb25maWdSZXNwb25zZRI2CgRkYXRhGAEgASgLMiguYXBlcmlvLnYxLkdvb2dsZVdvcmtzcGFjZUJpZ1F1ZXJ5Q29uZmlnIv8BCipVcGRhdGVHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZ1JlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkSDwoHZW5hYmxlZBgCIAEoCBISCgpwcm9qZWN0X2lkGAMgASgJEhYKDnJhd19kYXRhc2V0X2lkGAQgASgJEhIKCmRhdGFzZXRfaWQYBSABKAkSEAoIbG9jYXRpb24YBiABKAkSHQoVc2VydmljZV9hY2NvdW50X2VtYWlsGAcgASgJEiIKGndvcmtsb2FkX2lkZW50aXR5X3Byb3ZpZGVyGAggASgJEhMKC2FjY2Vzc19tb2RlGAkgASgJImUKK1VwZGF0ZUdvb2dsZVdvcmtzcGFjZUJpZ1F1ZXJ5Q29uZmlnUmVzcG9uc2USNgoEZGF0YRgBIAEoCzIoLmFwZXJpby52MS5Hb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZyLuAQodR29vZ2xlV29ya3NwYWNlQmlnUXVlcnlDb25maWcSDwoHZW5hYmxlZBgBIAEoCBISCgpwcm9qZWN0X2lkGAIgASgJEhYKDnJhd19kYXRhc2V0X2lkGAMgASgJEhIKCmRhdGFzZXRfaWQYBCABKAkSEAoIbG9jYXRpb24YBSABKAkSHQoVc2VydmljZV9hY2NvdW50X2VtYWlsGAYgASgJEiIKGndvcmtsb2FkX2lkZW50aXR5X3Byb3ZpZGVyGAcgASgJEhMKC2FjY2Vzc19tb2RlGAggASgJEhIKCnVwZGF0ZWRfYXQYCSABKAkiRgosVmFsaWRhdGVHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZ1JlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkiawotVmFsaWRhdGVHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZ1Jlc3BvbnNlEjoKBGRhdGEYASABKAsyLC5hcGVyaW8udjEuR29vZ2xlV29ya3NwYWNlQmlnUXVlcnlWYWxpZGF0aW9uIvoBCiFHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeVZhbGlkYXRpb24SFgoOaW50ZWdyYXRpb25faWQYASABKAkSCgoCb2sYAiABKAgSDwoHbWVzc2FnZRgDIAEoCRISCgpwcm9qZWN0X2lkGAQgASgJEhIKCmRhdGFzZXRfaWQYBSABKAkSFgoOYWN0aXZpdHlfdGFibGUYBiABKAkSEwoLdGFibGVfZm91bmQYByABKAgSEwoLc2FtcGxlX3Jvd3MYCCABKAUSFwoPZXN0aW1hdGVkX2J5dGVzGAkgASgDEh0KFXJ1bnRpbWVfdG9rZW5fcHJlc2VudBgKIAEoCCIwCiBTdGFydEdvb2dsZVdvcmtzcGFjZU9BdXRoUmVxdWVzdBIMCgRtb2RlGAEgASgJIkgKIVN0YXJ0R29vZ2xlV29ya3NwYWNlT0F1dGhSZXNwb25zZRIjCgRkYXRhGAEgASgLMhUuYXBlcmlvLnYxLk9BdXRoU3RhcnQiqQEKFkludGVncmF0aW9uT0F1dGhDbGllbnQSEAoIcHJvdmlkZXIYASABKAkSEQoJY2xpZW50X2lkGAIgASgJEhQKDHJlZGlyZWN0X3VyaRgDIAEoCRISCgpjb25maWd1cmVkGAQgASgIEhwKFGRlZmF1bHRfcmVkaXJlY3RfdXJpGAUgASgJEhIKCnVwZGF0ZWRfYXQYBiABKAkSDgoGc291cmNlGAcgASgJIjQKIEdldEludGVncmF0aW9uT0F1dGhDbGllbnRSZXF1ZXN0EhAKCHByb3ZpZGVyGAEgASgJIlQKIUdldEludGVncmF0aW9uT0F1dGhDbGllbnRSZXNwb25zZRIvCgRkYXRhGAEgASgLMiEuYXBlcmlvLnYxLkludGVncmF0aW9uT0F1dGhDbGllbnQidAogU2V0SW50ZWdyYXRpb25PQXV0aENsaWVudFJlcXVlc3QSEAoIcHJvdmlkZXIYASABKAkSEQoJY2xpZW50X2lkGAIgASgJEhUKDWNsaWVudF9zZWNyZXQYAyABKAkSFAoMcmVkaXJlY3RfdXJpGAQgASgJIlQKIVNldEludGVncmF0aW9uT0F1dGhDbGllbnRSZXNwb25zZRIvCgRkYXRhGAEgASgLMiEuYXBlcmlvLnYxLkludGVncmF0aW9uT0F1dGhDbGllbnQiNgoiQ2xlYXJJbnRlZ3JhdGlvbk9BdXRoQ2xpZW50UmVxdWVzdBIQCghwcm92aWRlchgBIAEoCSJWCiNDbGVhckludGVncmF0aW9uT0F1dGhDbGllbnRSZXNwb25zZRIvCgRkYXRhGAEgASgLMiEuYXBlcmlvLnYxLkludGVncmF0aW9uT0F1dGhDbGllbnQiGQoKT0F1dGhTdGFydBILCgN1cmwYASABKAkiNQobRm9yY2VTeW5jSW50ZWdyYXRpb25SZXF1ZXN0EhYKDmludGVncmF0aW9uX2lkGAEgASgJInQKHEZvcmNlU3luY0ludGVncmF0aW9uUmVzcG9uc2USLgoEZGF0YRgBIAEoCzIgLmFwZXJpby52MS5JbnRlZ3JhdGlvbkNvbm5lY3Rpb24SJAoEc3luYxgCIAEoCzIWLmFwZXJpby52MS5TeW5jU3VtbWFyeSJmCgtTeW5jU3VtbWFyeRIUCgxzYW1wbGVfY291bnQYASABKAUSFwoPZXZlbnRzX2luZ2VzdGVkGAIgASgFEhcKD2ZpbmRpbmdzX29wZW5lZBgDIAEoBRIPCgdzb3VyY2VzGAQgAygJIjkKH0dldEludGVncmF0aW9uU3luY1N0YXR1c1JlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkiUgogR2V0SW50ZWdyYXRpb25TeW5jU3RhdHVzUmVzcG9uc2USLgoEZGF0YRgBIAEoCzIgLmFwZXJpby52MS5JbnRlZ3JhdGlvblN5bmNTdGF0dXMiYwofUnVuSW50ZWdyYXRpb25Tb3VyY2VTeW5jUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCRITCgtzb3VyY2Vfa2luZBgCIAEoCRITCgtzdHJlYW1fbmFtZRgDIAEoCSJYCiBSdW5JbnRlZ3JhdGlvblNvdXJjZVN5bmNSZXNwb25zZRI0CgRkYXRhGAEgASgLMiYuYXBlcmlvLnYxLkludGVncmF0aW9uU291cmNlU3luY0FjdGlvbiJ3CiBCYWNrZmlsbEludGVncmF0aW9uU291cmNlUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCRITCgtzb3VyY2Vfa2luZBgCIAEoCRITCgtzdHJlYW1fbmFtZRgDIAEoCRIRCglmcm9tX3RpbWUYBCABKAkiWQohQmFja2ZpbGxJbnRlZ3JhdGlvblNvdXJjZVJlc3BvbnNlEjQKBGRhdGEYASABKAsyJi5hcGVyaW8udjEuSW50ZWdyYXRpb25Tb3VyY2VTeW5jQWN0aW9uIo8BChVJbnRlZ3JhdGlvblN5bmNTdGF0dXMSFgoOaW50ZWdyYXRpb25faWQYASABKAkSEAoIcHJvdmlkZXIYAiABKAkSFAoMZ2VuZXJhdGVkX2F0GAMgASgJEjYKB3NvdXJjZXMYBCADKAsyJS5hcGVyaW8udjEuSW50ZWdyYXRpb25Tb3VyY2VTeW5jU3RhdGUiywMKGkludGVncmF0aW9uU291cmNlU3luY1N0YXRlEhMKC3NvdXJjZV9raW5kGAEgASgJEhMKC3N0cmVhbV9uYW1lGAIgASgJEhQKDGRpc3BsYXlfbmFtZRgDIAEoCRIOCgZzdGF0dXMYBCABKAkSEwoLY3Vyc29yX3RpbWUYBSABKAkSFwoPbGFzdF9hdHRlbXB0X2F0GAYgASgJEhcKD2xhc3Rfc3VjY2Vzc19hdBgHIAEoCRISCgpsYXN0X2Vycm9yGAggASgJEhMKC2xhZ19zZWNvbmRzGAkgASgDEhEKCXJvd3Nfc2VlbhgKIAEoAxIVCg1yb3dzX2VucXVldWVkGAsgASgDEhQKDHF1ZXVlX3F1ZXVlZBgMIAEoAxIVCg1xdWV1ZV9ydW5uaW5nGA0gASgDEhQKDHF1ZXVlX2ZhaWxlZBgOIAEoAxIZChFxdWV1ZV9kZWFkX2xldHRlchgPIAEoAxIXCg9xdWV1ZV9zdWNjZWVkZWQYECABKAMSGgoSc3luY19ub3dfc3VwcG9ydGVkGBEgASgIEhoKEmJhY2tmaWxsX3N1cHBvcnRlZBgSIAEoCBIUCgxxdWV1ZV9zb3VyY2UYEyABKAkilgEKG0ludGVncmF0aW9uU291cmNlU3luY0FjdGlvbhIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCRITCgtzb3VyY2Vfa2luZBgCIAEoCRITCgtzdHJlYW1fbmFtZRgDIAEoCRIOCgZxdWV1ZWQYBCABKAgSDwoHbWVzc2FnZRgFIAEoCRIUCgxyZXF1ZXN0ZWRfYXQYBiABKAkiGAoWTGlzdFNpZW1DYXRhbG9nUmVxdWVzdCJNChdMaXN0U2llbUNhdGFsb2dSZXNwb25zZRIyCgRkYXRhGAEgAygLMiQuYXBlcmlvLnYxLlNpZW1EZXN0aW5hdGlvbkRlZmluaXRpb24ivwEKGVNpZW1EZXN0aW5hdGlvbkRlZmluaXRpb24SDAoEa2luZBgBIAEoCRIMCgRuYW1lGAIgASgJEg4KBnZlbmRvchgDIAEoCRITCgtkZXNjcmlwdGlvbhgEIAEoCRIQCghjYXRlZ29yeRgFIAEoCRIQCghkb2NzX3VybBgGIAEoCRIXCg9kZWZhdWx0X3N0cmVhbXMYByADKAkSJAoGZmllbGRzGAggAygLMhQuYXBlcmlvLnYxLlNpZW1GaWVsZCJ8CglTaWVtRmllbGQSCwoDa2V5GAEgASgJEg0KBWxhYmVsGAIgASgJEhMKC3BsYWNlaG9sZGVyGAMgASgJEg4KBmhlbHBlchgEIAEoCRIMCgR0eXBlGAUgASgJEhAKCHJlcXVpcmVkGAYgASgIEg4KBnNlY3JldBgHIAEoCCIdChtMaXN0U2llbURlc3RpbmF0aW9uc1JlcXVlc3QiSAocTGlzdFNpZW1EZXN0aW5hdGlvbnNSZXNwb25zZRIoCgRkYXRhGAEgAygLMhouYXBlcmlvLnYxLlNpZW1EZXN0aW5hdGlvbiKEAgoPU2llbURlc3RpbmF0aW9uEgoKAmlkGAEgASgJEgwKBGtpbmQYAiABKAkSDAoEbmFtZRgDIAEoCRIUCgxlbmRwb2ludF91cmwYBCABKAkSEQoJZmlsZV9wYXRoGAUgASgJEg0KBWluZGV4GAYgASgJEg8KB3N0cmVhbXMYByADKAkSDgoGc3RhdHVzGAggASgJEhgKEGxhc3RfZGVsaXZlcnlfYXQYCSABKAkSEgoKbGFzdF9lcnJvchgKIAEoCRIVCg1kZWxpdmVyaWVzX29rGAsgASgFEhcKD2RlbGl2ZXJpZXNfZmFpbBgMIAEoBRISCgpjcmVhdGVkX2F0GA0gASgJIpIBChxDcmVhdGVTaWVtRGVzdGluYXRpb25SZXF1ZXN0EgwKBGtpbmQYASABKAkSDAoEbmFtZRgCIAEoCRIUCgxlbmRwb2ludF91cmwYAyABKAkSEQoJZmlsZV9wYXRoGAQgASgJEg0KBWluZGV4GAUgASgJEg0KBXRva2VuGAYgASgJEg8KB3N0cmVhbXMYByADKAkiSQodQ3JlYXRlU2llbURlc3RpbmF0aW9uUmVzcG9uc2USKAoEZGF0YRgBIAEoCzIaLmFwZXJpby52MS5TaWVtRGVzdGluYXRpb24iKgocRGVsZXRlU2llbURlc3RpbmF0aW9uUmVxdWVzdBIKCgJpZBgBIAEoCSJGCh1EZWxldGVTaWVtRGVzdGluYXRpb25SZXNwb25zZRIlCgRkYXRhGAEgASgLMhcuYXBlcmlvLnYxLkRlbGV0ZVJlc3VsdCIoChpUZXN0U2llbURlc3RpbmF0aW9uUmVxdWVzdBIKCgJpZBgBIAEoCSJGChtUZXN0U2llbURlc3RpbmF0aW9uUmVzcG9uc2USJwoEZGF0YRgBIAEoCzIZLmFwZXJpby52MS5TaWVtVGVzdFJlc3VsdCJFCg5TaWVtVGVzdFJlc3VsdBIWCg5kZXN0aW5hdGlvbl9pZBgBIAEoCRIKCgJvaxgCIAEoCBIPCgdtZXNzYWdlGAMgASgJIh4KHExpc3RTaGFkb3dJdE9hdXRoQXBwc1JlcXVlc3QiSgodTGlzdFNoYWRvd0l0T2F1dGhBcHBzUmVzcG9uc2USKQoEZGF0YRgBIAMoCzIbLmFwZXJpby52MS5TaGFkb3dJdE9hdXRoQXBwIrACChBTaGFkb3dJdE9hdXRoQXBwEgoKAmlkGAEgASgJEhAKCHByb3ZpZGVyGAIgASgJEgwKBG5hbWUYAyABKAkSDwoHc3VtbWFyeRgEIAEoCRITCgtleHRlcm5hbF9pZBgFIAEoCRIOCgZsYWJlbHMYBiADKAkSEwoLY3JpdGljYWxpdHkYByABKAkSHwoXY29udGFpbnNfc2Vuc2l0aXZlX2RhdGEYCCABKAgSEgoKcmlza19zY29yZRgJIAEoBRIYChBsYXN0X29ic2VydmVkX2F0GAogASgJEhIKCnVzZXJfY291bnQYCyABKAUSDgoGc2NvcGVzGAwgAygJEjIKC2ludGVncmF0aW9uGA0gASgLMh0uYXBlcmlvLnYxLkZpbmRpbmdJbnRlZ3JhdGlvbiI1CiFMaXN0U2hhZG93SXRPYXV0aEFwcEdyYW50c1JlcXVlc3QSEAoIYXNzZXRfaWQYASABKAkiVQoiTGlzdFNoYWRvd0l0T2F1dGhBcHBHcmFudHNSZXNwb25zZRIvCgRkYXRhGAEgASgLMiEuYXBlcmlvLnYxLlNoYWRvd0l0T2F1dGhBcHBEZXRhaWwidwoWU2hhZG93SXRPYXV0aEFwcERldGFpbBIrCgNhcHAYASABKAsyHi5hcGVyaW8udjEuU2hhZG93SXRPYXV0aEFwcFJlZhIwCgZncmFudHMYAiADKAsyIC5hcGVyaW8udjEuU2hhZG93SXRPYXV0aEFwcEdyYW50IlYKE1NoYWRvd0l0T2F1dGhBcHBSZWYSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRITCgtleHRlcm5hbF9pZBgDIAEoCRIQCghwcm92aWRlchgEIAEoCSK9AQoVU2hhZG93SXRPYXV0aEFwcEdyYW50EgoKAmlkGAEgASgJEhIKCnVzZXJfZW1haWwYAiABKAkSGAoQdXNlcl9leHRlcm5hbF9pZBgDIAEoCRIZChF1c2VyX2Rpc3BsYXlfbmFtZRgEIAEoCRIOCgZzY29wZXMYBSADKAkSEQoJYW5vbnltb3VzGAYgASgIEhIKCm5hdGl2ZV9hcHAYByABKAgSGAoQbGFzdF9vYnNlcnZlZF9hdBgIIAEoCSIaChhHZXRUZW5hbnRTZXR0aW5nc1JlcXVlc3QiRAoZR2V0VGVuYW50U2V0dGluZ3NSZXNwb25zZRInCgRkYXRhGAEgASgLMhkuYXBlcmlvLnYxLlRlbmFudFNldHRpbmdzItMDChtVcGRhdGVUZW5hbnRTZXR0aW5nc1JlcXVlc3QSEQoEbmFtZRgBIAEoCUgAiAEBEh8KEm5vdGlmaWNhdGlvbl9lbWFpbBgCIAEoCUgBiAEBEiAKE2RhdGFfcmV0ZW50aW9uX2RheXMYAyABKAVIAogBARIkChdjcml0aWNhbF9yaXNrX3RocmVzaG9sZBgEIAEoBUgDiAEBEh4KEWRlZmF1bHRfc2xhX2hvdXJzGAUgASgFSASIAQESJgoZYXV0b19yZXNvbHZlX2xvd19zZXZlcml0eRgGIAEoCEgFiAEBEh0KEGVuZm9yY2Vfc3NvX29ubHkYByABKAhIBogBARIeChF3ZWJob29rX2FsZXJ0X3VybBgIIAEoCUgHiAEBQgcKBV9uYW1lQhUKE19ub3RpZmljYXRpb25fZW1haWxCFgoUX2RhdGFfcmV0ZW50aW9uX2RheXNCGgoYX2NyaXRpY2FsX3Jpc2tfdGhyZXNob2xkQhQKEl9kZWZhdWx0X3NsYV9ob3Vyc0IcChpfYXV0b19yZXNvbHZlX2xvd19zZXZlcml0eUITChFfZW5mb3JjZV9zc29fb25seUIUChJfd2ViaG9va19hbGVydF91cmwiRwocVXBkYXRlVGVuYW50U2V0dGluZ3NSZXNwb25zZRInCgRkYXRhGAEgASgLMhkuYXBlcmlvLnYxLlRlbmFudFNldHRpbmdzIq0CCg5UZW5hbnRTZXR0aW5ncxIKCgJpZBgBIAEoCRIMCgRuYW1lGAIgASgJEgwKBHNsdWcYAyABKAkSGgoSbm90aWZpY2F0aW9uX2VtYWlsGAQgASgJEhsKE2RhdGFfcmV0ZW50aW9uX2RheXMYBSABKAUSHwoXY3JpdGljYWxfcmlza190aHJlc2hvbGQYBiABKAUSGQoRZGVmYXVsdF9zbGFfaG91cnMYByABKAUSIQoZYXV0b19yZXNvbHZlX2xvd19zZXZlcml0eRgIIAEoCBIYChBlbmZvcmNlX3Nzb19vbmx5GAkgASgIEhkKEXdlYmhvb2tfYWxlcnRfdXJsGAogASgJEhIKCmNyZWF0ZWRfYXQYCyABKAkSEgoKdXBkYXRlZF9hdBgMIAEoCSIaChhMaXN0VGVuYW50TWVtYmVyc1JlcXVlc3QiQgoZTGlzdFRlbmFudE1lbWJlcnNSZXNwb25zZRIlCgRkYXRhGAEgAygLMhcuYXBlcmlvLnYxLlRlbmFudE1lbWJlciJTChlDcmVhdGVUZW5hbnRNZW1iZXJSZXF1ZXN0Eg0KBWVtYWlsGAEgASgJEhQKDGRpc3BsYXlfbmFtZRgCIAEoCRIRCglyb2xlX25hbWUYAyABKAkidAoaQ3JlYXRlVGVuYW50TWVtYmVyUmVzcG9uc2USJQoEZGF0YRgBIAEoCzIXLmFwZXJpby52MS5UZW5hbnRNZW1iZXISLwoKaW52aXRhdGlvbhgCIAEoCzIbLmFwZXJpby52MS5JbnZpdGF0aW9uUmVzdWx0IioKHENyZWF0ZU1lbWJlclJlc2V0TGlua1JlcXVlc3QSCgoCaWQYASABKAkicgodQ3JlYXRlTWVtYmVyUmVzZXRMaW5rUmVzcG9uc2USJQoEZGF0YRgBIAEoCzIXLmFwZXJpby52MS5UZW5hbnRNZW1iZXISKgoFcmVzZXQYAiABKAsyGy5hcGVyaW8udjEuSW52aXRhdGlvblJlc3VsdCI4ChdVcGRhdGVNZW1iZXJSb2xlUmVxdWVzdBIKCgJpZBgBIAEoCRIRCglyb2xlX25hbWUYAiABKAkiQQoYVXBkYXRlTWVtYmVyUm9sZVJlc3BvbnNlEiUKBGRhdGEYASABKAsyFy5hcGVyaW8udjEuVGVuYW50TWVtYmVyIu8BCgxUZW5hbnRNZW1iZXISCgoCaWQYASABKAkSDQoFZW1haWwYAiABKAkSFAoMZGlzcGxheV9uYW1lGAMgASgJEhEKCWlzX2FjdGl2ZRgEIAEoCBITCgttZmFfZW5hYmxlZBgFIAEoCBIVCg1sYXN0X2xvZ2luX2F0GAYgASgJEhYKDmlzX2JyZWFrX2dsYXNzGAcgASgIEgwKBHJvbGUYCCABKAkSEgoKYXV0aF9zdGF0ZRgJIAEoCRIhChlwZW5kaW5nX2FjdGlvbl9leHBpcmVzX2F0GAogASgJEhIKCmNyZWF0ZWRfYXQYCyABKAkiRQoQSW52aXRhdGlvblJlc3VsdBIQCghkZWxpdmVyeRgBIAEoCRILCgN1cmwYAiABKAkSEgoKZXhwaXJlc19hdBgDIAEoCSIWChRMaXN0QXVkaXRMb2dzUmVxdWVzdCI/ChVMaXN0QXVkaXRMb2dzUmVzcG9uc2USJgoEZGF0YRgBIAMoCzIYLmFwZXJpby52MS5BdWRpdExvZ0VudHJ5Io0BCg1BdWRpdExvZ0VudHJ5EgoKAmlkGAEgASgJEg4KBmFjdGlvbhgCIAEoCRITCgt0YXJnZXRfdHlwZRgDIAEoCRIRCgl0YXJnZXRfaWQYBCABKAkSDQoFYWN0b3IYBSABKAkSEgoKY3JlYXRlZF9hdBgGIAEoCRIVCg1tZXRhZGF0YV9qc29uGAcgASgJIhwKGkdldFNlY3VyaXR5T3ZlcnZpZXdSZXF1ZXN0IkgKG0dldFNlY3VyaXR5T3ZlcnZpZXdSZXNwb25zZRIpCgRkYXRhGAEgASgLMhsuYXBlcmlvLnYxLlNlY3VyaXR5T3ZlcnZpZXciiQQKEFNlY3VyaXR5T3ZlcnZpZXcSMwoHc3VtbWFyeRgBIAEoCzIiLmFwZXJpby52MS5TZWN1cml0eU92ZXJ2aWV3U3VtbWFyeRIvCgppZGVudGl0aWVzGAIgAygLMhsuYXBlcmlvLnYxLlNlY3VyaXR5SWRlbnRpdHkSJwoFZ3JhcGgYAyABKAsyGC5hcGVyaW8udjEuU2VjdXJpdHlHcmFwaBIsCgpvYXV0aF9hcHBzGAQgAygLMhguYXBlcmlvLnYxLlNlY3VyaXR5QXNzZXQSLQoLZGF0YV9hc3NldHMYBSADKAsyGC5hcGVyaW8udjEuU2VjdXJpdHlBc3NldBIrCgxhdHRhY2tfcGF0aHMYBiADKAsyFS5hcGVyaW8udjEuQXR0YWNrUGF0aBIwCg5vd25lcnNoaXBfZ2FwcxgHIAMoCzIYLmFwZXJpby52MS5TZWN1cml0eUFzc2V0EiwKCmV4Y2VwdGlvbnMYCCADKAsyGC5hcGVyaW8udjEuUmlza0V4Y2VwdGlvbhJAChdkb21haW5fd2lkZV9kZWxlZ2F0aW9ucxgJIAMoCzIfLmFwZXJpby52MS5Eb21haW5XaWRlRGVsZWdhdGlvbhI6Cg9jZXJlYnJvX2NvbnRleHQYCiABKAsyIS5hcGVyaW8udjEuU2VjdXJpdHlDZXJlYnJvQ29udGV4dCLoAQoXU2VjdXJpdHlPdmVydmlld1N1bW1hcnkSHQoVcHJpdmlsZWdlZF9pZGVudGl0aWVzGAEgASgFEiQKHGFkbWluX2lkZW50aXRpZXNfd2l0aG91dF9tZmEYAiABKAUSGAoQcmlza3lfb2F1dGhfYXBwcxgDIAEoBRIbChNleHBvc2VkX2RhdGFfYXNzZXRzGAQgASgFEhYKDnVub3duZWRfYXNzZXRzGAUgASgFEhkKEWFjdGl2ZV9leGNlcHRpb25zGAYgASgFEh4KFnRvcF9ibGFzdF9yYWRpdXNfc2NvcmUYByABKAUilwIKFlNlY3VyaXR5Q2VyZWJyb0NvbnRleHQSDgoGc291cmNlGAEgASgJEgwKBG1vZGUYAiABKAkSGQoRc291cmNlX3J1bnRpbWVfaWQYAyABKAkSGAoQZmluZGluZ19jb250cmFjdBgEIAEoCRITCgtjbGFpbV9jb3VudBgFIAEoBRIaChJncmFwaF9zaWduYWxfY291bnQYBiABKAUSFAoMZW50aXR5X2NvdW50GAcgASgFEhgKEGdyYXBoX3BhdGhfY291bnQYCCABKAUSMQoDbWNwGAkgASgLMiQuYXBlcmlvLnYxLlNlY3VyaXR5Q2VyZWJyb01DUENvbnRleHQSFgoOcmVzcG9uc2VfaGludHMYCiADKAkipQEKGVNlY3VyaXR5Q2VyZWJyb01DUENvbnRleHQSDgoGc2VydmVyGAEgASgJEhQKDHJlc291cmNlX3VyaRgCIAEoCRIQCghyZXNvdXJjZRgDIAEoCRINCgV0b29scxgEIAMoCRJBChJyZXNvdXJjZV90ZW1wbGF0ZXMYBSADKAsyJS5hcGVyaW8udjEuQ2VyZWJyb01DUFJlc291cmNlVGVtcGxhdGUi/gIKEFNlY3VyaXR5SWRlbnRpdHkSCgoCaWQYASABKAkSEQoJZW50aXR5X2lkGAIgASgJEgwKBGtpbmQYAyABKAkSDAoEbmFtZRgEIAEoCRINCgVlbWFpbBgFIAEoCRIQCghwcm92aWRlchgGIAEoCRIyCgtpbnRlZ3JhdGlvbhgHIAEoCzIdLmFwZXJpby52MS5GaW5kaW5nSW50ZWdyYXRpb24SDAoEcm9sZRgIIAEoCRISCgpwcml2aWxlZ2VkGAkgASgIEhMKC21mYV9lbmFibGVkGAogASgIEg4KBnN0YXR1cxgLIAEoCRITCgtpc19leHRlcm5hbBgMIAEoCBIYChBsYXN0X29ic2VydmVkX2F0GA0gASgJEhoKEmxpbmtlZF9hc3NldF9jb3VudBgOIAEoBRISCgpyaXNrX3Njb3JlGA8gASgFEh4KEW1mYV9lbmFibGVkX3N0YXRlGBAgASgISACIAQFCFAoSX21mYV9lbmFibGVkX3N0YXRlImkKDVNlY3VyaXR5R3JhcGgSKwoFbm9kZXMYASADKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlHcmFwaE5vZGUSKwoFZWRnZXMYAiADKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlHcmFwaEVkZ2UikQEKEVNlY3VyaXR5R3JhcGhOb2RlEgoKAmlkGAEgASgJEg0KBWxhYmVsGAIgASgJEgwKBGtpbmQYAyABKAkSEgoKcmlza19zY29yZRgEIAEoBRISCgpwcml2aWxlZ2VkGAUgASgIEhYKDmV4cG9zdXJlX2xldmVsGAYgASgJEhMKC2NyaXRpY2FsaXR5GAcgASgJImAKEVNlY3VyaXR5R3JhcGhFZGdlEgoKAmlkGAEgASgJEhEKCXNvdXJjZV9pZBgCIAEoCRIRCgl0YXJnZXRfaWQYAyABKAkSGQoRcmVsYXRpb25zaGlwX3R5cGUYBCABKAkizAEKCkF0dGFja1BhdGgSCgoCaWQYASABKAkSDQoFdGl0bGUYAiABKAkSDQoFc2NvcmUYAyABKAUSFQoNZmluZGluZ190aXRsZRgEIAEoCRITCgtlbnRyeV9wb2ludBgFIAEoCRIOCgZ0YXJnZXQYBiABKAkSDQoFb3duZXIYByABKAkSFgoOZXhwb3N1cmVfbGV2ZWwYCCABKAkSEwoLY3JpdGljYWxpdHkYCSABKAkSDgoGcmVhc29uGAogASgJEgwKBHBhdGgYCyADKAkirAIKFERvbWFpbldpZGVEZWxlZ2F0aW9uEhYKDmludGVncmF0aW9uX2lkGAEgASgJEhAKCHByb3ZpZGVyGAIgASgJEhQKDGRpc3BsYXlfbmFtZRgDIAEoCRIYChB3b3Jrc3BhY2VfZG9tYWluGAQgASgJEiQKHHNlcnZpY2VfYWNjb3VudF9jbGllbnRfZW1haWwYBSABKAkSDgoGc2NvcGVzGAYgAygJEg4KBnN0YXR1cxgHIAEoCRIaChJpbnRlZ3JhdGlvbl9zdGF0dXMYCCABKAkSDAoEbW9kZRgJIAEoCRIdChVvcGVuX21haWxib3hfZmluZGluZ3MYCiABKAUSFAoMbGFzdF9zeW5jX2F0GAsgASgJEhUKDWNvbmZpZ3VyZWRfYXQYDCABKAkiOAocTGlzdEVtYWlsRG9tYWluSGVhbHRoUmVxdWVzdBIYChByZWZyZXNoX2lmX3N0YWxlGAEgASgIIksKHUxpc3RFbWFpbERvbWFpbkhlYWx0aFJlc3BvbnNlEioKBGRhdGEYASADKAsyHC5hcGVyaW8udjEuRW1haWxEb21haW5IZWFsdGgiLQobR2V0RW1haWxEb21haW5IZWFsdGhSZXF1ZXN0Eg4KBmRvbWFpbhgBIAEoCSJQChxHZXRFbWFpbERvbWFpbkhlYWx0aFJlc3BvbnNlEjAKBGRhdGEYASABKAsyIi5hcGVyaW8udjEuRW1haWxEb21haW5IZWFsdGhEZXRhaWwiMQofUmVmcmVzaEVtYWlsRG9tYWluSGVhbHRoUmVxdWVzdBIOCgZkb21haW4YASABKAkiTgogUmVmcmVzaEVtYWlsRG9tYWluSGVhbHRoUmVzcG9uc2USKgoEZGF0YRgBIAMoCzIcLmFwZXJpby52MS5FbWFpbERvbWFpbkhlYWx0aCLmAQoRRW1haWxEb21haW5IZWFsdGgSDgoGZG9tYWluGAEgASgJEhgKEHByb3ZpZGVyX3NvdXJjZXMYAiADKAkSDgoGc3RhdHVzGAMgASgJEg0KBXNjb3JlGAQgASgFEhIKCnNwZl9zdGF0dXMYBSABKAkSEwoLZGtpbV9zdGF0dXMYBiABKAkSFAoMZG1hcmNfc3RhdHVzGAcgASgJEhcKD2xhc3RfY2hlY2tlZF9hdBgIIAEoCRITCgtpc3N1ZV9jb3VudBgJIAEoBRIbChNmYWlsaW5nX2lzc3VlX2NvdW50GAogASgFIo0BChZFbWFpbERvbWFpbkhlYWx0aElzc3VlEgoKAmlkGAEgASgJEhAKCHByb3RvY29sGAIgASgJEhAKCHNldmVyaXR5GAMgASgJEgwKBGNvZGUYBCABKAkSDQoFdGl0bGUYBSABKAkSDgoGZGV0YWlsGAYgASgJEhYKDnJlY29tbWVuZGF0aW9uGAcgASgJIl0KF0VtYWlsRG9tYWluRGtpbVNlbGVjdG9yEhAKCHNlbGVjdG9yGAEgASgJEg4KBnN0YXR1cxgCIAEoCRIQCghrZXlfYml0cxgDIAEoBRIOCgZyZWNvcmQYBCABKAkiZwodRW1haWxEb21haW5IZWFsdGhIaXN0b3J5UG9pbnQSEgoKY2hlY2tlZF9hdBgBIAEoCRIOCgZzdGF0dXMYAiABKAkSDQoFc2NvcmUYAyABKAUSEwoLaXNzdWVfY291bnQYBCABKAUitAMKF0VtYWlsRG9tYWluSGVhbHRoRGV0YWlsEiwKBmRvbWFpbhgBIAEoCzIcLmFwZXJpby52MS5FbWFpbERvbWFpbkhlYWx0aBITCgtzcGZfcmVjb3JkcxgCIAMoCRISCgpzcGZfcG9saWN5GAMgASgJEhgKEHNwZl9sb29rdXBfY291bnQYBCABKAUSFQoNZG1hcmNfcmVjb3JkcxgFIAMoCRIUCgxkbWFyY19wb2xpY3kYBiABKAkSEQoJZG1hcmNfcGN0GAcgASgFEhEKCWRtYXJjX3J1YRgIIAMoCRISCgpteF9yZWNvcmRzGAkgAygJEjoKDmRraW1fc2VsZWN0b3JzGAogAygLMiIuYXBlcmlvLnYxLkVtYWlsRG9tYWluRGtpbVNlbGVjdG9yEhcKD3JlbGF0ZWRfcmVjb3JkcxgLIAMoCRIxCgZpc3N1ZXMYDCADKAsyIS5hcGVyaW8udjEuRW1haWxEb21haW5IZWFsdGhJc3N1ZRI5CgdoaXN0b3J5GA0gAygLMiguYXBlcmlvLnYxLkVtYWlsRG9tYWluSGVhbHRoSGlzdG9yeVBvaW50IlsKGUxpc3RTZWN1cml0eUFzc2V0c1JlcXVlc3QSDAoEdHlwZRgBIAEoCRIYChBvd25lcnNoaXBfc3RhdHVzGAIgASgJEhYKDmludGVncmF0aW9uX2lkGAMgASgJIkQKGkxpc3RTZWN1cml0eUFzc2V0c1Jlc3BvbnNlEiYKBGRhdGEYASADKAsyGC5hcGVyaW8udjEuU2VjdXJpdHlBc3NldCKnBAoNU2VjdXJpdHlBc3NldBIKCgJpZBgBIAEoCRIMCgR0eXBlGAIgASgJEhAKCHByb3ZpZGVyGAMgASgJEgwKBG5hbWUYBCABKAkSDwoHc3VtbWFyeRgFIAEoCRITCgtleHRlcm5hbF9pZBgGIAEoCRIOCgZsYWJlbHMYByADKAkSEwoLY3JpdGljYWxpdHkYCCABKAkSFgoOZXhwb3N1cmVfbGV2ZWwYCSABKAkSGAoQb3duZXJzaGlwX3N0YXR1cxgKIAEoCRIfChdjb250YWluc19zZW5zaXRpdmVfZGF0YRgLIAEoCBIVCg1pc19wcml2aWxlZ2VkGAwgASgIEhIKCnJpc2tfc2NvcmUYDSABKAUSGAoQbGFzdF9vYnNlcnZlZF9hdBgOIAEoCRISCgpjcmVhdGVkX2F0GA8gASgJEhIKCnVwZGF0ZWRfYXQYECABKAkSMgoLaW50ZWdyYXRpb24YESABKAsyHS5hcGVyaW8udjEuRmluZGluZ0ludGVncmF0aW9uEisKBW93bmVyGBIgASgLMhwuYXBlcmlvLnYxLlNlY3VyaXR5UHJpbmNpcGFsEjQKDmJ1c2luZXNzX293bmVyGBMgASgLMhwuYXBlcmlvLnYxLlNlY3VyaXR5UHJpbmNpcGFsEhoKEm9wZW5fZmluZGluZ19jb3VudBgUIAEoBRIeChZhY3RpdmVfZXhjZXB0aW9uX2NvdW50GBUgASgFIkQKEVNlY3VyaXR5UHJpbmNpcGFsEgoKAmlkGAEgASgJEg0KBWVtYWlsGAIgASgJEhQKDGRpc3BsYXlfbmFtZRgDIAEoCSL8AgoaQ3JlYXRlU2VjdXJpdHlBc3NldFJlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkSFQoNb3duZXJfdXNlcl9pZBgCIAEoCRIeChZidXNpbmVzc19vd25lcl91c2VyX2lkGAMgASgJEgwKBHR5cGUYBCABKAkSEAoIcHJvdmlkZXIYBSABKAkSDAoEbmFtZRgGIAEoCRIPCgdzdW1tYXJ5GAcgASgJEhMKC2V4dGVybmFsX2lkGAggASgJEg4KBmxhYmVscxgJIAMoCRITCgtjcml0aWNhbGl0eRgKIAEoCRIWCg5leHBvc3VyZV9sZXZlbBgLIAEoCRIYChBvd25lcnNoaXBfc3RhdHVzGAwgASgJEh8KF2NvbnRhaW5zX3NlbnNpdGl2ZV9kYXRhGA0gASgIEhUKDWlzX3ByaXZpbGVnZWQYDiABKAgSEgoKcmlza19zY29yZRgPIAEoBRIYChBsYXN0X29ic2VydmVkX2F0GBAgASgJIkUKG0NyZWF0ZVNlY3VyaXR5QXNzZXRSZXNwb25zZRImCgRkYXRhGAEgASgLMhguYXBlcmlvLnYxLlNlY3VyaXR5QXNzZXQi8AUKGlVwZGF0ZVNlY3VyaXR5QXNzZXRSZXF1ZXN0EgoKAmlkGAEgASgJEhsKDmludGVncmF0aW9uX2lkGAIgASgJSACIAQESGgoNb3duZXJfdXNlcl9pZBgDIAEoCUgBiAEBEiMKFmJ1c2luZXNzX293bmVyX3VzZXJfaWQYBCABKAlIAogBARIRCgR0eXBlGAUgASgJSAOIAQESFQoIcHJvdmlkZXIYBiABKAlIBIgBARIRCgRuYW1lGAcgASgJSAWIAQESFAoHc3VtbWFyeRgIIAEoCUgGiAEBEhgKC2V4dGVybmFsX2lkGAkgASgJSAeIAQESDgoGbGFiZWxzGAogAygJEhYKDmxhYmVsc19wcmVzZW50GAsgASgIEhgKC2NyaXRpY2FsaXR5GAwgASgJSAiIAQESGwoOZXhwb3N1cmVfbGV2ZWwYDSABKAlICYgBARIdChBvd25lcnNoaXBfc3RhdHVzGA4gASgJSAqIAQESJAoXY29udGFpbnNfc2Vuc2l0aXZlX2RhdGEYDyABKAhIC4gBARIaCg1pc19wcml2aWxlZ2VkGBAgASgISAyIAQESFwoKcmlza19zY29yZRgRIAEoBUgNiAEBEh0KEGxhc3Rfb2JzZXJ2ZWRfYXQYEiABKAlIDogBAUIRCg9faW50ZWdyYXRpb25faWRCEAoOX293bmVyX3VzZXJfaWRCGQoXX2J1c2luZXNzX293bmVyX3VzZXJfaWRCBwoFX3R5cGVCCwoJX3Byb3ZpZGVyQgcKBV9uYW1lQgoKCF9zdW1tYXJ5Qg4KDF9leHRlcm5hbF9pZEIOCgxfY3JpdGljYWxpdHlCEQoPX2V4cG9zdXJlX2xldmVsQhMKEV9vd25lcnNoaXBfc3RhdHVzQhoKGF9jb250YWluc19zZW5zaXRpdmVfZGF0YUIQCg5faXNfcHJpdmlsZWdlZEINCgtfcmlza19zY29yZUITChFfbGFzdF9vYnNlcnZlZF9hdCJFChtVcGRhdGVTZWN1cml0eUFzc2V0UmVzcG9uc2USJgoEZGF0YRgBIAEoCzIYLmFwZXJpby52MS5TZWN1cml0eUFzc2V0IhsKGUxpc3RSaXNrRXhjZXB0aW9uc1JlcXVlc3QiRAoaTGlzdFJpc2tFeGNlcHRpb25zUmVzcG9uc2USJgoEZGF0YRgBIAMoCzIYLmFwZXJpby52MS5SaXNrRXhjZXB0aW9uIoIDCg1SaXNrRXhjZXB0aW9uEgoKAmlkGAEgASgJEg0KBXRpdGxlGAIgASgJEhEKCXJhdGlvbmFsZRgDIAEoCRIdChVjb21wZW5zYXRpbmdfY29udHJvbHMYBCADKAkSDgoGc3RhdHVzGAUgASgJEhIKCmV4cGlyZXNfYXQYBiABKAkSEwoLYXBwcm92ZWRfYXQYByABKAkSEgoKY3JlYXRlZF9hdBgIIAEoCRISCgp1cGRhdGVkX2F0GAkgASgJEiwKBWFzc2V0GAogASgLMh0uYXBlcmlvLnYxLlJpc2tFeGNlcHRpb25Bc3NldBIwCgdmaW5kaW5nGAsgASgLMh8uYXBlcmlvLnYxLlJpc2tFeGNlcHRpb25GaW5kaW5nEjAKCmNyZWF0ZWRfYnkYDCABKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlQcmluY2lwYWwSMQoLYXBwcm92ZWRfYnkYDSABKAsyHC5hcGVyaW8udjEuU2VjdXJpdHlQcmluY2lwYWwiPAoSUmlza0V4Y2VwdGlvbkFzc2V0EgoKAmlkGAEgASgJEgwKBG5hbWUYAiABKAkSDAoEdHlwZRgDIAEoCSJTChRSaXNrRXhjZXB0aW9uRmluZGluZxIKCgJpZBgBIAEoCRINCgV0aXRsZRgCIAEoCRIQCghzZXZlcml0eRgDIAEoCRIOCgZzdGF0dXMYBCABKAkilwEKGkNyZWF0ZVJpc2tFeGNlcHRpb25SZXF1ZXN0EhAKCGFzc2V0X2lkGAEgASgJEhIKCmZpbmRpbmdfaWQYAiABKAkSDQoFdGl0bGUYAyABKAkSEQoJcmF0aW9uYWxlGAQgASgJEh0KFWNvbXBlbnNhdGluZ19jb250cm9scxgFIAMoCRISCgpleHBpcmVzX2F0GAYgASgJIkUKG0NyZWF0ZVJpc2tFeGNlcHRpb25SZXNwb25zZRImCgRkYXRhGAEgASgLMhguYXBlcmlvLnYxLlJpc2tFeGNlcHRpb24i+gEKGlVwZGF0ZVJpc2tFeGNlcHRpb25SZXF1ZXN0EgoKAmlkGAEgASgJEhIKBXRpdGxlGAIgASgJSACIAQESFgoJcmF0aW9uYWxlGAMgASgJSAGIAQESHQoVY29tcGVuc2F0aW5nX2NvbnRyb2xzGAQgAygJEiUKHWNvbXBlbnNhdGluZ19jb250cm9sc19wcmVzZW50GAUgASgIEhMKBnN0YXR1cxgGIAEoCUgCiAEBEhcKCmV4cGlyZXNfYXQYByABKAlIA4gBAUIICgZfdGl0bGVCDAoKX3JhdGlvbmFsZUIJCgdfc3RhdHVzQg0KC19leHBpcmVzX2F0IkUKG1VwZGF0ZVJpc2tFeGNlcHRpb25SZXNwb25zZRImCgRkYXRhGAEgASgLMhguYXBlcmlvLnYxLlJpc2tFeGNlcHRpb24i7QIKD0V4ZWN1dGl2ZVJlcG9ydBIKCgJpZBgBIAEoCRIOCgZwZXJpb2QYAiABKAkSFAoMcGVyaW9kX3N0YXJ0GAMgASgJEhIKCnBlcmlvZF9lbmQYBCABKAkSDQoFdGl0bGUYBSABKAkSDwoHc3VtbWFyeRgGIAEoCRIOCgZzdGF0dXMYByABKAkSGQoRa3BpX3NuYXBzaG90X2pzb24YCCABKAkSEAoIaGFzX2h0bWwYCSABKAgSDwoHaGFzX3BkZhgKIAEoCBIQCghodG1sX3VybBgLIAEoCRIPCgdwZGZfdXJsGAwgASgJEhIKCmNyZWF0ZWRfYXQYDSABKAkSEgoKdXBkYXRlZF9hdBgOIAEoCRIUCgxnZW5lcmF0ZWRfYXQYDyABKAkSFQoNZXJyb3JfbWVzc2FnZRgQIAEoCRIcChRyZXF1ZXN0ZWRfYnlfdXNlcl9pZBgRIAEoCRIQCgh0ZW1wbGF0ZRgSIAEoCSIdChtMaXN0RXhlY3V0aXZlUmVwb3J0c1JlcXVlc3QiSAocTGlzdEV4ZWN1dGl2ZVJlcG9ydHNSZXNwb25zZRIoCgRkYXRhGAEgAygLMhouYXBlcmlvLnYxLkV4ZWN1dGl2ZVJlcG9ydCInChlHZXRFeGVjdXRpdmVSZXBvcnRSZXF1ZXN0EgoKAmlkGAEgASgJIkYKGkdldEV4ZWN1dGl2ZVJlcG9ydFJlc3BvbnNlEigKBGRhdGEYASABKAsyGi5hcGVyaW8udjEuRXhlY3V0aXZlUmVwb3J0InkKHENyZWF0ZUV4ZWN1dGl2ZVJlcG9ydFJlcXVlc3QSDgoGcGVyaW9kGAEgASgJEg0KBXRpdGxlGAIgASgJEhQKDHBlcmlvZF9zdGFydBgDIAEoCRISCgpwZXJpb2RfZW5kGAQgASgJEhAKCHRlbXBsYXRlGAUgASgJIkkKHUNyZWF0ZUV4ZWN1dGl2ZVJlcG9ydFJlc3BvbnNlEigKBGRhdGEYASABKAsyGi5hcGVyaW8udjEuRXhlY3V0aXZlUmVwb3J0IioKHERlbGV0ZUV4ZWN1dGl2ZVJlcG9ydFJlcXVlc3QSCgoCaWQYASABKAkiMAodRGVsZXRlRXhlY3V0aXZlUmVwb3J0UmVzcG9uc2USDwoHZGVsZXRlZBgBIAEoCCKQAQoUQ29ubmVjdG9yQnVpbHRJblJ1bGUSCgoCaWQYASABKAkSEAoIcHJvdmlkZXIYAiABKAkSDQoFdGl0bGUYAyABKAkSEwoLZGVzY3JpcHRpb24YBCABKAkSEAoIc2V2ZXJpdHkYBSABKAkSEwoLZXZlbnRfdHlwZXMYBiADKAkSDwoHZW5hYmxlZBgHIAEoCCItChlMaXN0RGV0ZWN0aW9uUGFja3NSZXF1ZXN0EhAKCHByb3ZpZGVyGAEgASgJIkQKGkxpc3REZXRlY3Rpb25QYWNrc1Jlc3BvbnNlEiYKBGRhdGEYASADKAsyGC5hcGVyaW8udjEuRGV0ZWN0aW9uUGFjayKOAQoNRGV0ZWN0aW9uUGFjaxIKCgJpZBgBIAEoCRIQCghwcm92aWRlchgCIAEoCRIMCgRuYW1lGAMgASgJEhMKC2Rlc2NyaXB0aW9uGAQgASgJEg8KB3ZlcnNpb24YBSABKAkSKwoFcnVsZXMYBiADKAsyHC5hcGVyaW8udjEuRGV0ZWN0aW9uUGFja1J1bGUiogEKEURldGVjdGlvblBhY2tSdWxlEgoKAmlkGAEgASgJEg0KBXRpdGxlGAIgASgJEhMKC2Rlc2NyaXB0aW9uGAMgASgJEhAKCHNldmVyaXR5GAQgASgJEhMKC2V2ZW50X3R5cGVzGAUgAygJEhgKEG1pdHJlX3RlY2huaXF1ZXMYBiADKAkSDgoGaW50ZW50GAcgASgJEgwKBHRhZ3MYCCADKAkiqQEKE0Nvbm5lY3RvckN1c3RvbVJ1bGUSCgoCaWQYASABKAkSDAoEbmFtZRgCIAEoCRIQCghzZXZlcml0eRgDIAEoCRISCgpldmVudF90eXBlGAQgASgJEhYKDnByZWRpY2F0ZV9qc29uGAUgASgJEg8KB2VuYWJsZWQYBiABKAgSEgoKdXBkYXRlZF9hdBgHIAEoCRIVCg1zdWJqZWN0X2ZpZWxkGAggASgJIjMKGUxpc3RDb25uZWN0b3JSdWxlc1JlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkiqQEKGkxpc3RDb25uZWN0b3JSdWxlc1Jlc3BvbnNlEhYKDmludGVncmF0aW9uX2lkGAEgASgJEhAKCHByb3ZpZGVyGAIgASgJEjEKCGJ1aWx0X2luGAMgAygLMh8uYXBlcmlvLnYxLkNvbm5lY3RvckJ1aWx0SW5SdWxlEi4KBmN1c3RvbRgEIAMoCzIeLmFwZXJpby52MS5Db25uZWN0b3JDdXN0b21SdWxlIqUBChdDcmVhdGVDdXN0b21SdWxlUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCRIMCgRuYW1lGAIgASgJEhAKCHNldmVyaXR5GAMgASgJEhIKCmV2ZW50X3R5cGUYBCABKAkSFgoOcHJlZGljYXRlX2pzb24YBSABKAkSDwoHZW5hYmxlZBgGIAEoCBIVCg1zdWJqZWN0X2ZpZWxkGAcgASgJIiYKGENyZWF0ZUN1c3RvbVJ1bGVSZXNwb25zZRIKCgJpZBgBIAEoCSK2AQoXVXBkYXRlQ3VzdG9tUnVsZVJlcXVlc3QSFgoOaW50ZWdyYXRpb25faWQYASABKAkSDwoHcnVsZV9pZBgCIAEoCRIMCgRuYW1lGAMgASgJEhAKCHNldmVyaXR5GAQgASgJEhIKCmV2ZW50X3R5cGUYBSABKAkSFgoOcHJlZGljYXRlX2pzb24YBiABKAkSDwoHZW5hYmxlZBgHIAEoCBIVCg1zdWJqZWN0X2ZpZWxkGAggASgJIiYKGFVwZGF0ZUN1c3RvbVJ1bGVSZXNwb25zZRIKCgJpZBgBIAEoCSJCChdEZWxldGVDdXN0b21SdWxlUmVxdWVzdBIWCg5pbnRlZ3JhdGlvbl9pZBgBIAEoCRIPCgdydWxlX2lkGAIgASgJIiYKGERlbGV0ZUN1c3RvbVJ1bGVSZXNwb25zZRIKCgJpZBgBIAEoCTLLPgoNQXBlcmlvU2VydmljZRJACgdDYWxsQXBpEhkuYXBlcmlvLnYxLkNhbGxBcGlSZXF1ZXN0GhouYXBlcmlvLnYxLkNhbGxBcGlSZXNwb25zZRI9CgZTaWdudXASGC5hcGVyaW8udjEuU2lnbnVwUmVxdWVzdBoZLmFwZXJpby52MS5TaWdudXBSZXNwb25zZRI6CgVMb2dpbhIXLmFwZXJpby52MS5Mb2dpblJlcXVlc3QaGC5hcGVyaW8udjEuTG9naW5SZXNwb25zZRJeChFHZXRDdXJyZW50U2Vzc2lvbhIjLmFwZXJpby52MS5HZXRDdXJyZW50U2Vzc2lvblJlcXVlc3QaJC5hcGVyaW8udjEuR2V0Q3VycmVudFNlc3Npb25SZXNwb25zZRJnChRMb2dvdXRDdXJyZW50U2Vzc2lvbhImLmFwZXJpby52MS5Mb2dvdXRDdXJyZW50U2Vzc2lvblJlcXVlc3QaJy5hcGVyaW8udjEuTG9nb3V0Q3VycmVudFNlc3Npb25SZXNwb25zZRJVCg5MaXN0V29ya3NwYWNlcxIgLmFwZXJpby52MS5MaXN0V29ya3NwYWNlc1JlcXVlc3QaIS5hcGVyaW8udjEuTGlzdFdvcmtzcGFjZXNSZXNwb25zZRJYCg9Td2l0Y2hXb3Jrc3BhY2USIS5hcGVyaW8udjEuU3dpdGNoV29ya3NwYWNlUmVxdWVzdBoiLmFwZXJpby52MS5Td2l0Y2hXb3Jrc3BhY2VSZXNwb25zZRJnChRSZXF1ZXN0UGFzc3dvcmRSZXNldBImLmFwZXJpby52MS5SZXF1ZXN0UGFzc3dvcmRSZXNldFJlcXVlc3QaJy5hcGVyaW8udjEuUmVxdWVzdFBhc3N3b3JkUmVzZXRSZXNwb25zZRJSCg1SZXNldFBhc3N3b3JkEh8uYXBlcmlvLnYxLlJlc2V0UGFzc3dvcmRSZXF1ZXN0GiAuYXBlcmlvLnYxLlJlc2V0UGFzc3dvcmRSZXNwb25zZRJPCgxBY2NlcHRJbnZpdGUSHi5hcGVyaW8udjEuQWNjZXB0SW52aXRlUmVxdWVzdBofLmFwZXJpby52MS5BY2NlcHRJbnZpdGVSZXNwb25zZRJhChJCZWdpbk1mYUVucm9sbG1lbnQSJC5hcGVyaW8udjEuQmVnaW5NZmFFbnJvbGxtZW50UmVxdWVzdBolLmFwZXJpby52MS5CZWdpbk1mYUVucm9sbG1lbnRSZXNwb25zZRJGCglFbmFibGVNZmESGy5hcGVyaW8udjEuRW5hYmxlTWZhUmVxdWVzdBocLmFwZXJpby52MS5FbmFibGVNZmFSZXNwb25zZRJJCgpEaXNhYmxlTWZhEhwuYXBlcmlvLnYxLkRpc2FibGVNZmFSZXF1ZXN0Gh0uYXBlcmlvLnYxLkRpc2FibGVNZmFSZXNwb25zZRJMCgtDaGVja0hlYWx0aBIdLmFwZXJpby52MS5DaGVja0hlYWx0aFJlcXVlc3QaHi5hcGVyaW8udjEuQ2hlY2tIZWFsdGhSZXNwb25zZRJkChNHZXREYXNoYm9hcmRNZXRyaWNzEiUuYXBlcmlvLnYxLkdldERhc2hib2FyZE1ldHJpY3NSZXF1ZXN0GiYuYXBlcmlvLnYxLkdldERhc2hib2FyZE1ldHJpY3NSZXNwb25zZRJPCgxMaXN0RmluZGluZ3MSHi5hcGVyaW8udjEuTGlzdEZpbmRpbmdzUmVxdWVzdBofLmFwZXJpby52MS5MaXN0RmluZGluZ3NSZXNwb25zZRJJCgpHZXRGaW5kaW5nEhwuYXBlcmlvLnYxLkdldEZpbmRpbmdSZXF1ZXN0Gh0uYXBlcmlvLnYxLkdldEZpbmRpbmdSZXNwb25zZRJkChNVcGRhdGVGaW5kaW5nU3RhdHVzEiUuYXBlcmlvLnYxLlVwZGF0ZUZpbmRpbmdTdGF0dXNSZXF1ZXN0GiYuYXBlcmlvLnYxLlVwZGF0ZUZpbmRpbmdTdGF0dXNSZXNwb25zZRJbChBSZW1lZGlhdGVGaW5kaW5nEiIuYXBlcmlvLnYxLlJlbWVkaWF0ZUZpbmRpbmdSZXF1ZXN0GiMuYXBlcmlvLnYxLlJlbWVkaWF0ZUZpbmRpbmdSZXNwb25zZRJeChFMaXN0U2Fhc0luY2lkZW50cxIjLmFwZXJpby52MS5MaXN0U2Fhc0luY2lkZW50c1JlcXVlc3QaJC5hcGVyaW8udjEuTGlzdFNhYXNJbmNpZGVudHNSZXNwb25zZRJYCg9HZXRTYWFzSW5jaWRlbnQSIS5hcGVyaW8udjEuR2V0U2Fhc0luY2lkZW50UmVxdWVzdBoiLmFwZXJpby52MS5HZXRTYWFzSW5jaWRlbnRSZXNwb25zZRJhChJDcmVhdGVTYWFzSW5jaWRlbnQSJC5hcGVyaW8udjEuQ3JlYXRlU2Fhc0luY2lkZW50UmVxdWVzdBolLmFwZXJpby52MS5DcmVhdGVTYWFzSW5jaWRlbnRSZXNwb25zZRJzChhVcGRhdGVTYWFzSW5jaWRlbnRTdGF0dXMSKi5hcGVyaW8udjEuVXBkYXRlU2Fhc0luY2lkZW50U3RhdHVzUmVxdWVzdBorLmFwZXJpby52MS5VcGRhdGVTYWFzSW5jaWRlbnRTdGF0dXNSZXNwb25zZRJ2ChlQcm9wb3NlU2Fhc1Jlc3BvbnNlQWN0aW9uEisuYXBlcmlvLnYxLlByb3Bvc2VTYWFzUmVzcG9uc2VBY3Rpb25SZXF1ZXN0GiwuYXBlcmlvLnYxLlByb3Bvc2VTYWFzUmVzcG9uc2VBY3Rpb25SZXNwb25zZRJ2ChlBcHByb3ZlU2Fhc1Jlc3BvbnNlQWN0aW9uEisuYXBlcmlvLnYxLkFwcHJvdmVTYWFzUmVzcG9uc2VBY3Rpb25SZXF1ZXN0GiwuYXBlcmlvLnYxLkFwcHJvdmVTYWFzUmVzcG9uc2VBY3Rpb25SZXNwb25zZRJ2ChlFeGVjdXRlU2Fhc1Jlc3BvbnNlQWN0aW9uEisuYXBlcmlvLnYxLkV4ZWN1dGVTYWFzUmVzcG9uc2VBY3Rpb25SZXF1ZXN0GiwuYXBlcmlvLnYxLkV4ZWN1dGVTYWFzUmVzcG9uc2VBY3Rpb25SZXNwb25zZRJhChJMaXN0RGV0ZWN0aW9uUGFja3MSJC5hcGVyaW8udjEuTGlzdERldGVjdGlvblBhY2tzUmVxdWVzdBolLmFwZXJpby52MS5MaXN0RGV0ZWN0aW9uUGFja3NSZXNwb25zZRJnChRMaXN0Q29ubmVjdG9yQ2F0YWxvZxImLmFwZXJpby52MS5MaXN0Q29ubmVjdG9yQ2F0YWxvZ1JlcXVlc3QaJy5hcGVyaW8udjEuTGlzdENvbm5lY3RvckNhdGFsb2dSZXNwb25zZRJbChBMaXN0SW50ZWdyYXRpb25zEiIuYXBlcmlvLnYxLkxpc3RJbnRlZ3JhdGlvbnNSZXF1ZXN0GiMuYXBlcmlvLnYxLkxpc3RJbnRlZ3JhdGlvbnNSZXNwb25zZRJeChFDcmVhdGVJbnRlZ3JhdGlvbhIjLmFwZXJpby52MS5DcmVhdGVJbnRlZ3JhdGlvblJlcXVlc3QaJC5hcGVyaW8udjEuQ3JlYXRlSW50ZWdyYXRpb25SZXNwb25zZRJeChFEZWxldGVJbnRlZ3JhdGlvbhIjLmFwZXJpby52MS5EZWxldGVJbnRlZ3JhdGlvblJlcXVlc3QaJC5hcGVyaW8udjEuRGVsZXRlSW50ZWdyYXRpb25SZXNwb25zZRJnChRHZXRJbnRlZ3JhdGlvbkNoZWNrcxImLmFwZXJpby52MS5HZXRJbnRlZ3JhdGlvbkNoZWNrc1JlcXVlc3QaJy5hcGVyaW8udjEuR2V0SW50ZWdyYXRpb25DaGVja3NSZXNwb25zZRJwChdVcGRhdGVJbnRlZ3JhdGlvbkNoZWNrcxIpLmFwZXJpby52MS5VcGRhdGVJbnRlZ3JhdGlvbkNoZWNrc1JlcXVlc3QaKi5hcGVyaW8udjEuVXBkYXRlSW50ZWdyYXRpb25DaGVja3NSZXNwb25zZRJhChJMaXN0Q29ubmVjdG9yUnVsZXMSJC5hcGVyaW8udjEuTGlzdENvbm5lY3RvclJ1bGVzUmVxdWVzdBolLmFwZXJpby52MS5MaXN0Q29ubmVjdG9yUnVsZXNSZXNwb25zZRJbChBDcmVhdGVDdXN0b21SdWxlEiIuYXBlcmlvLnYxLkNyZWF0ZUN1c3RvbVJ1bGVSZXF1ZXN0GiMuYXBlcmlvLnYxLkNyZWF0ZUN1c3RvbVJ1bGVSZXNwb25zZRJbChBVcGRhdGVDdXN0b21SdWxlEiIuYXBlcmlvLnYxLlVwZGF0ZUN1c3RvbVJ1bGVSZXF1ZXN0GiMuYXBlcmlvLnYxLlVwZGF0ZUN1c3RvbVJ1bGVSZXNwb25zZRJbChBEZWxldGVDdXN0b21SdWxlEiIuYXBlcmlvLnYxLkRlbGV0ZUN1c3RvbVJ1bGVSZXF1ZXN0GiMuYXBlcmlvLnYxLkRlbGV0ZUN1c3RvbVJ1bGVSZXNwb25zZRJ5ChpHZXRHb29nbGVNYWlsYm94U2NhbkNvbmZpZxIsLmFwZXJpby52MS5HZXRHb29nbGVNYWlsYm94U2NhbkNvbmZpZ1JlcXVlc3QaLS5hcGVyaW8udjEuR2V0R29vZ2xlTWFpbGJveFNjYW5Db25maWdSZXNwb25zZRKCAQodVXBkYXRlR29vZ2xlTWFpbGJveFNjYW5Db25maWcSLy5hcGVyaW8udjEuVXBkYXRlR29vZ2xlTWFpbGJveFNjYW5Db25maWdSZXF1ZXN0GjAuYXBlcmlvLnYxLlVwZGF0ZUdvb2dsZU1haWxib3hTY2FuQ29uZmlnUmVzcG9uc2USiwEKIEdldEdvb2dsZVdvcmtzcGFjZUJpZ1F1ZXJ5Q29uZmlnEjIuYXBlcmlvLnYxLkdldEdvb2dsZVdvcmtzcGFjZUJpZ1F1ZXJ5Q29uZmlnUmVxdWVzdBozLmFwZXJpby52MS5HZXRHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZ1Jlc3BvbnNlEpQBCiNVcGRhdGVHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZxI1LmFwZXJpby52MS5VcGRhdGVHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZ1JlcXVlc3QaNi5hcGVyaW8udjEuVXBkYXRlR29vZ2xlV29ya3NwYWNlQmlnUXVlcnlDb25maWdSZXNwb25zZRKaAQolVmFsaWRhdGVHb29nbGVXb3Jrc3BhY2VCaWdRdWVyeUNvbmZpZxI3LmFwZXJpby52MS5WYWxpZGF0ZUdvb2dsZVdvcmtzcGFjZUJpZ1F1ZXJ5Q29uZmlnUmVxdWVzdBo4LmFwZXJpby52MS5WYWxpZGF0ZUdvb2dsZVdvcmtzcGFjZUJpZ1F1ZXJ5Q29uZmlnUmVzcG9uc2USdgoZU3RhcnRHb29nbGVXb3Jrc3BhY2VPQXV0aBIrLmFwZXJpby52MS5TdGFydEdvb2dsZVdvcmtzcGFjZU9BdXRoUmVxdWVzdBosLmFwZXJpby52MS5TdGFydEdvb2dsZVdvcmtzcGFjZU9BdXRoUmVzcG9uc2USdgoZR2V0SW50ZWdyYXRpb25PQXV0aENsaWVudBIrLmFwZXJpby52MS5HZXRJbnRlZ3JhdGlvbk9BdXRoQ2xpZW50UmVxdWVzdBosLmFwZXJpby52MS5HZXRJbnRlZ3JhdGlvbk9BdXRoQ2xpZW50UmVzcG9uc2USdgoZU2V0SW50ZWdyYXRpb25PQXV0aENsaWVudBIrLmFwZXJpby52MS5TZXRJbnRlZ3JhdGlvbk9BdXRoQ2xpZW50UmVxdWVzdBosLmFwZXJpby52MS5TZXRJbnRlZ3JhdGlvbk9BdXRoQ2xpZW50UmVzcG9uc2USfAobQ2xlYXJJbnRlZ3JhdGlvbk9BdXRoQ2xpZW50Ei0uYXBlcmlvLnYxLkNsZWFySW50ZWdyYXRpb25PQXV0aENsaWVudFJlcXVlc3QaLi5hcGVyaW8udjEuQ2xlYXJJbnRlZ3JhdGlvbk9BdXRoQ2xpZW50UmVzcG9uc2USZwoURm9yY2VTeW5jSW50ZWdyYXRpb24SJi5hcGVyaW8udjEuRm9yY2VTeW5jSW50ZWdyYXRpb25SZXF1ZXN0GicuYXBlcmlvLnYxLkZvcmNlU3luY0ludGVncmF0aW9uUmVzcG9uc2UScwoYR2V0SW50ZWdyYXRpb25TeW5jU3RhdHVzEiouYXBlcmlvLnYxLkdldEludGVncmF0aW9uU3luY1N0YXR1c1JlcXVlc3QaKy5hcGVyaW8udjEuR2V0SW50ZWdyYXRpb25TeW5jU3RhdHVzUmVzcG9uc2UScwoYUnVuSW50ZWdyYXRpb25Tb3VyY2VTeW5jEiouYXBlcmlvLnYxLlJ1bkludGVncmF0aW9uU291cmNlU3luY1JlcXVlc3QaKy5hcGVyaW8udjEuUnVuSW50ZWdyYXRpb25Tb3VyY2VTeW5jUmVzcG9uc2USdgoZQmFja2ZpbGxJbnRlZ3JhdGlvblNvdXJjZRIrLmFwZXJpby52MS5CYWNrZmlsbEludGVncmF0aW9uU291cmNlUmVxdWVzdBosLmFwZXJpby52MS5CYWNrZmlsbEludGVncmF0aW9uU291cmNlUmVzcG9uc2USWAoPTGlzdFNpZW1DYXRhbG9nEiEuYXBlcmlvLnYxLkxpc3RTaWVtQ2F0YWxvZ1JlcXVlc3QaIi5hcGVyaW8udjEuTGlzdFNpZW1DYXRhbG9nUmVzcG9uc2USZwoUTGlzdFNpZW1EZXN0aW5hdGlvbnMSJi5hcGVyaW8udjEuTGlzdFNpZW1EZXN0aW5hdGlvbnNSZXF1ZXN0GicuYXBlcmlvLnYxLkxpc3RTaWVtRGVzdGluYXRpb25zUmVzcG9uc2USagoVQ3JlYXRlU2llbURlc3RpbmF0aW9uEicuYXBlcmlvLnYxLkNyZWF0ZVNpZW1EZXN0aW5hdGlvblJlcXVlc3QaKC5hcGVyaW8udjEuQ3JlYXRlU2llbURlc3RpbmF0aW9uUmVzcG9uc2USagoVRGVsZXRlU2llbURlc3RpbmF0aW9uEicuYXBlcmlvLnYxLkRlbGV0ZVNpZW1EZXN0aW5hdGlvblJlcXVlc3QaKC5hcGVyaW8udjEuRGVsZXRlU2llbURlc3RpbmF0aW9uUmVzcG9uc2USZAoTVGVzdFNpZW1EZXN0aW5hdGlvbhIlLmFwZXJpby52MS5UZXN0U2llbURlc3RpbmF0aW9uUmVxdWVzdBomLmFwZXJpby52MS5UZXN0U2llbURlc3RpbmF0aW9uUmVzcG9uc2USagoVTGlzdFNoYWRvd0l0T2F1dGhBcHBzEicuYXBlcmlvLnYxLkxpc3RTaGFkb3dJdE9hdXRoQXBwc1JlcXVlc3QaKC5hcGVyaW8udjEuTGlzdFNoYWRvd0l0T2F1dGhBcHBzUmVzcG9uc2USeQoaTGlzdFNoYWRvd0l0T2F1dGhBcHBHcmFudHMSLC5hcGVyaW8udjEuTGlzdFNoYWRvd0l0T2F1dGhBcHBHcmFudHNSZXF1ZXN0Gi0uYXBlcmlvLnYxLkxpc3RTaGFkb3dJdE9hdXRoQXBwR3JhbnRzUmVzcG9uc2USXgoRR2V0VGVuYW50U2V0dGluZ3MSIy5hcGVyaW8udjEuR2V0VGVuYW50U2V0dGluZ3NSZXF1ZXN0GiQuYXBlcmlvLnYxLkdldFRlbmFudFNldHRpbmdzUmVzcG9uc2USZwoUVXBkYXRlVGVuYW50U2V0dGluZ3MSJi5hcGVyaW8udjEuVXBkYXRlVGVuYW50U2V0dGluZ3NSZXF1ZXN0GicuYXBlcmlvLnYxLlVwZGF0ZVRlbmFudFNldHRpbmdzUmVzcG9uc2USXgoRTGlzdFRlbmFudE1lbWJlcnMSIy5hcGVyaW8udjEuTGlzdFRlbmFudE1lbWJlcnNSZXF1ZXN0GiQuYXBlcmlvLnYxLkxpc3RUZW5hbnRNZW1iZXJzUmVzcG9uc2USYQoSQ3JlYXRlVGVuYW50TWVtYmVyEiQuYXBlcmlvLnYxLkNyZWF0ZVRlbmFudE1lbWJlclJlcXVlc3QaJS5hcGVyaW8udjEuQ3JlYXRlVGVuYW50TWVtYmVyUmVzcG9uc2USagoVQ3JlYXRlTWVtYmVyUmVzZXRMaW5rEicuYXBlcmlvLnYxLkNyZWF0ZU1lbWJlclJlc2V0TGlua1JlcXVlc3QaKC5hcGVyaW8udjEuQ3JlYXRlTWVtYmVyUmVzZXRMaW5rUmVzcG9uc2USWwoQVXBkYXRlTWVtYmVyUm9sZRIiLmFwZXJpby52MS5VcGRhdGVNZW1iZXJSb2xlUmVxdWVzdBojLmFwZXJpby52MS5VcGRhdGVNZW1iZXJSb2xlUmVzcG9uc2USUgoNTGlzdEF1ZGl0TG9ncxIfLmFwZXJpby52MS5MaXN0QXVkaXRMb2dzUmVxdWVzdBogLmFwZXJpby52MS5MaXN0QXVkaXRMb2dzUmVzcG9uc2USZAoTR2V0U2VjdXJpdHlPdmVydmlldxIlLmFwZXJpby52MS5HZXRTZWN1cml0eU92ZXJ2aWV3UmVxdWVzdBomLmFwZXJpby52MS5HZXRTZWN1cml0eU92ZXJ2aWV3UmVzcG9uc2USagoVTGlzdEVtYWlsRG9tYWluSGVhbHRoEicuYXBlcmlvLnYxLkxpc3RFbWFpbERvbWFpbkhlYWx0aFJlcXVlc3QaKC5hcGVyaW8udjEuTGlzdEVtYWlsRG9tYWluSGVhbHRoUmVzcG9uc2USZwoUR2V0RW1haWxEb21haW5IZWFsdGgSJi5hcGVyaW8udjEuR2V0RW1haWxEb21haW5IZWFsdGhSZXF1ZXN0GicuYXBlcmlvLnYxLkdldEVtYWlsRG9tYWluSGVhbHRoUmVzcG9uc2UScwoYUmVmcmVzaEVtYWlsRG9tYWluSGVhbHRoEiouYXBlcmlvLnYxLlJlZnJlc2hFbWFpbERvbWFpbkhlYWx0aFJlcXVlc3QaKy5hcGVyaW8udjEuUmVmcmVzaEVtYWlsRG9tYWluSGVhbHRoUmVzcG9uc2USYQoSTGlzdFNlY3VyaXR5QXNzZXRzEiQuYXBlcmlvLnYxLkxpc3RTZWN1cml0eUFzc2V0c1JlcXVlc3QaJS5hcGVyaW8udjEuTGlzdFNlY3VyaXR5QXNzZXRzUmVzcG9uc2USZAoTQ3JlYXRlU2VjdXJpdHlBc3NldBIlLmFwZXJpby52MS5DcmVhdGVTZWN1cml0eUFzc2V0UmVxdWVzdBomLmFwZXJpby52MS5DcmVhdGVTZWN1cml0eUFzc2V0UmVzcG9uc2USZAoTVXBkYXRlU2VjdXJpdHlBc3NldBIlLmFwZXJpby52MS5VcGRhdGVTZWN1cml0eUFzc2V0UmVxdWVzdBomLmFwZXJpby52MS5VcGRhdGVTZWN1cml0eUFzc2V0UmVzcG9uc2USYQoSTGlzdFJpc2tFeGNlcHRpb25zEiQuYXBlcmlvLnYxLkxpc3RSaXNrRXhjZXB0aW9uc1JlcXVlc3QaJS5hcGVyaW8udjEuTGlzdFJpc2tFeGNlcHRpb25zUmVzcG9uc2USZAoTQ3JlYXRlUmlza0V4Y2VwdGlvbhIlLmFwZXJpby52MS5DcmVhdGVSaXNrRXhjZXB0aW9uUmVxdWVzdBomLmFwZXJpby52MS5DcmVhdGVSaXNrRXhjZXB0aW9uUmVzcG9uc2USZAoTVXBkYXRlUmlza0V4Y2VwdGlvbhIlLmFwZXJpby52MS5VcGRhdGVSaXNrRXhjZXB0aW9uUmVxdWVzdBomLmFwZXJpby52MS5VcGRhdGVSaXNrRXhjZXB0aW9uUmVzcG9uc2USZwoUTGlzdEV4ZWN1dGl2ZVJlcG9ydHMSJi5hcGVyaW8udjEuTGlzdEV4ZWN1dGl2ZVJlcG9ydHNSZXF1ZXN0GicuYXBlcmlvLnYxLkxpc3RFeGVjdXRpdmVSZXBvcnRzUmVzcG9uc2USYQoSR2V0RXhlY3V0aXZlUmVwb3J0EiQuYXBlcmlvLnYxLkdldEV4ZWN1dGl2ZVJlcG9ydFJlcXVlc3QaJS5hcGVyaW8udjEuR2V0RXhlY3V0aXZlUmVwb3J0UmVzcG9uc2USagoVQ3JlYXRlRXhlY3V0aXZlUmVwb3J0EicuYXBlcmlvLnYxLkNyZWF0ZUV4ZWN1dGl2ZVJlcG9ydFJlcXVlc3QaKC5hcGVyaW8udjEuQ3JlYXRlRXhlY3V0aXZlUmVwb3J0UmVzcG9uc2USagoVRGVsZXRlRXhlY3V0aXZlUmVwb3J0EicuYXBlcmlvLnYxLkRlbGV0ZUV4ZWN1dGl2ZVJlcG9ydFJlcXVlc3QaKC5hcGVyaW8udjEuRGVsZXRlRXhlY3V0aXZlUmVwb3J0UmVzcG9uc2VCMVovZ2l0aHViLmNvbS93cml0ZXIvYXBlcmlvL2dlbi9hcGVyaW8vdjE7YXBlcmlvdjFiBnByb3RvMw", [file_google_protobuf_timestamp]); /** * @generated from message aperio.v1.CallApiRequest @@ -6955,6 +6955,136 @@ export type ConnectorBuiltInRule = Message<"aperio.v1.ConnectorBuiltInRule"> & { export const ConnectorBuiltInRuleSchema: GenMessage = /*@__PURE__*/ messageDesc(file_aperio_v1_api, 223); +/** + * @generated from message aperio.v1.ListDetectionPacksRequest + */ +export type ListDetectionPacksRequest = Message<"aperio.v1.ListDetectionPacksRequest"> & { + /** + * Optional provider filter (e.g. "GOOGLE_WORKSPACE"). Empty returns every pack. + * + * @generated from field: string provider = 1; + */ + provider: string; +}; + +/** + * Describes the message aperio.v1.ListDetectionPacksRequest. + * Use `create(ListDetectionPacksRequestSchema)` to create a new message. + */ +export const ListDetectionPacksRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_aperio_v1_api, 224); + +/** + * @generated from message aperio.v1.ListDetectionPacksResponse + */ +export type ListDetectionPacksResponse = Message<"aperio.v1.ListDetectionPacksResponse"> & { + /** + * @generated from field: repeated aperio.v1.DetectionPack data = 1; + */ + data: DetectionPack[]; +}; + +/** + * Describes the message aperio.v1.ListDetectionPacksResponse. + * Use `create(ListDetectionPacksResponseSchema)` to create a new message. + */ +export const ListDetectionPacksResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_aperio_v1_api, 225); + +/** + * @generated from message aperio.v1.DetectionPack + */ +export type DetectionPack = Message<"aperio.v1.DetectionPack"> & { + /** + * @generated from field: string id = 1; + */ + id: string; + + /** + * @generated from field: string provider = 2; + */ + provider: string; + + /** + * @generated from field: string name = 3; + */ + name: string; + + /** + * @generated from field: string description = 4; + */ + description: string; + + /** + * @generated from field: string version = 5; + */ + version: string; + + /** + * @generated from field: repeated aperio.v1.DetectionPackRule rules = 6; + */ + rules: DetectionPackRule[]; +}; + +/** + * Describes the message aperio.v1.DetectionPack. + * Use `create(DetectionPackSchema)` to create a new message. + */ +export const DetectionPackSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_aperio_v1_api, 226); + +/** + * @generated from message aperio.v1.DetectionPackRule + */ +export type DetectionPackRule = Message<"aperio.v1.DetectionPackRule"> & { + /** + * @generated from field: string id = 1; + */ + id: string; + + /** + * @generated from field: string title = 2; + */ + title: string; + + /** + * @generated from field: string description = 3; + */ + description: string; + + /** + * @generated from field: string severity = 4; + */ + severity: string; + + /** + * @generated from field: repeated string event_types = 5; + */ + eventTypes: string[]; + + /** + * @generated from field: repeated string mitre_techniques = 6; + */ + mitreTechniques: string[]; + + /** + * @generated from field: string intent = 7; + */ + intent: string; + + /** + * @generated from field: repeated string tags = 8; + */ + tags: string[]; +}; + +/** + * Describes the message aperio.v1.DetectionPackRule. + * Use `create(DetectionPackRuleSchema)` to create a new message. + */ +export const DetectionPackRuleSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_aperio_v1_api, 227); + /** * @generated from message aperio.v1.ConnectorCustomRule */ @@ -7005,7 +7135,7 @@ export type ConnectorCustomRule = Message<"aperio.v1.ConnectorCustomRule"> & { * Use `create(ConnectorCustomRuleSchema)` to create a new message. */ export const ConnectorCustomRuleSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_aperio_v1_api, 224); + messageDesc(file_aperio_v1_api, 228); /** * @generated from message aperio.v1.ListConnectorRulesRequest @@ -7022,7 +7152,7 @@ export type ListConnectorRulesRequest = Message<"aperio.v1.ListConnectorRulesReq * Use `create(ListConnectorRulesRequestSchema)` to create a new message. */ export const ListConnectorRulesRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_aperio_v1_api, 225); + messageDesc(file_aperio_v1_api, 229); /** * @generated from message aperio.v1.ListConnectorRulesResponse @@ -7054,7 +7184,7 @@ export type ListConnectorRulesResponse = Message<"aperio.v1.ListConnectorRulesRe * Use `create(ListConnectorRulesResponseSchema)` to create a new message. */ export const ListConnectorRulesResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_aperio_v1_api, 226); + messageDesc(file_aperio_v1_api, 230); /** * @generated from message aperio.v1.CreateCustomRuleRequest @@ -7101,7 +7231,7 @@ export type CreateCustomRuleRequest = Message<"aperio.v1.CreateCustomRuleRequest * Use `create(CreateCustomRuleRequestSchema)` to create a new message. */ export const CreateCustomRuleRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_aperio_v1_api, 227); + messageDesc(file_aperio_v1_api, 231); /** * @generated from message aperio.v1.CreateCustomRuleResponse @@ -7118,7 +7248,7 @@ export type CreateCustomRuleResponse = Message<"aperio.v1.CreateCustomRuleRespon * Use `create(CreateCustomRuleResponseSchema)` to create a new message. */ export const CreateCustomRuleResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_aperio_v1_api, 228); + messageDesc(file_aperio_v1_api, 232); /** * @generated from message aperio.v1.UpdateCustomRuleRequest @@ -7170,7 +7300,7 @@ export type UpdateCustomRuleRequest = Message<"aperio.v1.UpdateCustomRuleRequest * Use `create(UpdateCustomRuleRequestSchema)` to create a new message. */ export const UpdateCustomRuleRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_aperio_v1_api, 229); + messageDesc(file_aperio_v1_api, 233); /** * @generated from message aperio.v1.UpdateCustomRuleResponse @@ -7187,7 +7317,7 @@ export type UpdateCustomRuleResponse = Message<"aperio.v1.UpdateCustomRuleRespon * Use `create(UpdateCustomRuleResponseSchema)` to create a new message. */ export const UpdateCustomRuleResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_aperio_v1_api, 230); + messageDesc(file_aperio_v1_api, 234); /** * @generated from message aperio.v1.DeleteCustomRuleRequest @@ -7209,7 +7339,7 @@ export type DeleteCustomRuleRequest = Message<"aperio.v1.DeleteCustomRuleRequest * Use `create(DeleteCustomRuleRequestSchema)` to create a new message. */ export const DeleteCustomRuleRequestSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_aperio_v1_api, 231); + messageDesc(file_aperio_v1_api, 235); /** * @generated from message aperio.v1.DeleteCustomRuleResponse @@ -7226,7 +7356,7 @@ export type DeleteCustomRuleResponse = Message<"aperio.v1.DeleteCustomRuleRespon * Use `create(DeleteCustomRuleResponseSchema)` to create a new message. */ export const DeleteCustomRuleResponseSchema: GenMessage = /*@__PURE__*/ - messageDesc(file_aperio_v1_api, 232); + messageDesc(file_aperio_v1_api, 236); /** * @generated from service aperio.v1.AperioService @@ -7440,6 +7570,14 @@ export const AperioService: GenService<{ input: typeof ExecuteSaasResponseActionRequestSchema; output: typeof ExecuteSaasResponseActionResponseSchema; }, + /** + * @generated from rpc aperio.v1.AperioService.ListDetectionPacks + */ + listDetectionPacks: { + methodKind: "unary"; + input: typeof ListDetectionPacksRequestSchema; + output: typeof ListDetectionPacksResponseSchema; + }, /** * @generated from rpc aperio.v1.AperioService.ListConnectorCatalog */ diff --git a/proto/aperio/v1/api.proto b/proto/aperio/v1/api.proto index 8e0b5f6e..d13fed23 100644 --- a/proto/aperio/v1/api.proto +++ b/proto/aperio/v1/api.proto @@ -33,6 +33,7 @@ service AperioService { rpc ProposeSaasResponseAction(ProposeSaasResponseActionRequest) returns (ProposeSaasResponseActionResponse); rpc ApproveSaasResponseAction(ApproveSaasResponseActionRequest) returns (ApproveSaasResponseActionResponse); rpc ExecuteSaasResponseAction(ExecuteSaasResponseActionRequest) returns (ExecuteSaasResponseActionResponse); + rpc ListDetectionPacks(ListDetectionPacksRequest) returns (ListDetectionPacksResponse); rpc ListConnectorCatalog(ListConnectorCatalogRequest) returns (ListConnectorCatalogResponse); rpc ListIntegrations(ListIntegrationsRequest) returns (ListIntegrationsResponse); rpc CreateIntegration(CreateIntegrationRequest) returns (CreateIntegrationResponse); @@ -1595,6 +1596,35 @@ message ConnectorBuiltInRule { bool enabled = 7; } +message ListDetectionPacksRequest { + // Optional provider filter (e.g. "GOOGLE_WORKSPACE"). Empty returns every pack. + string provider = 1; +} + +message ListDetectionPacksResponse { + repeated DetectionPack data = 1; +} + +message DetectionPack { + string id = 1; + string provider = 2; + string name = 3; + string description = 4; + string version = 5; + repeated DetectionPackRule rules = 6; +} + +message DetectionPackRule { + string id = 1; + string title = 2; + string description = 3; + string severity = 4; + repeated string event_types = 5; + repeated string mitre_techniques = 6; + string intent = 7; + repeated string tags = 8; +} + message ConnectorCustomRule { string id = 1; string name = 2; diff --git a/tests/fe-contracts.test.ts b/tests/fe-contracts.test.ts index f13bffc8..8def0885 100644 --- a/tests/fe-contracts.test.ts +++ b/tests/fe-contracts.test.ts @@ -58,7 +58,8 @@ test("frontend-consumed AperioService RPC inventory is implemented and wrapped", readRepoFile("internal/bootstrap/app.go"), readRepoFile("internal/bootstrap/typed_compat.go"), readRepoFile("internal/bootstrap/saas_dr.go"), - readRepoFile("internal/bootstrap/oauth_clients.go") + readRepoFile("internal/bootstrap/oauth_clients.go"), + readRepoFile("internal/bootstrap/detection_packs.go") ].join("\n"); const rpcs = serviceRpcNames(proto); @@ -115,6 +116,7 @@ test("React-facing API exports cover typed product RPCs without exposing CallApi ProposeSaasResponseAction: "proposeSaasResponseAction", ApproveSaasResponseAction: "approveSaasResponseAction", ExecuteSaasResponseAction: "executeSaasResponseAction", + ListDetectionPacks: "fetchDetectionPacks", ListConnectorCatalog: "fetchConnectorCatalog", ListIntegrations: "fetchIntegrations", CreateIntegration: "connectIntegration",